예제 #1
0
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()
예제 #2
0
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}}})
예제 #3
0
 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()
예제 #4
0
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
예제 #5
0
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)
예제 #6
0
 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__)
예제 #7
0
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__":
예제 #8
0
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():
예제 #9
0
        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()
예제 #10
0
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:
예제 #11
0
파일: publish.py 프로젝트: stevewoolley/IoT
#!/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}}})

예제 #12
0
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)
예제 #13
0
    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)
예제 #14
0
    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()
예제 #15
0
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()
예제 #16
0
        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)



예제 #17
0
    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()
예제 #18
0
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
예제 #19
0
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()
예제 #20
0
    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)}}})
예제 #21
0
파일: chomp.py 프로젝트: stevewoolley/IoT
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
0
               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}}})
예제 #23
0
    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
예제 #24
0
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()
예제 #25
0
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)
예제 #26
0
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()