getting startedvolangvolangvmprogramminglogic

# Volang と VolangVM: スマートホームに専用の自動化言語が必要な理由

スマートホームには2つの層があります。1つ目は物理硬件: 盤モジュール、センサー、スイッチ、ブラインドモーター、冷暖房源。2つ目はロジック、入力状態が変わったときに何をすべきかを決めるルールです。ボタンを押したら照明を点ける。温度閾値を超えたら冷却を始める。特定の時間帯に動きを検知したら廊下を照らす。ただし外が暗いときだけ。

多くのユーザーは1層目から Voldeno を見ます。HubI/ORelay1-WireAnalog Input モジュールが DIN rail 上に並び、Voldeno Bus でつながっています。2層目のロジックはその下で動き、「モジュールの集まり」を「自分の望みどおりに動くシステム」に変えます。

この記事では、Voldeno でその2層目がどう整理されているかを説明します。Volang とは何か、VolangVM とは何か、なぜ既存の人気言語を再利用せず独自言語を作ったのか、実際の利用者にとって何を意味するのか。プログラミング経験が少ない読者向けに、要点を順に説明します。

# スマートホームにおける「ロジック」の意味

ロジックは ルール にすぎません。「A なら B を実行」。条件が1つなことも、7つなことも、タイミング(2分後)、カウンタ、ヒステリシス、時刻依存などが絡むこともあります。

最も単純なロジックは平易な2文です。「このボタンが押されたら、この照明を点ける」。頭の中で保持でき、アプリで1回ドラッグすれば設定できます。複雑なロジックは、互いに影響し合うルールの連鎖です。設定値はスケジュールに依存し、スケジュールはホームモードに、ホームモードは在宅状態に、在宅状態は複数センサーとアプリの最終ログインに依存する、といった構造です。「シーン」と「自動化」の緩い一覧だけに置くと、保守が非常に難しくなります。

ロジックは どこかで実行 されなければなりません。Voldeno ではその場所は Hub です。選択されたケースでは拡張モジュール上でも動きます。問題は、Hub が正確に何をすべきか分かるよう、ロジックをどの形式で保持するかです。

# クリックだけではダメなのか

できます。日常の多くのシナリオでは、まさにその方法です。Voldeno Studio では、既製の部品からロジック全体を組み立てられます。その部品を Logic Blocks と呼びます。スイッチ、スケジュール、気候レギュレータ、シーン、カウンタ、連携ブリッジがあります。ワイヤで接続します。1ブロックの出力を別ブロックの入力へ。典型的なホームオートメーションプロジェクトは、コードを1行も書かずに構築できます。

この方法には明確な限界があります。組み込みブロックは有限の一覧です。設計どおりのことしかしません。例えば次のような要件では:

  • エネルギーメーターのパルスを数え、1キロワット時ごとにクラウドへイベントを発行する
  • メーカー非対応の特殊なガレージドアシーケンスを実装する
  • 特定インストール向けにモードとヒステリシスを調整した独自のヒートポンプ制御アルゴリズムを書く
  • まだ連携一覧にないプロトコルで外部システムと統合する

既製ブロックでは届きません。正確に何が起きるべきか を、コンピューターが文字どおり実行できる形で記述する必要があります。それがプログラミング言語の役割です。

# ロジックのために「言語」が存在する理由

プログラミング言語は ルールを非常に正確に書き下す方法 です。人間がテキストを書き、コンパイラ(翻訳プログラム)が合意した規則に従っているか確認し、デバイスがその記述を文字どおり、ステップごとに、何百万回も、解釈を挟まず実行します。

本格的なビルディングオートメーションシステムは、それぞれロジックを記録する独自の方法を持っています。KNX には ETS とグループアドレス設定があります。産業用 PLC には IEC 61131-3 言語群(ラダー、ファンクションブロック、命令リスト、構造化テキスト)があります。Home Assistant は YAML と Python を使います。システムができることが増えるほど、内部の「言語」も精密である必要があります。

何らかの言語から逃れられない理由は単純です。GUI の Logic Block も言語です。各ブロックは隠れた関数、各接続は隠れたコード行です。違いは、その「言語」がどれだけ見えるか、どれだけ柔軟かです。ビジュアル言語は始めやすく、ロジックが大きくなると手間になります。テキストベースは始めは難しく、プロジェクトが大きくなるとはるかに持続可能です。

# Python や JavaScript など既存言語を使わなかった理由

最初に自問したのがこの点です。Python と JavaScript はどこにでもあります。Lua は組み込みデバイスで人気です。私たちもそれらの言語を尊重し、エコシステムの別部分(バックエンドツール、デスクトップアプリ)では使っています。DIN rail モジュール上で動くロジックについては、独自のものを構築することを選びました。理由は次のとおりです。

