Example #1
0
def switch_toggle_loop():
    """Toggle the switch on all devices in the directory"""

    global switch_state

    if Registry.size() > 0 and sendSwitchTimer.check():
        print("transmit")
        radio.transmitter()

        for sensorid in Registry.get_sensorids():
            # Only try to toggle the switch for devices that actually have a switch
            header = Registry.get_info(sensorid)["header"]
            mfrid = header["mfrid"]
            productid = header["productid"]

            if Devices.hasSwitch(mfrid, productid):
                request = OpenThings.alterMessage(Messages.SWITCH,
                    header_sensorid=sensorid,
                    recs_0_value=switch_state)
                p = OpenThings.encode(request)
                print("Sending switch message to %s %s" % (hex(productid), hex(sensorid)))
                # Transmit multiple times, hope one of them gets through
                radio.transmit(p, inner_times=2)

        radio.receiver()
        switch_state = (switch_state+1) % 2 # toggle
Example #2
0
def main():
    global outputFile, directory
    try:
        opts, args = getopt.getopt(sys.argv[1:],"ho:",["output="])
    except getopt.GetoptError:
        print '%s -o <outputfile>' % sys.argv[0]
        sys.exit(2)

    for opt, arg in opts:
      if opt == '-h':
         print '%s -o <outputfile>' % sys.argv[0]
         sys.exit()
      elif opt in ("-o", "--output"):
         outputFile = arg

    if outputFile == None:
        print "No output file specified, output to console."

    radio.init()
    OpenThings.init(Devices.CRYPT_PID)

    try:
        dumpDirectory()
        monitor_loop()

    finally:
        radio.finished()
        directory = {"__META": {"time": int(time.time())}}
        dumpDirectory()
Example #3
0
def switch_toggle_loop():
    """Toggle the switch on all devices in the directory"""

    global switch_state

    if Registry.size() > 0 and sendSwitchTimer.check():
        print("transmit")
        radio.transmitter()

        for sensorid in Registry.get_sensorids():
            # Only try to toggle the switch for devices that actually have a switch
            header = Registry.get_info(sensorid)["header"]
            mfrid = header["mfrid"]
            productid = header["productid"]

            if Devices.hasSwitch(mfrid, productid):
                request = OpenThings.alterMessage(Messages.SWITCH,
                                                  header_sensorid=sensorid,
                                                  recs_0_value=switch_state)
                p = OpenThings.encode(request)
                print("Sending switch message to %s %s" %
                      (hex(productid), hex(sensorid)))
                # Transmit multiple times, hope one of them gets through
                radio.transmit(p, inner_times=2)

        radio.receiver()
        switch_state = (switch_state + 1) % 2  # toggle
Example #4
0
    def handle_message(self, payload):
        # send a message whilst receive window is open, this MUST be done first
        if len(self.send_queue) > 0:
            message = self.send_queue.pop(0)
            self.send_message(message)
            # logging.debug("Sent message %s" % str(message))
            # logging.debug("MIHO013 send %s (%s remaining)" % (self.device_id, len(self.send_queue)))

        # check if it's time to refresh readings
        now = time.time()
        if self.voltageReadingPeriod is not None and (
                self.lastVoltageReading is None
                or now - self.lastVoltageReading > self.voltageReadingPeriod):
            self.queue_message(
                OpenThings.Message(MIHO013_BATTERY_LEVEL,
                                   header=self.__class__.header()))
            self.lastVoltageReading = now

        if self.diagnosticsReadingPeriod is not None and (
                self.lastDiagnosticsReading is None or now -
                self.lastDiagnosticsReading > self.diagnosticsReadingPeriod):
            self.queue_message(
                OpenThings.Message(MIHO013_DIAGNOSTICS,
                                   header=self.__class__.header()))
            self.lastDiagnosticsReading = now

        # extract data from message
        for rec in payload["recs"]:
            paramid = rec["paramid"]
            if "value" in rec:
                value = rec["value"]
                # logging.debug("MIHO013 new data %s %s %s" % (self.device_id, OpenThings.paramid_to_paramname(paramid), value))
                if paramid == OpenThings.PARAM_TEMPERATURE:
                    self.readings.ambient_temperature = value
                    HandlerRegistry.handle_reading(self.uuid,
                                                   'ambient_temperature',
                                                   value)
                    if value < self._temperature_alarm_low:
                        HandlerRegistry.alarm(self.uuid, 'ambient_temperature',
                                              value, 'Temperature Too Low')
                    elif value > self._temperature_alarm_high:
                        HandlerRegistry.alarm(self.uuid, 'ambient_temperature',
                                              value, 'Temperature Too High')

                elif paramid == OpenThings.PARAM_VOLTAGE:
                    self.readings.battery_voltage = value
                    HandlerRegistry.handle_reading(self.uuid,
                                                   'battery_voltage', value)
                    if value < self._battery_alarm_low:
                        HandlerRegistry.alarm(self.uuid, 'battery_voltage',
                                              value, 'Battery Running Low')

                elif paramid == OpenThings.PARAM_DIAGNOSTICS:
                    self.readings.diagnostic_flags = value
                    HandlerRegistry.handle_reading(self.uuid,
                                                   'diagnostic_flags', value)
                else:
                    logging.debug("Unhandled param id %s" % str(paramid))
Example #5
0
def send_join_ack(mfrid, productid, sensorid):
    # send back a JOIN ACK, so that join light stops flashing
    response = OpenThings.alterMessage(Messages.JOIN_ACK,
        header_mfrid=mfrid,
        header_productid=productid,
        header_sensorid=sensorid)
    p = OpenThings.encode(response)
    radio.transmitter()
    radio.transmit(p)
    radio.receiver()
Example #6
0
 def set_valve_position(self, position: int):
     payload = OpenThings.Message(MIHO013_SET_VALVE_POSITION,
                                  header=self.__class__.header()).copyof()
     payload.set(recs_VALVE_POSITION_value=position)
     self._valvePosition = position
     # HandlerRegistry.handle_reading(self.uuid, 'valve_position', position)
     self.queue_message(payload)
Example #7
0
 def turn_off(self):
     # TODO: header construction should be in MiHomeDevice as it is shared?
     payload = OpenThings.Message(SWITCH, header=self.__class__.header())
     payload.set(header_productid=self.__class__._product_id,
                 header_sensorid=self.device_id,
                 recs_SWITCH_STATE_value=False)
     self.send_message(payload)
Example #8
0
 def join_req(cls, mfrid, productid, deviceid):
     """Used for testing, synthesises a JOIN_REQ message from this device"""
     msg = OpenThings.Message(JOIN_REQ, header=cls.header())
     msg["header_mfrid"]     = mfrid
     msg["header_productid"] = productid
     msg["header_sensorid"]  = deviceid
     return msg
Example #9
0
    def join_ack(self):
        """Send a join-ack to the real device"""
        # msg = OpenThings.Message(header_mfrid=MFRID_ENERGENIE, header_productid=self.product_id, header_sensorid=self.device_id)
        # msg[OpenThings.PARAM_JOIN] = {"wr":False, "typeid":OpenThings.Value.UINT, "length":0}
        # self.send_message(msg)

        payload = OpenThings.Message(JOIN_ACK, header=self.__class__.header())
        payload.set(header_productid=self.__class__._product_id,
                    header_sensorid=self.device_id)
        self.send_message(payload)
Example #10
0
 def set_setpoint_temperature(self, temperature: float):
     self.readings.setpoint_temperature = temperature
     # HandlerRegistry.handle_reading(self.uuid, 'setpoint_temperature', position)
     payload = OpenThings.Message(MIHO013_SET_TEMPERATURE,
                                  header=self.__class__.header()).copyof()
     if temperature < 0:
         temperature = 0
     if temperature > 30:
         temperature = 30
     payload.set(recs_TEMPERATURE_value=int(temperature * 256))
     self.queue_message(payload)
