この記事で扱っていること
- 簡単なログイン画面を作る方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
作りたいプログラムによっては、ユーザーごとに異なる設定を持たせるために、どのユーザーがそのプログラムを使用するかの場合分けを行う場面があると思います。
そんなときに、ユーザーの認証を行うためのログイン画面があると便利です。
この記事では、あらかじめ登録されたユーザー名とパスワードと照合してログイン操作を行わせるための仕組みの簡単な実装例を紹介しています。
ログインが終わったらそのユーザー名を元に特定のiniファイルを読ませて初期設定を行う、などといったことも可能になります。
どんな結果になるか
フロントパネルはいたってシンプルにしていて、ユーザー名とパスワードを表示させるようにしています。また、新規で登録を行う機能も付けています。
プログラムを実行し、ユーザー名とパスワードを入力して認証ボタンを押すと認証操作が行われ、もしユーザー名とパスワード両方共が登録があるのなら認証成功、パスワードが違う場合やユーザー名も違う場合などで異なるメッセージを出すようにしています。
プログラムの構造
デザインパターンは、この手のプログラムではお決まりの、イベント駆動型ステートマシンとしています。
簡単に実装するという目的なので、ローカル変数をいくつか用いています。本来ローカル変数はメモリのコピーを増やしたりプログラムのフロー(ワイヤ配線で実行順序を制御するLabVIEW特有の書き方)に反するので、フロントパネルの制御器等の初期化以外には推奨されませんが、パフォーマンスを気にしないような場合においては設計にあまり時間をかけなくてもプログラムが書けるというメリット(?)があります。
この記事の後半で、ローカル変数を使用しないバージョンも紹介します。
では、それぞれのステートを見ていきます。
まずはinitializeステートです。ログイン情報が含まれたファイルを読み込んだりフロントパネルの制御器の初期化を行います。
もしこのプログラムを動かすのが初めてで、ログイン情報が含まれたファイルがまだない場合には「区切られたスプレッドシートを読み取る」関数でエラーが起こりますが、自動エラー処理を無効にしていればそのままプログラムは進むので無視します。
次にwait for eventステートです。ここで、フロントパネル上の操作によって次にどのステートに移動するかが決まります。
各イベントはとてもシンプルで、フロントパネルのブール制御器の値変更イベントのみにしています。
必要に応じて、「パネルを閉じる?」のイベントを追加してもいいと思います。
次はinfo checkステートです。フロントパネル上でユーザー名やパスワードが入力されたものに対して、登録された情報と照合し、一致する文字列があるかどうかで判定しています。
情報を登録する際には、ユーザー名とパスワードがセットで1行となり、このセットが列方向に複数あるといった2次元配列の形式となります。
そのため、ユーザー名の情報が並ぶ2次元配列の1列目(配列指標だと0列目)の中から、フロントパネル上のユーザー名入力と一致したものがあるかを探し、もしあればそれがこの1列目の配列の何番目だったかを取得し、この値を次のパスワードとの照合に使用しています。
照合の結果によって、それが合っていたか間違っていたかなどのメッセージを出すのですが、それはmessageステートで行います。
次にregisterステートです。新規登録するための処理を書いています。登録情報はregistered infoという2次元配列でまとめているので、この2次元配列をそのまま「区切られたスプレッドシートに書き込む」の関数に配線するだけです。
ファイル形式は別に何でもいいのですが、今回はcsvファイルとしています。なので、「区切られたスプレッドシートに書き込む」にはデリミタとして「カンマ」を指定しています。
次はmessageステートです。入力したユーザー名とパスワードの組み合わせがどうだったのかの結果をメッセージとして表示するようにしています。
このステートは、このプログラムでは認証ボタンを押した場合でないと進まず、認証が成功すればプログラム自体を終了させますし、認証に失敗したら再びwait for eventとなります。
認証が成功するというのはinfo checkステートにおいてユーザー名とパスワードが一致して「認証しました」という文字列がシフトレジスタで渡されたときのみなので、これを条件にfinishステートに移行するかどうかを決めています。
次はcancelステートです。キャンセルボタンが押された時に実行され、キャンセルフラグをTRUEにします。このフラグをコネクタペーンに設定すれば、例えばこのプログラムをサブVIとして使用したときに、メインVIに「ログインの操作がキャンセルされた」ということを伝えることができます。
最後はfinishステートです。認証終了後にプログラムを終了します。
これで簡単なログイン画面が実装できます。
新規登録した情報の確認画面を表示させる
上のプログラムでログイン操作はできるのですが、新規でログイン情報を作成して新規ボタンを押しても、特に反応はしません。
実際はちゃんと登録されているのですが、ボタンを押しても無反応、だと本当に登録されたかわからないですよね。
なので、ちゃんと登録されたことを示す機能を追加することを考えます。また、ついでに、もし既に同じユーザー名あるいはパスワードが使われている場合には新規登録ができないような仕組みも実装します。
ステートマシンでは機能拡張が容易にできるので、以下のステートを追加することで新規登録についてのメッセージを出すことができるようになります。(ステート追加に伴って、ステートマシンで使われているタイプ定義された列挙体を編集する必要があります)
ローカル変数を使用しない場合
では最後に、ローカル変数を使用しないでプログラムを書く場合の例を紹介します。
元々ローカル変数を使用していた理由としては、複数のステートをまたいで、ユーザー名やパスワードの制御器の値を読み取る必要があるためでした。
なので、このユーザー名とパスワードの値を読み取るというステート(frontpanelcheck)を新たに設けてそこから各処理に移ればいいことになります。
ただし、「各処理」とは、認証処理かあるいは新規登録処理の2種類があり、frontpanelcheckのステートの後にどちらのステートに移るかの判断をどのようにさせるか考える必要があります。
ここでは、配列を用いた変則型ステートマシンでの実装例を紹介します。配列を用いる事で、特定の順番で処理を行うという順番付けをイベントストラクチャの方で設けることができます。
各ステートは、上で紹介したものと同じ部分の説明は割愛します。
initializeステートでは、VIサーバーリファレンスを使用してインボークノードで「デフォルト値」「すべてをデフォルトに戻す」をすることによって、制御器の初期化を行っています。
上で紹介したプログラムになかったクラスタとして、ユーザー名とパスワードをセットにしたクラスタ(FP infoのワイヤをあてています)を用意しています。
wait for eventステートは以下の通りです。
認証ボタンを押した際に、frontpanelcheck、info checkの順でステートが実行されるようにするといった、複数のステートの順番を指定することができるのがこの変則ステートマシンの特長です。
frontpanelcheckのステートでは、フロントパネル上のユーザー名とパスワードを読み取って、この後のステートでこれらを読み取るようにします。
info checkステートです。frontpanelcheckステートで読み取った値に対して認証操作を行います。
なお、Falseケースは上で紹介したプログラムと同じ内容です。
次はregisterステートです。ここでは、新規作成した後に確認の画面を出していませんが、確認画面を出すようにするには、「新規登録した情報の確認画面を表示させる」の項目の内容を参考にしてみてください。
messageステートです。
cancelステートです。
最後にfinishステートです。
結局各ステートの中の処理は一番最初に紹介したプログラムとほぼ同じですが、フロントパネルの情報を読み取るfrontpanelcheckのステートをかますことでローカル変数の使用を回避するようにしました。
同じようなプログラムは、配列の代わりにキューを使用しても組めます。
本記事では簡単なログイン画面を作る方法を紹介しました。
ファイル読み込みを伴う操作で、ステートマシンを用いてファイルの中身の情報をシフトレジスタで各ステートに渡す手法はよく使いますが、その代表的な実装方法が今回の記事で紹介したプログラムのようなやり方なので、知っておくとログイン画面の作成以外でも役に立つと思います。
ここまで読んでいただきありがとうございました。
コメント