サイズ。 Hub のメモリと CPU は限られており、拡張モジュールはさらに少ないです。フル Python インタープリタは多くのメガバイトの RAM を消費し、巨大な依存エコシステムを引きずります。私たちのモジュールには高すぎます。Volang は小さく、省メモリで、起動が速いよう設計されています。

安全性。 ユーザー記述ロジックが Hub をクラッシュさせたり、同一デバイス上の他プロジェクトに影響したりしてはなりません。許可される操作と実行時間に厳密な上限が必要です。汎用 Python や JavaScript でも可能ですが、多大な労力がかかり、しばしば不完全です。狭く専用の言語なら、制限を外付けではなく設計そのものに組み込めます。

予測可能な実行時間。 暖房、照明、ゲートを制御するシステムでは「だいたい速い」では不十分です。同じコードが常にほぼ同じ時間で動き、バックグラウンドで魔法をしない(多くの汎用ランタイムのようにランダムなタイミングでメモリ解放するなど)言語が欲しかった。Volang には、スクリプト実行を予期せぬ瞬間に一時停止させうるガベージコレクタがありません。

自動化向け設計。 Volang では output::set("relay_1", true)input::value() のようなコードが最初の行から意味を持ちます。「input」「output」「channel」「block」といった概念は標準ライブラリの一部です。Python や JavaScript ではそれらの層を上に構築・維持する必要があり、ユーザーはそれでも学ぶ必要があります。

時間経過に対する安定性。 Volang の構文と標準ライブラリの進化は私たちが決めます。外部コミュニティではありません。Python や JavaScript では新バージョンが既存関数を変えたり非推奨にしたりし、プロジェクトを時々調整する必要があります。Volang では、今日書いたスクリプトが2年後、10年後も変更なしで動き続けることを目指しています。

MicroPython はどうか。 よく聞かれるので簡潔に。MicroPythonCircuitPython はマイコン向けに削った Python で、そのクラスでは本当に優れています。私たちの用途で選ばなかった理由は、上記と同じで、より鋭く言えば: 依然として数百 KB のメモリを取り、予測不能なミリ秒単位でスクリプトを一時停止するガベージコレクタがあり、妥当なサンドボックスを作るには Python を切り詰めすぎて、結局より狭い独自言語になる。「ほぼ Python」は罠でもあり、ユーザーが突然効かない習慣に陥ります。

これは原則として「すべて自作」という姿勢ではありません。意味がある場所では将来追加言語を差し込むことも検討しています。ブロックロジック層そのものについては、狭い独自言語が最良のトレードオフを与えてくれます。

# VolangVM とは

VM(仮想マシン)は威圧的に聞こえますが、実際には 小さく特化したプログラム で、単純なコンピューターのふりをして Volang 命令を実行します。

Studio でスクリプトを書くと、次が起きます。

  1. Volang ソーステキストの構文と型がチェックされます。これが コンパイル ステップです。
  2. 問題がなければ、コンパイラがテキストを バイトコード と呼ぶコンパクトなバイナリ命令に変換します。バイトコードは人間には数字の並びに見えますが、機械には読み取りが速いです。
  3. バイトコードが Hub(および順次、選択された拡張モジュール)に送られ、VolangVM がロードします。
  4. VolangVM が命令を1つずつ実行します。入力を読み、条件を評価し、出力を設定し、標準ライブラリ関数を呼び出します。

比較のため: VM がなければ Hub は毎回スクリプトテキストを再解析し、検証し、動作に翻訳する必要があります。VM があればその作業は1回で済み、デバイス上の実行は用意済み命令を読むだけになります。

# コンパイラは Studio だけにない

重要で見落とされがちな点: 同じ Volang コンパイラが Voldeno Studio と Hub の両方にあります

典型的なワークフローでは、インストーラーがコンピューター上の Studio でプロジェクトを開き、スクリプトを編集し、ローカルでコンパイルし、シミュレータで確認し、コンパイル済みバイトコードを Hub にアップロードします。Studio が構文エラーと警告を即座に示すため、最も速く便利な経路です。

Hub はコードが事前コンパイル済みである必要はありません。生の Volang テキスト も受け取り、実行前に自前でコンパイルできます。構文チェック、型チェック、整合性検証、バイトコード生成。Hub はすべて単独で実行できます。

