from espcore import * import json import threading from queue import Queue from logging import getLogger import time import re SENSOR_TYPE_SINGLE = 1 SENSOR_TYPE_TEMP_HUM = 2 SENSOR_TYPE_TEMP_BARO = 3 SENSOR_TYPE_TEMP_HUM_BARO = 4 SENSOR_TYPE_DUAL = 5 SENSOR_TYPE_TRIPLE = 6 SENSOR_TYPE_QUAD = 7 SENSOR_TYPE_TEMP_EMPTY_BARO = 8 SENSOR_TYPE_SWITCH = 10 SENSOR_TYPE_DIMMER = 11 SENSOR_TYPE_ULONG = 20 SENSOR_TYPE_WIND = 21 class ControllerEmu: """class that emulates and decodes various types of controllers. run various threads in the background to recveive and queue stuff""" def __init__(self): self.log=logging.getLogger("controller") self.start_mqtt() self.start_http() self.start_linebased() self.log_enabled=True def start_mqtt(self): """generic mqtt receiver. just queues all reqeived mqtt messages on all topics""" getLogger("mqtt").debug("Connecting to {mqtt_broker}".format(mqtt_broker=config.mqtt_broker)) import paho.mqtt.client as mqtt mqtt_client = mqtt.Client() mqtt_client.connect(config.mqtt_broker, 1883, 60) mqtt_client.loop_start() mqtt_client.subscribe('#') self.mqtt_messages=Queue() def mqtt_on_message(client, userdata, message): if self.log_enabled: logging.getLogger("mqtt").debug("Received message '" + str(message.payload) + "' on topic '" + message.topic + "' with QoS " + str(message.qos)) self.mqtt_messages.put(message) mqtt_client.on_message=mqtt_on_message def clear_mqtt(self): """clear queue""" time.sleep(1) while not self.mqtt_messages.empty(): self.mqtt_messages.get() def start_http(self): """generic http receiver. just queues all shallow copy of all http requests objects""" import bottle self.http_requests = Queue() @bottle.post('') @bottle.get('') def urlhandler(filename): if self.log_enabled: logging.getLogger("http").debug(bottle.request.method+" "+str(dict(bottle.request.params))) self.http_requests.put(bottle.request.copy()) http_thread=threading.Thread(target=bottle.run, kwargs=dict(host='0.0.0.0', port=config.http_port, reloader=False, quiet=True)) http_thread.daemon=True http_thread.start() def clear_http(self): """clear queue""" while not self.http_requests.empty(): self.http_requests.get() def start_linebased(self): """generic linebased receiver (like telnet). for nodo plugin""" import socket import sys self.linebased_lines=Queue() def handle_connect(connection, client_address): if self.log_enabled: logging.getLogger("linebased").debug("Connect from "+str(client_address)) fh = connection.makefile() for line in fh: line=line.rstrip() if self.log_enabled: logging.getLogger("linebased").debug("Recv from "+str(client_address)+" :"+line) self.linebased_lines.put( ( client_address, line ) ) if self.log_enabled: logging.getLogger("linebased").debug("Disconnect from "+str(client_address)) def wait_accept(): # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = ('', config.linebased_port) sock.bind(server_address) sock.listen() while True: # Wait for a connection connection, client_address = sock.accept() connect_thread=threading.Thread(target=handle_connect, kwargs=dict(connection=connection, client_address=client_address)) connect_thread.daemon=True connect_thread.start() accept_thread=threading.Thread(target=wait_accept) accept_thread.daemon=True accept_thread.start() def clear_linebased(self): """clear queue""" while not self.linebased_lines.empty(): self.linebased_lines.get() def clear(self, sleep=0): self.clear_http() self.clear_mqtt() self.clear_linebased() time.sleep(sleep) def recv_domoticz_http(self, sensor_type, idx, timeout=60): """recv a domoticz http request from espeasy, and convert back to espeasy values""" start_time=time.time() self.log.info("Waiting for domoticz http request idx {idx} with sensortype {sensor_type}".format(sensor_type=sensor_type,idx=idx)) # self.clear_http() # read and parse http requests while time.time()-start_time