0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Node-redでEchonetlite単機能照明(Panasonic アドバンスリンクプラス)を制御する 改良版

Last updated at Posted at 2022-03-21

前回の反省

  • ステータス反映時にESVをチェックしていなかったためEDTがない場合(ESV0x71など)に挙動がおかしかった

ESV0x72(プロパティ値読み出し応答)0x73(プロパティ値通知)をチェック

  • 設定値の確認をしていなった

tidをflowコンストラクタで設定して戻りのESV0x71で同一tidであることを確認(本来はGet0x62で確認推奨)

同一tidとなるまでwait0.2secをかけてループ(本来は20sec空ける必要あり)

  • 並列処理ができないことを考慮せず

さらなる反省点・感想

最初から規格書(pdf)を読んでいればおかしな挙動はなかった。panasonic謹製アプリでもエラーとなることから無線アダプタでの処理には時間がかかる模様。

フロー図

image.png

flow.json

[{"id":"b85c21964717f67c","type":"tab","label":"sample","disabled":false,"info":"","env":[]},{"id":"107c117ed3e88b49","type":"function","z":"b85c21964717f67c","name":"Parse EL1","func":"// Parse ECHONET Lite packet\n// Assumption: OPC = 1\n\n//  OUTPUT:\n//  msg.elr.ip      // ip address (String)\n//  msg.elr.ehd     // EHD (Int)\n//  msg.elr.tid     // TID (Int)\n//  msg.elr.seoj    // SEOJ ([Int:device, Int:instance])\n//  msg.elr.deoj    // DEOJ ([Int:device, Int:instance])\n//  msg.elr.esv     // ESV (Int)\n//  msg.elr.opc     // OPC (Int)\n//  msg.elr.epc     // EPC (Int)\n//  msg.elr.pdc     // PDC (Int)\n//  msg.elr.edt     // EDT ([Int]) or [](no EDT data)\n\nconst buffer = msg.payload;\nmsg.elr = null;\n\nif (buffer.length >= 14) {\n  const ehd_buffer = buffer.slice(0, 2);\n  const tid_buffer = buffer.slice(2, 4);\n  const seoj_device_buffer = buffer.slice(4, 6);\n  const seoj_instance_buffer = buffer.slice(6, 7);\n  const deoj_device_buffer = buffer.slice(7, 9);\n  const deoj_instance_buffer = buffer.slice(9, 10);\n  const esv_buffer = buffer.slice(10, 11);\n  const opc_buffer = buffer.slice(11, 12);\n  const epc_buffer = buffer.slice(12, 13);\n  const pdc_buffer = buffer.slice(13, 14);\n\n  const ehd = ehd_buffer.readUInt16BE(0);\n  const tid = tid_buffer.readUInt16BE(0);\n  const seoj_device = seoj_device_buffer.readUInt16BE(0);\n  const seoj_instance = seoj_instance_buffer.readUInt8(0);\n  const seoj = [seoj_device, seoj_instance];\n  const deoj_device = deoj_device_buffer.readUInt16BE(0);\n  const deoj_instance = deoj_instance_buffer.readUInt8(0);\n  const deoj = [deoj_device, deoj_instance];\n  const esv = esv_buffer.readUInt8(0);\n  const opc = opc_buffer.readUInt8(0);\n  const epc = epc_buffer.readUInt8(0);\n  const pdc = pdc_buffer.readUInt8(0);\n  let edt = [];\n  \n  if (buffer.length >= 15) {\n    const edt_buffer = buffer.slice(14);\n    for (var i = 0; i < edt_buffer.length; i++) {\n        edt[i] = edt_buffer.readUInt8(i);\n    }\n  }\n\n  // ECHONET Lite header check\n  if (ehd == 0x1081) {\n    msg.elr = {\n        \"ip\"            : msg.ip,\n        \"ehd\"           : ehd,\n        \"tid\"           : tid,\n        \"seoj\"          : seoj,\n        \"deoj\"          : deoj,\n        \"esv\"           : esv,\n        \"opc\"           : opc,\n        \"epc\"           : epc,\n        \"pdc\"           : pdc,\n        \"edt\"           : edt\n    };\n  }\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":230,"y":480,"wires":[["625ebf051f146439"]]},{"id":"3f9cf3c7fce15c9a","type":"udp in","z":"b85c21964717f67c","name":"EL receive","iface":"","port":"3610","ipv":"udp4","multicast":"true","group":"224.0.23.0","datatype":"buffer","x":80,"y":480,"wires":[["107c117ed3e88b49"]]},{"id":"5d2c38d0e47d2d88","type":"function","z":"b85c21964717f67c","name":"EL set","func":"//  msg.els.ip_string   // ip address (String)\n//  msg.els.tid         // TID (Int)\n//  msg.els.seoj        // SEOJ ([Int:device, Int:instance])\n//  msg.els.deoj        // DEOJ ([Int:device, Int:instance])\n//  msg.els.esv         // ESV (Int)\n//  msg.els.epc         // EPC (Int)\n//  msg.els.edt_int     // EDT ([Int])\n\nmsg.els = {\n    \"ip\" : flow.get(\"ip\"),\n    \"tid\" : flow.get(\"tid\"),\n    \"seoj\" : [0x05ff,1],\n    \"deoj\" : [0x0291,flow.get(\"num\")],\n    \"esv\" : 0x61,\n    \"epc\" : 0x80,\n    \"edt\" : [msg.payload]\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":250,"y":340,"wires":[["60024e3da3add6fc","ade4ebce158594b1"]]},{"id":"60024e3da3add6fc","type":"function","z":"b85c21964717f67c","name":"Send EL1","func":"// Send ECHONET Lite packet\n// Assumption: OPC = 1\n//\n//  Usage:\n//      Input following data\n//\n//  msg.els.ip      // ip address (String)\n//  msg.els.tid     // TID (Int)\n//  msg.els.seoj    // SEOJ ([Int:device, Int:instance])\n//  msg.els.deoj    // DEOJ ([Int:device, Int:instance])\n//  msg.els.esv     // ESV (Int)\n//  msg.els.epc     // EPC (Int)\n//  msg.els.edt     // EDT ([Int])\n//          // in case of no EDT data, no edt or []\n\nconst tid_buffer = Buffer.allocUnsafe(2);\nlet   seoj_buffer = Buffer.allocUnsafe(3);\nconst seoj = msg.els.seoj;\nlet   deoj_buffer = Buffer.allocUnsafe(3);\nconst deoj = msg.els.deoj;\nconst esv_buffer = Buffer.allocUnsafe(1);\nconst opc_buffer = Buffer.from([1]);\nconst epc_buffer = Buffer.allocUnsafe(1);\nconst pdc_buffer = Buffer.allocUnsafe(1);\nlet edt = msg.els.edt;\n\ntid_buffer.writeUInt16BE(msg.els.tid, 0);\nesv_buffer.writeUInt8(msg.els.esv, 0);\nepc_buffer.writeUInt8(msg.els.epc, 0);\n\nseoj_buffer.writeUInt16BE(seoj[0], 0);\nseoj_buffer.writeUInt8(seoj[1], 2);\ndeoj_buffer.writeUInt16BE(deoj[0], 0);\ndeoj_buffer.writeUInt8(deoj[1], 2);\n\n// edt[]からedt_bufferを作成\nif ((typeof edt) == \"undefined\") {\n    edt = [];\n}\n\nconst edt_buffer = Buffer.allocUnsafe(edt.length);\nfor (var i = 0; i < edt.length; i++) {\n    edt_buffer.writeUInt8(edt[i], i);\n}\n\npdc_buffer.writeUInt8(edt_buffer.length, 0);\n\n// Create ECHONET Lite packet\nconst el_buffer = Buffer.from([\n\t0x10, 0x81,\n\ttid_buffer[0], tid_buffer[1],\n\tseoj_buffer[0], seoj_buffer[1], seoj_buffer[2],\n\tdeoj_buffer[0], deoj_buffer[1], deoj_buffer[2],\n\tesv_buffer[0], opc_buffer[0], epc_buffer[0], pdc_buffer[0]]);\n\n// add EDT data\nif (edt_buffer.length !== 0) {\n    msg.payload = Buffer.concat([el_buffer, edt_buffer], \n        (el_buffer.length + edt_buffer.length));\n} else {\n    msg.payload = el_buffer;\n}\n\nmsg.ip = msg.els.ip;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":400,"y":340,"wires":[["086e9c37aeaeb73f"]]},{"id":"086e9c37aeaeb73f","type":"udp out","z":"b85c21964717f67c","name":"","addr":"","iface":"","port":"3610","ipv":"udp4","outport":"","base64":false,"multicast":"multi","x":560,"y":340,"wires":[]},{"id":"1bcfe5e32bfb7ee8","type":"inject","z":"b85c21964717f67c","name":"init.","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payloadType":"date","x":90,"y":40,"wires":[["477f97c0baea1ab2"]]},{"id":"477f97c0baea1ab2","type":"change","z":"b85c21964717f67c","name":"set const","rules":[{"t":"set","p":"tid","pt":"flow","to":"0","tot":"num"},{"t":"set","p":"rtntid","pt":"flow","to":"0","tot":"num"},{"t":"set","p":"ip","pt":"flow","to":"xxx.xxx.xxx.xxx","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":260,"y":40,"wires":[["38f51eccb6f2d466"]]},{"id":"a3a6770475bca34a","type":"change","z":"b85c21964717f67c","name":"tid up","rules":[{"t":"set","p":"tid","pt":"flow","to":"$flowContext(\"tid\") > 254 ? 1 :$flowContext(\"tid\")+1\t","tot":"jsonata"},{"t":"set","p":"num","pt":"flow","to":"num","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":90,"y":340,"wires":[["5d2c38d0e47d2d88"]]},{"id":"dcbb3d3bd2864920","type":"change","z":"b85c21964717f67c","name":"trigger","rules":[{"t":"set","p":"trigger","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":410,"y":420,"wires":[["717bdb12c53fca9f"]]},{"id":"ade4ebce158594b1","type":"delay","z":"b85c21964717f67c","name":"","pauseType":"delay","timeout":"200","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":110,"y":420,"wires":[["3e68f05414f9ae49"]]},{"id":"3e68f05414f9ae49","type":"switch","z":"b85c21964717f67c","name":"loop?","property":"tid","propertyType":"flow","rules":[{"t":"eq","v":"rtntid","vt":"flow"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":270,"y":420,"wires":[["dcbb3d3bd2864920"],["5d2c38d0e47d2d88"]]},{"id":"625ebf051f146439","type":"switch","z":"b85c21964717f67c","name":"filter light","property":"elr.seoj[0]","propertyType":"msg","rules":[{"t":"eq","v":"0x0291","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":380,"y":480,"wires":[["0f40e70fdff1d4ac"],[]]},{"id":"0f40e70fdff1d4ac","type":"switch","z":"b85c21964717f67c","name":"ESV","property":"elr.esv","propertyType":"msg","rules":[{"t":"eq","v":"0x71","vt":"num"},{"t":"eq","v":"0x72","vt":"num"},{"t":"eq","v":"0x73","vt":"num"}],"checkall":"true","repair":false,"outputs":3,"x":510,"y":480,"wires":[["e9bd206124b655b2"],["eeeebc86a9fcfd46"],["eeeebc86a9fcfd46"]]},{"id":"e9bd206124b655b2","type":"change","z":"b85c21964717f67c","name":"set rtntid","rules":[{"t":"set","p":"rtntid","pt":"flow","to":"elr.tid","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":640,"y":440,"wires":[[]]},{"id":"1e174b2edd341b8c","type":"ui_switch","z":"b85c21964717f67c","name":"","label":"switch","tooltip":"","group":"f13025dc.ef0068","order":4,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"topic","topicType":"msg","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","animate":false,"className":"","x":130,"y":100,"wires":[["7d40b967aae0c187"]]},{"id":"7d40b967aae0c187","type":"change","z":"b85c21964717f67c","name":"set var","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"0x30","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"0x31","tot":"str"},{"t":"set","p":"num","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":100,"wires":[["717bdb12c53fca9f"]]},{"id":"eeeebc86a9fcfd46","type":"switch","z":"b85c21964717f67c","name":"EPC","property":"elr.epc","propertyType":"msg","rules":[{"t":"eq","v":"0x80","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":630,"y":480,"wires":[["f942085872416cdb"]]},{"id":"f942085872416cdb","type":"change","z":"b85c21964717f67c","name":"set sw","rules":[{"t":"set","p":"payload","pt":"msg","to":"elr.edt[0]","tot":"msg"},{"t":"change","p":"payload","pt":"msg","from":"0x30","fromt":"num","to":"true","tot":"bool"},{"t":"change","p":"payload","pt":"msg","from":"0x31","fromt":"num","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":70,"y":560,"wires":[["0c3fafda21ad5275"]]},{"id":"0c3fafda21ad5275","type":"switch","z":"b85c21964717f67c","name":"sw sort","property":"elr.seoj[1]","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"num"},{"t":"eq","v":"4","vt":"num"}],"checkall":"true","repair":false,"outputs":4,"x":220,"y":560,"wires":[["1e174b2edd341b8c"],["355136b001189a5e"],["95feeb20a4b43e0c"],["f6ae3629061dc573"]]},{"id":"717bdb12c53fca9f","type":"simple-queue","z":"b85c21964717f67c","name":"","firstMessageBypass":true,"bypassInterval":"0","x":460,"y":180,"wires":[["a3a6770475bca34a"]]},{"id":"355136b001189a5e","type":"ui_switch","z":"b85c21964717f67c","name":"","label":"switch","tooltip":"","group":"f13025dc.ef0068","order":4,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"topic","topicType":"msg","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","animate":false,"className":"","x":130,"y":160,"wires":[["47fbee85f4135747"]]},{"id":"47fbee85f4135747","type":"change","z":"b85c21964717f67c","name":"set var","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"0x30","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"0x31","tot":"str"},{"t":"set","p":"num","pt":"msg","to":"2","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":160,"wires":[["717bdb12c53fca9f"]]},{"id":"38f51eccb6f2d466","type":"function","z":"b85c21964717f67c","name":"status","func":"//  msg.els.ip_string   // ip address (String)\n//  msg.els.tid         // TID (Int)\n//  msg.els.seoj        // SEOJ ([Int:device, Int:instance])\n//  msg.els.deoj        // DEOJ ([Int:device, Int:instance])\n//  msg.els.esv         // ESV (Int)\n//  msg.els.epc         // EPC (Int)\n//  msg.els.edt_int     // EDT ([Int])\n\nmsg.els = {\n    \"ip\" : flow.get(\"ip\"),\n    \"tid\" : 0,\n    \"seoj\" : [0x05ff,1],\n    \"deoj\" : [0x0291,0],\n    \"esv\" : 0x62,\n    \"epc\" : 0x80,\n    \"edt\" : [0x30]\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":40,"wires":[["60024e3da3add6fc"]]},{"id":"95feeb20a4b43e0c","type":"ui_switch","z":"b85c21964717f67c","name":"","label":"switch","tooltip":"","group":"f13025dc.ef0068","order":4,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"topic","topicType":"msg","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","animate":false,"className":"","x":130,"y":220,"wires":[["b94d8e1d738f9cb9"]]},{"id":"b94d8e1d738f9cb9","type":"change","z":"b85c21964717f67c","name":"set var","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"0x30","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"0x31","tot":"str"},{"t":"set","p":"num","pt":"msg","to":"3","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":220,"wires":[["717bdb12c53fca9f"]]},{"id":"f6ae3629061dc573","type":"ui_switch","z":"b85c21964717f67c","name":"","label":"switch","tooltip":"","group":"f13025dc.ef0068","order":4,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"topic","topicType":"msg","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","animate":false,"className":"","x":130,"y":280,"wires":[["c0f226aa7e24935c"]]},{"id":"c0f226aa7e24935c","type":"change","z":"b85c21964717f67c","name":"set var","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"0x30","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"0x31","tot":"str"},{"t":"set","p":"num","pt":"msg","to":"4","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":280,"wires":[["717bdb12c53fca9f"]]},{"id":"f13025dc.ef0068","type":"ui_group","name":"buttons","tab":"67ec7f3f.c65bb8","order":6,"disp":false,"width":1,"collapse":false},{"id":"67ec7f3f.c65bb8","type":"ui_tab","name":"ホーム","icon":"dashboard","disabled":false,"hidden":false}]
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?