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
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()
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
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))
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()
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)
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)
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
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)
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)
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)
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)
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)
# 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
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
def set_identify(self): self.queue_message( OpenThings.Message(MIHO013_IDENTIFY, header=self.__class__.header()).copyof())
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:
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
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: