Example #1
0
    def handle_message(self, payload):

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

        if self.diagnosticsReadingPeriod != None and (
                self.lastDiagnosticsReading == None or now -
                self.lastDiagnosticsReading > self.diagnosticsReadingPeriod):
            self.queue_message(OpenThings.Message(MIHO013_DIAGNOSTICS))
            self.lastDiagnosticsReading = now

        # send a message whilst receive window is open
        if len(self.send_queue) > 0:
            message = self.send_queue.pop(0)
            self.send_message(message)
            #print ("MIHO013 send %s",self.device_id)

        #extract data from message
        for rec in payload["recs"]:
            paramid = rec["paramid"]
            if "value" in rec:
                value = rec["value"]
                #print("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
                if paramid == OpenThings.PARAM_VOLTAGE:
                    self.readings.battery_voltage = value
                if paramid == OpenThings.PARAM_DIAGNOSTICS:
                    self.readings.diagnostic_flags = value
Example #2
0
def init():
    """Start the Energenie system running"""

    global registry, fsk_router, ook_router

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

    fsk_router = Registry.Router("fsk")

    #OOK receive not yet written
    #It will be used to be able to learn codes from Energenie legacy hand remotes
    ##ook_router = Registry.Router("ook")

    registry = Registry.DeviceRegistry()
    registry.set_fsk_router(fsk_router)
    ##registry.set_ook_router(ook_router

    path = os.path.join(sys.path[0], registry.DEFAULT_FILENAME)
    if os.path.isfile(path):
        registry.load_from(path)
        print("loaded registry from file")
        registry.list()
        fsk_router.list()

    # Default discovery mode, unless changed by app
    ##discovery_none()
    ##discovery_auto()
    ##discovery_ask(ask)
    discovery_autojoin()
Example #3
0
def init():
    """Start the Energenie system running"""

    global registry, fsk_router, ook_router

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

    fsk_router = Registry.Router("fsk")

    #OOK receive not yet written
    #It will be used to be able to learn codes from Energenie legacy hand remotes
    ##ook_router = Registry.Router("ook")

    registry = Registry.DeviceRegistry()
    registry.set_fsk_router(fsk_router)
    ##registry.set_ook_router(ook_router

    if os.path.isfile(registry.DEFAULT_FILENAME):
        registry.load_from(registry.DEFAULT_FILENAME)
        print("loaded registry from file")
        registry.list()
        fsk_router.list()

    # Default discovery mode, unless changed by app
    ##discovery_none()
    ##discovery_auto()
    ##discovery_ask(ask)
    discovery_autojoin()
Example #4
0
def send_join_ack(radio, mfrid, productid, sensorid):
    # send back a JOIN ACK, so that join light stops flashing
    response = OpenThings.alterMessage(JOIN_ACK,
                                       header_mfrid=mfrid,
                                       header_productid=productid,
                                       header_sensorid=sensorid)
    p = OpenThings.encode(response)
    radio.transmitter()
    radio.transmit(p, inner_times=2)
    radio.receiver()
Example #5
0
def send_join_ack(radio, mfrid, productid, sensorid):
    # send back a JOIN ACK, so that join light stops flashing
    response = OpenThings.alterMessage(JOIN_ACK,
                                       header_mfrid=mfrid,
                                       header_productid=productid,
                                       header_sensorid=sensorid)
    p = OpenThings.encode(response)
    radio.transmitter()
    radio.transmit(p, inner_times=2)
    radio.receiver()
Example #6
0
def transmit(payload, outer_times=1, inner_times=8, outer_delay=0):
    """Transmit a single payload using the present modulation scheme"""
    #Note, this optionally does a mode change before and after
    #extern void radio_transmit(uint8_t* payload, uint8_t len, uint8_t repeats);

    if DEBUG:
        print("***TX %s" % payload)
        import OpenThings
        if payload[0] < 20:  # crude way to reject ook messages
            print("PAYLOAD: %s" % OpenThings.decode(payload))
        # remember that the sensorId is encrypted too

    framelen = len(payload)
    if framelen < 1 or framelen > 255:
        raise ValueError("frame len must be 1..255")
    if outer_times < 1:
        raise ValueError("outer_times must be >0")
    if inner_times < 1 or inner_times > 255:
        raise ValueError("tx times must be 0..255")

    framelen = len(payload)
    Frame = ctypes.c_ubyte * framelen
    txframe = Frame(*payload)
    inner_times = ctypes.c_ubyte(inner_times)

    for i in range(outer_times):
        #TODO: transmit() will mode change if required
        #this means that outer_times will keep popping and pushing the mode
        #that might be ok, as it will force all the flags to clear?
        radio_transmit_fn(txframe, framelen, inner_times)
        if outer_delay != 0:
            time.sleep(outer_delay)