システム設計者として、これはアーキテクチャの基盤です。Studio と Hub は 同じコンパイラコードと同じ VM を使います。1か所でコンパイルしたスクリプトは、別の場所で実行しても同一に振る舞います。「Studio 方言」と「Hub 方言」はありません。Studio なしでロジックを更新する将来シナリオ(例: Voldeno Cloud からのリモート更新、インテグレーターツールからのプログラム更新)への道を開きます。現時点では、主経路は依然 Studio での編集とコンパイルです。

// Short example - check which input changed
// and toggle the "relay_1" output accordingly.
channel = input::channel()
value = input::value()

if (channel == "input" and value) {
    output::toggle("relay_1")
}

この数行のロジックは数十バイトのバイトコードにコンパイルされ、ブロック入力が変わるたびに VolangVM が実行します。

# VolangVM が実際にもたらすもの

サンドボックス、すなわち分離。 各スクリプトは囲い込まれた環境で動きます。1ブロック内のランタイムエラー(例: ゼロ除算)は そのスクリプトだけ を止め、Hub 全体は止めません。他の自動化は動き続けます。照明は反応し、暖房は制御し、スケジュールは発火します。

小さな硬件での性能。 バイトコードは小さく実行が速い。VM は汎用インタープリタが入らない場所に収まります。Hub 中央だけでなく拡張モジュール上でも直接ロジックを実行する道を開きます。

Voldeno Studio で同一のシミュレーション。 VM アーキテクチャの最も重要な帰結の1つです。Hub で動くのと同じ VolangVM が、インストーラーのコンピューター上の Studio でも動きます。スクリプトを「ドライ」実行し、テスト入力を与え、実機と同一に振る舞うことを保証できます。「自分の PC では動くが現場では動かない」状況を避けられます。

移植性。 バイトコードはモジュール内 CPU の詳細に依存しません。VolangVM が動く限り、将来新硬件でもプロジェクトコードを変えずにロジックを実行できる可能性があります。

分散実行。 選択されたロジック片は中央ではなく拡張モジュール上、硬件の近くで動けます。遅延を下げ、重要な反応(例: 電流超過時に即座に接点を開く)をバスが一時的に混雑していてもローカルで実行できます。

ロールバックしやすい更新。 スクリプトはプロジェクト内でバージョン管理されます。新バージョンのアップロードはモジュールファームウェアを置き換えず、VM の内容だけを更新します。緊急時の以前バージョンへのロールバックは安価で速いです。

# Volang 標準ライブラリ: すべてのスクリプトが最初から得るもの

言語自体は半分です。もう半分は 標準ライブラリ、インストールやコピペ、インターネットからのパッケージ取得なしですぐ呼べる既製関数の集合です。

本格的なプログラミング言語には標準ライブラリがあります。Python では osmathdatetimejson など数百。JavaScript では MathJSONDatefetch。理由は単純です。標準ライブラリがなければ、基本を毎回書く必要があります。数の掛け算は言語構文の一部ですが、「平方根」「現在時刻」「テキストを数に変換」「切り上げ」は関数です。標準ライブラリは「言語が起動した時点で既に何ができるか」に答えます。

Volang の標準ライブラリはいくつかのグループに分かれます。スクリプトが何を使えるか具体化するため、一覧します。

  • ブロック入出力input::channelinput::valueinput::getoutput::setoutput::toggle など)。基盤です。Volang の目的は入力イベントへの反応と出力設定です。これらがなければインストールの他部分と通信できません。
  • ブロック状態と設定state::setstate::getconfig::get など)。イベント間でブロックに記憶させ(例: パルスカウンタ)、Studio で設定したパラメータを読みます。
  • 時間とスケジューリングtime::now、コールバック)。「5分点けてから消す」ルールはこれなしでは書けません。
  • テキスト、数値、配列、マップの操作(文字列操作、数学、array、map)。日常ツール: カウント、ソート、テキスト分割、範囲チェック。
  • JSON と Base64。 ロジックが外部と話すときに必要な標準形式。
  • HTTP とネットワーク(選択された制御された形)。スクリプトがデバイス外に届く唯一の経路。「インターネットから何でも import」はありません。「VM が知り理解する特定関数を使う」だけです。
  • 暗号とヘルパー操作。 署名、ハッシュ、エンコード。安全な連携構築に必要な分だけ(例: Google Cloud Next デモの Google Cloud 向け JWT)。
  • 非同期操作。 実行をブロックせず、後の動作をスケジュールできます。

Volang では標準ライブラリは「大きな」言語にないもう1つの役割を持ちます。セキュリティ境界でもある からです。パッケージをインストールしたり任意モジュールを import できないため、スクリプトが外部世界にできることは stdlib にある必要があります。そこにある関数はすべて、サンドボックス内から呼ぶよう意図的に設計されています。「裏口」から漏れません。裏口自体がありません。

言語の学び方も変わります。大きな言語では「これをやるライブラリを探す」で学びます。Volang では「どの stdlib 関数がこれをやるか」を確認します。一覧は有限ですが、その代わり中身はすべて安定、高速、安全です。

関数の完全な一覧は Volang 標準ライブラリ にあります。

# Volang の限界: しないこと

Volang は意図的に狭いです。ないもの を列挙する方が、できること全部を並べるより正直です。

  • 自由なインターネットアクセスなし。 ネットワーク通信は特定の用意された stdlib 関数経由(例: HTTP 呼び出し、MQTT クライアント、Google Pub/Sub への publish)。スクリプト内に import requests はありません。
  • 第三者ライブラリのインストール不可。 呼べるのは Volang 標準ライブラリか Voldeno が提供する Logic Blocks のみ。
  • ファイルアクセスなし。 スクリプトは Hub ディスク上のファイルを読み書きしません。状態はブロック変数と入出力にあります。
  • システム操作なし。 外部プログラム起動、ソケットの手動オープン、コンテナ実行はできません。意図的であり、システムの安全性はこれに依存しています。
  • 狭い構文。 ループは while のみ、for はありません。グローバルは関数内から見えません。引数は明示的に渡す必要があります。キーワード一覧は短いです。

プロのプログラマーにとって制限一覧は長く見えます。設計どおりです。Volang は「また1つの汎用言語」ではなく、自動化のアイデアから Hub 内で動く安全で予測可能なスクリプトへの最短経路を目指しています。

# 知っておくべきリスク

独自ロジックを書くことは力であり、力には結果があります。覚えておくべき点をいくつか。

不適切な硬件制御。 200 ms ごとにボイラー加熱器をトグルするスクリプトはコンタクタを破壊します。ブラインドを同時に開閉しようとするスクリプトはモーターのサーマルリミッタを作動させます。VolangVM は接点の向こうに何がつながっているかは知りません。ロジック設計者の責任です。

終わらないループ。 条件が false にならない while ループはブロック内のスクリプト実行をブロックします。正常終了しないため、以降の入力イベントにも応答せず、ブロックが停止します。while を書くときはカウンタや入力値に条件を基づけ、ループ内で必ずそれを変える処理を入れてください。またはフォールバック条件に結びついた break を追加。Volang は意図的に for がないため、ループ終了の責任はスクリプト作者にあります。

「ドライ」では理にかなうが物理現実では合わないロジック。 Studio シミュレータはスクリプトの振る舞いが正しいか確認しますが、14時に太陽が真上で窓が微換気で傾いていて駆動に引っかかるリビングのブラインドが本当に開けるかは確認しません。実インストールでの現場テストは省略できません。

ドキュメントより速く複雑化するロジック。 条件、変数、依存を1つ足すのは簡単です。1年後にそのファイルに戻って理由を理解するのは難しい。ロジックを小さなブロックに分割し、コードだけでは判断理由が分からない箇所にコメントを付けることを推奨します。

静かに振る舞いを変える更新。 Volang 言語と stdlib は安定していますが、自動化プロジェクトは進化します。スクリプト変更は本番 Hub に載せる前に Studio シミュレーションで実行してください。

これらのリスクは現実的ですが、プログラム可能な自動化システムでは普通です。だから3原則を守ります: スクリプトはサンドボックスで動く、同じスクリプトを Hub に載せる前に Studio で実行できる、以前のバージョンは常に復元できる。

# Logic Blocks: Volang の上の層

締めくくりの実務メモ。多くのユーザーとインストーラーは Volang を1行も書きません。彼らにとってロジックは既製 Logic Blocks(スイッチ、気候レギュレータ、スケジュール、シーン)から来ます。Studio がビジュアルに配線し、Hub が実行します。各ブロックの下はコンパイル済み Volang ですが、ユーザーからは入出力ポート付き部品に見えます。

Volang が活きるのは:

  • ライブラリにない独自ブロックを追加したい
  • 外部システムとの連携を構築する
  • 特定顧客向けの特殊自動化を書く
  • 複数インストールで独自の「ハウスブロック」セットを維持するインストーラー・インテグレーター

こうした場合、Volang で書く方が、多数の組み込みブロックを横に並べるより速く、長期的にも持続可能です。

# 次に読むもの

スマートホームにおける「ロジック」の本質、クリックだけでは足りない理由、Python や JavaScript ではなく Voldeno が独自言語を選んだ理由、専用仮想マシン上で実行することのメリット。