Example #11
0
def switch_sniff_loop():
    """Listen to sensor messages and add them to the Registry"""

    # See if there is a payload, and if there is, process it
    if radio.is_receive_waiting():
        ##trace("receiving payload")
        payload = radio.receive()
        try:
            decoded = OpenThings.decode(payload)
            now = time.time()
        except OpenThings.OpenThingsException as e:
            warning("Can't decode payload:" + str(e))
            return

        OpenThings.showMessage(decoded, timestamp=now)
        # Any device that reports will be added to the non-persistent directory
        Registry.update(decoded)
        ##trace(decoded)

        # Process any JOIN messages by sending back a JOIN-ACK to turn the LED off
        if len(decoded["recs"]) == 0:
            # handle messages with zero recs in them silently
            print("Empty record:%s" % decoded)
        else:
            # assume only 1 rec in a join, for now
            if decoded["recs"][0]["paramid"] == OpenThings.PARAM_JOIN:
                mfrid = OpenThings.getFromMessage(decoded, "header_mfrid")
                productid = OpenThings.getFromMessage(decoded,
                                                      "header_productid")
                sensorid = OpenThings.getFromMessage(decoded,
                                                     "header_sensorid")
                Messages.send_join_ack(radio, mfrid, productid, sensorid)
Example #12
0
def monitor_loop():
    """Capture any incoming messages and log to CSV file"""

    radio.receiver()

    while True:
        # See if there is a payload, and if there is, process it
        if radio.is_receive_waiting():
            trace("receiving payload")
            payload = radio.receive()
            try:
                decoded = OpenThings.decode(payload)
                now = time.time()
            except OpenThings.OpenThingsException as e:
                warning("Can't decode payload:" + str(e))
                continue
                      
            OpenThings.showMessage(decoded, timestamp=now)
            # Any device that reports will be added to the non-persistent directory
            Registry.update(decoded)
            ##trace(decoded)
            Logger.logMessage(decoded)

            # Process any JOIN messages by sending back a JOIN-ACK to turn the LED off
            if len(decoded["recs"]) == 0:
                # handle messages with zero recs in them silently
                print("Empty record:%s" % decoded)
            else:
                # assume only 1 rec in a join, for now
                if decoded["recs"][0]["paramid"] == OpenThings.PARAM_JOIN:
                    mfrid     = OpenThings.getFromMessage(decoded, "header_mfrid")
                    productid = OpenThings.getFromMessage(decoded, "header_productid")
                    sensorid  = OpenThings.getFromMessage(decoded, "header_sensorid")
                    Messages.send_join_ack(radio, mfrid, productid, sensorid)
Example #13
0
def monitor_loop():
    radio.receiver()

    while True:
        if radio.isReceiveWaiting():
            payload = radio.receive()
            try:
                decoded = OpenThings.decode(payload)
            except OpenThings.OpenThingsException as e:
                continue

            updateDirectory(decoded)
            tidyDirectory()
            dumpDirectory()

            # Process any JOIN messages by sending back a JOIN-ACK to turn the LED off
            if len(decoded["recs"]) != 0:
                if decoded["recs"][0]["paramid"] == OpenThings.PARAM_JOIN:
                    header    = decoded["header"]
                    mfrid     = header["mfrid"]
                    productid = header["productid"]
                    sensorid  = header["sensorid"]
                    send_join_ack(mfrid, productid, sensorid)
Example #14
0
# combined.py  15/05/2016  D.J.Whale
#
# A simple demo of combining both FSK (MiHome) and OOK (green button legacy)
#
# NOTE: This is only a test harness.
# If you really want a nice way to control these devices, wait for the 'device classes'
# issues to be implemented and tested on top of the raw radio interface, as these
# will be much nicer to use.

import time
from energenie import Messages, OpenThings, radio, encoder, Devices

# build FSK messages for MiHome purple

OpenThings.init(Devices.CRYPT_PID)

PURPLE_ID = 0x68B # captured from a real device using Monitor.py
m = OpenThings.alterMessage(
    Messages.SWITCH,
    header_sensorid=PURPLE_ID,
    recs_0_value=1)
purple_on = OpenThings.encode(m)

m = OpenThings.alterMessage(
    Messages.SWITCH,
    header_sensorid=PURPLE_ID,
    recs_0_value=0)
purple_off = OpenThings.encode(m)

