class ModemManager(): """ Serial modem management Class """ def serial_packet_received(self, packet): """ Function called whenever a serial frame is received by the serial modem @param packet serial packet received """ self.mqtt_client.publish_network_status(packet) def mqtt_packet_received(self, packet): """ Function called whenever a MQTT message is received @param packet mqtt packet received """ self.modem.send(packet) def __init__(self, portname, speed, verbose, mqtt_server, mqtt_port, mqtt_topic, user_key, gateway_key, coordinates): """ Class constructor @param portname: Name/path of the serial port @param speed: Serial baudrate in bps @param verbose: Print out SWAP traffic (True or False) @param mqtt_server MQTT server @param mqtt_port MQTT port @param mqtt_topic Main MQTT topic @param user_key User key @param gateway_key gateway key @param coordinates gateway latitude-longitude """ try: # Create and start serial modem self.modem = SerialModem(portname, speed, verbose) # Declare receiving callback function self.modem.set_rx_callback(self.serial_packet_received) # MQTT client self.mqtt_client = MqttClient(mqtt_server, mqtt_port, mqtt_topic, user_key, gateway_key, coordinates) # Declare receiving callback function self.mqtt_client.set_rx_callback(self.mqtt_packet_received) except StationException as ex: ex.show()
def receive_command(client, userdata, message): message_json = MqttClient.parse_payload(message.payload) if has_key_chain(message_json, 'state', 'desired', VIDEO_MONITOR): my_state = message_json['state']['desired'][VIDEO_MONITOR] logger.info('video-monitor: received: %s %s' % (VIDEO_MONITOR, my_state)) _set_monitoring(my_state) MqttClient.publish(args, args.topic, {'state': { 'reported': {VIDEO_MONITOR: my_state}}}) if has_key_chain(message_json, 'state', 'desired', SNAPSHOT): my_state = message_json['state']['desired'][SNAPSHOT] logger.info('video-monitor: received: %s %s' % (SNAPSHOT, my_state)) move_to_s3(video.snapshot(), args.bucket, FOLDER, args.hostname + '.png') MqttClient.publish(args, args.topic, {'state': {'reported': {SNAPSHOT: my_state}}})
def __init__(self, portname, speed, verbose, mqtt_server, mqtt_port, mqtt_topic, user_key, gateway_key, coordinates): """ Class constructor @param portname: Name/path of the serial port @param speed: Serial baudrate in bps @param verbose: Print out SWAP traffic (True or False) @param mqtt_server MQTT server @param mqtt_port MQTT port @param mqtt_topic Main MQTT topic @param user_key User key @param gateway_key gateway key @param coordinates gateway latitude-longitude """ try: # Create and start serial modem self.modem = SerialModem(portname, speed, verbose) # Declare receiving callback function self.modem.set_rx_callback(self.serial_packet_received) # MQTT client self.mqtt_client = MqttClient(mqtt_server, mqtt_port, mqtt_topic, user_key, gateway_key, coordinates) # Declare receiving callback function self.mqtt_client.set_rx_callback(self.mqtt_packet_received) except StationException as ex: ex.show()
def receive_command(client, userdata, message): message_json = MqttClient.parse_payload(message.payload) if has_key_chain(message_json, 'state', 'desired', args.name): logger.info('gpio-subscriber: receive_command: relay_pulse %s %s' % ( args.name, str(message_json['state']['desired'][args.name]))) relay.pulse() else: logger.debug( "gpio-subscriber: receive_command: unmatched %s not_in %s" % (args.name, str(message_json))) # debug
def receive_command(client, userdata, message): if SUBSCRIPTIONS.has_key(message.topic): logger.debug("buzzer: received: %s %s" % (message.topic, message.payload)) message_json = MqttClient.parse_payload(message.payload) for k, v in SUBSCRIPTIONS[message.topic].iteritems(): if has_key_array(message_json, k.split('/')): if v == None or v == dict_value(message_json, k.split('/')): logger.info('buzzer-monitor: beep %s' % str(v)) buzzer.beep(beep_duration=args.beep_duration, quiet_duration=args.quiet_duration, count=args.beep_count)
def __init__(self, host, port): """Create the RoundRobin object.""" self.host = host self.port = port self.mqtt_client = MqttClient(host, port) self.thread = None self.stop_event = Event() self.active_requests = [] self.app_args = [ { "app_id": "netflix", "startup-args": { "args": [] }, "args": { "args": [ "m=https://api-global.netflix.com/catalog/titles/movie/80223967&trackId=14855318" ] } }, { "app_id": "prime-video", "startup-args": { "args": [] }, "args": { "contentId": "B015YJRQ8U", "mediaType": "movie" } }, { "app_id": "youtube", "startup-args": {}, "args": { "video_id": "KEcbFSaLpoM" } }, ] self.logger = logging.getLogger(__name__)
from RflinkInterface import RflinkInterface from ProtocolPacket import ProtocolPacket from mqttclient import MqttClient import TranslatePacketValues import json import logger logger = createLogger.logger()mt = MqttClient() def convertered2json(line): func = TranslatePacketValues.translates try: for pp in ProtocolPacket(line): yield json.dumps({k: func(k, v) for k, v in pp.keyvaluepair.items()}) except KeyError: logger.error(line) def main(): rflinkInterface = RflinkInterface() while True: for line in rflinkInterface: for json_ in convertered2json(line): logger.info(json_) mt.publish("433mhz/incomming", json_) if __name__ == "__main__":
webserver = WebServer() #webserver.start() webThread = _thread.start_new_thread(webserver.start, ()) type = state.get_value('type') if type == 'temperature': sensor = sensor.TemperatureSensor() elif type == 'power': sensor = sensor.PowerSensor() elif type == 'ambient': sensor = sensor.AmbientSensor() webserver.router.set_sensor(sensor) mqttClient = MqttClient(sensor=sensor) sta_if = network.WLAN(network.STA_IF) sta_if.active(True) if not state.is_configured(): print('Sensor not configured') # Main loop publish_delay = 500 check_server_delay = 100 last_publish = utime.ticks_ms() print('entering main loop') while True: if not util.wifi_is_connected(): if state.is_configured():
self._last_user_activity = time.time() self._activate_screensaver(False) return super().on_touch_down(touch) def _activate_screensaver(self, activate): if self._screensaver_active != activate: self._screensaver_active = activate try: with open('/sys/class/backlight/rpi_backlight/bl_power', 'w') as file: file.write('1' if activate else '0') except: logger.error('Could not ' + ('activate' if activate else 'deactivate') + ' screensaver') class DataLoggerApp(App): def build(self): return DataLoggerWidget() if __name__ == '__main__': logger.error('Starting application') Config.set('graphics', 'width', '800') Config.set('graphics', 'height', '480') mqtt_client = MqttClient() mqtt_client.use_signals_config(signal_sources_config) mqtt_client.start() DataLoggerApp().run()
from flask import Flask, request from mqttclient import MqttClient from sense import messageAsync app = Flask(__name__) try: print("MQTT - Trying to connect") mqtt = MqttClient('mosquitto') except: print("MQTT - Failed to connect") mqtt = None @app.route('/') def hello_world(): return 'Hello World!' @app.route('/banner', methods=['GET', 'POST']) def banner(): try: text = request.get_json().get('message') except: text = "Unicorn!" messageAsync(text) return text if __name__ == '__main__': if mqtt:
#!/usr/bin/env python import argparse, sys, logging, json from mqttclient import MqttClient # parse arguments parser = argparse.ArgumentParser() parser.add_argument("-e", "--endpoint", help="AWS IoT endpoint") parser.add_argument("-r", "--ca_file", help="Certificate Authority file", default='rootCA.pem') parser.add_argument("-c", "--client_cert_file", help="Client certificate file", default='certificate.pem') parser.add_argument("-k", "--client_key_file", help="Client Key File", default='private.pem') parser.add_argument("-p", "--port", help="MQTT port", type=int, default=8883) parser.add_argument("-q", "--qos", help="MQTT QoS", type=int, default=1) parser.add_argument("-t", "--topic", help="MQTT topic") parser.add_argument("-g", "--log_level", help="log level", type=int, default=logging.INFO) parser.add_argument("-s", "--topic_key", help="MQTT topic key", default='foo') parser.add_argument("-v", "--value", help="value", default='bar') args = parser.parse_args() if args.endpoint is None: sys.exit("Error: MQTT connection information needed") # publish MqttClient.publish(args, args.topic, {'state': {'reported': {args.topic_key: args.value}}})
parser.add_argument("-g", "--log_level", help="log level", type=int, default=logging.INFO) args = parser.parse_args() # setup payload data = dict() data["state"] = {} data["state"]["reported"] = {} data["state"]["reported"]["cpuTemp"] = system_info.get_temperature() try: data["state"]["reported"]["wlan0IpAddress"] = system_info.get_ip_address('wlan0') except: pass try: data["state"]["reported"]["eth0IpAddress"] = system_info.get_ip_address('eth0') except: pass data["state"]["reported"]["totalDiskSpaceRoot"] = system_info.getDiskSpace('/')[0] data["state"]["reported"]["usedDiskSpaceRoot"] = system_info.getDiskSpace('/')[1] data["state"]["reported"]["networkConnections"] = system_info.get_connections() data["state"]["reported"]["ramTotal"] = system_info.get_ram()[0] data["state"]["reported"]["ramAvailable"] = system_info.get_ram()[1] data["state"]["reported"]["processCount"] = system_info.get_process_count() data["state"]["reported"]["upTime"] = system_info.get_up_stats()[0] data["state"]["reported"]["cpuLoad5min"] = system_info.get_up_stats()[1] # publish MqttClient.publish(args, args.topic, data) if args.topic2 is not None: MqttClient.publish(args, args.topic2, data)
widgetlist.append(gardentemp) widgetlist.append(vorgartentemp) widgetlist.append(arbeitszimmertemp) widgetlist.append(arbeitszimmerhum) widgetlist.append(arbeitszimmerqual) widgetlist.append(loggiatemp) widgetlist.append(pingrouter) widgetlist.append(haustuerOffen) widgetlist.append(telefon) widgetlist.append(esKlingelt) widgetlist.append(esRegnet) widgetlist.append(allefenster) widgetlist.append(motion) widgetlist.append(aussentemperatur) client = MqttClient() client.subscribe("/Chattenweg5/Garten/temperature", gardentemp.update) client.subscribe("/Chattenweg5/Garten/rain", regenAlert) client.subscribe("/Chattenweg5/2OG-Loggia/raindrops", regenTropfen) client.subscribe("/Chattenweg5/Vorgarten/temperature", vorgartentemp.update) client.subscribe("/Chattenweg5/Arbeitszimmer/temperature", arbeitszimmertemp.update) client.subscribe("/Chattenweg5/Arbeitszimmer/humidity", arbeitszimmerhum.update) client.subscribe("/Chattenweg5/Arbeitszimmer/CO2", arbeitszimmerqual.update) client.subscribe("/Chattenweg5/2OG-Loggia/temperature", loggiatemp.update) client.subscribe("/Wallclock/Countdown", mycountdown.mqttstart) client.subscribe("/Wallclock/countdown", mycountdown.mqttstart) client.subscribe("/Chattenweg5/Wallclock/Countdown", mycountdown.mqttstart)
else: logger.debug( "gpio-subscriber: receive_command: unmatched %s not_in %s" % (args.name, str(message_json))) # debug # parse arguments parser = argparse.ArgumentParser() parser.add_argument("-e", "--endpoint", help="AWS IoT endpoint", required=True) parser.add_argument("-r", "--ca_file", help="Certificate Authority file", default='rootCA.pem') parser.add_argument("-c", "--client_cert_file", help="Client certificate file", default='certificate.pem') parser.add_argument("-k", "--client_key_file", help="Client Key File", default='private.pem') parser.add_argument("-p", "--port", help="MQTT port", type=int, default=8883) parser.add_argument("-q", "--qos", help="MQTT QoS", type=int, default=1) parser.add_argument("-t", "--topic", help="MQTT topic") parser.add_argument("-i", "--pin", help="gpio pin (using BCM numbering)", type=int, required=True) parser.add_argument("-s", "--name", help="topic name", required=True) parser.add_argument("-g", "--log_level", help="log level", type=int, default=logging.INFO) args = parser.parse_args() # logging setup logger = set_logger(level=args.log_level) relay = Relay(args.pin) relay.start() mqtt = MqttClient(args.endpoint, args.log_level, args.port) mqtt.set_tls(args.ca_file, args.client_cert_file, args.client_key_file) mqtt.add_callback(args.topic, receive_command) mqtt.add_subscription(args.topic, qos=args.qos) # subscribe or not? mqtt.run()
parser.add_argument("-k", "--client_key_file", help="Client Key File", default='private.pem') parser.add_argument("-p", "--port", help="MQTT port", type=int, default=8883) parser.add_argument("-q", "--qos", help="MQTT QoS", type=int, default=1) parser.add_argument("-d", "--beep_duration", help="time in seconds for a beep duration", type=float, default=0.06) parser.add_argument("-w", "--quiet_duration", help="time in seconds between beeps", type=float, default=0.1) parser.add_argument("-n", "--beep_count", help="number of beeps", type=int, default=2) parser.add_argument("-i", "--pin", help="gpio pin (using BCM numbering)", type=int, default=6) parser.add_argument("-s", "--buzzer_name", help="buzzer name", default='buzzer') parser.add_argument("-y", "--config_file", help="yaml config file", default='buzzer.yml') parser.add_argument("-g", "--log_level", help="log level", type=int, default=logging.INFO) args = parser.parse_args() # logging setup logger = set_logger(level=args.log_level) # read subscriptions from config and create buzzer buzzer = Buzzer(args.buzzer_name, args.pin) buzzer.start() SUBSCRIPTIONS = yaml.load(open(args.config_file)) # connect with Amazon IoT and go mqtt = MqttClient(args.endpoint, args.log_level, args.port) mqtt.set_tls(args.ca_file, args.client_cert_file, args.client_key_file) for sub in SUBSCRIPTIONS.keys(): mqtt.add_callback(sub, receive_command) mqtt.add_subscription(sub, qos=args.qos) mqtt.run()
someonehome = True else: someonehome = False def motionMessage(topic,msg): global someonehome if topic == None or msg == None: return v = msg.decode() print("Presence:",someonehome," Motion:",v) if someonehome and v == "ON": print("starting wall clock") subprocess.run(["systemctl","start","wallclock"]) print("ending program") subprocess.run(["systemctl","stop","start-wallclock"]) time.sleep(1) sys.exit() if __name__ == "__main__": client = MqttClient() client.subscribe("Chattenweg5/Residents",residentsMessage) client.subscribe("Chattenweg5/2OG-Flur/sensor/binary_sensor/2og-flur_motion/state",motionMessage) while True: time.sleep(1)
def run(self): sensors = None datalogger = None try: # initialise objects sensors = Sensors(self.T_OFFSET,self.P_OFFSET,self.H_OFFSET) datalogger = DataLogger(self.DATALOGFILE, self.DATALOGKEYS, self.DATALOGMAXFILESIZE) self.scheduler = HeaterScheduler() self.modemanager = ModeManager( scheduler=self.scheduler, callbackfunc=self.modemanagercallbackfunc) self.mqttclient = MqttClient(subscribelist=self.SUBSCRIBELIST) self.heatercontroller = HeaterController() # initialise state self.modemanager.setMode(self.modemanager.AUTO) # initial data t_avg,p_avg,h_avg = sensors.getData() # present ourselves self.mqttclient.publish({topics.IOTHERMSTATUS:'Active'}) self.mqttclient.publish({topics.IOTHERMVERSION:__version__ +' '+ __status__}) self.mqttclient.publish({topics.MODE:self.modemanager.currentmode.name}) self.mqttclient.publish({topics.TARGETTEMPERATURE:self.modemanager.currentmode.targettemperature}) t = 0 while True: t_,p,h = sensors.getData() messages = self.mqttclient.getData() # use temperature value from mqtt if self.USE_OTHERTEMPERATURE and topics.OTHERTEMPERATURE in messages: t = float( messages[topics.OTHERTEMPERATURE] ) if not self.USE_OTHERTEMPERATURE: t = t_ # calculate averages t_avg = (t_avg + t)/2 p_avg = (p_avg + p)/2 h_avg = (h_avg + h)/2 # calculate derivatives d_t = (t - t_avg)/self.REFRESH_SECONDS d_p = (p - p_avg)/self.REFRESH_SECONDS d_h = (h - h_avg)/self.REFRESH_SECONDS # process data from subscribed topics self.processMessages( messages ) # prepare for publishing messages = self.prepareMessages(t, p, h, d_t, d_p, d_h) datalogger.log(messages) self.mqttclient.publish(messages) # update the heatercontroller with the current and target temperatures #print('targettemperature = {}'.format(self.modemanager.currentmode.targettemperature)) self.heatercontroller.update(t,self.modemanager.currentmode.targettemperature) sleep(self.REFRESH_SECONDS) finally: print('IOThermostat: Stopping IOThermostat..') if datalogger: datalogger.close() if sensors: sensors.close() if self.scheduler: self.scheduler.close() if self.heatercontroller: self.heatercontroller.close() if self.mqttclient: self.mqttclient.close()
class BasePlugin: mqttClient = None def ShouldSendRemoteTemp(self): return self.RemoteTempDeviceId != None and self.RemoteTempDeviceId def __init__(self): self.mappedDevicesByUnit = {} self.HeatpumpTopic = None self.HeatpumpSetTopic = None self.RoomTempTopic = None self.HardwareID = None self.PluginKey = None self.RemoteTempDeviceId = None self.DomoticzBaseUrl = None self.RemoteTempMaxEllapsedMinutes = 60 self.RemoteTempLastSentValue = None return def onStart(self): try: #Domoticz.Trace(True) Domoticz.Heartbeat(10) self.PluginKey = "ToshibaHpMqtt" self.HardwareID = Parameters["HardwareID"] self.debugging = Parameters["Mode6"] if self.debugging == "Verbose": Domoticz.Debugging(2 + 4 + 8 + 16 + 64) if self.debugging == "Debug": Domoticz.Debugging(2) self.HeatpumpTopic = Parameters["Mode5"] self.HeatpumpSetTopic = self.HeatpumpTopic + "/set" self.RoomTempTopic = self.HeatpumpTopic + "/status" self.RemoteTempDeviceId = Parameters["Mode1"] self.DomoticzBaseUrl = Parameters["Mode2"] if (self.ShouldSendRemoteTemp() and not self.DomoticzBaseUrl): self.RemoteTempDeviceId = None Domoticz.Error( "Domoticz base url required and not set in plugin parameters. Remote temp sending disabled" ) try: self.RemoteTempMaxEllapsedMinutes = int(Parameters["Mode3"]) except ValueError: self.RemoteTempMaxEllapsedMinutes = 30 Domoticz.Error( "Wrong parameter value for remote temp sensor maximum minutes, setting default : " + str(self.RemoteTempMaxEllapsedMinutes)) self.mappedDevicesByUnit = {} self.payloadKeyToDevice = bijection.Bijection() Domoticz.Debug("Mapping power") self.powerDeviceMapping = SwitchDeviceMapping(Devices, Images, self.PluginKey, self.HardwareID, "Power", "POW", "power", usedByDefault=True, switchType=0, dzValues={ 0: "OFF", 1: "ON" }) self.mappedDevicesByUnit[self.powerDeviceMapping.dzDevice. Unit] = self.powerDeviceMapping self.payloadKeyToDevice["power"] = self.powerDeviceMapping Domoticz.Debug("Mapping mode") self.modeDeviceMapping = SelectorDeviceMapping( Devices, Images, self.PluginKey, self.HardwareID, "Mode", "MODE", "mode", usedByDefault=True, dzLevelsCodes=[('Auto', 'AUTO'), ('Froid', 'COOL'), ('Déshum.', 'DRY'), ('Chaud', 'HEAT'), ('Ventil.', 'FAN')], offHidden=True) self.mappedDevicesByUnit[ self.modeDeviceMapping.dzDevice.Unit] = self.modeDeviceMapping self.payloadKeyToDevice["mode"] = self.modeDeviceMapping Domoticz.Debug("Mapping fan") self.fanDeviceMapping = SelectorDeviceMapping(Devices, Images, self.PluginKey, self.HardwareID, "Flux", "FAN", "fan", usedByDefault=True, dzLevelsCodes=[ ('Auto', 'AUTO'), ('Silence', 'QUIET'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4') ], offHidden=True) self.mappedDevicesByUnit[ self.fanDeviceMapping.dzDevice.Unit] = self.fanDeviceMapping self.payloadKeyToDevice["fan"] = self.fanDeviceMapping Domoticz.Debug("Mapping vane") self.vVaneDeviceMapping = SelectorDeviceMapping( Devices, Images, self.PluginKey, self.HardwareID, "Inclinaison", "VVANE", "vane", usedByDefault=True, dzLevelsCodes=[('Auto', 'AUTO'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('Oscillant', 'SWING')], offHidden=True) self.mappedDevicesByUnit[self.vVaneDeviceMapping.dzDevice. Unit] = self.vVaneDeviceMapping self.payloadKeyToDevice["vane"] = self.vVaneDeviceMapping Domoticz.Debug("Mapping wvane") self.wVaneDeviceMapping = SelectorDeviceMapping(Devices, Images, self.PluginKey, self.HardwareID, "Direction", "WVANE", "wideVane", usedByDefault=True, dzLevelsCodes=[ ('<<', '<<'), ('<', '<'), ('V', '|'), ('>', '>'), ('>>', '>>'), ('Oscillant', 'SWING') ], offHidden=True) self.mappedDevicesByUnit[self.wVaneDeviceMapping.dzDevice. Unit] = self.wVaneDeviceMapping self.payloadKeyToDevice["wideVane"] = self.wVaneDeviceMapping Domoticz.Debug("Mapping setpoint") self.setpointDeviceMapping = SetpointDeviceMapping( Devices, Images, self.PluginKey, self.HardwareID, "Thermostat", "TEMPSET", "temperature", usedByDefault=True) self.mappedDevicesByUnit[self.setpointDeviceMapping.dzDevice. Unit] = self.setpointDeviceMapping self.payloadKeyToDevice["temperature"] = self.setpointDeviceMapping Domoticz.Debug("Mapping temperature") self.temperatureDevicemapping = TemperatureDeviceMapping( Devices, Images, self.PluginKey, self.HardwareID, "T° Split", "TEMP", "roomTemperature", usedByDefault=True) self.mappedDevicesByUnit[self.temperatureDevicemapping.dzDevice. Unit] = self.temperatureDevicemapping self.mqttserveraddress = Parameters["Address"].strip() self.mqttserverport = Parameters["Port"].strip() clientIdPrefix = 'Domoticz_' + Parameters['Key'] + '_' + str( Parameters['HardwareID']) self.mqttClient = MqttClient(self.mqttserveraddress, self.mqttserverport, clientIdPrefix, self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, None) except Exception as e: Domoticz.Error("Start error: " + str(e)) self.mqttClient = None def onStop(self): Domoticz.Debug("onStop called") def onCommand(self, Unit, Command, Level, Color): # react to commands arrived from Domoticz if self.mqttClient is None: return False Domoticz.Debug("Command: " + Command + " (" + str(Level) + ") Color:" + Color) try: Domoticz.Debug(" getting device for unit " + str(Unit)) if (Unit in self.mappedDevicesByUnit): Domoticz.Debug(" found") Domoticz.Debug( " key : " + str(self.mappedDevicesByUnit[Unit].externalDeviceId)) Domoticz.Debug(" value : " + str(self.mappedDevicesByUnit[Unit]. DzCommandToExt(Command, str(Level)))) payloaddic = { self.mappedDevicesByUnit[Unit].externalDeviceId: self.mappedDevicesByUnit[Unit].DzCommandToExt( Command, str(Level)) } Domoticz.Debug(str(payloaddic)) if (not payloaddic is None): Domoticz.Debug(" publishing on " + self.HeatpumpSetTopic + " : " + str(json.dumps(payloaddic))) self.mqttClient.Publish(self.HeatpumpSetTopic, json.dumps(payloaddic)) except Exception as e: Domoticz.Debug(str(e)) return False def onConnect(self, Connection, Status, Description): if self.mqttClient is not None: self.mqttClient.onConnect(Connection, Status, Description) def onDisconnect(self, Connection): if self.mqttClient is not None: self.mqttClient.onDisconnect(Connection) def onMessage(self, Connection, Data): if self.mqttClient is not None: self.mqttClient.onMessage(Connection, Data) #workaround for issue https://bugs.python.org/issue27400 def strptime(self, datestring, format): parsedDate = None try: parsedDate = datetime.datetime.strptime(datestring, format) except TypeError: parsedDate = datetime.datetime.fromtimestamp( time.mktime(time.strptime(datestring, format))) return parsedDate def TrySendRemoteTemp(self): Domoticz.Debug("TrySendRemoteTemp") domoticzRemoteTempUrl = self.DomoticzBaseUrl + '/json.htm?type=devices&rid=' + str( self.RemoteTempDeviceId) Domoticz.Debug(" Querying Domoticz remote temp : " + domoticzRemoteTempUrl) request = urllib.request.Request(domoticzRemoteTempUrl) response = urllib.request.urlopen(request, timeout=0.5) requestResponse = response.read() json_object = json.loads(requestResponse) if not json_object["status"] == "OK": raise ValueError( 'Bad response for remote temperature device request') if not json_object["result"]: raise ValueError( 'No device found for parametrized remote temperature device Idx (' + str(self.RemoteTempDeviceId) + ')') if not "Temp" in json_object["result"][0]: raise ValueError( 'Parametrized device for remote temperature is not a temperature device' ) lastUpdateString = json_object["result"][0][ 'LastUpdate'] #YYYY-mm-dd hh:mm:ss remoteTempToSend = json_object["result"][0]['Temp'] remoteTempToSend = round(remoteTempToSend * 2) / 2 #compute lastseen lastUpdateTime = self.strptime(lastUpdateString, '%Y-%m-%d %H:%M:%S') now = datetime.datetime.now() ellapsedMinutesSinceLastSeen = (now - lastUpdateTime).total_seconds() / 60 if (ellapsedMinutesSinceLastSeen > self.RemoteTempMaxEllapsedMinutes): Domoticz.Debug(" temperature value too old (" + str(ellapsedMinutesSinceLastSeen) + ") resetting remote temp") remoteTempToSend = 0 #send 0 if the temperature is too old so the VAC use its internal sensor #send temp or reset #does not resend the special value 0 if previously sent (no need to spam) if (self.RemoteTempLastSentValue == 0 and remoteTempToSend == 0): Domoticz.Debug(" remote temp is already 0, sending discarded") return payloaddic = {'remoteTemp': remoteTempToSend} Domoticz.Debug(" publishing on " + self.HeatpumpSetTopic + " : " + str(json.dumps(payloaddic))) self.mqttClient.Publish(self.HeatpumpSetTopic, json.dumps(payloaddic)) self.RemoteTempLastSentValue = remoteTempToSend def onHeartbeat(self): # Domoticz.Debug("Heartbeating...") if self.mqttClient is not None: try: # Reconnect if connection has dropped if (self.mqttClient.mqttConn is None) or (not self.mqttClient.isConnected): Domoticz.Debug("Reconnecting") self.mqttClient.Open() else: # Domoticz.Debug("Ping...") self.mqttClient.Ping() except Exception as e: Domoticz.Error(str(e)) #Remote temp if (self.ShouldSendRemoteTemp() and self.mqttClient.isConnected): try: self.TrySendRemoteTemp() except Exception as e: Domoticz.Error("Failed to send remote temp : " + traceback.format_exc()) def onMQTTConnected(self): if self.mqttClient is not None: self.mqttClient.Subscribe([self.HeatpumpTopic, self.RoomTempTopic]) def onMQTTDisconnected(self): Domoticz.Debug("onMQTTDisconnected") def onMQTTPublish(self, topic, message): # process incoming MQTT statuses jsondic = json.loads(message.decode('utf8')) for mappedDevice in self.mappedDevicesByUnit.values(): if (mappedDevice.externalDeviceId in jsondic): mappedDevice.UpdateDz(jsondic[mappedDevice.externalDeviceId]) return
class IOThermostat: # constants UPTIMEFILE = '/proc/uptime' STARTTIME = datetime.now() REFRESH_SECONDS = 3 T_OFFSET = -0.5 H_OFFSET = 0 P_OFFSET = 0 SUBSCRIBELIST = [topics.MODE, topics.TARGETTEMPERATURE, topics.SCHEDULE, topics.OTHERTEMPERATURE] USE_OTHERTEMPERATURE = False DATALOGFILE = '/home/iothermostat/iothermostat.csv' DATALOGMAXFILESIZE = 2*1000*1000 # 2MB in Bytes # topics to log, options are: # topics.TEMPERATURE,topics.PRESSURE,topics.HUMIDITY,topics.D_TEMPERATURE,topics.D_PRESSURE,topics.D_HUMIDITY, # topics.HEATERON,topics.IOTHERMUPTIME,topics.SYSTEMUPTIME DATALOGKEYS = [topics.TEMPERATURE,topics.PRESSURE,topics.HUMIDITY,topics.HEATERON] # default variable values previousmessages = None # objects scheduler = None mqttclient = None heatercontroller = None modemanager = None def schedulercallbackfunc(self, arg): # used for scheduler set temperature callback. # arg is not an array, unlike the array that was given to apscheduler.add_job self.setTargetTemperature(arg) def modemanagercallbackfunc(self): # used for modemanager previous mode callback self.mqttclient.publish( {topics.MODE:self.modemanager.currentmode.name} ) def setTargetTemperature(self,temperature,publish=True): self.modemanager.currentmode.targettemperature = temperature if publish: self.mqttclient.publish({topics.TARGETTEMPERATURE:temperature}) def publishModeEndTime(self, endtime): if endtime: self.mqttclient.publish({topics.MODEENDTIME:endtime}) def getSelfUptime(self): uptime = datetime.now() - self.STARTTIME uptime_string = str(uptime.days) return uptime_string def getSystemUptime(self): uptime_seconds = -1 with open(self.UPTIMEFILE, 'r') as f: uptime_seconds = float(f.readline().split()[0]) uptime_string = str(timedelta(seconds = uptime_seconds).days) return uptime_string def processMessages(self, messages): # process new targettemperature if topics.TARGETTEMPERATURE in messages: self.modemanager.currentmode.targettemperature = float( messages[topics.TARGETTEMPERATURE] ) # process new schedule if topics.SCHEDULE in messages: schedule = self.scheduler.stringToSchedule( messages[topics.SCHEDULE], self.schedulercallbackfunc, self.modemanager.OFF.targettemperature ) self.modemanager.AUTO.schedule = schedule # reload schedule if mode is auto if self.modemanager.currentmode == self.modemanager.AUTO: self.scheduler.setSchedule(schedule) # process new mode if topics.MODE in messages: mode = self.modemanager.stringToMode( messages[topics.MODE] ) self.modemanager.setMode( mode ) self.mqttclient.publish({topics.TARGETTEMPERATURE:self.modemanager.currentmode.targettemperature}) self.publishModeEndTime(mode.endtime) def prepareMessages(self, t, p, h, d_t, d_p, d_h): messages = {} # collect sensor states for publishing messages[topics.TEMPERATURE] = t messages[topics.PRESSURE] = int(p) messages[topics.HUMIDITY] = int(h) messages[topics.D_TEMPERATURE] = d_t messages[topics.D_PRESSURE] = d_p messages[topics.D_HUMIDITY] = d_h messages[topics.HEATERON] = self.heatercontroller.isHeaterEnabled() messages[topics.IOTHERMUPTIME] = self.getSelfUptime() messages[topics.SYSTEMUPTIME] = self.getSystemUptime() # only keep new data if self.previousmessages: newmessages = {} for topic,value in messages.items(): if not topic in self.previousmessages or not value == self.previousmessages[topic]: newmessages[topic] = value self.previousmessages[topic] = value messages = newmessages else: self.previousmessages = messages.copy() return messages def run(self): sensors = None datalogger = None try: # initialise objects sensors = Sensors(self.T_OFFSET,self.P_OFFSET,self.H_OFFSET) datalogger = DataLogger(self.DATALOGFILE, self.DATALOGKEYS, self.DATALOGMAXFILESIZE) self.scheduler = HeaterScheduler() self.modemanager = ModeManager( scheduler=self.scheduler, callbackfunc=self.modemanagercallbackfunc) self.mqttclient = MqttClient(subscribelist=self.SUBSCRIBELIST) self.heatercontroller = HeaterController() # initialise state self.modemanager.setMode(self.modemanager.AUTO) # initial data t_avg,p_avg,h_avg = sensors.getData() # present ourselves self.mqttclient.publish({topics.IOTHERMSTATUS:'Active'}) self.mqttclient.publish({topics.IOTHERMVERSION:__version__ +' '+ __status__}) self.mqttclient.publish({topics.MODE:self.modemanager.currentmode.name}) self.mqttclient.publish({topics.TARGETTEMPERATURE:self.modemanager.currentmode.targettemperature}) t = 0 while True: t_,p,h = sensors.getData() messages = self.mqttclient.getData() # use temperature value from mqtt if self.USE_OTHERTEMPERATURE and topics.OTHERTEMPERATURE in messages: t = float( messages[topics.OTHERTEMPERATURE] ) if not self.USE_OTHERTEMPERATURE: t = t_ # calculate averages t_avg = (t_avg + t)/2 p_avg = (p_avg + p)/2 h_avg = (h_avg + h)/2 # calculate derivatives d_t = (t - t_avg)/self.REFRESH_SECONDS d_p = (p - p_avg)/self.REFRESH_SECONDS d_h = (h - h_avg)/self.REFRESH_SECONDS # process data from subscribed topics self.processMessages( messages ) # prepare for publishing messages = self.prepareMessages(t, p, h, d_t, d_p, d_h) datalogger.log(messages) self.mqttclient.publish(messages) # update the heatercontroller with the current and target temperatures #print('targettemperature = {}'.format(self.modemanager.currentmode.targettemperature)) self.heatercontroller.update(t,self.modemanager.currentmode.targettemperature) sleep(self.REFRESH_SECONDS) finally: print('IOThermostat: Stopping IOThermostat..') if datalogger: datalogger.close() if sensors: sensors.close() if self.scheduler: self.scheduler.close() if self.heatercontroller: self.heatercontroller.close() if self.mqttclient: self.mqttclient.close()
return reading # parse arguments parser = argparse.ArgumentParser() parser.add_argument("-e", "--endpoint", help="AWS IoT endpoint", required=True) parser.add_argument("-r", "--ca_file", help="Certificate Authority file", default='rootCA.pem') parser.add_argument("-c", "--client_cert_file", help="Client certificate file", default='certificate.pem') parser.add_argument("-k", "--client_key_file", help="Client Key File", default='private.pem') parser.add_argument("-p", "--port", help="MQTT port", type=int, default=8883) parser.add_argument("-q", "--qos", help="MQTT QoS", type=int, default=1) parser.add_argument("-o", "--topic2", help="Additional MQTT topic") parser.add_argument("-t", "--topic", help="MQTT topic") parser.add_argument("-g", "--log_level", help="log level", type=int, default=logging.INFO) parser.add_argument("-i", "--pin", help="gpio pin (using BCM numbering)", type=int, default=5) args = parser.parse_args() # collect data and figure out median for results GPIO.setmode(GPIO.BCM) arr = [] for i in range(0, 10): arr.append(PCtime(args.pin)) # publish if args.topic is not None: MqttClient.publish(args, args.topic, {'state': {'reported': {'photocell': numpy.median(arr)}}}) if args.topic2 is not None: MqttClient.publish(args, args.topic2, {'state': {'reported': {'photocell': numpy.median(arr)}}})
def receive_command(client, obj, message): message_json = MqttClient.parse_payload(message.payload) print("chomp: %s %s %s" % (mqtt.endpoint, message.topic, str(message_json)))
22: Adafruit_DHT.DHT22, 2302: Adafruit_DHT.AM2302} # parse arguments parser = argparse.ArgumentParser() parser.add_argument("-e", "--endpoint", help="AWS IoT endpoint", required=True) parser.add_argument("-r", "--ca_file", help="Certificate Authority file", default='rootCA.pem') parser.add_argument("-c", "--client_cert_file", help="Client certificate file", default='certificate.pem') parser.add_argument("-k", "--client_key_file", help="Client Key File", default='private.pem') parser.add_argument("-p", "--port", help="MQTT port", type=int, default=8883) parser.add_argument("-q", "--qos", help="MQTT QoS", type=int, default=1) parser.add_argument("-i", "--pin", help="gpio pin (using BCM numbering)", type=int, default=4) parser.add_argument("-o", "--topic2", help="Additional MQTT topic") parser.add_argument("-t", "--topic", help="MQTT topic") parser.add_argument("-y", "--dht_type", help="DHT sensor type %s" % (str(SENSOR_ARGS.keys())), type=int, default=Adafruit_DHT.DHT22) parser.add_argument("-g", "--log_level", help="log level", type=int, default=logging.INFO) args = parser.parse_args() if args.dht_type not in SENSOR_ARGS: sys.exit("Error: Invalid sensor type") humidity, temperature = Adafruit_DHT.read(SENSOR_ARGS[args.dht_type], args.pin) # publish if args.topic is not None: MqttClient.publish(args, args.topic, {'state': {'reported': {'temperature': temperature, 'humidity': humidity}}}) if args.topic2 is not None: MqttClient.publish(args, args.topic2, {'state': {'reported': {'temperature': temperature, 'humidity': humidity}}})
def onStart(self): try: #Domoticz.Trace(True) Domoticz.Heartbeat(10) self.PluginKey = "ToshibaHpMqtt" self.HardwareID = Parameters["HardwareID"] self.debugging = Parameters["Mode6"] if self.debugging == "Verbose": Domoticz.Debugging(2 + 4 + 8 + 16 + 64) if self.debugging == "Debug": Domoticz.Debugging(2) self.HeatpumpTopic = Parameters["Mode5"] self.HeatpumpSetTopic = self.HeatpumpTopic + "/set" self.RoomTempTopic = self.HeatpumpTopic + "/status" self.RemoteTempDeviceId = Parameters["Mode1"] self.DomoticzBaseUrl = Parameters["Mode2"] if (self.ShouldSendRemoteTemp() and not self.DomoticzBaseUrl): self.RemoteTempDeviceId = None Domoticz.Error( "Domoticz base url required and not set in plugin parameters. Remote temp sending disabled" ) try: self.RemoteTempMaxEllapsedMinutes = int(Parameters["Mode3"]) except ValueError: self.RemoteTempMaxEllapsedMinutes = 30 Domoticz.Error( "Wrong parameter value for remote temp sensor maximum minutes, setting default : " + str(self.RemoteTempMaxEllapsedMinutes)) self.mappedDevicesByUnit = {} self.payloadKeyToDevice = bijection.Bijection() Domoticz.Debug("Mapping power") self.powerDeviceMapping = SwitchDeviceMapping(Devices, Images, self.PluginKey, self.HardwareID, "Power", "POW", "power", usedByDefault=True, switchType=0, dzValues={ 0: "OFF", 1: "ON" }) self.mappedDevicesByUnit[self.powerDeviceMapping.dzDevice. Unit] = self.powerDeviceMapping self.payloadKeyToDevice["power"] = self.powerDeviceMapping Domoticz.Debug("Mapping mode") self.modeDeviceMapping = SelectorDeviceMapping( Devices, Images, self.PluginKey, self.HardwareID, "Mode", "MODE", "mode", usedByDefault=True, dzLevelsCodes=[('Auto', 'AUTO'), ('Froid', 'COOL'), ('Déshum.', 'DRY'), ('Chaud', 'HEAT'), ('Ventil.', 'FAN')], offHidden=True) self.mappedDevicesByUnit[ self.modeDeviceMapping.dzDevice.Unit] = self.modeDeviceMapping self.payloadKeyToDevice["mode"] = self.modeDeviceMapping Domoticz.Debug("Mapping fan") self.fanDeviceMapping = SelectorDeviceMapping(Devices, Images, self.PluginKey, self.HardwareID, "Flux", "FAN", "fan", usedByDefault=True, dzLevelsCodes=[ ('Auto', 'AUTO'), ('Silence', 'QUIET'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4') ], offHidden=True) self.mappedDevicesByUnit[ self.fanDeviceMapping.dzDevice.Unit] = self.fanDeviceMapping self.payloadKeyToDevice["fan"] = self.fanDeviceMapping Domoticz.Debug("Mapping vane") self.vVaneDeviceMapping = SelectorDeviceMapping( Devices, Images, self.PluginKey, self.HardwareID, "Inclinaison", "VVANE", "vane", usedByDefault=True, dzLevelsCodes=[('Auto', 'AUTO'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('Oscillant', 'SWING')], offHidden=True) self.mappedDevicesByUnit[self.vVaneDeviceMapping.dzDevice. Unit] = self.vVaneDeviceMapping self.payloadKeyToDevice["vane"] = self.vVaneDeviceMapping Domoticz.Debug("Mapping wvane") self.wVaneDeviceMapping = SelectorDeviceMapping(Devices, Images, self.PluginKey, self.HardwareID, "Direction", "WVANE", "wideVane", usedByDefault=True, dzLevelsCodes=[ ('<<', '<<'), ('<', '<'), ('V', '|'), ('>', '>'), ('>>', '>>'), ('Oscillant', 'SWING') ], offHidden=True) self.mappedDevicesByUnit[self.wVaneDeviceMapping.dzDevice. Unit] = self.wVaneDeviceMapping self.payloadKeyToDevice["wideVane"] = self.wVaneDeviceMapping Domoticz.Debug("Mapping setpoint") self.setpointDeviceMapping = SetpointDeviceMapping( Devices, Images, self.PluginKey, self.HardwareID, "Thermostat", "TEMPSET", "temperature", usedByDefault=True) self.mappedDevicesByUnit[self.setpointDeviceMapping.dzDevice. Unit] = self.setpointDeviceMapping self.payloadKeyToDevice["temperature"] = self.setpointDeviceMapping Domoticz.Debug("Mapping temperature") self.temperatureDevicemapping = TemperatureDeviceMapping( Devices, Images, self.PluginKey, self.HardwareID, "T° Split", "TEMP", "roomTemperature", usedByDefault=True) self.mappedDevicesByUnit[self.temperatureDevicemapping.dzDevice. Unit] = self.temperatureDevicemapping self.mqttserveraddress = Parameters["Address"].strip() self.mqttserverport = Parameters["Port"].strip() clientIdPrefix = 'Domoticz_' + Parameters['Key'] + '_' + str( Parameters['HardwareID']) self.mqttClient = MqttClient(self.mqttserveraddress, self.mqttserverport, clientIdPrefix, self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, None) except Exception as e: Domoticz.Error("Start error: " + str(e)) self.mqttClient = None
is_monitoring = False # logging setup logger = set_logger(level=args.log_level) video = Video( rotation=args.rotation, horizontal_resolution=args.horizontal_resolution, vertical_resolution=args.vertical_resolution ) video.start() pir = PIR(args.pin) pir.start() mqtt = MqttClient(args.endpoint, args.log_level, args.port) mqtt.set_tls(args.ca_file, args.client_cert_file, args.client_key_file) mqtt.add_callback(args.topic + args.subtopic, receive_command) mqtt.add_subscription(args.topic + args.subtopic, qos=args.qos) mqtt.loop_start() # loop while True: is_moving = pir.detects_movement() if is_monitoring: if not is_moving: if video.recording: Video.generate_thumbnail(video.stop_recording(), hres=args.horizontal_resolution, vres=args.vertical_resolution) elif is_moving: video.start_recording()
parser.add_argument("-s", "--topic_key", help="MQTT topic key", required=True) parser.add_argument("-w", "--wait", help="time between readings", type=float, default=0.5) parser.add_argument("-i", "--pin", help="gpio pin (BCM)", type=int, required=True) parser.add_argument("-y", "--high_value", help="high value", default=Sensor.HIGH) parser.add_argument("-z", "--low_value", help="low value", default=Sensor.LOW) parser.add_argument("-g", "--log_level", help="logging level", type=int, default=logging.INFO) args = parser.parse_args() # logging setup logger = set_logger(level=args.log_level) sensor = Sensor(args.pin) sensor.start() last_state = None status = None while True: current_state = sensor.reading() if current_state != last_state: last_state = current_state # reset state value if current_state == Sensor.LOW: status = args.low_value else: status = args.high_value logger.debug("sensor-monitor: changed %s %s" % (args.topic_key, str(status))) # publish MqttClient.publish(args, args.topic, {'state': {'reported': {args.topic_key: status}}}) if args.topic2 is not None: MqttClient.publish(args, args.topic2, {'state': {'reported': {args.topic_key: status}}}) sleep(args.wait)
class RoundRobin: """Round robin through all the discovered media apps This class will walk through the list of discovered media apps, launching each one and waiting for it's status to change to "running". """ def __init__(self, host, port): """Create the RoundRobin object.""" self.host = host self.port = port self.mqtt_client = MqttClient(host, port) self.thread = None self.stop_event = Event() self.active_requests = [] self.app_args = [ { "app_id": "netflix", "startup-args": { "args": [] }, "args": { "args": [ "m=https://api-global.netflix.com/catalog/titles/movie/80223967&trackId=14855318" ] } }, { "app_id": "prime-video", "startup-args": { "args": [] }, "args": { "contentId": "B015YJRQ8U", "mediaType": "movie" } }, { "app_id": "youtube", "startup-args": {}, "args": { "video_id": "KEcbFSaLpoM" } }, ] self.logger = logging.getLogger(__name__) def execute(self, request): """Execute a request. Basically block until a request has been executed and the response returned. """ self.active_requests.append(request) response = request.execute() self.active_requests.remove(request) return response @staticmethod def build_app_topic(app, topic): return "apps/{}/{}".format(app["app_id"], topic) @staticmethod def build_platform_topic(capability, topic): return "platform/{}/{}".format(capability, topic) def start_app(self, app, content_reference): """Attempt to launch the specified app. This function executes the start request and waits for the app status to change to "running". """ req = MqttRequest(self.mqtt_client, self.build_app_topic(app, "app/start"), json.dumps(content_reference)) response = self.execute(req) if response["status"] == 200: wait = MqttWait(self.mqtt_client, self.build_app_topic(app, "status/lifecycle"), {"status": "started"}, 30.0) response = self.execute(wait) if not response: raise Exception('Timeout waiting for app status') else: raise Exception('Bad status from request: ' + json.dumps(response)) def stop_app(self, app): """Attempt to launch the specified app. This function executes the start request and waits for the app status to change to "running". """ req = MqttRequest(self.mqtt_client, self.build_app_topic(app, "app/stop"), json.dumps({"args": []})) response = self.execute(req) if response["status"] == 200: wait = MqttWait(self.mqtt_client, self.build_app_topic(app, "status/lifecycle"), {"status": "stopped"}, 30.0) response = self.execute(wait) if not response: raise Exception('Timeout waiting for app status') else: raise Exception('Bad status from request: ' + json.dumps(response)) def start_media(self, app, content_reference): """Attempt to play specified content on the specified app. This function executes the media/start request and waits for the media status to change to "playing". """ req = MqttRequest(self.mqtt_client, self.build_app_topic(app, "media/start"), json.dumps(content_reference)) response = self.execute(req) if response["status"] == 200: wait = MqttWait(self.mqtt_client, self.build_app_topic(app, "status/media"), {"status": "playing"}, 30.0) response = self.execute(wait) if not response: raise Exception('Timeout waiting for media status') else: raise Exception('Bad status from request: ' + json.dumps(response)) def send_input_event(self, app, device, key): req = MqttRequest( self.mqtt_client, self.build_platform_topic("input", "{}/{}".format(device, key)), json.dumps({"app_id": app["app_id"]})) response = self.execute(req) if response["status"] != 200: raise Exception('Bad status from request: ' + json.dumps(response)) def memory_monitor(self, app, action): """Control monitoring memory on the specified app. This function executes the telemetry/memory/monitor/<action> request. """ req = MqttRequest( self.mqtt_client, self.build_platform_topic("telemetry", "{}/{}".format("monitor", action)), json.dumps({"app_id": app["app_id"]})) response = self.execute(req) if response["status"] != 200: raise Exception('Bad status from request: ' + json.dumps(response)) def run_test(self, app): self.logger.info("Running test on {}".format(app["name"])) self.logger.info("Starting app...") if not self.stop_event.is_set(): # Start the app and wait for it to startup content_reference = next(args for args in self.app_args if args["app_id"] == app["app_id"]) if content_reference: self.start_app(app, content_reference["startup-args"]) else: raise Exception("No args found for app {}.".format( app["name"])) time.sleep(1) self.memory_monitor(app, "start") if app["name"] == "Netflix": # Enter the default profile for Netflix time.sleep(5) self.send_input_event(app, "remote", "OK") time.sleep(2) if app["name"] == "Prime Video": self.send_input_event(app, "remote", "down") time.sleep(2) self.send_input_event(app, "remote", "down") time.sleep(2) self.send_input_event(app, "remote", "right") time.sleep(2) self.send_input_event(app, "remote", "right") time.sleep(2) self.send_input_event(app, "remote", "down") time.sleep(2) self.logger.info("Starting playback...") if not self.stop_event.is_set(): # Play some media content_reference = next(args for args in self.app_args if args["app_id"] == app["app_id"]) if content_reference: self.start_media(app, content_reference["args"]) else: raise Exception("No args found for app {}.".format( app["name"])) # Let playback start and run for a bit... sleep_time_seconds = 10 self.logger.info("Play for {} seconds...".format(sleep_time_seconds)) if not self.stop_event.is_set(): time.sleep(sleep_time_seconds) # Pause playback self.send_input_event(app, "remote", "pause") time.sleep(5) self.send_input_event(app, "remote", "play") time.sleep(5) self.send_input_event(app, "remote", "pause") time.sleep(5) self.send_input_event(app, "remote", "play") time.sleep(5) self.memory_monitor(app, "stop") self.logger.info("Stopping app...") if not self.stop_event.is_set(): # Stop the app self.stop_app(app) self.logger.info("Test complete.") def _start(self): """Private start function that starts the client and loops through the apps forever.""" self.mqtt_client.start() discovered_apps = self.mqtt_client.get_discovered_apps() while not self.stop_event.is_set(): for app in discovered_apps: self.run_test(app) def start(self): """Public start function to get the party started.""" self.thread = Thread(target=self._start, daemon=True) self.thread.start() return self.thread def stop(self): """Party's over.""" self.mqtt_client.stop() self.stop_event.set() for active_request in self.active_requests: active_request.cancel()