Skip to content

Commit

Permalink
Added support for Node-Red
Browse files Browse the repository at this point in the history
  • Loading branch information
JsBergbau authored Nov 25, 2020
1 parent fd22129 commit 93953a8
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 7 deletions.
1 change: 1 addition & 0 deletions MiTemperature2 Node-Red Flows.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"id":"daf0a88c.dc899","type":"exec","z":"b451655f.5db818","command":"/home/pi/MiTemperature2/LYWSD03MMC.py","addpay":true,"append":"","useSpawn":"true","timer":"","oldrc":false,"name":"","x":890,"y":580,"wires":[["2aba88fc.35ad48"],[],[]]},{"id":"7792f3e3.90fa54","type":"debug","z":"b451655f.5db818","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":990,"y":800,"wires":[]},{"id":"95cb1a53.33c6e","type":"http in","z":"b451655f.5db818","name":"","url":"/MiTemperature2Input","method":"post","upload":false,"swaggerDoc":"","x":140,"y":960,"wires":[["2039f2f0.1132a6","9c3ed4d1.6fdfa"]]},{"id":"2039f2f0.1132a6","type":"http response","z":"b451655f.5db818","name":"","statusCode":"","headers":{},"x":470,"y":1020,"wires":[]},{"id":"9c3ed4d1.6fdfa","type":"change","z":"b451655f.5db818","name":"sensorlist","rules":[{"t":"set","p":"sensors","pt":"msg","to":"{\"info\":{\"info1\":\"MAC Adresses must be in UPPERCASE otherwise sensor won't be found by the script\",\"info2\":\"now all available options are listet. If offset1, offset2, calpoint1 and calpoint2 are given 2Point calibration is used instead of humidityOffset.\",\"info3\":\"Note options are case sensitive\",\"sensorname\":\"Specify an easy readable name\",\"humidityoffset\":-5,\"offset1\":-10,\"offset2\":10,\"calpoint1\":33,\"calpoint2\":75},\"BD:AD:CA:1F:4D:12\":{\"sensorname\":\"Living Room\",\"offset1\":-2,\"offset2\":2,\"calpoint1\":33,\"calpoint2\":75}}","tot":"json"},{"t":"set","p":"processOnlyListedSensors","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":960,"wires":[["5ea7697d.8ef96"]]},{"id":"5ea7697d.8ef96","type":"function","z":"b451655f.5db818","name":"Process and calibrate sensors","func":"processOnlyListedSensors = msg.processOnlyListedSensors || false;\n\nfunction calibrateHumidity2Points(humidity, offset1, offset2, calpoint1, calpoint2)\n{\n p1y=calpoint1\n\tp2y=calpoint2\n\tp1x=p1y - offset1\n\tp2x=p2y - offset2\n\tm = (p1y - p2y) * 1.0 / (p1x - p2x)\n\tb = p2y - m * p2x //would be more efficient to do this calculations only once\n\thumidityCalibrated=m*humidity + b\n\tif (humidityCalibrated > 100 ) //with correct calibration this should not happen\n\t{\n\t humidityCalibrated = 100\n\t}\n\telse if (humidityCalibrated < 0)\n\t{\n\t\thumidityCalibrated = 0\n\t}\n\thumidityCalibrated=Math.round(humidityCalibrated,0)\n\treturn humidityCalibrated\n}\n\n//\"A4:C1:38:69:E2:7C\"\nmsg.topic = msg.payload.sensor;\n\nif (msg.payload.sensor in msg.sensors )\n{\n sensor = msg.payload.sensor;\n sensordaten = msg.sensors[sensor];\n msg.payload.sensor = sensordaten.sensorname;\n msg.topic = msg.payload.sensor;\n if (\"offset1\" in sensordaten && \"offset2\" in sensordaten && \"calpoint1\" in sensordaten && \"calpoint2\" in sensordaten)\n {\n msg.payload.humidity = calibrateHumidity2Points(msg.payload.humidity, sensordaten.offset1, sensordaten.offset2, sensordaten.calpoint1,sensordaten.calpoint2);\n }\n else if (\"humidityOffset\" in sensordaten)\n {\n msg.payload.humidity = msg.payload.humidity + sensordaten.humidityOffset\n }\n \n return msg;\n}\nelse if (! processOnlyListedSensors)\n{\n return msg;\n}\n//drop message because only listed sensors should be processed here","outputs":1,"noerr":0,"initialize":"","finalize":"","x":750,"y":960,"wires":[["7792f3e3.90fa54","bf91ceb1.25764","90123f90.4d9d68","638a88d4.074aa8"]]},{"id":"bf91ceb1.25764","type":"change","z":"b451655f.5db818","name":"Process for influxdb","rules":[{"t":"set","p":"measurement","pt":"msg","to":"tempMeasurement","tot":"str"},{"t":"set","p":"precision","pt":"msg","to":"s","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"[\t{\t \"Temperature\" : $.payload.temperature,\t \"humidity\" : $.payload.humidity,\t \"voltage\": $.payload.voltage,\t \"time\" : $floor($.payload.timestamp/25)*25\t},\t{\t \"Sensorname\": $.topic\t}\t]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1080,"y":960,"wires":[["a438ce61.05b658"]]},{"id":"ed315d87.37ac4","type":"inject","z":"b451655f.5db818","name":"Start LYWSD03MMC.py in ATC Mode","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"--atc --watchdogtimer 5 --callback sendToNodeRed.sh","payloadType":"str","x":190,"y":520,"wires":[["fe9408d0.f79758"]]},{"id":"2aba88fc.35ad48","type":"debug","z":"b451655f.5db818","name":"Check if everything is correct running","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1290,"y":560,"wires":[]},{"id":"b3c3da71.8e80b8","type":"comment","z":"b451655f.5db818","name":"Execute LYWSD03MMC.py directly in Node-RED","info":"Of course you can still run it via normal commandline / cronjob / ...\n","x":200,"y":460,"wires":[]},{"id":"4128ee0d.2701d8","type":"comment","z":"b451655f.5db818","name":"Node-Red input interface for LYWSD03MMC sensors ","info":"","x":220,"y":740,"wires":[]},{"id":"a438ce61.05b658","type":"influxdb out","z":"b451655f.5db818","influxdb":"f1b4eaef.a4fb88","name":"","measurement":"","precision":"","retentionPolicy":"","x":1410,"y":960,"wires":[]},{"id":"8a07fb58.2a3da8","type":"comment","z":"b451655f.5db818","name":"Change here for your sensorlist","info":"If you want to output all your sensors, not only from your sensorlist, set \"processOnlyListedSensors\" to \"false\"","x":550,"y":920,"wires":[]},{"id":"7e5b3940.65cf3","type":"comment","z":"b451655f.5db818","name":"Change here your measurement name","info":"The time for influx chunked into 25s segments, ideal for an advertisment intervall of 10s in ATC firmware. With storing the data every 25s, almost every timestamp is stored. This leads to RLE compression of the timestamp thus saving a lot of space in influxdb.\nWith an interval of 20 seconds in tests it occured quite often, that timestamp slots were not filled and thus no RLE compression can be used.","x":1130,"y":920,"wires":[]},{"id":"638a88d4.074aa8","type":"switch","z":"b451655f.5db818","name":"Filter sensor","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"Living Room","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1050,"y":1160,"wires":[["78bc1bab.99eb6c"]]},{"id":"78bc1bab.99eb6c","type":"debug","z":"b451655f.5db818","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1350,"y":1160,"wires":[]},{"id":"90123f90.4d9d68","type":"switch","z":"b451655f.5db818","name":"Filter receiver","property":"req.ip","propertyType":"msg","rules":[{"t":"eq","v":"192.168.178.14","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":1060,"y":1100,"wires":[["d5118881.e987d8"]]},{"id":"d5118881.e987d8","type":"debug","z":"b451655f.5db818","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1370,"y":1100,"wires":[]},{"id":"36855753.1717e8","type":"comment","z":"b451655f.5db818","name":"Debug / informational part","info":"You can filter here for output of the values of different sensors\n\nAnd you can filter which device sent the input in case you have multiple receivers.","x":1090,"y":1040,"wires":[]},{"id":"5a8ecb18.98f1b4","type":"inject","z":"b451655f.5db818","name":"Stop Process","props":[{"p":"kill","v":"","vt":"date"},{"p":"reset","v":"","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":110,"y":580,"wires":[["fe9408d0.f79758","daf0a88c.dc899"]]},{"id":"fe9408d0.f79758","type":"trigger","z":"b451655f.5db818","name":"Ensure only one instance","op1":"","op2":"0","op1type":"pay","op2type":"str","duration":"0","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":530,"y":520,"wires":[["daf0a88c.dc899"]]},{"id":"f1b4eaef.a4fb88","type":"influxdb","hostname":"192.168.0.5","port":"8086","protocol":"http","database":"my_db","name":"","usetls":false,"tls":"46d32926.4dead8"},{"id":"46d32926.4dead8","type":"tls-config","name":"","cert":"","key":"","ca":"","certname":"m2mqtt_srv.crt","keyname":"m2mqtt_srv.key","caname":"m2mqtt_ca.crt","verifyservercert":false}]
46 changes: 46 additions & 0 deletions iniToJSON.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/python3

import configparser
import argparse
import os
import json as JSON

parser = argparse.ArgumentParser(allow_abbrev=False)
parser.add_argument("--readfile", "-rf", help="Specify filename of ini-File to convert",
metavar='filename', required=True)
parser.add_argument("--writefile", "-wf", help="Specify filename of json-File to convert",
metavar='filename')
args=parser.parse_args()

if not os.path.exists(args.readfile):
print("Error specified device list file '",
args.devicelistfile, "' not found")
os._exit(1)
sensors = configparser.ConfigParser()
sensors.read(args.readfile)

json="{"
for sensor in sensors:
if sensor == "DEFAULT":
continue

json +='"'+sensor+'" : {'
for option in sensors.options(sensor):
json += '"' + option +'" : '
if option == "sensorname" or option[:-1] == "info":
optionvalue = '"'+sensors[sensor][option] + '",'
else:
optionvalue = sensors[sensor][option] + ','
json += optionvalue + ""
json = json[:-1] + "},"
json = json[:-1] + "}"

#print(json)

json=JSON.loads(json)

if args.writefile:
output = open(args.writefile,"x")
output.write(JSON.dumps(json, indent=4))
else:
print(JSON.dumps(json, indent=4))
28 changes: 28 additions & 0 deletions jsonToIni.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/python3

import configparser
import argparse
import os
import json as JSON

parser = argparse.ArgumentParser(allow_abbrev=False)
parser.add_argument("--readfile", "-rf", help="Specify filename of json-File to convert",
metavar='filename', required=True)
parser.add_argument("--writefile", "-wf", help="Specify filename of json-File to convert",
metavar='filename', required=True)
args = parser.parse_args()

if not os.path.exists(args.readfile):
print("Error specified device list file '",
args.devicelistfile, "' not found")
os._exit(1)

with open (args.readfile,"r") as json_file:
json=JSON.load(json_file)

# for key in json:
# print(key)
sensors = configparser.ConfigParser()
sensors.read_dict(json)
with open (args.writefile,"x") as ini_file:
sensors.write(ini_file)
10 changes: 10 additions & 0 deletions sendToNodeRed.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

#use e.g with that script: MySensors.sh
#!/bin/bash
#DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
#$DIR/LYWSD03MMC.py --atc --watchdogtimer 5 --callback sendToNodeRed.sh


curl -s -i -XPOST http://192.168.178.21:1880/MiTemperature2Input -H "Content-Type: application/json" --data "{\"sensor\": \"$2\", \"temperature\" : $3 , \"humidity\" : $4 , \"voltage\" :$5, \"timestamp\": $6 }"

16 changes: 9 additions & 7 deletions sensors.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[default]
[info]
info1=MAC Adresses must be in UPPERCASE otherwise sensor won't be found by the script
info2=now all available options are listet. If offset1, offset2, calpoint1 and calpoint2 are given 2Point calibration is used instead of humidityOffset.
info3= Note options are case sensitive
Expand All @@ -7,18 +7,20 @@ sensorname=Specify an easy readable name
humidityOffset=-5
offset1 = -10
offset2 = 10
calpoint1 = 75
calpoint2 = 33
calpoint1 = 33
calpoint2 = 75
;[AA:BB:CC:DD:EE:FF]
; sensorname=Bathroom
; humidityOffset=-30
; offset1 = -10
; offset2 = -10
; calpoint1 = 75
; calpoint2 = 33
; calpoint1 = 33
; calpoint2 = 75
[BD:AD:CA:1F:4D:12]
sensorname=Living Room
humidityOffset=10
offset1 = -10
offset1 = -2
offset2 = 2
calpoint1 = 33
calpoint2 = 75

0 comments on commit 93953a8

Please sign in to comment.