diff --git a/doc/branch_ook_radio_config.txt b/doc/branch_ook_radio_config.txt index 60470c5..3b9a8af 100644 --- a/doc/branch_ook_radio_config.txt +++ b/doc/branch_ook_radio_config.txt @@ -11,10 +11,10 @@ STEPS REQUIRED -1. Devices.py/LegacyDevice/send_message() +DONE 1. Devices.py/LegacyDevice/send_message() needs to read the radio config parameters from it's most concrete instance -2. Use these to send to the air_interface +DONE 2. Use these to send to the air_interface (which is actually ook_interface, which is a OnAir.TwoBitAirInterface instance). diff --git a/src/energenie/Devices.py b/src/energenie/Devices.py index 3058073..69a59e1 100644 --- a/src/energenie/Devices.py +++ b/src/energenie/Devices.py @@ -390,10 +390,10 @@ device_id = (LegacyDevice.DEFAULT_HOUSE_ADDRESS, device_id[1]) EnergenieDevice.__init__(self, device_id, ook_interface) - #TODO: These might now just be implied by the ook_interface adaptor - self.radio_config.frequency = 433.92 - self.radio_config.modulation = "OOK" - self.radio_config.codec = "4bit" + #TODO: These are now just be implied by the ook_interface adaptor + ##self.radio_config.frequency = 433.92 + ##self.radio_config.modulation = "OOK" + ##self.radio_config.codec = "4bit" def __repr__(self): return "LegacyDevice(%s)" % str(self.device_id) @@ -407,18 +407,8 @@ def send_message(self, payload): - #TODO: interface with air_interface - # Encode the payload two bits per byte as per OOK spec - #TODO: should we just pass a payload (as a pydict or tuple) to the air_interface adaptor - #and let it encode it, to be consistent with the FSK MiHome devices? - #payload could be a 3-tuple of (house_address, device_address, state) - ##bytes = TwoBit.build_switch_msg(payload, house_address=self.device_id[0], device_address=self.device_id[1]) - if self.air_interface != None: - #TODO: might want to send the config, either as a send parameter, - #or by calling air_interface.configure() first? - #i.e. radio.modulation(MODULATION_OOK) - self.air_interface.send(payload) #TODO: or (ha, da, s) + self.air_interface.send(payload, radio_config=self.radio_config) else: d = self.device_id print("send_message(mock[%s]):%s" % (str(d), payload)) @@ -430,9 +420,10 @@ if air_interface == None: air_interface = fsk_interface EnergenieDevice.__init__(self, device_id, air_interface) - self.radio_config.frequency = 433.92 - self.radio_config.modulation = "FSK" - self.radio_config.codec = "OpenThings" + #TODO: These are now implied by the air_interface adaptor + ##self.radio_config.frequency = 433.92 + ##self.radio_config.modulation = "FSK" + ##self.radio_config.codec = "OpenThings" self.manufacturer_id = MFRID_ENERGENIE self.product_id = None @@ -503,7 +494,7 @@ """A green-button switch""" def __init__(self, device_id, air_interface=None): LegacyDevice.__init__(self, device_id, air_interface) - self.radio_config.tx_repeats = 8 + self.radio_config.inner_times = 8 self.capabilities.switch = True self.capabilities.receive = True @@ -546,7 +537,7 @@ """Base for all MiHomeLight variants. Receive only OOK device""" def __init__(self, device_id, air_interface=None): LegacyDevice.__init__(self, device_id, air_interface) - self.radio_config.tx_repeats = 75 + self.radio_config.inner_times = 75 self.capabilities.switch = True self.capabilities.receive = True @@ -562,8 +553,6 @@ "device_index": self.device_id[1], "on": True } - #TODO: Need to pass forward the new radio config OUTER_TIMES=1 OUTER_DELAY=1 INNER_TIMES=75 - #using self.radio_config.tx_repeats self.send_message(payload) def turn_off(self): @@ -575,8 +564,6 @@ "device_index": self.device_id[1], "on": False } - #TODO: Need to pass forward the new radio config OUTER_TIMES=1 OUTER_DELAY=1 INNER_TIMES=75 - #using self.radio_config.tx_repeats self.send_message(payload) def set_switch(self, state): @@ -630,7 +617,7 @@ reactive_power = None real_power = None self.readings = Readings() - self.radio_config.tx_repeats = 4 + self.radio_config.inner_times = 4 self.capabilities.send = True self.capabilities.receive = True self.capabilities.switch = True @@ -783,7 +770,7 @@ setpoint_temperature = None valve_position = None self.readings = Readings() - self.radio_config.tx_repeats = 10 + self.radio_config.inner_times = 10 self.capabilities.send = True self.capabilities.receive = True @@ -924,29 +911,43 @@ # i.e. this might be the EnergenieDeviceFactory, there might be others # for other product ranges like wirefree doorbells + class DeviceFactory(): """A place to come to, to get instances of device classes""" # If you know the name of the device, use this table device_from_name = { # official name friendly name - "ENER002": ENER002, "GreenButton": ENER002, - "MIHO005": MIHO005, "AdaptorPlus": MIHO005, - "MIHO006": MIHO006, "HomeMonitor": MIHO006, - "MIHO013": MIHO013, "eTRV": MIHO013, - "MIHO032": MIHO032, "MotionSensor": MIHO032, - "MIHO033": MIHO033, "OpenSensor": MIHO033 + "ENER002": ENER002, "GreenButton": ENER002, + + ##"MIHO002": MIHO002, "Controller": MIHO002, # OOK + ##"MIHO004": MIHO004, "Monitor"" MIHO004, #TODO + "MIHO005": MIHO005, "AdaptorPlus": MIHO005, + "MIHO006": MIHO006, "HomeMonitor": MIHO006, + "MIHO008": MIHO008, "MiHomeLightWhite": MIHO008, # OOK + "MIHO013": MIHO013, "eTRV": MIHO013, + "MIHO024": MIHO024, "MiHomeLightBlack": MIHO024, # OOK + "MIHO025": MIHO025, "MiHomeLightChrome": MIHO025, # OOK + "MIHO026": MIHO026, "MiHomeLightSteel": MIHO026, # OOK + "MIHO032": MIHO032, "MotionSensor": MIHO032, + "MIHO033": MIHO033, "OpenSensor": MIHO033, } #TODO: These are MiHome devices only, but might add in mfrid prefix too # If you know the mfrid, productid of the device, use this table device_from_id = { + #MIHO002 control only switch is an OOK + #MIHO008 is an OOK PRODUCTID_MIHO004: MIHO004, PRODUCTID_MIHO005: MIHO005, PRODUCTID_MIHO006: MIHO006, PRODUCTID_MIHO013: MIHO013, + #MIHO024 is an OOK + #MIHO025 is an OOK + #MIHO026 is an OOK PRODUCTID_MIHO032: MIHO032, PRODUCTID_MIHO033: MIHO033 - #ENER product range does not have deviceid, as it does not transmit + ##PRODUCTID_MIHO004 : MIHO004 #TODO + #ENER*** product range does not have deviceid, as it does not transmit } default_air_interface = None diff --git a/src/energenie/OnAir.py b/src/energenie/OnAir.py index 3b4b9a1..13f3868 100644 --- a/src/energenie/OnAir.py +++ b/src/energenie/OnAir.py @@ -13,7 +13,7 @@ # NOTE: This also might include intelligent power level selection based # on RSSI reports from different devices. -##from lifecycle import * +from lifecycle import * import time try: @@ -37,10 +37,10 @@ modulation = radio.RADIO_MODULATION_FSK class TxDefaults(RadioDefaults): - power_level = 0 - inner_repeats = 4 + ##power_level = 0 + inner_times = 4 outer_delay = 0 - outer_repeats = 0 + outer_times = 0 self.tx_defaults = TxDefaults() class RxDefaults(RadioDefaults): @@ -48,22 +48,22 @@ timeout = 1000 #ms self.rx_defaults = RxDefaults() - ##@log_method - def send(self, payload, radio_params=None): + @log_method + 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 - pass #TODO + ##print("SEND payload %s config %s" % (payload, radio_config)) p = OpenThings.encode(payload) - #TODO: merge radio_params with self.tx_defaults - #TODO: configure radio modulation based on merged params + #TODO: Override self.tx_defaults with any settings in radio_config, if provided + outer_times = 1 + outer_delay = 0 + inner_times = 4 radio.transmitter(fsk=True) - #TODO: configure other radio parameters - #TODO: transmit payload - radio.transmit(p, outer_times=1, inner_times=4, outer_delay=0) + radio.transmit(p, outer_times=outer_times, inner_times=inner_times, outer_delay=outer_delay) # radio auto-returns to previous state after transmit completes ##@log_method - def receive(self, radio_params): # -> (radio_measurements, address or None, payload or None) + 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 @@ -106,9 +106,9 @@ class TxDefaults(RadioDefaults): power_level = 0 - inner_repeats = 8 + inner_times = 8 outer_delay = 0 - outer_repeats = 0 + outer_times = 0 self.tx_defaults = TxDefaults() class RxDefaults(RadioDefaults): @@ -116,10 +116,11 @@ timeout = 1000 #ms self.rx_defaults = RxDefaults() - ##@log_method - def send(self, payload, radio_params=None): + @log_method + def send(self, payload, radio_config=None): # payload is just a list of bytes, or a byte buffer - # radio_params is an overlay on top of radio tx defaults + # radio_config is an overlay on top of radio tx defaults + print("SEND payload %s config %s inner_times %s" % (payload, str(radio_config), radio_config.inner_times)) house_address = payload["house_address"] device_index = payload["device_index"] @@ -128,14 +129,15 @@ radio.modulation(ook=True) #TODO: merge radio_params with self.tx_defaults - #TODO: configure radio modulation based on merged params - #TODO: transmit payload + outer_times = 1 + outer_delay = 0 + inner_times = 8 - radio.transmit(bytes, outer_times=1, inner_times=8, outer_delay=0) #TODO: radio params + radio.transmit(bytes, outer_times=outer_times, inner_times=inner_times, outer_delay=outer_delay) # radio auto-pops to state before transmit ##@log_method - def receive(self, radio_params): # -> (radio_measurements, address or None, payload or None) + 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 #TODO: merge radio_params with self.tx_defaults diff --git a/src/registry.kvs b/src/registry.kvs index 678732d..d8473ec 100644 --- a/src/registry.kvs +++ b/src/registry.kvs @@ -14,3 +14,7 @@ type=MIHO032 device_id=4042 +ADD white_light +type=MIHO008 +device_id=[0x6C6C6, 2] +