リモコンUIを作る
エアコンのリモコン用として、足し引きしたゲージを表示したい。
リモコンのUIを作るうえでは以下のサイトから参考にした。
Node-RedおよびDashboardのプラグインの準備は以下から実施している。
ON/OFF/機能/温度の表示をしてみた
とりあえず作ってみたもの
自宅にある互換リモコンを参考に作ってみた。
On/Offは当然として、暖房や冷房なども付け加えている。温度に関するボタンもあるが、あくまでもゲージが動くだけであり、Raspberry Piのほうには関係はない。
ちなみにアイコンの色はここから参照している。
以下がNode-RedのFlowである。無駄が多いのは申し訳ないです。勉強しながら書いているので、試行錯誤しながらのFlowです。きれいに書く方法はいくらでもありそう。
一番最後にJSONファイルの中身を掲載する。
回路図は以下の図のようになっている。LEDが抵抗にぶら下がっているだけである。手持ちにあったLEDと合わせて、そして余った抵抗を使っているので、厳密に以下の回路図通りの抵抗値ではない。
GIPOの配置図は、以下を参照。
動作確認
動作させてみました。以下の同課のようになっています。
ちなみに動作させてみたときのなるべき挙動などは以下の説明から。
●状態がOFFのとき(最初)
LEDは全部消灯
●「ON」を押したとき
動作ONの時に光る白LED+初期状態で入っていたCoolerの青LEDが点灯
●「Heater」を押したとき
動作ONの時に光る白LED+Heaterの赤LEDが点灯
●「Cooler」を押したとき
動作ONの時に光る白LED+Coolerの青LEDが点灯
●「Auto」を押したとき
動作ONの時に光る白LED+Autoの緑LEDが点灯
●「Dehumidifier」を押したとき
動作ONの時に光る白LED+Dehumidifierの黄LEDが点灯
●「OFF」を押したとき
LED全消灯
●再度「ON」を押したとき
動作ONの時に光る白LED+OFFの状態で記憶されていたDehumidifierの黄LEDが点灯
おまけ
JSONファイルを以下に示す。これを取り込んでやれば、おそらく上記のようなフローが読み込めるはずである。
申し訳ないのですが、動作は保証しません。お試しのツールだと思っていただければと思います。
[
{
"id": "61f2bf91.fa8e7",
"type": "tab",
"label": "フロー 2",
"disabled": false,
"info": ""
},
{
"id": "7325bbf8.4e5624",
"type": "ui_gauge",
"z": "61f2bf91.fa8e7",
"name": "",
"group": "5398ebf4.9198d4",
"order": 1,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "Temperature-gauge",
"label": "℃",
"format": "{{value}}",
"min": "10",
"max": "30",
"colors": [
"#0080ff",
"#e6e600",
"#ff8000"
],
"seg1": "",
"seg2": "",
"x": 690,
"y": 340,
"wires": []
},
{
"id": "a8bec375.2ade",
"type": "ui_button",
"z": "61f2bf91.fa8e7",
"name": "",
"group": "5398ebf4.9198d4",
"order": 3,
"width": 2,
"height": 1,
"passthru": false,
"label": "Temp -",
"tooltip": "",
"color": "#000000",
"bgcolor": "#C0DEED",
"icon": "",
"payload": "-1",
"payloadType": "num",
"topic": "",
"x": 90,
"y": 380,
"wires": [
[
"22dedd13.caf922"
]
]
},
{
"id": "316a7b2.184ef84",
"type": "ui_button",
"z": "61f2bf91.fa8e7",
"name": "",
"group": "5398ebf4.9198d4",
"order": 4,
"width": 2,
"height": 1,
"passthru": false,
"label": "Temp +",
"tooltip": "",
"color": "#000000",
"bgcolor": "#FFAAAA",
"icon": "",
"payload": "+1",
"payloadType": "num",
"topic": "",
"x": 100,
"y": 340,
"wires": [
[
"22dedd13.caf922"
]
]
},
{
"id": "22dedd13.caf922",
"type": "function",
"z": "61f2bf91.fa8e7",
"name": "Temperature_adder",
"func": "\n\nvar MAX_TEMPERATURE = 30\nvar MIN_TEMPERATURE = 10\n\nvar global_temperature = global.get('temperature')||20;\n\n\nglobal_temperature = global_temperature + msg.payload\n\nif(global_temperature < MIN_TEMPERATURE){\n global_temperature = MIN_TEMPERATURE\n}else if(global_temperature > MAX_TEMPERATURE){\n global_temperature = MAX_TEMPERATURE\n}\n\nglobal.set('temperature',global_temperature)\n\nmsg.payload = global_temperature\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 370,
"y": 340,
"wires": [
[
"7325bbf8.4e5624",
"725d146c.873b4c"
]
]
},
{
"id": "52f37ce7.2339d4",
"type": "ui_text",
"z": "61f2bf91.fa8e7",
"group": "5398ebf4.9198d4",
"order": 2,
"width": 2,
"height": 1,
"name": "",
"label": "Temperature",
"format": "",
"layout": "row-spread",
"x": 110,
"y": 300,
"wires": []
},
{
"id": "cd38317a.5e18e",
"type": "ui_button",
"z": "61f2bf91.fa8e7",
"name": "",
"group": "235f1439.1e69bc",
"order": 3,
"width": 2,
"height": 1,
"passthru": false,
"label": "Heater",
"tooltip": "",
"color": "#000000",
"bgcolor": "#FFAAAA",
"icon": "",
"payload": "Heater",
"payloadType": "str",
"topic": "",
"x": 90,
"y": 500,
"wires": [
[
"3f5324d0.6b956c"
]
]
},
{
"id": "ed8b68e4.9349e8",
"type": "ui_button",
"z": "61f2bf91.fa8e7",
"name": "",
"group": "235f1439.1e69bc",
"order": 4,
"width": 2,
"height": 1,
"passthru": false,
"label": "Cooler",
"tooltip": "",
"color": "#000000",
"bgcolor": "#C0DEED",
"icon": "",
"payload": "Cooler",
"payloadType": "str",
"topic": "",
"x": 90,
"y": 540,
"wires": [
[
"3f5324d0.6b956c"
]
]
},
{
"id": "cc1099d9.7b8fa8",
"type": "ui_button",
"z": "61f2bf91.fa8e7",
"name": "",
"group": "235f1439.1e69bc",
"order": 6,
"width": 2,
"height": 1,
"passthru": false,
"label": "Auto",
"tooltip": "",
"color": "#000000",
"bgcolor": "#C7E9C0",
"icon": "",
"payload": "Auto",
"payloadType": "str",
"topic": "",
"x": 90,
"y": 580,
"wires": [
[
"3f5324d0.6b956c"
]
]
},
{
"id": "7e7c78c0.50b678",
"type": "ui_button",
"z": "61f2bf91.fa8e7",
"name": "",
"group": "235f1439.1e69bc",
"order": 7,
"width": 2,
"height": 1,
"passthru": false,
"label": "Dehumidifier",
"tooltip": "",
"color": "#000000",
"bgcolor": "#FDF0C2",
"icon": "",
"payload": "Dehumidifier",
"payloadType": "str",
"topic": "",
"x": 110,
"y": 620,
"wires": [
[
"3f5324d0.6b956c"
]
]
},
{
"id": "5babadd4.327f84",
"type": "ui_button",
"z": "61f2bf91.fa8e7",
"name": "",
"group": "235f1439.1e69bc",
"order": 2,
"width": 2,
"height": 1,
"passthru": false,
"label": "On",
"tooltip": "",
"color": "#000000",
"bgcolor": "#E9967A",
"icon": "",
"payload": "true",
"payloadType": "bool",
"topic": "",
"x": 90,
"y": 220,
"wires": [
[
"fcf40ffc.b5512"
]
]
},
{
"id": "6950da99.a4e934",
"type": "ui_button",
"z": "61f2bf91.fa8e7",
"name": "",
"group": "235f1439.1e69bc",
"order": 5,
"width": 2,
"height": 1,
"passthru": false,
"label": "Off",
"tooltip": "",
"color": "#000000",
"bgcolor": "#A6BBCF",
"icon": "",
"payload": "false",
"payloadType": "bool",
"topic": "",
"x": 90,
"y": 260,
"wires": [
[
"fcf40ffc.b5512"
]
]
},
{
"id": "6bfdf6b2.a13338",
"type": "ui_text",
"z": "61f2bf91.fa8e7",
"group": "235f1439.1e69bc",
"order": 1,
"width": 0,
"height": 0,
"name": "",
"label": "Air Conditioner",
"format": "{{msg.payload}}",
"layout": "row-spread",
"x": 680,
"y": 220,
"wires": []
},
{
"id": "fcf40ffc.b5512",
"type": "function",
"z": "61f2bf91.fa8e7",
"name": "Temperature_On/Off",
"func": "global.set('MODE_OFF',\"OFF\")\nglobal.set('MODE_ON',\"ON\")\n\nvar on_off = { payload:msg.payload };\n\nif(msg.payload === true){\n on_off.payload = global.get('air_conditioner_mode')||\"Auto\";\n}else if (msg.payload === false){\n on_off.payload = global.get('MODE_OFF')\n}\n\nreturn on_off;",
"outputs": 1,
"noerr": 0,
"x": 380,
"y": 220,
"wires": [
[
"6bfdf6b2.a13338",
"bb55f458.fd3758",
"9340357b.1f6358"
]
]
},
{
"id": "bb55f458.fd3758",
"type": "debug",
"z": "61f2bf91.fa8e7",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 670,
"y": 260,
"wires": []
},
{
"id": "725d146c.873b4c",
"type": "debug",
"z": "61f2bf91.fa8e7",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 670,
"y": 380,
"wires": []
},
{
"id": "e6e9465f.dc9c98",
"type": "inject",
"z": "61f2bf91.fa8e7",
"name": "ON",
"topic": "",
"payload": "true",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 110,
"y": 120,
"wires": [
[
"fcf40ffc.b5512"
]
]
},
{
"id": "49cc2bbb.a69ba4",
"type": "inject",
"z": "61f2bf91.fa8e7",
"name": "OFF",
"topic": "",
"payload": "false",
"payloadType": "bool",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 110,
"y": 160,
"wires": [
[
"fcf40ffc.b5512"
]
]
},
{
"id": "3f5324d0.6b956c",
"type": "function",
"z": "61f2bf91.fa8e7",
"name": "Air_Conditioner_Define_Status",
"func": "\nglobal.set('MODE_HEATER',\"Heater\")\nglobal.set('MODE_COOLER',\"Cooler\")\nglobal.set('MODE_AUTO',\"Auto\")\nglobal.set('MODE_DEHUMIDIFIER',\"Dehumidifier\")\nglobal.set('MODE_OFF',\"Off\")\n\nvar global_air_mode = global.get('air_conditioner_mode')||\"Auto\";\n\nglobal_air_mode = msg.payload\nglobal.set('air_conditioner_mode',global_air_mode)\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 410,
"y": 460,
"wires": [
[
"9340357b.1f6358",
"6bfdf6b2.a13338"
]
]
},
{
"id": "9340357b.1f6358",
"type": "function",
"z": "61f2bf91.fa8e7",
"name": "Changer_Air_Conditioner_Status_LED",
"func": "\nvar status_off = 0\nvar status_on = 1\n\nvar msg1 = { payload:status_off };\nvar msg2 = { payload:status_off };\nvar msg3 = { payload:status_off };\nvar msg4 = { payload:status_off };\nvar msg5 = { payload:status_on };\n\nif( msg.payload === global.get('MODE_HEATER')){\n msg1.payload = status_on\n}else if( msg.payload === global.get('MODE_COOLER')){\n msg2.payload = status_on\n}else if( msg.payload === global.get('MODE_AUTO')){\n msg3.payload = status_on\n}else if( msg.payload === global.get('MODE_DEHUMIDIFIER')){\n msg4.payload = status_on\n}else if( msg.payload === global.get('MODE_OFF')){\n msg5.payload = status_off\n}\n\nreturn [ msg1, msg2, msg3 , msg4 ,msg5];\n\n\n",
"outputs": 5,
"noerr": 0,
"x": 750,
"y": 460,
"wires": [
[
"f8d382a9.88b6e"
],
[
"b616afbb.54448"
],
[
"7dc9e066.9c0a9"
],
[
"b7f7daf8.99e9c8"
],
[
"57af153b.cae60c"
]
]
},
{
"id": "f8d382a9.88b6e",
"type": "rpi-gpio out",
"z": "61f2bf91.fa8e7",
"name": "Heater_LED_GPIO07",
"pin": "7",
"set": true,
"level": "0",
"freq": "",
"out": "out",
"x": 1100,
"y": 400,
"wires": []
},
{
"id": "b616afbb.54448",
"type": "rpi-gpio out",
"z": "61f2bf91.fa8e7",
"name": "Cooler_LED_GPIO11",
"pin": "11",
"set": true,
"level": "0",
"freq": "",
"out": "out",
"x": 1100,
"y": 460,
"wires": []
},
{
"id": "7dc9e066.9c0a9",
"type": "rpi-gpio out",
"z": "61f2bf91.fa8e7",
"name": "Auto_LED_GPIO27",
"pin": "13",
"set": true,
"level": "0",
"freq": "",
"out": "out",
"x": 1090,
"y": 520,
"wires": []
},
{
"id": "b7f7daf8.99e9c8",
"type": "rpi-gpio out",
"z": "61f2bf91.fa8e7",
"name": "Dehumidifier_LED_GPIO22",
"pin": "15",
"set": true,
"level": "0",
"freq": "",
"out": "out",
"x": 1120,
"y": 580,
"wires": []
},
{
"id": "57af153b.cae60c",
"type": "rpi-gpio out",
"z": "61f2bf91.fa8e7",
"name": "ON_LED_GPIO25",
"pin": "22",
"set": true,
"level": "0",
"freq": "",
"out": "out",
"x": 1090,
"y": 640,
"wires": []
},
{
"id": "e2eda504.76c648",
"type": "comment",
"z": "61f2bf91.fa8e7",
"name": "Air Conditioner Flow",
"info": "",
"x": 130,
"y": 60,
"wires": []
},
{
"id": "5398ebf4.9198d4",
"type": "ui_group",
"z": "",
"name": "Temperature",
"tab": "6d09b1c4.d69af",
"order": 2,
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "235f1439.1e69bc",
"type": "ui_group",
"z": "",
"name": "Status",
"tab": "6d09b1c4.d69af",
"order": 1,
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "6d09b1c4.d69af",
"type": "ui_tab",
"z": "",
"name": "Air conditioner",
"icon": "dashboard",
"order": 2,
"disabled": false,
"hidden": false
}
]