NEWS
MQTT loop_start und loop_forever
-
Moin,
ich habe in meinem SmartMirror nun mal ein Python Script für MQTT zusammengewurstelt.
Ich würde gern alle 60 Sekunden die Temperatur und Luftfeuchtigkeit via MQTT übermitteln. Das ist also eine entsprechende Schleife mit client.loop_start.
Zusätzlich möchte ich gern eine Variable setzen (damit wird der Monitor aus/an geschaltet). Hier habe ich auch ne Schleife die entsprechend auf Änderungen reagiert. client.loop_forever
Muss ich beides parallel laufen lassen oder kann man das irgendwie zusammen in einen MQTT-Client bekommen?
Das erste verwendet client.loop_forever und das mit der Temperatur client.loop_start. Ich weiss- loop_start startet einen eignen threat. Ideen wie ich das hinbekomme oder soll ich einfach beide Programme parallel beim boot starten?
Temperatur/ Luftfeuchtigkeit
#!/usr/bin/python import posix from fcntl import ioctl import time import os import sys import paho.mqtt.client as mqtt import json HOST = 'hostadresse' # Data capture and upload interval in seconds. INTERVAL=60 sensor_data = {'temperature': 0, 'humidity': 0} next_reading = time.time() client = mqtt.Client("P2") # Set access token client.username_pw_set("user", "passwort") class AM2320: I2C_ADDR = 0x5c I2C_SLAVE = 0x0703 def __init__(self, i2cbus = 1): self._i2cbus = i2cbus @staticmethod def _calc_crc16(data): crc = 0xFFFF for x in data: crc = crc ^ x for bit in range(0, 8): if (crc & 0x0001) == 0x0001: crc >>= 1 crc ^= 0xA001 else: crc >>= 1 return crc @staticmethod def _combine_bytes(msb, lsb): return msb << 8 | lsb def readSensor(self): fd = posix.open("/dev/i2c-%d" % self._i2cbus, posix.O_RDWR) ioctl(fd, self.I2C_SLAVE, self.I2C_ADDR) # wake AM2320 up, goes to sleep to not warm up and affect the humidity sensor # This write will fail as AM2320 won't ACK this write try: posix.write(fd, b'\0x00') except: pass time.sleep(0.001) #Wait at least 0.8ms, at most 3ms # write at addr 0x03, start reg = 0x00, num regs = 0x04 */ posix.write(fd, b'\x03\x00\x04') time.sleep(0.0016) #Wait at least 1.5ms for result # Read out 8 bytes of result data # Byte 0: Should be Modbus function code 0x03 # Byte 1: Should be number of registers to read (0x04) # Byte 2: Humidity msb # Byte 3: Humidity lsb # Byte 4: Temperature msb # Byte 5: Temperature lsb # Byte 6: CRC lsb byte # Byte 7: CRC msb byte data = bytearray(posix.read(fd, 8)) # Check data[0] and data[1] if data[0] != 0x03 or data[1] != 0x04: raise Exception("First two read bytes are a mismatch") # CRC check if self._calc_crc16(data[0:6]) != self._combine_bytes(data[7], data[6]): raise Exception("CRC failed") # Temperature resolution is 16Bit, # temperature highest bit (Bit15) is equal to 1 indicates a # negative temperature, the temperature highest bit (Bit15) # is equal to 0 indicates a positive temperature; # temperature in addition to the most significant bit (Bit14 ~ Bit0) # indicates the temperature sensor string value. # Temperature sensor value is a string of 10 times the # actual temperature value. temp = self._combine_bytes(data[4], data[5]) if temp & 0x8000: temp = -(temp & 0x7FFF) temp /= 10.0 humi = self._combine_bytes(data[2], data[3]) / 10.0 return (temp, humi) am2320 = AM2320(1) (t,h) = am2320.readSensor() # Connect to ThingsBoard using default MQTT port and 60 seconds keepalive interval client.connect(HOST, 1888, 60) client.loop_start() try: while True: # humidity,temperature = dht.read_retry(dht.DHT22, 4) # humidity = round(humidity, 2) # temperature = round(temperature, 2) humidity = h temperature = t print(u"Temperature: {:g}\u00b0C, Humidity: {:g}%".format(temperature, humidity)) sensor_data['temperature'] = temperature sensor_data['humidity'] = humidity # Sending humidity and temperature data to ThingsBoard client.publish('SmartMirror/AM2320', json.dumps(sensor_data), 1) next_reading += INTERVAL sleep_time = next_reading-time.time() if sleep_time > 0: time.sleep(sleep_time) except KeyboardInterrupt: pass client.loop_stop() client.disconnect()
und hier das setzen des Monitorstatus:
#!/usr/bin/env python3 #source: https://www.thedigitalpictureframe.com/control-your-digital-picture-frame-with-home-assistents-wifi-presence-detection-and-mqtt/ import paho.mqtt.client as mqtt import subprocess def hdmi_on(): CONTROL = "vcgencmd" CONTROL_BLANK = [CONTROL, "display_power", "1"] subprocess.call(CONTROL_BLANK) print ( "I turned the screen on!" ) def hdmi_off(): CONTROL = "vcgencmd" CONTROL_BLANK = [CONTROL, "display_power", "0"] subprocess.call(CONTROL_BLANK) print ( "I turned the screen off!" ) def on_connect(client, userdata, flags, rc): print("Connected to MQTT broker") def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload)) if msg.payload.decode() == "true": hdmi_on() client.publish("SmartMirror/monitor", "true", qos=0, retain=True) elif msg.payload.decode() == "false": hdmi_off() client.publish("SmartMirror/monitor", "false", qos=0, retain=True) else: pass def on_subscribe(client, userdata, mid, granted_qos): print("Subscribed to topic : " + str(mid) +" with QoS" + str(granted_qos)) client = mqtt.Client() client.username_pw_set("user", "pass") client.connect( "host", 1888, 60) client.subscribe( "SmartMirror/monitor" , qos=0) client.on_connect = on_connect client.on_message = on_message client.loop_forever()
-
Nach etwas Recherche werde ich dann wohl die regelmäßige Abfrage des Temperatursensors und publischen einfach als Crontab ausführen.