Example #7
0
def loop(receive_time=1):
    radio.receiver(fsk=True)
    timeout = time.time() + receive_time
    handled = False

    while True:
        if radio.is_receive_waiting():
            payload = radio.receive_cbp()
            now = time.time()
            try:
                msg = OpenThings.decode(payload, receive_timestamp=now)
                hdr = msg["header"]
                mfr_id = hdr["mfrid"]
                product_id = hdr["productid"]
                device_id = hdr["sensorid"]
                address = (mfr_id, product_id, device_id)
                msg_list = msg["recs"]
                handled = True
            except OpenThings.OpenThingsException:
                pass
                # print("Can't decode payload:%s" % payload)

        now = time.time()
        if now > timeout: break

    # print("handled: {handled}".format(handled=handled))
    if handled:
        return msg_list
    else:
        return handled
Example #8
0
def loop(receive_time=1):
    """Handle receive processing"""
    radio.receiver(fsk=True)
    timeout = time.time() + receive_time
    handled = False

    while True:
        if radio.is_receive_waiting():
            payload = radio.receive_cbp()
            now = time.time()
            try:
                msg = OpenThings.decode(payload, receive_timestamp=now)
                hdr = msg["header"]
                mfr_id = hdr["mfrid"]
                product_id = hdr["productid"]
                device_id = hdr["sensorid"]
                address = (mfr_id, product_id, device_id)

                registry.fsk_router.incoming_message(address, msg)
                handled = True
            except OpenThings.OpenThingsException:
                print("Can't decode payload:%s" % payload)

        now = time.time()
        if now > timeout: break

    return handled
Example #9
0
def loop(receive_time=1):
    """Handle receive processing"""
    radio.receiver(fsk=True)
    timeout = time.time() + receive_time
    handled = False

    while True:
        if radio.is_receive_waiting():
            payload = radio.receive_cbp()
            now = time.time()
            try:
                msg        = OpenThings.decode(payload, receive_timestamp=now)
                hdr        = msg["header"]
                mfr_id     = hdr["mfrid"]
                product_id = hdr["productid"]
                device_id  = hdr["sensorid"]
                address    = (mfr_id, product_id, device_id)

                registry.fsk_router.incoming_message(address, msg)
                handled = True
            except OpenThings.OpenThingsException:
                print("Can't decode payload:%s" % payload)

        now = time.time()
        if now > timeout: break

    return handled
Example #10
0
File: radio.py Project: maxf/home
def transmit(payload, outer_times=1, inner_times=8, outer_delay=0):
    """Transmit a single payload using the present modulation scheme"""
    #Note, this optionally does a mode change before and after
    #extern void radio_transmit(uint8_t* payload, uint8_t len, uint8_t repeats);

    if DEBUG:
        print("***TX %s" % payload)
        import OpenThings
        if payload[0] < 20: # crude way to reject ook messages
            print("PAYLOAD: %s" % OpenThings.decode(payload))
        # remember that the sensorId is encrypted too

    framelen = len(payload)
    if framelen < 1 or framelen > 255:
        raise ValueError("frame len must be 1..255")
    if outer_times < 1:
        raise ValueError("outer_times must be >0")
    if inner_times < 1 or inner_times > 255:
        raise ValueError("tx times must be 0..255")

    framelen     = len(payload)
    Frame        = ctypes.c_ubyte * framelen
    txframe      = Frame(*payload)
    inner_times  = ctypes.c_ubyte(inner_times)
    
    for i in range(outer_times):
        #TODO: transmit() will mode change if required
        #this means that outer_times will keep popping and pushing the mode
        #that might be ok, as it will force all the flags to clear?
        radio_transmit_fn(txframe, framelen, inner_times)
        if outer_delay != 0:
            time.sleep(outer_delay)
Example #11
0
 def turn_on(self):
     #TODO: header construction should be in MiHomeDevice as it is shared?
     payload = OpenThings.Message(SWITCH)
     payload.set(header_productid=self.product_id,
                 header_sensorid=self.device_id,
                 recs_SWITCH_STATE_value=True)
     return self.send_message(payload)  # tx_silence remaining
Example #12
0
 def get_join_req(mfrid, productid, deviceid):
     """Used for testing, synthesises a JOIN_REQ message from this device"""
     msg = OpenThings.Message(JOIN_REQ)
     msg["header_mfrid"]     = mfrid
     msg["header_productid"] = productid
     msg["header_sensorid"]  = deviceid
     return msg
Example #13
0
File: OnAir.py Project: maxf/home
    def receive(self, radio_config=None): # -> (radio_measurements, address or None, payload or None)
        #   radio_params is an overlay on top of radio rx defaults (e.g. poll rate, timeout, min payload, max payload)
        #   radio_measurements might include rssi reading, short payload report, etc
        pass # TODO
        #TODO: set radio to receive mode
        #TODO: merge radio_params with self.tx_defaults
        #TODO: configure radio modulation based on merged params

        #TODO: poll radio at rate until timeout or received
        #TODO: start timeout timer
        payload = None
        radio.receiver(fsk=True)
        while True: # timer not expired
            if radio.is_receive_waiting():
                payload = radio.receive() #TODO: payload, radio_measurements = radio.receive()
                now = time.time()
                p = OpenThings.decode(payload, receive_timestamp=now)
                #TODO: if crc failure, report it, but keep trying
                #if crc check passes...
                break
            #TODO: inter-try delay
        #TODO: return radio to state it was before receiver (e.g. standby) - radio needs a pop() on this too?

        if payload == None: # nothing received in timeout
            return (None, None, None) # (radio_measurements, address, payload) #TODO: might be measurements, average min max?

        #TODO: extract addresses: header_manufacturerid, header_productid header_deviceid -> (m, p, d)
        m, p, d = None, None, None
        radio_measurements = None #TODO: get from radio.receive()
        address = (m, p, d)
        return (radio_measurements, address, payload)
Example #14
0
File: OnAir.py Project: maxf/home
    def send(self, payload, radio_config=None):
        #   payload is a pydict suitable for OpenThings
        #   radio_params is an overlay on top of radio tx defaults
        p = OpenThings.encode(payload)

        # Set radio defaults, if no override
        outer_times = self.tx_defaults.outer_times
        outer_delay = self.tx_defaults.outer_delay
        inner_times = self.tx_defaults.inner_times

        # Merge any wanted radio params, if provided
        if radio_config != None:
            try:
                outer_times = radio_config.outer_times
            except AttributeError: pass
            try:
                outer_delay = radio_config.outer_delay
            except AttributeError: pass
            try:
                inner_times = radio_config.inner_times
            except AttributeError: pass

        radio.transmitter(fsk=True)
        ##print("inner times %s" % inner_times)
        radio.transmit(p, outer_times=outer_times, inner_times=inner_times, outer_delay=outer_delay)
Example #15
0
    def send(self, payload, radio_config=None):
        #   payload is a pydict suitable for OpenThings
        #   radio_params is an overlay on top of radio tx defaults
        p = OpenThings.encode(payload)

        # Set radio defaults, if no override
        outer_times = self.tx_defaults.outer_times
        outer_delay = self.tx_defaults.outer_delay
        inner_times = self.tx_defaults.inner_times

        # Merge any wanted radio params, if provided
        if radio_config != None:
            try:
                outer_times = radio_config.outer_times
            except AttributeError:
                pass
            try:
                outer_delay = radio_config.outer_delay
            except AttributeError:
                pass
            try:
                inner_times = radio_config.inner_times
            except AttributeError:
                pass

        radio.transmitter(fsk=True)
        ##print("inner times %s" % inner_times)
        radio.transmit(p,
                       outer_times=outer_times,
                       inner_times=inner_times,
                       outer_delay=outer_delay)
Example #16
0
 def turn_off(self):
     #TODO: header construction should be in MiHomeDevice as it is shared?
     payload = OpenThings.Message(SWITCH)
     payload.set(header_productid=self.product_id,
                 header_sensorid=self.device_id,
                 recs_SWITCH_STATE_value=False)
     self.send_message(payload)
