Last active
August 29, 2015 14:02
-
-
Save industrialinternet/54c2fe757801babc0b5b to your computer and use it in GitHub Desktop.
Node-Red EnOcean Radio telegram functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
These are very basic Node-Red funtions I will in time convert to NR nodes. | |
They require the ENO300 USB module and use nr-serail-in | |
57600 8 None 1 | |
Split input: after fixed timeout 50ms | |
and deliver: binary buffers | |
I've done all my testing on Raspberry PI. | |
Please note the send switch funtion need you to set a Base ID to support 128 ID else it will only use the chip ID which means only 1 channel. That said any EnOcean-ers out thier that can help get chip ID working would love your help :) | |
Will add a standalone setBaseID.js node.js that sp you can configure from command line. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[{"id":"42ec8800.bd1378","type":"serial-port","serialport":"/dev/ttyUSB0","serialbaud":"57600","databits":"8","parity":"none","stopbits":"1","newline":"50","bin":"bin","out":"time","addchar":"false"},{"id":"312bf663.ced40a","type":"serial in","name":"enocean","serial":"42ec8800.bd1378","x":92,"y":105,"z":"a853296f.57acd8","wires":[["9d8d2bd7.6272d8"]]},{"id":"9d8d2bd7.6272d8","type":"function","name":"Enocean - Decode","func":"// EnOcean in v0.1\n// Only supports: Packet Type 1: RADIO \n// Only supports: RPS Switch and 4Byte Telegrams\n\nvar data = msg.payload;\n//console.log('telgram in: ' + data.toString('hex')+' len:'+data.length);\n// handel RPS and 4BS telegrams \nif( toHex(data[0]) == \"55\" && (data.length >=12 && toHex(data[6]) ==\"f6\") || (data.length >=15 && toHex(data[6]) ==\"a5\")){\t\n\tpacket = data.toString('hex');\n\tif(toHex(data[6]) == \"f6\"){\n\t\tENOreciveSW(toHex(data[7]),packet);\n\t\tmsg.not4bs = true;\n\t}\t\t\t\t\n\telse if(toHex(data[6]) == \"a5\"){\n\t\tENOrecive4BS(packet);\n\t}\n\telse {\n\t\tmsg.payload = null;\n\t}\n}\n// handle responce from CO_RD_IDBASE - read base id\nif(toHex(data[0]) == \"55\" && toHex(data[4]) ==\"2\" && toHex(data[6]) ==\"0\" && data.length >=12){\n\t//console.log(\"read base ID responce:\"+ data.toString('hex'));\n\tvar d= new Date();\n\tvar utc = d.toUTCString();\n\tvar baseID = toHex(data[7])+toHex(data[8])+toHex(data[9])+toHex(data[10]);\n\tvar noOfWritesLeft = toHex(data[11]);\n\t//msg.payload= {\"baseID\":\"\"+baseID+\"\",\"noOfWritesLeft\":+\"\"+\"\"};\n\tmsg.payload= {\"baseID\":\"\"+baseID+\"\",\"noOfWritesLeft\":+noOfWritesLeft,\"utc\":\"\"+utc+\"\"};\n\tmsg.not4bs = true;\n\tmsg.baseID= baseID;\n\tmsg.noOfWritesLeft = noOfWritesLeft;\n\tmsg.fileName=\"enoWrites.json\";\n\tmsg.utc=utc;\n}\t\n// handle responce from CO_WR_IDBASE - write base id\nif( toHex(data[2]) == \"1\" && toHex(data[4]) == \"2\"){\n\tif(toHex(data[6]) == \"0\"){\n\t\tmsg.ENOresponce= 'OK';\n\t} else if (toHex(data[6]) == \"2\"){\n\t\tmsg.ENOresponce= 'Error: baseID not surported';\n\t} else if (toHex(data[6]) == \"82\"){\n\t\tmsg.ENOresponce= 'Error: writing baseID to flash!';\n\t} else if (toHex(data[6]) == \"90\"){\n\t\tmsg.writeBaseRes= 'Error: baseID out of range!';\n\t} else if (toHex(data[6]) == \"91\"){\n\t\tmsg.ENOresponces= \"Eoor: can't write baseID no more changes allowed!\";\n\t} \n}\n// complete\nreturn msg;\n\n// support funtions\nfunction toHex(s){\n\t return _s = s.toString(16);\n} \nfunction ENOreciveSW(swState,packet){\n\tmsg.type= \"F6: RPS Telegram\";\n\tif(swState == \"ff\"){ // invalid sw states\n\t\tmsg.payload= null;\n\t\tmsg.state= swState;\n\t\treturn;\n\t}\n\tif(swState == \"00\" || swState == \"0\"){ // Rocker released \n\t\tmsg.payload= packet.substring(16,24);\n\t\tmsg.state= \"released\";\n\t\treturn;\n\t}\n\tif(swState == \"10\" || swState == \"50\" || swState == \"30\" || swState == \"70\"){ // Rocker pressed 1 or 2 gang switch\n\t\tif(swState == \"10\" || swState == \"50\"){msg.state= true;}\n\t\tif(swState == \"30\" || swState == \"70\"){msg.state= false;}\n\t\tif(swState == \"10\" || swState == \"30\"){msg.rocker= \"b\";}\n\t\tif(swState == \"50\" || swState == \"70\"){msg.rocker= \"a\";}\t\t\t\n\t\tmsg.payload= packet.substring(16,24); \n\t\tmsg.dPID= msg.payload+\"_\"+msg.rocker;\n\t}\n}\nfunction ENOrecive4BS(packet){\n\tmsg.type = \"A5: 4BS Telegram\";\n\tmsg.DB3= packet.substring(14,16);\n\tmsg.DB2= packet.substring(16,18);\n\tmsg.DB1= packet.substring(18,20);\n\tmsg.DB0= packet.substring(20,22);\n\tmsg.DBall=[msg.DB0,msg.DB1,msg.DB2,msg.DB3];\n\tmsg.payload= packet.substring(22,30);\n\tmsg.dPID= msg.payload;\n}\n","outputs":"1","x":290,"y":105,"z":"a853296f.57acd8","wires":[["db22762c.24dd88","f39a026b.0c66","3fcf9af0.c03066"]]},{"id":"db22762c.24dd88","type":"debug","name":"","active":true,"console":"false","complete":"true","x":469,"y":63,"z":"a853296f.57acd8","wires":[]},{"id":"5b39c164.a4c64","type":"comment","name":"In","info":"","x":90,"y":67,"z":"a853296f.57acd8","wires":[]},{"id":"ad54be5d.52ab4","type":"comment","name":"EnOcean canvas v0.1","info":"","x":1050,"y":35,"z":"a853296f.57acd8","wires":[]},{"id":"3bb0ae8.fc44f52","type":"function","name":"Send telegramd","func":"var CRC8Table = [\n 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, \n 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, \n 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, \n 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, \n 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, \n 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, \n 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, \n 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, \n 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, \n 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, \n 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, \n 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, \n 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, \n 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a, \n 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, \n 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, \n 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, \n 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, \n 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, \n 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, \n 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, \n 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, \n 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c, \n 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, \n 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, \n 0x76, 0x71, 0x78, 0x7f, 0x6A, 0x6d, 0x64, 0x63, \n 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, \n 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, \n 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, \n 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8D, 0x84, 0x83, \n 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, \n 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3\n];\n// EnOcean telegram crc & functions\nfunction proccrc8(CRC, u8Data){ \n\treturn CRC8Table[(CRC ^ u8Data) & 0xff];\n}\nfunction ESP3HeaderCRC(telegramHeader){\n\tu8CRC = 0;\n\tu8CRC = proccrc8(u8CRC,telegramHeader[1]);\n\tu8CRC = proccrc8(u8CRC,telegramHeader[2]);\n\tu8CRC = proccrc8(u8CRC,telegramHeader[3]);\n\tu8CRC = proccrc8(u8CRC,telegramHeader[4]);\n\treturn u8CRC;\n}\nfunction ESP3DataCRC(telegramData){\n\tu8CRC = 0;\n\tfor (var dbyte in telegramData){\n\t\tu8CRC = proccrc8(u8CRC,telegramData[dbyte])\n\t}\n\treturn u8CRC;\n}\nfunction ESP3Header(packetType,packetData){\n\tpHeader = [0x55]; \t\t\t\t\t//sync\n\tpHeader.push(0x00); \t\t\t\t//MSB Data Length\n\tpHeader.push(packetData.length);\t//LSB Data Length\n\tpHeader.push(0x00); \t\t\t\t//optional data length\n\tpHeader.push(packetType); \t\t\t//packet type\n\tpHeader.push(ESP3HeaderCRC(pHeader));//Header CRC\n\treturn pHeader;\n}\n\nfunction sendESP3Packet_V2(packetType, packetData){\n\n\tpESP3Packet = ESP3Header(packetType,packetData);\n\tfor(pi=0; pi<packetData.length; pi++){\n\t\tpESP3Packet.push(packetData[pi]); \n\t}\t\n\tpESP3Packet.push(ESP3DataCRC(packetData)); \n\t//console.log(\"tel:\"+pESP3Packet.toString('hex'));\n\n\t//var stel = new Buffer ([0x55,0x00,0x07,0x00,0x01,0x11,0xF6,0x30,0xFF,0x8D,0x67,0x80,0x30,0xD7]); \n\t//var pk = ['syn','dlo','dl1','opl','pt','crc','org','sw','id0','id1','id2','id3','status','crc'];\n\tvar stel = new Buffer(pESP3Packet.length);\n\t\t\n\tfor(bi=0; bi<pESP3Packet.length; bi++){\n\t\t//var hexno = pESP3Packet[bi].toString(16);\n\t\tstel[bi]= pESP3Packet[bi];\n\t\t//console.log(\"stel[\"+bi+\"]\"+stel[bi]+\" hex:\"+hexno+\" dec:\"+pESP3Packet[bi]+\" pk:\"+pk[bi]);\t\t\t\t\n\t}\t\n\tmsg.payload=stel;\n\t//msg.payload=null;\n\tmsg.topic=\"send eno\";\n}\n\nfunction sendESP3Packet(packetType, packetData){\n\n\tpESP3Packet = ESP3Header(packetType,packetData);\n\tfor(pi=0; pi<7; pi++){\n\t\tpESP3Packet.push(packetData[pi]); \n\t}\t\n\tpESP3Packet.push(ESP3DataCRC(packetData)); \n\t//return pESP3Packet;\n\n\t//var stel = new Buffer ([0x55,0x00,0x07,0x00,0x01,0x11,0xF6,0x30,0xFF,0x8D,0x67,0x80,0x30,0xD7]); \n\t//var pk = ['syn','dlo','dl1','opl','pt','crc','org','sw','id0','id1','id2','id3','status','crc'];\n\tvar stel = new Buffer(14);\n\t\t\n\tfor(bi=0; bi<14; bi++){\n\t\t//var hexno = pESP3Packet[bi].toString(16);\n\t\tstel[bi]= pESP3Packet[bi];\n\t\t//console.log(\"stel[\"+bi+\"]\"+stel[bi]+\" hex:\"+hexno+\" dec:\"+pESP3Packet[bi]+\" pk:\"+pk[bi]);\t\t\t\t\n\t}\t\n\tmsg.payload=stel;\n\tmsg.topic=\"send eno\";\n}\nfunction toHex(s){\n return _s = s.toString(16);\n}\n\nfunction ENOsendSW(_ch,_state){\n\t// Note math only good for base + 78 channels re-wite to support 128\n\t//var x=parseInt(enoBaseIDlastByte);\n\tvar x=parseInt( enoBaseID[3]);\n\tvar z=x+_ch;\n\tvar channel = \"0x\"+z.toString(16);\n\tif(_state==true || _state==\"true\"){ \n\t\tsendESP3Packet_V2(0x01, [0xF6,0x10,enoBaseID[0],enoBaseID[1],enoBaseID[2],\"\"+channel+\"\",0x30]); // on/up/dim-up pressed\n\t} else {\t// Radio =01 RORG=F6 State BaseID Status \n\t\tsendESP3Packet_V2(0x01, [0xF6,0x30,enoBaseID[0],enoBaseID[1],enoBaseID[2],\"\"+channel+\"\",0x30]); // off/down/dim-down pressed\n\t}\n}\n// To use all 128 channels use setbase id\nvar enoBaseID= [0xFF,0xFF,0x46,0x80]; \n\n// Handel send switch\n// console.log(\"msg.state:\"+msg.state);\nif(msg.action == \"setSW\"){\n\tENOsendSW(msg.channel,msg.state);\n}\n\n// Handel set baseID WARNING you only write 10 times \nif(msg.action == \"setBaseID\"){\n\t// set baseID\n\tsendESP3Packet_V2(0x05, [0x07,enoBaseID[0],enoBaseID[1],enoBaseID[2],enoBaseID[3]]); // on/up/dim-up pressed\n}\nreturn msg;","outputs":1,"x":497,"y":233,"z":"a853296f.57acd8","wires":[["84af399d.7b50c8","5c7eb0b1.a3815"]]},{"id":"84af399d.7b50c8","type":"serial out","name":"enocean out","serial":"42ec8800.bd1378","x":719,"y":233,"z":"a853296f.57acd8","wires":[]},{"id":"e7800889.187ff8","type":"inject","name":"Toggle","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":110,"y":233,"z":"a853296f.57acd8","wires":[["ee5b7895.11a488"]]},{"id":"5c7eb0b1.a3815","type":"debug","name":"","active":false,"console":"false","complete":"true","x":703,"y":275,"z":"a853296f.57acd8","wires":[]},{"id":"b1acc523.4e5338","type":"comment","name":"Out","info":"","x":88,"y":194,"z":"a853296f.57acd8","wires":[]},{"id":"f39a026b.0c66","type":"function","name":"EnOcean - 4BS EEP","func":"// Convert 4Bs to equipment profile\n// Only supports profiles:\n// A5.02.05 & A5.10.03 \t\n\nif(msg.payload == null){\n\treturn;\n} else { \n\tvar ENOid = msg.payload;\n}\n\n// add the id & profile of your sensor below \nvar profileConfig = {\n\t\"0000deff\": {\n\t\t\"type\": \"A5.02.05\",\n\t\t \"name\": \"EnOcean: external temp\"\n\t}, \t\n\t\"0000de7b\": {\n\t\t\"type\": \"A5.10.03\",\n\t\t\"name\": \"EnOcean: office temp\",\n\t\t\"scaleSetpoint\" : [0,25]\t\t\n\t}\n};\n\nvar type = null;\nif(ENOid in profileConfig){\n\ttype = profileConfig[ENOid].type;\n} \n//console.log(\"ENOid\"+ENOid+\" DBall\"+msg.DBall+\" type:\"+type);\n\nENO_A5_4BS_profiles(ENOid,msg.DBall,type);\nreturn msg;\n\nfunction ENO_A5_4BS_profiles(ENOid,DBall,type){ \n\t// only supports profiles:\n\t// A5.02.05 & A5.10.03 \t\n\tswitch(type)\n\t\t{\n\t\tcase \"A5.02.02\":\n\t\t\tvar rawTmp= parseInt(DBall[1],16) * 0.3137254;\n\t\t\tvar tmp= 60.0 - rawTmp;\n\t\t\ttemprature= tmp.toFixed(1);\n\t\t\tmsg.type= \"A5.02.05\";\n\t\t\tmsg.DB1= temprature;\n\t\t\tbreak;\n\t\tcase \"A5.10.03\":\n\t\t\tvar rawTmp= parseInt(DBall[1],16) * 0.15686;\n\t\t\tvar tmp= 40.0 - rawTmp;\n\t\t\ttemprature= tmp.toFixed(1); \n\t\t\tmsg.type= \"A5.10.03\";\n\t\t\tmsg.DB2= DBall[2];\n\t\t\tmsg.DB1=temprature;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tmsg.type= \"No profile for id:\"+ENOid;\n\t\t\t//console.log('EnOcean: no profile match for sensor id:'+msg.payload);\n\t\t}\n}","outputs":1,"x":511,"y":105,"z":"a853296f.57acd8","wires":[[]]},{"id":"4a3a6496.b5c59c","type":"function","name":"get baseID","func":"var stel = new Buffer ([0x55,0x00,0x01,0x00,0x05,0x70,0x08,0x38]);\n // 55 00 01 00 05 70 08 38\nmsg.payload=stel;\nmsg.topic=\"get base id\";\nreturn msg;","outputs":1,"x":484,"y":519,"z":"a853296f.57acd8","wires":[["84af399d.7b50c8"]]},{"id":"aece928d.51317","type":"inject","name":"Get baseID","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":106,"y":519,"z":"a853296f.57acd8","wires":[["4a3a6496.b5c59c"]]},{"id":"ee5b7895.11a488","type":"function","name":"setSw ch:1","func":"context.state = context.state || false;\nif(context.state == false){\n context.state = true;\n} else {\n context.state = false;\n}\n// msg\nmsg.action = \"setSW\";\nmsg.channel = 0x01;\nmsg.state= context.state;\nreturn msg;","outputs":1,"x":243,"y":233,"z":"a853296f.57acd8","wires":[["3bb0ae8.fc44f52"]]},{"id":"c257ad31.3da85","type":"function","name":"setSw ch:2","func":"context.state = context.state || false;\nif(context.state == false){\n context.state = true;\n} else {\n context.state = false;\n}\n// msg\nmsg.action = \"setSW\";\nmsg.channel = 0x02;\nmsg.state= context.state;\nreturn msg;","outputs":1,"x":245,"y":281,"z":"a853296f.57acd8","wires":[["3bb0ae8.fc44f52"]]},{"id":"66cdd1e.f99323","type":"inject","name":"Toggle","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":108,"y":281,"z":"a853296f.57acd8","wires":[["c257ad31.3da85"]]},{"id":"991cf300.66e31","type":"inject","name":"Set baseID","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":106,"y":477,"z":"a853296f.57acd8","wires":[["76bdfc09.894204"]]},{"id":"c96627bb.3699d8","type":"function","name":"setBaseID","func":"// msg\nconsole.log(\"gateway:\"+msg.payload);\nmsg.action = \"setBaseID\";\nreturn msg;","outputs":1,"x":701,"y":477,"z":"a853296f.57acd8","wires":[["3bb0ae8.fc44f52"]]},{"id":"76bdfc09.894204","type":"file in","name":"","filename":"enoWrites.json","format":"utf8","x":281,"y":477,"z":"a853296f.57acd8","wires":[["c92fd527.36d028"]]},{"id":"bf96985e.406968","type":"file","name":"","filename":"enoWrites.json","appendNewline":false,"overwriteFile":true,"x":713,"y":552,"z":"a853296f.57acd8","wires":[]},{"id":"c92fd527.36d028","type":"json","name":"baseIDobj","x":483,"y":478,"z":"a853296f.57acd8","wires":[["c96627bb.3699d8"]]},{"id":"3fcf9af0.c03066","type":"switch","name":"write to file?","property":"fileName","rules":[{"t":"eq","v":"enoWrites.json"},{"t":"eq","v":""}],"checkall":"false","outputs":2,"x":487,"y":558,"z":"a853296f.57acd8","wires":[["bf96985e.406968"],[]]},{"id":"cbb799f8.344868","type":"comment","name":"Set & Manage baseID","info":"","x":121,"y":428,"z":"a853296f.57acd8","wires":[]}] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// EnOcean in v0.1 | |
// Only supports: Packet Type 1: RADIO | |
// Only supports: RPS Switch and 4Byte Telegrams | |
var data = msg.payload; | |
//console.log('telgram in: ' + data.toString('hex')+' len:'+data.length); | |
if( toHex(data[0]) == "55" && (data.length >=12 && toHex(data[6]) =="f6") || (data.length >=15 && toHex(data[6]) =="a5")){ | |
packet = data.toString('hex'); | |
if(toHex(data[6]) == "f6"){ | |
ENOreciveSW(toHex(data[7]),packet); | |
} | |
else if(toHex(data[6]) == "a5"){ | |
ENOrecive4BS(packet); | |
} | |
else { | |
msg.payload = null; | |
} | |
} | |
// handle responce from CO_RD_IDBASE - read base id | |
if(toHex(data[0]) == "55" && toHex(data[4]) =="2" && toHex(data[6]) =="0" && data.length >=12){ | |
console.log("read base ID responce:"+ data.toString('hex')); | |
msg.payload= null; | |
msg.baseID= toHex(data[7])+toHex(data[8])+toHex(data[9])+toHex(data[10]); | |
msg.noOfWrites = +toHex(data[11]); | |
} | |
return msg; | |
function toHex(s){ | |
return _s = s.toString(16); | |
} | |
function ENOreciveSW(swState,packet){ | |
msg.type= "F6: RPS Telegram"; | |
if(swState == "ff"){ // invalid sw states | |
msg.payload= null; | |
msg.state= swState; | |
return; | |
} | |
if(swState == "00" || swState == "0"){ // Rocker released | |
msg.payload= packet.substring(16,24); | |
msg.state= "released"; | |
return; | |
} | |
if(swState == "10" || swState == "50" || swState == "30" || swState == "70"){ // Rocker pressed 1 or 2 gang switch | |
if(swState == "10" || swState == "50"){msg.state= true;} | |
if(swState == "30" || swState == "70"){msg.state= false;} | |
if(swState == "10" || swState == "30"){msg.rocker= "b";} | |
if(swState == "50" || swState == "70"){msg.rocker= "a";} | |
msg.payload= packet.substring(16,24); | |
msg.dPID= msg.payload+"_"+msg.rocker; | |
} | |
} | |
function ENOrecive4BS(packet){ | |
msg.type = "A5: 4BS Telegram"; | |
msg.DB3= packet.substring(14,16); | |
msg.DB2= packet.substring(16,18); | |
msg.DB1= packet.substring(18,20); | |
msg.DB0= packet.substring(20,22); | |
msg.DBall=[msg.DB0,msg.DB1,msg.DB2,msg.DB3]; | |
msg.payload= packet.substring(22,30); | |
msg.dPID= msg.payload; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Convert 4Bs to equipment profile | |
// Only supports profiles: | |
// A5.02.05 & A5.10.03 | |
if(msg.payload == null){ | |
return; | |
} else { | |
var ENOid = msg.payload; | |
} | |
// add the id & profile of your sensor below | |
var profileConfig = { | |
"0000deff": { | |
"type": "A5.02.05", | |
"name": "EnOcean: external temp" | |
}, | |
"0000de7b": { | |
"type": "A5.10.03", | |
"name": "EnOcean: office temp", | |
"scaleSetpoint" : [0,25] | |
} | |
}; | |
var type = null; | |
if(ENOid in profileConfig){ | |
type = profileConfig[ENOid].type; | |
} | |
//console.log("ENOid"+ENOid+" DBall"+msg.DBall+" type:"+type); | |
ENO_A5_4BS_profiles(ENOid,msg.DBall,type); | |
return msg; | |
function ENO_A5_4BS_profiles(ENOid,DBall,type){ | |
// only supports profiles: | |
// A5.02.05 & A5.10.03 | |
switch(type) | |
{ | |
case "A5.02.02": | |
var rawTmp= parseInt(DBall[1],16) * 0.3137254; | |
var tmp= 60.0 - rawTmp; | |
temprature= tmp.toFixed(1); | |
msg.type= "A5.02.05"; | |
msg.DB1= temprature; | |
break; | |
case "A5.10.03": | |
var rawTmp= parseInt(DBall[1],16) * 0.15686; | |
var tmp= 40.0 - rawTmp; | |
temprature= tmp.toFixed(1); | |
msg.type= "A5.10.03"; | |
msg.DB2= DBall[2]; | |
msg.DB1=temprature; | |
break; | |
default: | |
msg.type= "No profile for id:"+ENOid; | |
//console.log('EnOcean: no profile match for sensor id:'+msg.payload); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var CRC8Table = [ | |
0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, | |
0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, | |
0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, | |
0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, | |
0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, | |
0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, | |
0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, | |
0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, | |
0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, | |
0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, | |
0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, | |
0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, | |
0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, | |
0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a, | |
0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, | |
0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, | |
0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, | |
0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, | |
0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, | |
0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, | |
0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, | |
0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, | |
0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c, | |
0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, | |
0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, | |
0x76, 0x71, 0x78, 0x7f, 0x6A, 0x6d, 0x64, 0x63, | |
0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, | |
0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, | |
0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, | |
0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8D, 0x84, 0x83, | |
0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, | |
0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3 | |
]; | |
// EnOcean telegram crc & functions | |
function proccrc8(CRC, u8Data){ | |
return CRC8Table[(CRC ^ u8Data) & 0xff]; | |
} | |
function ESP3HeaderCRC(telegramHeader){ | |
u8CRC = 0; | |
u8CRC = proccrc8(u8CRC,telegramHeader[1]); | |
u8CRC = proccrc8(u8CRC,telegramHeader[2]); | |
u8CRC = proccrc8(u8CRC,telegramHeader[3]); | |
u8CRC = proccrc8(u8CRC,telegramHeader[4]); | |
return u8CRC; | |
} | |
function ESP3DataCRC(telegramData){ | |
u8CRC = 0; | |
for (var dbyte in telegramData){ | |
u8CRC = proccrc8(u8CRC,telegramData[dbyte]) | |
} | |
return u8CRC; | |
} | |
function ESP3Header(packetType,packetData){ | |
pHeader = [0x55]; //sync | |
pHeader.push(0x00); //MSB Data Length | |
pHeader.push(packetData.length); //LSB Data Length | |
pHeader.push(0x00); //optional data length | |
pHeader.push(packetType); //packet type | |
pHeader.push(ESP3HeaderCRC(pHeader));//Header CRC | |
return pHeader; | |
} | |
function sendESP3Packet(packetType, packetData){ | |
pESP3Packet = ESP3Header(packetType,packetData); | |
for(pi=0; pi<7; pi++){ | |
pESP3Packet.push(packetData[pi]); | |
} | |
pESP3Packet.push(ESP3DataCRC(packetData)); | |
//return pESP3Packet; | |
//var stel = new Buffer ([0x55,0x00,0x07,0x00,0x01,0x11,0xF6,0x30,0xFF,0x8D,0x67,0x80,0x30,0xD7]); | |
var pk = ['syn','dlo','dl1','opl','pt','crc','org','sw','id0','id1','id2','id3','status','crc']; | |
var stel = new Buffer(14); | |
for(bi=0; bi<14; bi++){ | |
var hexno = pESP3Packet[bi].toString(16); | |
stel[bi]= pESP3Packet[bi]; | |
//console.log("stel["+bi+"]"+stel[bi]+" hex:"+hexno+" dec:"+pESP3Packet[bi]+" pk:"+pk[bi]); | |
} | |
msg.payload=stel; | |
msg.topic="send eno"; | |
} | |
function toHex(s){ | |
return _s = s.toString(16); | |
} | |
function ENOsendSW(_ch,_state){ | |
// Note math only good for base + 78 channels re-wite to support 128 | |
//var x=parseInt(enoBaseIDlastByte); | |
var x=parseInt( enoBaseID[3]); | |
var z=x+_ch; | |
var channel = "0x"+z.toString(16); | |
if(_state==true || _state=="true"){ | |
sendESP3Packet(0x01, [0xF6,0x10,enoBaseID[0],enoBaseID[1],enoBaseID[2],""+channel+"",0x30]); // on/up/dim-up pressed | |
} else { | |
sendESP3Packet(0x01, [0xF6,0x30,enoBaseID[0],enoBaseID[1],enoBaseID[2],""+channel+"",0x30]); // off/down/dim-down pressed | |
} | |
} | |
// To use all 128 channels use setbase id | |
var enoBaseID= [0xFF,0xFF,0x46,0x80]; | |
// Simple inject toggle | |
context.state = context.state || false; | |
if(context.state == false){ | |
ENOsendSW(0x01,true); | |
context.state = true; | |
} else { | |
ENOsendSW(0x01,false); | |
context.state = false; | |
} | |
return msg; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var stel = new Buffer ([0x55,0x00,0x01,0x00,0x05,0x70,0x08,0x38]); | |
// 55 00 01 00 05 70 08 38 | |
msg.payload=stel; | |
msg.topic="get base id"; | |
return msg; | |
function sendESP3Packet(packetType, packetData){ | |
pESP3Packet = ESP3Header(packetType,packetData); | |
for(pi=0; pi<7; pi++){ | |
pESP3Packet.push(packetData[pi]); | |
} | |
pESP3Packet.push(ESP3DataCRC(packetData)); | |
//return pESP3Packet; | |
//var stel = new Buffer ([0x55,0x00,0x07,0x00,0x01,0x11,0xF6,0x30,0xFF,0x8D,0x67,0x80,0x30,0xD7]); | |
//var pk = ['syn','dlo','dl1','opl','pt','crc','org','sw','id0','id1','id2','id3','status','crc']; | |
var stel = new Buffer(14); | |
for(bi=0; bi<14; bi++){ | |
//var hexno = pESP3Packet[bi].toString(16); | |
stel[bi]= pESP3Packet[bi]; | |
//console.log("stel["+bi+"]"+stel[bi]+" hex:"+hexno+" dec:"+pESP3Packet[bi]+" pk:"+pk[bi]); | |
} | |
msg.payload=stel; | |
msg.topic="send eno"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment