デバイスモジュール作成ガイドライン =============================== .. contents:: 目次: :depth: 3 概要 ########################### デバイス制御モジュールを作成する際のガイドラインについて記述する。 新しい機器を導入する場合には本ガイドラインの内容に従ってデバイス制御モジュールを作成することが求められる。 デバイスモジュールのフォルダ ############################# デバイスモジュールに関するコード類は :file:`iroha-device-server/devices` 以下に作成されたモジュールフォルダに格納する。 フォルダ名 *************************** 動作上、フォルダ名は任意でも問題ないが、以下のような規則で命名している。 <メーカー名><機器種類>_<型番> 例えば、Lake Shore製の温度コントローラーLS350のフォルダ名は `LSTempCont_350` となる。 また、BL独自のデバイスを作成した場合にはフォルダ名の末尾に装置コード名を付与する。 例えば、BL01用の1軸ゴニオのフォルダ名は `TJCPmc04_1AxisGonio_SIK` となる。 フォルダ構成 *************************** デバイスモジュールのフォルダは以下の構成とする。 .. csv-table:: デバイスモジュールフォルダ構成 :header-rows: 1 :widths: 8, 20, 78 :name: module_folder_structure 項番, フォルダ/ファイル, 説明 1, dh~.py, デバイスハンドラ 2, dm~.py, デバイスモデル 3, devinfo.tpl, デバイス設定テンプレート 4, devstatus.tpl, デバイスステータステンプレート 5, params.tpl, パラメータテンプレート 6, views/, Web UIの表示をオーバーライドするHTMLファイルを格納するフォルダ 7, devhelp.md, デバイス監視画面のヘルプ 8, devadminhelp.tpl, デバイス管理画面のヘルプ その他、必要に応じてファイルを追加する。 デバイスモデルの作成 ########################### デバイスモデルはファイル名が `dm` で始まるPythonスクリプトに定義される。 ファイル名は :file:`dm+デバイスモジュールフォルダ名.py` とする(すべて小文字)。 デバイスモデルではデバイス制御サーバーで定義されている関数をオーバーライドすることで機器制御を実現する。 クラス *************************** デバイスモデルでは、 `irhlibdev.irhdevicemodel.IrhDeviceModel` を継承したクラスを作成する。 クラス名は以下の様に命名する。 Dm<デバイスモジュールフォルダ名> 例えば、Lake Shore製の温度コントローラーLS350のフォルダ名は `LSTempCont_350` となるため、 デバイスモデルのクラス名は `DmLSTempCont_350` となる。 制御関数 *************************** `irhlibdev.irhdevicemodel.IrhDeviceModel` で定義されているいくつかの関数をオーバーライドし、機器制御を実現する。 OnCycleConnecting --------------------------------- `引数` なし `返り値` 成功/失敗(bool) この関数はデバイスモジュール起動時に呼び出される。 つまり、デバイス制御サーバー起動時やデバイスインスタンス作成時、リセット時に呼び出される。 この関数のデフォルトの動作はTrueを返すだけなので、必ずオーバーライドで動作を定義する必要がある。 この関数では、 - devinfo.tplの値の読み込み - デバイスとの接続 - OnCycleUploadParamsの呼び出し - OnCycleUploadDevStatusの呼び出し 等を行う。 この関数の実行中は、デバイスの状態はConnectingとなる。 処理に成功した場合にはTrueを、失敗した場合にはFalseを返す必要がある。 接続に成功した場合、デバイスの状態はReadyとなる。 接続に失敗した場合は再接続を6度繰り返し、最後まで失敗した場合にはデバイスの状態はDisconnectとなる。 OnCycleUploadParams --------------------------------- `引数` なし `返り値` 成功/失敗(bool) この関数はデバイス接続開始時とStopParamsでキャンセルされる場合に呼び出される。 この関数のデフォルトの動作はTrueを返すだけなので、必ずオーバーライドで動作を定義する必要がある。 この関数では、 :file:`params.tpl` で定義されたデバイスパラメータの初期値の設定を行う。 処理に成功した場合にはTrueを、失敗した場合にはFalseを返す必要がある。 OnCycleUploadDevStatus --------------------------------- `引数` なし `返り値` 成功/失敗(bool) この関数は定周期で呼び出される。 この関数のデフォルトの動作はTrueを返すだけなので、必ずオーバーライドで動作を定義する必要がある。 この関数では、 :file:`devstatus.tpl` で定義されたデバイスステータスについて、 状態を収集し、デバイスステータスに値を格納する。 処理に成功した場合にはTrueを、失敗した場合にはFalseを返す必要がある。 処理に失敗した場合、デバイスの状態はReadyからConnectingへと遷移し、再度OnCycleConnectingが呼び出される。 OnCycleDownloadParams --------------------------------- `引数` なし `返り値` 成功/失敗(bool) この関数はパラメータ送信時に呼び出される。 この関数はデフォルトでは以下の処理を行う。 - 送信されたすべてのパラメータについて、以下の処理を行う - 送信されたパラメータの値と現在のパラメータの値が異なる場合、OnCycleDownloadParamsElmを呼び出す - ただし、 :file:`params.tpl` において、パラメータに `forceUpdate=true` 属性が追加されていた場合、パラメータ値が変化していない場合でもOnCycleDownloadParamsElmを呼び出す - OnCycleDownloadParamsElmがFalseを返してきた場合、即座にFalseを返す。 - すべてのパラメータについて、OnCycleDownloadParamsElmがTrueを返してきた場合、Trueを返す。 したがって、実際にデバイスへパラメータを送信するのはOnCycleDownloadParamsElmの役割である。 このデフォルトの動作ではうまく制御できない場合に、この関数自体をオーバーライドする。 この関数がTrueを返した場合、デバイスの状態はInProgressへと遷移する。 Falseを返した場合、デバイスの状態はReadyからConnectingへと遷移し、再度OnCycleConnectingが呼び出される。 OnCycleDownloadParamsElm --------------------------------- `引数` パラメータのXMLオブジェクト `返り値` 成功/失敗(bool) この関数はOnCycleDownloadParamsから呼び出される。 この関数のデフォルトの動作はTrueを返すだけなので、使用する場合にはオーバーライドで動作を定義する必要がある。 この関数では、OnCycleDownloadParamsから渡されたパラメータのXMLオブジェクトから値を読み取ってデバイスに送信する。 処理に成功した場合にはTrueを、失敗した場合にはFalseを返す必要がある。 OnCycleInProgress --------------------------------- `引数` なし `返り値` なし この関数はOnCycleDownloadParamsが成功した後、定周期で呼び出される。 この関数ではデバイスの状態を確認し、デバイスが定常状態になったと判断した場合にデバイスの状態をReadyに遷移させる。 この関数でデバイスの状態をReadyにしない限りは、定周期でこの関数が呼び出され続ける。 デフォルトの動作は、単にデバイスの状態をReadyにするだけなので、デバイスの定常状態を正確に判断したい場合には、必ずオーバーライドする必要がある。 この関数では値を返す必要はない(デバイス状態をReadyに遷移させるかさせないかで次の処理が変わる)。 OnDelete --------------------------------- `引数` なし `返り値` なし (v2.7より導入) この関数はデバイスインスタンスが削除される際に呼び出される。 デフォルトでは何もしない。 デバイスインスタンス削除時にsocketを閉じる処理などを行う場合には、 この関数をオーバーライドして処理を実装する。 GetHomeInformation --------------------------------- `引数` なし `返り値` デバイスの情報(str) この関数ではWebUIのホームページに表示するメッセージを取得する。 デフォルトでは「No Information」と表示されるだけである。 ホームページにそのデバイスの情報を表示したい場合には、この関数をオーバーライドし、表示したい文字列を返す必要がある。 ライブラリ関数 *************************** `irhlibdev.irhdevicemodel.IrhDeviceModel` を継承したクラスでは以下に示す関数を使用することができる。 GetDevInfo --------------------------------- `引数` なし `返り値` デバイス情報のXMLオブジェクト devinfo.tplで定義されたデバイス情報をXMLオブジェクトとして取得する。 デバイスの接続に必要な情報などが含まれているため、主に `OnCycleConnecting` において使用する。 GetDevStatus --------------------------------- `引数` なし `返り値` デバイス状態のXMLオブジェクト devstatus.tplで定義されたデバイス状態をXMLオブジェクトとして取得する。 主に `OnCycleUploadDevStatus` において、デバイスから取得した状態を書き込むために使用される。 GetParams --------------------------------- `引数` なし `返り値` デバイスパラメータのXMLオブジェクト params.tplで定義されたデバイスパラメータをXMLオブジェクトとして取得する。 `OnCycleUploadParams` において、パラメータの初期値を書き込むために使用される。 また、 `OnCycleDownloadParams` においては、デバイスへ送信したパラメータの値を書き込むために使用される。 GetRequestParams --------------------------------- `引数` なし `返り値` Web UIから送信されたデバイスパラメータのXMLオブジェクト Web UIから送信されたデバイスパラメータをXMLオブジェクトとして取得する。 このXMLには、Web UIにおいて値を変更したかどうかに関わらず、設定できるすべてのパラメータの値が含まれている。 したがって、値が変更されたパラメータのみを処理したい場合には、 `GetParams` を利用して値の比較を行う必要がある。 SetStatus --------------------------------- `引数` デバイス状態(str) `返り値` なし デバイスの状態を引数で指定した状態に遷移させる。 主に `OnCycleInProgress` でInProgress状態からReady状態に遷移させるために使用される。 GetLogOper --------------------------------- `引数` なし `返り値` ロガーオブジェクト デバイス操作ログのロガーオブジェクトを取得する。 このロガーオブジェクトはログ出力用のメソッドを有しており、それぞれのログレベルに応じたログを出力する。 - info・・・INFOレベルのログを出力するメソッド - warning・・・WARNINGレベルのログを出力するメソッド - error・・・ERRORレベルのログを出力するメソッド - debug・・・DEBUGレベルのログを出力するメソッド SetInformationMessage --------------------------------- `引数` メッセージ(str) `返り値` なし Web UI画面にInformationメッセージを表示するために使用される。 この関数で設定したメッセージを実際にWeb UI上に表示させるためには、 HTMLファイルに埋め込んだPythonスクリプトにおいて `GetInformationMessage` を用いて設定したメッセージを取得する必要がある。 SetErrorMessage --------------------------------- `引数` メッセージ(str) `返り値` なし Web UI画面にErrorメッセージを表示するために使用される。 この関数で設定したメッセージを実際にWeb UI上に表示させるためには、 HTMLファイルに埋め込んだPythonスクリプトにおいて `GetErrorMessage` を用いて設定したメッセージを取得する必要がある。 デバイスハンドラーの作成 ########################### デバイスハンドラーはファイル名が `dh` で始まるPythonスクリプトに定義される。 ファイル名は :file:`dh+デバイスモジュールフォルダ名.py` とする(すべて小文字)。 デバイスハンドラーではデバイス制御サーバーで定義されている関数をオーバーライドすることでPOST/GET処理のカスタマイズを行う。 クラス *************************** デバイスハンドラーでは、 `irhlibdev.irhdevicemh.IrhDeviceMh` を継承したクラスを作成する。 クラス名は以下の様に命名する。 Dh<デバイスモジュールフォルダ名> 例えば、Lake Shore製の温度コントローラーLS350のフォルダ名は `LSTempCont_350` となるため、 デバイスハンドラーのクラス名は `DhLSTempCont_350` となる。 制御関数 *************************** `irhlibdev.irhdevicemh.IrhDeviceMh` で定義されているいくつかの関数をオーバーライドする。 以下に示した関数以外にもオーバーライド可能な関数があるため、既存のデバイスモジュール等を参考に実装する。 OnGetDevHome --------------------------------- この関数をオーバーライドすることで、カスタマイズしたデバイスホームページを表示することができる。 OnGetDevInfo --------------------------------- この関数をオーバーライドすることで、カスタマイズしたデバイス情報ページを表示することができる。 OnGetDevStatusUi --------------------------------- この関数をオーバーライドすることで、カスタマイズしたデバイス状態ページを表示することができる。 OnGetDevParamsUi --------------------------------- この関数をオーバーライドすることで、カスタマイズしたパラメータ表示ページを表示することができる。 OnGetDevMeasLog --------------------------------- この関数をオーバーライドすることで、カスタマイズした測定ログページを表示することができる。 OnGetDevMeasGraph --------------------------------- この関数をオーバーライドすることで、カスタマイズした測定ロググラフページを表示することができる。 OnGetDevSurvLog --------------------------------- この関数をオーバーライドすることで、カスタマイズした監視ログページを表示することができる。 OnGetDevOperLog --------------------------------- この関数をオーバーライドすることで、カスタマイズした操作ログページを表示することができる。 OnGetDevExt --------------------------------- 未定義のURIに対するGETリクエストが送られてきた際の処理を実装する。 OnPostDevExt --------------------------------- 未定義のURIに対するPOSTリクエストが送られてきた際の処理を実装する。 ライブラリ関数 *************************** `irhlibdev.irhdevicemh.IrhDeviceMh` を継承したクラスでは以下に示す関数を使用することができる。 DevSrvSubTemplate --------------------------------- `引数` HTMLファイルのパス, サーバーモデル, デバイスモデル `返り値` 展開されたHTML この関数はサーバー監視画面の各サブコンテンツのHTMLを作成するために使用される。 デバイスハンドラーの制御関数において使用し、Web UIの画面をカスタマイズする。 DevAdmSubTemplate --------------------------------- `引数` HTMLファイルのパス, サーバーモデル, デバイスモデル `返り値` 展開されたHTML この関数はサーバー管理画面の各サブコンテンツのHTMLを作成するために使用される。 デバイスハンドラーの制御関数において使用し、Web UIの画面をカスタマイズする。 .. note:: デバイスハンドラーによる画面のカスタマイズについての詳細は、既存のデバイスモジュールを参考にすること。 tplファイルの作成 ########################### 各デバイスモジュールには :file:`devinfo.tpl` :file:`devstatus.tpl` :file:`params.tpl` の3種類のtplファイルがある。 これらのファイルはデバイスモジュールがインスタンス化された(デバイスをAddした)際に作成される設定ファイルのひな型となる。 devinfo.tpl *************************** デバイス情報を記述するXMLファイルであり、デバイス名やホスト名、ポート番号など、接続に必要な値や接続後は変更しないを定義する。 ルート要素の要素名は `DevInfo<デバイスモジュール名>` となる。 例えば、Lake Shore製の温度コントローラーLS350のモジュール名は `LSTempCont_350` であるから、 ルート要素名は `DevInfoLSTempCont_350` となる。 ルート要素の下には要素と要素を定義する。 要素にはインスタンス化時に入力したデバイス名が入る。 要素にはデバイスから情報を収集する時間間隔などの情報を入れる。 - intervalReady・・・未測定時のデバイスからの情報収集間隔 - intervalInProgress・・・InProgress時のデバイスからの情報収集間隔 - intervelMeasurement・・・測定時のデバイスからの情報収集間隔 また、ホスト名やポート番号など、その他の情報については任意の階層に定義してよい。 作成例:Sampleデバイス --------------------------------- .. code-block:: bash newName 999 999 9 localhost 30101 10 5 1 on 3 no off off devstatus.tpl *************************** デバイス状態を記述するXMLファイルであり、デバイスの状態を表すパラメータの定義を行う。 ルート要素の要素名は `DevStatus` となる。 ルート要素の下には要素と要素、要素を定義する。 要素にはインスタンス化時に入力したデバイス名が入る。 要素には定期的に収集されるデバイスインスタンスの状態が入る。 要素の下には各パラメータの要素を入れる。 ただし、既存のデバイスモジュールと揃えるため、要素の下に要素を作り、その下に各パラメータの要素を入れる。 各パラメータの要素にはいくつかの属性を定義することができる。 - measLog・・・onにするとそのパラメータの値は測定ログに記録される(インスタンス作成後に設定可能) - logging・・・meassLog=onとする場合にはonにする - logName・・・測定ログのヘッダーに使用するパラメータ名 - type・・・パラメータの型(int/float/string) - unit・・・パラメータの単位(測定ログのヘッダーに使用) - range・・・パラメータの範囲(上限:下限:幅) 作成例:Sampleデバイス --------------------------------- .. code-block:: bash Idle Off 0 0 123.455 Zero 123.455 3000.9 100 params.tpl *************************** デバイスパラメータを記述するXMLファイルであり、デバイスへ送信するパラメータの定義を行う。 ルート要素の要素名は `params` となる。 ルート要素の下には要素を定義し、その下に各パラメータの要素を入れる。 各パラメータの要素にはいくつかの属性を定義することができる。 - type・・・パラメータの型(int/float/string) - range・・・パラメータの範囲(上限:下限:幅) - unit・・・パラメータの単位 - forceUpdate・・・trueの場合、パラメータ値に変化がない場合にもパラメータ表示画面のUpdateを更新する - default・・・値が設定されている場合、パラメータの送信後にパラメータの表示値をその値にする(v2.7より導入) .. note:: ルート要素の下に直接各パラメータの要素を入れることはできるが、 シーケンス管理サーバーのファサード自動作成機能を使用するためには ルート要素の下に要素を定義してその下に各パラメータの要素を定義する必要がある。 .. note:: params.tplの要素の要素名は任意の名前に変更してもよい。 例えば、LSTempCont_350ではとしている。 作成例:Sampleデバイス --------------------------------- 要素の代わりに要素を使用している。 .. code-block:: bash on 1 1 HTMLファイルの作成 ########################### IROHA2ではWebアプリケーションフレームワークとしてbottle.pyを使用しており、 テンプレートの機能を使うことで動的にHTMLファイルの内容を変更することができる。 具体的には、Pythonスクリプトを埋め込んだHTMLファイルをデバイスハンドラーで指定し、 そのPythonスクリプトを実行することでその結果に応じたHTMLが生成される。 HTMLファイルは各デバイスモジュールフォルダの :file:`views` フォルダに格納する。 ファイル名は任意で良いが、既存のデバイスと統一感を持たせるため、 `dev-sc-<デバイスを表す言葉>-<ページを表す言葉>.html` という法則で命名する。 ヘルプの作成 ########################### 各デバイスモジュールのヘルプページはMarkdown形式で記述する。 devhelp.md *************************** デバイス監視画面において :guilabel:`Help` ボタンを押下した際に表示されるヘルプページを記述する。 devadminhelp.md *************************** デバイス管理画面において :guilabel:`Help` ボタンを押下した際に表示されるヘルプページを記述する。