#! /usr/bin/python3 import time import sys from paho.mqtt import client as mqtt_client import os import serial MAXIMUM_COMMUNICATION_FAILURE=100 # MQTT Settings mqtt_server=os.environ['MQTT_SERVER'] mqtt_topic=os.environ['MQTT_TOPIC'] # SERIAL Port serial_device=os.environ['SERIAL_DEVICE'] # The callback for when a PUBLISH message is received from the server. def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.payload)) # Start mqtt client_id = f'python-fan-ctrl' client = mqtt_client.Client(mqtt_client.CallbackAPIVersion.VERSION2) client.on_message = on_message if (not (mqtt_server)): print("MQTT_SERVER is not set") if (not (mqtt_topic)): print("MQTT_TOPIC is not set") # Start MQTT Client client.connect(mqtt_server, 1883) client.loop_start() # Start Serial communication ser = serial.Serial(serial_device, 115200, timeout=1) # open serial port client.publish(mqtt_topic + "device", ser.name) # check which port was really used SerialCommunicationFailureCounter=0 # Endless Loop while True: try: try: if (not (ser.is_open)): ser.open() continue except (serial.SerialException): client.publish(mqtt_topic + "exception", "serial reopen") # check which port was really used time.sleep(1.0) try: line = ser.readline() # read a '\n' terminated line except (serial.SerialException): SerialCommunicationFailureCounter = SerialCommunicationFailureCounter + 1 client.publish(mqtt_topic + "serialcom/failure", str(SerialCommunicationFailureCounter)) line=None if (SerialCommunicationFailureCounter > MAXIMUM_COMMUNICATION_FAILURE): raise serial.SerialException("device reports readiness / device disconnected " + str(MAXIMUM_COMMUNICATION_FAILURE) + " times") if (line): client.publish(mqtt_topic + "exception", "") # clear exception # convert byte array to string l = line.decode("utf-8") try: # Parse the controller information # e.g. : 22.00;0%;0RPM temperatur, percent, rpm = l.split(";") except (ValueError): # activate debug code temperatur = None percent = None rpm = None if ((temperatur) and (percent) and (rpm)): parseError=False temperatur = temperatur.strip() client.publish(mqtt_topic + "temperatur", str(temperatur)) if (percent.endswith('/100')): client.publish(mqtt_topic + "target", str(percent[:-4])) else: client.publish(mqtt_topic + "debug", "target%% invalid:" + str(percent)) parseError=True # remove new line for last element rpm = rpm.replace('\r','').replace('\n','') if (rpm.endswith('RPM')): client.publish(mqtt_topic + "rpm", str(rpm[:-3])) else: client.publish(mqtt_topic + "debug", "RPM invalid:" + str(rpm)) parseError=True # cleanup debugging if (parseError == False): client.publish(mqtt_topic + "debug", None) else: client.publish(mqtt_topic + "debug", line) # line was invalid and could not be parsed else: time.sleep(0.2) except (KeyboardInterrupt, SystemExit): cleanAndExit() client.loop_stop()