123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- #!/usr/bin/python3 -u
- #
- import serial
- from time import sleep
- import os
- import sys
- import paho.mqtt.client as mqtt
- import json
- from datetime import datetime
- # --- CONFIGURATION ---
- import config
- # --- END CONFIGURATION ---
- # --- GLOBAL VARS ---
- noReceiveCount = 0 # increase everytime the serial readline times out (1s timeout)
- #getStatusCount = 0 # used as heartbeat, get status every 30s
- verbose = False
- debug = False
- quiet = True
- lastState_P2 = None
- lastState_P3 = None
- lastState_P4 = None
- lastState_P5 = None
- # --- END GLOBAL VARS ---
- if len(sys.argv) >= 2:
- if sys.argv[1] == "-q":
- verbose = False
- debug = False
- quiet = True
- #print("VERBOSE=ON")
- elif sys.argv[1] == "-v":
- verbose = True
- debug = False
- quiet = False
- #print("VERBOSE=ON")
- elif sys.argv[1] == "-d":
- verbose = True
- quiet = False
- debug = True
- #print("DEBUG=ON")
- def on_connect(client, userdata, flags, rc):
- if not quiet:
- print("MQTT connected with result code " + str(rc))
- #client.subscribe(mqtt_topic_cmd)
-
- #def on_message(client, userdata, msg):
- # if msg.topic == mqtt_topic_cmd:
- # payload = msg.payload.decode('ascii')
- # if payload == "status" or payload == "get conf" or payload == "clear" or payload == "open door" or payload.startswith("set prof ") or payload.startswith("set conf "):
- # if verbose:
- # print("serCmd: " + payload)
- # serCmd = payload + '\n'
- # ser.write(serCmd.encode('ascii'))
- # elif verbose:
- # print("unknown command:", payload)
- def touch(fname, times=None):
- with open(fname, 'a'):
- os.utime(fname, times)
- mqttc = mqtt.Client()
- mqttc.on_connect = on_connect
- #mqttc.on_disconnect = on_disconnect
- #mqttc.on_message = on_message
- mqttc.username_pw_set(config.mqtt_user, config.mqtt_password)
- mqttc.connect(config.mqtt_server, config.mqtt_port, 60)
- mqttc.loop_start()
- ser = serial.Serial(port=config.serialPort,
- baudrate = config.serialBaud,
- parity=serial.PARITY_NONE,
- stopbits=serial.STOPBITS_ONE,
- bytesize=serial.EIGHTBITS,
- timeout=config.serialTimeout)
-
- try:
- while True:
- ##ser.flushInput() ## attention truncates incoming strings if there is little time between them
-
- #read buffer until cr/lf
- serLine = ser.readline().strip()
-
- # catch exception on invalid char coming in: UnicodeDecodeError: 'ascii' codec can't decode byte 0xf4 in position 6: ordinal not in range(128)
- try:
- serLine = serLine.decode('ascii')
- except:
- serLine = ""
-
- # if there came something in...
- if(serLine):
- noReceiveCount = 0
-
- # touch status file if configured
- try:
- config.statusFile
- except:
- if debug:
- print("statusFile not defined")
- else:
- if config.statusFile is not None and config.statusFile != "":
- try:
- touch(config.statusFile)
- except:
- if debug:
- print("ERROR - could not touch statusFile '" + str(config.statusFile) + "'")
- else:
- if debug:
- print("statusFile not configured")
-
- if verbose:
- print ('RX: ' + repr(serLine)) #Echo the serial buffer bytes up to the CRLF back to screen
- mqttc.publish(config.mqtt_base_topic + "/RX", str(serLine), qos=0, retain=False)
-
- # digital input P2
- if serLine.startswith('P2='):
- newState = None
- if serLine == "P2=L":
- newState = "OFF"
- elif serLine == "P2=H":
- newState = "ON"
-
- if newState is not None and (lastState_P2 != newState or not config.P2_MQTT_SendOnlyIfValueChanged):
- lastState_P2 = newState
- mqttc.publish(config.P2_MQTT_Topic, newState, qos=0, retain=config.P2_MQTT_SendRetained)
- if config.P2_MQTT_SendLastUpdate:
- mqttc.publish(config.P2_MQTT_Topic + "_lastUpdate", datetime.now().isoformat(), qos=0, retain=config.P2_MQTT_SendRetained)
-
- # digital input P3
- if serLine.startswith('P3='):
- newState = None
- if serLine == "P3=L":
- newState = "OFF"
- elif serLine == "P3=H":
- newState = "ON"
-
- if newState is not None and (lastState_P3 != newState or not config.P3_MQTT_SendOnlyIfValueChanged):
- lastState_P3 = newState
- mqttc.publish(config.P3_MQTT_Topic, newState, qos=0, retain=config.P3_MQTT_SendRetained)
- if config.P3_MQTT_SendLastUpdate:
- mqttc.publish(config.P3_MQTT_Topic + "_lastUpdate", datetime.now().isoformat(), qos=0, retain=config.P3_MQTT_SendRetained)
-
- # digital input P4
- if serLine.startswith('P4='):
- newState = None
- if serLine == "P4=L":
- newState = "OFF"
- elif serLine == "P4=H":
- newState = "ON"
-
- if newState is not None and (lastState_P4 != newState or not config.P4_MQTT_SendOnlyIfValueChanged):
- lastState_P4 = newState
- mqttc.publish(config.P4_MQTT_Topic, newState, qos=0, retain=config.P4_MQTT_SendRetained)
- if config.P4_MQTT_SendLastUpdate:
- mqttc.publish(config.P4_MQTT_Topic + "_lastUpdate", datetime.now().isoformat(), qos=0, retain=config.P4_MQTT_SendRetained)
-
- # digital input P5
- if serLine.startswith('P5='):
- newState = None
- if serLine == "P5=L":
- newState = "OFF"
- elif serLine == "P5=H":
- newState = "ON"
-
- if newState is not None and (lastState_P5 != newState or not config.P5_MQTT_SendOnlyIfValueChanged):
- lastState_P5 = newState
- mqttc.publish(config.P5_MQTT_Topic, newState, qos=0, retain=config.P5_MQTT_SendRetained)
- if config.P5_MQTT_SendLastUpdate:
- mqttc.publish(config.P5_MQTT_Topic + "_lastUpdate", datetime.now().isoformat(), qos=0, retain=config.P5_MQTT_SendRetained)
-
- # DHT TH sensor
- # {"T":26.60,"H":36}
- if serLine.startswith('{"T":'):
- th = json.loads(serLine)
- t = round(float(th["T"]), 1)
- h = int(th["H"])
- if t >= -20 and t <= 50:
- mqttc.publish(config.DHT22_MQTT_Topic_Temp, str(t), qos=0, retain=config.DHT22_MQTT_SendRetained)
- if h >= 0 and h <= 100:
- mqttc.publish(config.DHT22_MQTT_Topic_Hum, str(h), qos=0, retain=config.DHT22_MQTT_SendRetained)
- if config.DHT22_MQTT_SendLastUpdate:
- mqttc.publish(config.DHT22_MQTT_Topic_Temp + "_lastUpdate", datetime.now().isoformat(), qos=0, retain=config.DHT22_MQTT_SendRetained)
-
- # nothing came in this time...
- else:
- noReceiveCount += 1
- if debug:
- print("noReceiveCount=" + str(noReceiveCount))
-
- # quit script if nothing has been received for some time - will be restarted by systemd
- if noReceiveCount >= config.quitOnNoReceiveTimeout:
- quit()
-
- except KeyboardInterrupt:
- print('\n')
|