# build OOK messages for legacy green button
Example #15
0
            Registry.update(decoded)
            ##trace(decoded)
            Logger.logMessage(decoded)

            # Process any JOIN messages by sending back a JOIN-ACK to turn the LED off
            if len(decoded["recs"]) == 0:
                # handle messages with zero recs in them silently
                print("Empty record:%s" % decoded)
            else:
                # assume only 1 rec in a join, for now
                if decoded["recs"][0]["paramid"] == OpenThings.PARAM_JOIN:
                    mfrid     = OpenThings.getFromMessage(decoded, "header_mfrid")
                    productid = OpenThings.getFromMessage(decoded, "header_productid")
                    sensorid  = OpenThings.getFromMessage(decoded, "header_sensorid")
                    Messages.send_join_ack(radio, mfrid, productid, sensorid)


if __name__ == "__main__":
    
    trace("starting monitor tester")
    radio.init()
    OpenThings.init(Devices.CRYPT_PID)

    try:
        monitor_loop()

    finally:
        radio.finished()

# END
Example #16
0
 def set_identify(self):
     self.queue_message(
         OpenThings.Message(MIHO013_IDENTIFY,
                            header=self.__class__.header()).copyof())
Example #17
0
                    header_sensorid=sensorid,
                    recs_0_value=switch_state)
                p = OpenThings.encode(request)
                print("Sending switch message to %s %s" % (hex(productid), hex(sensorid)))
                # Transmit multiple times, hope one of them gets through
                radio.transmit(p, inner_times=2)

        radio.receiver()
        switch_state = (switch_state+1) % 2 # toggle
        

if __name__ == "__main__":
    
    trace("starting switch tester")
    radio.init()
    OpenThings.init(Devices.CRYPT_PID)

    # Seed the registry with a known device, to simplify tx-only testing
    SENSOR_ID = 0x68B # captured from a real device
    device_header = OpenThings.alterMessage(Messages.REGISTERED_SENSOR,
        header_mfrid     = Devices.MFRID,
        header_productid = Devices.PRODUCTID_MIHO005, # adaptor plus
        header_sensorid  = SENSOR_ID)
    Registry.update(device_header)


    sendSwitchTimer    = Timer(TX_RATE, 1)   # every n seconds offset by initial 1
    switch_state       = 0 # OFF
    radio.receiver()

    try:
Example #18
0
            Logger.logMessage(decoded)

            # Process any JOIN messages by sending back a JOIN-ACK to turn the LED off
            if len(decoded["recs"]) == 0:
                # handle messages with zero recs in them silently
                print("Empty record:%s" % decoded)
            else:
                # assume only 1 rec in a join, for now
                if decoded["recs"][0]["paramid"] == OpenThings.PARAM_JOIN:
                    mfrid = OpenThings.getFromMessage(decoded, "header_mfrid")
                    productid = OpenThings.getFromMessage(
                        decoded, "header_productid")
                    sensorid = OpenThings.getFromMessage(
                        decoded, "header_sensorid")
                    Messages.send_join_ack(radio, mfrid, productid, sensorid)


if __name__ == "__main__":

    trace("starting monitor tester")
    radio.init()
    OpenThings.init(Devices.CRYPT_PID)

    try:
        monitor_loop()

    finally:
        radio.finished()

# END
Example #19
0
                                                  recs_0_value=switch_state)
                p = OpenThings.encode(request)
                print("Sending switch message to %s %s" %
                      (hex(productid), hex(sensorid)))
                # Transmit multiple times, hope one of them gets through
                radio.transmit(p, inner_times=2)

        radio.receiver()
        switch_state = (switch_state + 1) % 2  # toggle


if __name__ == "__main__":

    trace("starting switch tester")
    radio.init()
    OpenThings.init(Devices.CRYPT_PID)

    # Seed the registry with a known device, to simplify tx-only testing
    SENSOR_ID = 0x68B  # captured from a real device
    device_header = OpenThings.alterMessage(
        Messages.REGISTERED_SENSOR,
        header_mfrid=Devices.MFRID,
        header_productid=Devices.PRODUCTID_MIHO005,  # adaptor plus
        header_sensorid=SENSOR_ID)
    Registry.update(device_header)

    sendSwitchTimer = Timer(TX_RATE, 1)  # every n seconds offset by initial 1
    switch_state = 0  # OFF
    radio.receiver()

    try: