プロジェクトでスケジューラーを使用するには、始める前にいくつかの手順を行う必要があります。
ここでは2つの方法があります。以下はより簡単な方法です。
extract_dll_from_project(project : str, path_to : str)を呼び出します。def extract_parameters_from_project(project : str, tsvdir : str, script_to : str, scenario : str = "") -> bool:を呼び出します。環境をできるだけ軽量に保ちたい場合は、次のようにします。
setParallelJobsdef setParallelJobs(self, jobs)
一度に実行するシミュレーションの数を設定します。その他のスケジュール済みシミュレーションは、これらのシミュレーションが終了するまで実行を開始できず待機します。この関数が呼び出されない場合、デフォルトは1です。
| jobs | 一度に実行するジョブの数 |
なし
setMaxJobReusedef setMaxJobReuse(self, reuse)
プロセスを再起動するまでに1つのプロセスで実行するシミュレーションの数を設定します。プロセスが再利用されるのは、同じモデルで複数のシミュレーションがスケジュールされた場合のみです。デフォルト値は10です。内容を十分理解している場合を除き、この値は変更しないでください。
| reuse | 1つのプロセスで実行するジョブの最大数 |
なし
setLogDetailsdef setLogDetails(self, level)
スケジューラーがコンソールに何を出力するかを決定します。
| level | 1 - ジョブからの未知のメッセージがすべてログに記録される 2 - ジョブからのメッセージがログに記録される 4 - ジョブへのメッセージがすべてログに記録される 6 - ジョブとの間のすべてのメッセージ(送受信)がログに記録される |
なし
message_callbackmessage_callback
メッセージハンドラーへのハンドルを保持します。メッセージコールバックは、ジョブIDを整数(integer)で、メッセージを文字列(string)で受け取ります。
ds.sumo.message_callback = msg_callback
def msg_callback(job, msg):
print("MSG #" + str(job) + ": '" + msg + "'")
if (ds.sumo.isSimFinishedMsg(msg)):
ds.sumo.finish(job)
datacomm_callbackdatacomm_callback
データハンドラーへのハンドルを保持します。データコールバックは、ジョブIDを整数(integer)で、データを辞書(dictionary)で受け取ります。
ds.sumo.datacomm_callback = data_callback
def data_callback(job, data):
print(f"DC #{job} - {data['Sumo__Time']}")
scheduledef schedule (self, model, commands, variables, blockDatacomm=False, jobData=None)
新しいシミュレーションをスケジュールします。シミュレーションはすぐには実行されず、定義済みのコールバックを介して通信します。
| model | SUMOから抽出したモデルの.dllファイルへのパス(.sumoファイル内のsumoproject.dll) |
| commands | シミュレーションエンジンへのコマンドのリスト。利用可能なコマンドについては、SumoCoreコマンドのドキュメントを参照してください。 |
| variables | 監視(リッスン)する変数のリスト。変数名はSumoのAdvanced -> Core Windowからコピーできます。 |
| blockDatacomm | Pythonが処理内容を決定する間、シミュレーションを待機させますか?シミュレーションを制御したい場合はtrueに設定し、それ以外の場合はより高速な結果を得るためfalseのままにします。 |
| jobData | ジョブとともに保存され、後でアクセスできる追加情報(辞書)。シミュレーション終了後もデータを保持するには、sumo.persistentフラグを設定できます。 |
この関数は、シミュレーションを識別するために参照できるJobIDを返します。
job1 = ds.sumo.schedule(
"sumoproject.dll"
commands = [
f"load state.xml",
f"set Sumo__StopTime {10*ds.sumo.dur.day};",
f"set Sumo__DataComm {1*ds.sumo.dur.hour};",
f"set Sumo__Plant__Influent__param__frSNHx_TKN 2;",
"mode dynamic;",
"start;"],
variables = ["Sumo__Time",
"Sumo__Plant__Effluent__SNOx",
"Sumo__Plant__Effluent__SPO4"],
jobData = {
ds.sumo.persistent: True,
"results" : { }
},
);
sendCommanddef sendCommand(self, job, command)
ジョブにコマンドを送信します。まだ開始していないシミュレーションにコマンドを送信した場合、そのコマンドは開始時に実行されます。
| job | 対象ジョブのID |
| command | シミュレーションエンジンへのコマンド。利用可能なコマンドについては、SumoCoreコマンドのドキュメントを参照してください。 |
なし
ds.sumo.sendCommand(job1, "pause")
sendCommandsdef sendCommands(self, job, commands)
ジョブにコマンドのリストを送信します。まだ開始していないシミュレーションにコマンドを送信した場合、それらのコマンドは開始時に実行されます。
| job | 対象ジョブのID |
| commands | シミュレーションエンジンへのコマンドのリスト。利用可能なコマンドについては、SumoCoreコマンドのドキュメントを参照してください。 |
なし
ds.sumo.sendCommands(job1, ["set Sumo__StopTime 86400000", "set Sumo__DataComm 3600000", "start"])
末尾のセミコロン(;)文字は不要です。
getJobDatadef getJobData(self, jobId):
スケジュール時にジョブへ割り当てたデータを取得します。このデータは変更でき、変更内容は保持されます。
| jobId | 対象ジョブのID |
schedule関数を呼び出したときに定義した辞書。ジョブデータを定義していなかった場合、この関数はnullを返します。
jobData = ds.sumo.getJobData(job)
finishdef finish(self, job)
指定したジョブIDのジョブを終了させ、他のジョブが実行できるようにします。終了できるのは実行を開始したジョブのみです。スケジュールされたがまだ実行されていないジョブは終了できません。多くの場合、シミュレーションが完了したときにそのジョブを終了させることになります。ジョブが終了すると、そのジョブデータはクリアされます。ただし、sumo.persistentフラグが設定されている場合は保持されます。
通常は、1つのジョブにつき1回のシミュレーションのみ行う方がよいでしょう。スケジューラーはオーバーヘッドを減らすため、可能であれば同一プロセス内でジョブを実行するよう最適化しますが、1つのジョブを使いすぎると、そのジョブの動作が遅くなる可能性があります。他のジョブがまったく実行されなくなり、それらに影響を与える場合もあります。
| job | 終了させたいジョブのID |
なし
def msg_callback(job, msg):
if (ds.sumo.isSimFinishedMsg(msg)):
ds.sumo.finish(job)
cleanupdef cleanup(self)
SumoSchedulerが確保したすべてのリソースを解放し、アンロードします。Pythonスクリプトの最後でのみ実行してください。クリーンアップ後にシミュレーションをスケジュールすると、問題が発生する可能性があります。また、persistentとしてマークされたジョブデータも含めてすべてクリーンアップします。
なし
なし
isSimFinishedMsgdef isSimFinishedMsg(self, msg)
メッセージがシミュレーションの終了を示すものかどうかを判定します。
| msg | 判定するメッセージ(message_callback が受け取った文字列) |
シミュレーション終了メッセージであればtrue、そうでなければfalse
def msg_callback(job, msg):
if (ds.sumo.isSimFinishedMsg(msg)):
ds.sumo.finish(job)