Example #17
0
 def set_setpoint_temperature(self, temperature):
     self.readings.setpoint_temperature = temperature;
     payload = OpenThings.Message(MIHO013_SET_TEMPERATURE).copyof()
     if temperature<0:
         temperature=0
     if temperature>30:
         temperature=30
     payload.set(recs_TEMPERATURE_value=int(temperature*256))
     self.queue_message(payload)
Example #18
0
    def test_rx_seq(self):
        """Test that the rx sequence increments on each received message"""
        fan = Devices.DeviceFactory.get_device_from_name("AdaptorPlus",
                                                         device_id=0x68b)

        msg = OpenThings.Message(Devices.MIHO005_REPORT)
        print(fan.get_receive_count())

        fan.incoming_message(msg)
        print(fan.get_receive_count())
Example #19
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
     }
     return self.send_message(msg)  # tx_silence remaining
Example #20
0
    def join_ack(self):
        """Send a join-ack to the real device"""
        print "send join ack"
        #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)
        payload.set(header_productid=self.product_id,
                    header_sensorid=self.device_id)
        self.send_message(payload)
Example #21
0
    def receive(self,
                radio_config=None
                ):  # -> (radio_measurements, address or None, payload or None)
        #   radio_params is an overlay on top of radio rx defaults (e.g. poll rate, timeout, min payload, max payload)
        #   radio_measurements might include rssi reading, short payload report, etc
        pass  # TODO
        #TODO: set radio to receive mode
        #TODO: merge radio_params with self.tx_defaults
        #TODO: configure radio modulation based on merged params

        #TODO: poll radio at rate until timeout or received
        #TODO: start timeout timer
        payload = None
        radio.receiver(fsk=True)
        while True:  # timer not expired
            if radio.is_receive_waiting():
                payload = radio.receive(
                )  #TODO: payload, radio_measurements = radio.receive()
                now = time.time()
                p = OpenThings.decode(payload, receive_timestamp=now)
                #TODO: if crc failure, report it, but keep trying
                #if crc check passes...
                break
            #TODO: inter-try delay
        #TODO: return radio to state it was before receiver (e.g. standby) - radio needs a pop() on this too?

        if payload == None:  # nothing received in timeout
            return (
                None, None, None
            )  # (radio_measurements, address, payload) #TODO: might be measurements, average min max?

        #TODO: extract addresses: header_manufacturerid, header_productid header_deviceid -> (m, p, d)
        m, p, d = None, None, None
        radio_measurements = None  #TODO: get from radio.receive()
        address = (m, p, d)
        return (radio_measurements, address, payload)
Example #22
0
 def set_identify(self):
     self.queue_message(OpenThings.Message(MIHO013_IDENTIFY).copyof())
Example #23
0
def init():
    """Start the Energenie system running"""
    radio.DEBUG = True
    radio.init()
    OpenThings.init(Devices.CRYPT_PID)
Example #24
0
 def set_valve_position(self, position):
     payload = OpenThings.Message(MIHO013_SET_VALVE_POSITION).copyof()
     payload.set(recs_VALVE_POSITION_value=position)
     self.queue_message(payload)
Example #25
0
def init():
    """Start the Energenie system running"""
    radio.DEBUG = True
    radio.init()
    OpenThings.init(Devices.CRYPT_PID)
        def no(a,b): return False
        def yes(a,b): return True

        d = JoinConfirmedDiscovery(self.registry, self.fsk_router, no) # Discovery ASK JOIN(NO)

        # Poke synthetic unknown JOIN into the router and let it route to unknown handler
        msg = Devices.MIHO005.get_join_req(UNKNOWN_SENSOR_ID)
        self.fsk_router.incoming_message(
            (Devices.MFRID_ENERGENIE, Devices.PRODUCTID_MIHO005, UNKNOWN_SENSOR_ID), msg)

        # expect reject
        self.registry.list()
        self.fsk_router.list()

        d = JoinConfirmedDiscovery(self.registry, self.fsk_router, yes) # Discovery ASK JOIN(YES)

        self.fsk_router.incoming_message(
            (Devices.MFRID_ENERGENIE, Devices.PRODUCTID_MIHO005, UNKNOWN_SENSOR_ID), msg)

        # expect auto accept and join_ack logic to fire
        self.registry.list()
        self.fsk_router.list()


if __name__ == "__main__":
    import OpenThings
    OpenThings.init(Devices.CRYPT_PID)

    unittest.main()

# END