def decode_0x20(message, subtype, seqnbr, id1, id2): """ 0x20 Security1 Credit: Dimitri Clatot """ result = list() try: display_subtype = RFX.rfx_subtype_20[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 + ByteToHex(message[6]) result.append({'key': 'Id', 'value': sensor_id}) try: status = RFX.rfx_subtype_20_status[ByteToHex(message[7])] except KeyError: status = '0x' + ByteToHex(message[7]) result.append({'key': 'Status', 'value': status}) battery = rfxdecode.decode_battery(message[8]) result.append({'key': 'Battery', 'value': battery}) signal = rfxdecode.decode_signal(message[8]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('battery', battery), ('signal_level', signal), ('id', sensor_id), ('status', status)] return result, output_extra
def decode_0x30(message, subtype, seqnbr, id1): """ 0x30 Remote control and IR """ result = list() try: display_subtype = RFX.rfx_subtype_30[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) command_hex = ByteToHex(message[5]) cmndtype_hex = ByteToHex(message[7]) command = None cmndtype = None toggle = None if subtype == '00': try: command = RFX.rfx_subtype_30_atiremotewonder[command_hex] except KeyError: command = '0x' + command_hex elif subtype == '02': command = RFX.rfx_subtype_30_medion[command_hex] elif subtype == '04': if cmndtype_hex == '00': cmndtype = "PC" elif cmndtype_hex == '01': cmndtype = "AUX1" elif cmndtype_hex == '02': cmndtype = "AUX2" elif cmndtype_hex == '03': cmndtype = "AUX3" elif cmndtype_hex == '04': cmndtype = "AUX4" else: cmndtype = "Unknown" result.append({'key': 'Command type', 'value': cmndtype}) toggle = ByteToHex(message[6]) result.append({'key': 'Toggle', 'value': toggle}) result.append({'key': 'Command', 'value': command}) result.append({'key': 'Id', 'value': id1}) signal = rfxdecode.decode_signal(message[6]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [ ('signal_level', signal), ('id', id1), ('toggle', toggle), ('cmndtype', cmndtype), ('command', command)] return result, output_extra
def decode_0x40(message, subtype, seqnbr, id1, id2): """ 0x40 - Thermostat1 Credit: Jean-François Pucheu """ result = list() try: display_subtype = RFX.rfx_subtype_40[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) temperature = int(ByteToHex(message[6]), 16) result.append({'key': 'Temperature', 'value': temperature, 'unit': 'C'}) temperature_set = int(ByteToHex(message[7]), 16) result.append({ 'key': 'Temperature set', 'value': temperature_set, 'unit': 'C' }) status_hex = str(testBit(int(ByteToHex(message[8]), 16), 0) + \ testBit(int(ByteToHex(message[8]), 16), 1)) try: status = RFX.rfx_subtype_40_status[status_hex] except KeyError: status = '0x' + status_hex result.append({'key': 'Status', 'value': status}) if testBit(int(ByteToHex(message[8]), 16), 7) == 128: mode = RFX.rfx_subtype_40_mode['1'] else: mode = RFX.rfx_subtype_40_mode['0'] result.append({'key': 'Mode', 'value': mode}) signal = rfxdecode.decode_signal(message[9]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('signal_level', signal), ('mode', mode), ('id', sensor_id), ('status', status), ('temperature_set', temperature_set), ('temperature', temperature)] return result, output_extra
def decode_0x70(message, subtype, seqnbr, id1): """ 0x70 RFXsensor """ result = list() try: display_subtype = RFX.rfx_subtype_70[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) result.append({'key': 'Id', 'value': id1}) temperature = 0 if subtype == '00': temperature = float(rfxdecode.decode_temperature(message[5], message[6])) temperature = temperature * 0.1 result.append({'key': 'Temperature', 'value': temperature, 'unit': 'C'}) voltage = 0 if subtype == '01' or subtype == '02': voltage_hi = int(ByteToHex(message[5]), 16) * 256 voltage_lo = int(ByteToHex(message[6]), 16) voltage = voltage_hi + voltage_lo result.append({'key': 'Voltage', 'value': voltage, 'unit': 'mV'}) sensor_message = '0x' + message[6] if subtype == '03': try: sensor_message = RFX.rfx_subtype_70_msg03[message[6]] except KeyError: sensor_message = '0x' + message[6] result.append({'key': 'Message', 'value': sensor_message}) signal = rfxdecode.decode_signal(message[7]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [ ('signal_level', signal), ('id', id1), ('message', message), ('temperature', temperature), ('voltage', voltage)] return result, output_extra
def decode_power(message_1, message_2, message_3): """ Decode power bytes. """ power_1 = ByteToHex(message_1) power_2 = ByteToHex(message_2) power_3 = ByteToHex(message_3) power_1 = int(power_1, 16) power_1 = power_1 << 16 power_2 = int(power_2, 16) << 8 power_3 = int(power_3, 16) power = (power_1 + power_2 + power_3) power_str = str(power) return power_str
def decode_0x55(message, subtype, seqnbr, id1, id2): """ 0x55 Rain sensors """ result = list() try: display_subtype = RFX.rfx_subtype_55[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) rainrate_high = ByteToHex(message[6]) rainrate_low = ByteToHex(message[7]) rainrate = 'not implemented' if subtype == '01': rainrate = int(rainrate_high, 16) * 0x100 + int(rainrate_low, 16) elif subtype == '02': rainrate = float( int(rainrate_high, 16) * 0x100 + int(rainrate_low, 16)) / 100 result.append({'key': 'Rainrate', 'value': rainrate, 'unit': 'mm/h'}) raintotal = 'not implemented' if subtype != '06': raintotal = float( \ (int(ByteToHex(message[8]), 16) * 0x1000) + \ (int(ByteToHex(message[9]), 16) * 0x100) + \ int(ByteToHex(message[10]), 16)) / 10 result.append({'key': 'Rain', 'value': raintotal, 'unit': 'mm'}) signal = rfxdecode.decode_signal(message[11]) result.append({'key': 'Signal level', 'value': signal}) battery = rfxdecode.decode_battery(message[11]) result.append({'key': 'Battery', 'value': battery}) output_extra = [('rainrate', rainrate), ('raintotal', raintotal), ('battery', battery), ('id', sensor_id), ('signal_level', signal)] return result, output_extra
def decode_0x03(message, subtype, seqnbr): """ 0x03 - Undecoded Message """ result = list() result.append({'key': 'Subtype', 'value': RFX.rfx_subtype_03[subtype]}) result.append({'key': 'Sequence number', 'value': seqnbr}) indata = ByteToHex(message) # remove all spaces for i in whitespace: indata = indata.replace(i, "") indata = indata[4:] result.append({'key': 'Message', 'value': indata}) return result, [('message', indata)]
def rfx_setmode(protocol, state): """ Create setmode message """ LOGGER.debug("Send status message") res = None try: res = rfx_sendmsg(RFXCMD.status) LOGGER.debug("Result: %s", str(res)) except Exception as err: LOGGER.error(err) raise LOGGER.debug("Result: %s", str(ByteToHex(res))) if res: LOGGER.debug("Decode result") try: bstr = rfx_decode(res) LOGGER.debug("Result: %s", str(bstr)) except Exception as err: LOGGER.error(err) raise LOGGER.debug("Binary: %s" % str(bstr)) # Change bstr[protocol] = str(state) LOGGER.debug("Binary: " % str(bstr)) # Complete message msg3 = bstr[0] + bstr[1] + bstr[2] + bstr[3] + bstr[4] + bstr[5] + bstr[6] + bstr[7] msg3_int = int(msg3, 2) msg3_hex = hex(msg3_int)[2:].zfill(2) msg4 = bstr[8] + bstr[9] + bstr[10] + bstr[11] + bstr[12] + bstr[13] + bstr[14] + bstr[15] msg4_int = int(msg4, 2) msg4_hex = hex(msg4_int)[2:].zfill(2) msg5 = bstr[16] + bstr[17] + bstr[18] + bstr[19] + bstr[20] + bstr[21] + bstr[22] + bstr[23] msg5_int = int(msg5, 2) msg5_hex = hex(msg5_int)[2:].zfill(2) LOGGER.debug("msg3: %s / %s" % (str(msg3), msg3_hex)) LOGGER.debug("msg4: %s / %s" % (str(msg4), msg4_hex)) LOGGER.debug("msg5: %s / %s" % (str(msg5), msg5_hex)) # Send command command = "0D000000035300%s%s%s00000000" % (msg3_hex, msg4_hex, msg5_hex) LOGGER.debug("Command: %s" % command.upper()) try: rfx_decodestatus(rfx_sendmsg(command.upper())) except Exception as err: LOGGER.error(err) raise return True LOGGER.error("Invalid result received") return False
def decode_0x42(message, subtype, seqnbr, id1, id2): """ 0x40 - Thermostat1 Credit: Jean-François Pucheu """ result = list() try: display_subtype = RFX.rfx_subtype_42[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) command_hex = ByteToHex(message[7]) try: if subtype == '00': unitcode = ByteToHex(message[4]) command = RFX.rfx_subtype_42_cmd00[command_hex] elif subtype == '01': unitcode = ByteToHex(message[4]) + ByteToHex( message[5]) + ByteToHex(message[6]) command = RFX.rfx_subtype_42_cmd01[command_hex] else: unitcode = '00' command = '0x' + command_hex except KeyError: command = '0x' + command_hex result.append({'key': 'Unitcode', 'value': unitcode}) result.append({'key': 'Command', 'value': command}) signal = rfxdecode.decode_signal(message[8]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('signal_level', signal), ('id', sensor_id), ('unitcode', unitcode), ('command', command)] return result, output_extra
def decode_0x5c(message, subtype, seqnbr, id1, id2): """ 0x5C Power Sensors """ result = list() try: display_subtype = RFX.rfx_subtype_5C[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) voltage = int(ByteToHex(message[6]), 16) result.append({'key': 'Voltage', 'value': voltage, 'unit': 'V'}) current = (int(ByteToHex(message[7]), 16) * 0x100 + int(ByteToHex(message[8]), 16)) * 0.01 result.append({'key': 'Current', 'value': current, 'unit': 'A'}) power = (int(ByteToHex(message[9]), 16) * 0x100 + int(ByteToHex(message[10]), 16)) * 0.1 result.append({'key': 'Instant power', 'value': power, 'unit': 'W'}) energy = (int(ByteToHex(message[11]), 16) * 0x100 + int(ByteToHex(message[12]), 16)) * 0.01 result.append({'key': 'Total usage', 'value': energy, 'unit': 'kWh'}) powerfactor = (int(ByteToHex(message[13]), 16)) * 0.01 result.append({'key': 'Power factor', 'value': powerfactor}) freq = int(ByteToHex(message[14]), 16) result.append({'key': 'Frequency', 'value': freq, 'unit': 'Hz'}) signal = rfxdecode.decode_signal(message[15]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('id', sensor_id), ('voltage', voltage), ('current', current), ('instant_power', power), ('total_usage', energy), ('powerfactor', powerfactor), ('freq', freq), ('signal_level', signal)] return result, output_extra
def decode_temperature(message_high, message_low): """ Decode temperature bytes. """ temp_high = ByteToHex(message_high) temp_low = ByteToHex(message_low) polarity = testBit(int(temp_high, 16), 7) if polarity == 128: polarity_sign = "-" else: polarity_sign = "" temp_high = clearBit(int(temp_high, 16), 7) temp_high = temp_high << 8 temperature = (temp_high + int(temp_low, 16)) * 0.1 temperature_str = polarity_sign + str(temperature) return temperature_str
def decode_0x52(message, subtype, seqnbr, id1, id2): """ 0x52 Temperature and humidity sensors """ result = list() try: display_subtype = RFX.rfx_subtype_52[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) temperature = rfxdecode.decode_temperature(message[6], message[7]) result.append({'key': 'Temperature', 'value': temperature, 'unit': 'C'}) humidity = int(ByteToHex(message[8]), 16) result.append({'key': 'Humidity', 'value': humidity, 'unit': '%'}) try: humidity_status = RFX.rfx_subtype_52_humstatus[ByteToHex(message[9])] except KeyError: humidity_status = '0x' + ByteToHex(message[9]) result.append({'key': 'Humidity Status', 'value': humidity_status}) signal = rfxdecode.decode_signal(message[10]) result.append({'key': 'Signal level', 'value': signal}) battery = rfxdecode.decode_battery(message[10]) result.append({'key': 'Battery', 'value': battery}) output_extra = [('id', sensor_id), ('humidity_status', humidity_status), ('temperature', temperature), ('humidity', humidity), ('battery', battery), ('signal_level', signal)] return result, output_extra
def decode_0x56(message, subtype, seqnbr, id1, id2): """ 0x56 Wind sensors """ result = list() try: display_subtype = RFX.rfx_subtype_56[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) direction = ((int(ByteToHex(message[6]), 16) * 256) + \ int(ByteToHex(message[7]), 16)) result.append({ 'key': 'Wind direction', 'value': direction, 'unit': 'degrees' }) av_speed = 'not implemented' if subtype != '05': av_speed = ((int(ByteToHex(message[8]), 16) * 256) + \ int(ByteToHex(message[9]), 16)) * 0.1 result.append({ 'key': 'Wind speed (average)', 'value': av_speed, 'unit': 'm/s' }) gust = ((int(ByteToHex(message[10]), 16) * 256) + \ int(ByteToHex(message[11]), 16)) * 0.1 result.append({'key': 'Wind gust', 'value': gust, 'unit': 'm/s'}) temperature = 'not implemented' windchill = 'not implemented' if subtype == "04": temperature = rfxdecode.decode_temperature(message[12], message[13]) windchill = rfxdecode.decode_temperature(message[14], message[15]) result.append({'key': 'Temperature', 'value': temperature, 'unit': 'C'}) result.append({'key': 'Wind chill', 'value': windchill, 'unit': 'C'}) signal = rfxdecode.decode_signal(message[16]) result.append({'key': 'Signal level', 'value': signal}) battery = rfxdecode.decode_battery(message[16]) result.append({'key': 'Battery', 'value': battery}) output_extra = [('battery', battery), ('signal_level', signal), ('id', sensor_id), ('temperature', temperature), ('wind_average_speed', av_speed), ('wind_gust', gust), ('wind_direction', direction), ('wind_chill', windchill)] return result, output_extra
def test_message(message): """ Test, filter and verify that the incoming message is valid Return true if valid, False if not """ # Remove any whitespaces and linebreaks message = message.replace(' ', '') message = message.replace("\r", "") message = message.replace("\n", "") # Remove all invalid characters message = stripped(message) # Test the string if it is hex format try: int(message, 16) except Exception: return False # Check that length is even if len(message) % 2: return False # Check that first byte is not 00 if ByteToHex(codecs_decode(message, "hex")[0]) == "00": return False # Length more than one byte if not len(codecs_decode(message, "hex")) > 1: return False # Check if string is the length that it reports to be cmd_len = int(ByteToHex(codecs_decode(message, "hex")[0]), 16) if not len(codecs_decode(message, "hex")) == (cmd_len + 1): return False return True
def decode_0x11(message, subtype, seqnbr): """ 0x11 Lighting2 """ result = list() try: display_subtype = RFX.rfx_subtype_11[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = ByteToHex(message[4]) + ByteToHex(message[5]) + \ ByteToHex(message[6]) + ByteToHex(message[7]) result.append({'key': 'Id', 'value': sensor_id}) unitcode = int(ByteToHex(message[8]), 16) result.append({'key': 'Unitcode', 'value': unitcode}) try: command = RFX.rfx_subtype_11_cmnd[ByteToHex(message[9])] except KeyError: command = '0x' + ByteToHex(message[9]) result.append({'key': 'Command', 'value': command}) try: dimlevel = RFX.rfx_subtype_11_dimlevel[ByteToHex(message[10])] except KeyError: dimlevel = '0x' + ByteToHex(message[10]) result.append({'key': 'Dim level', 'value': dimlevel, 'unit': '%'}) signal = rfxdecode.decode_signal(message[11]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('signal_level', signal), ('id', sensor_id), ('command', command), ('unitcode', unitcode), ('dim_level', dimlevel)] return result, output_extra
def decode_0x1a(message, subtype, seqnbr, id1, id2): """ 0x11 RTS """ result = list() try: display_subtype = RFX.rfx_subtype_1A[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 + ByteToHex(message[6]) result.append({'key': 'Id1-3', 'value': sensor_id}) if subtype == '00' and ByteToHex(message[6]) == '00': unitcode = 'All' else: unitcode = '0x' + ByteToHex(message[6]) result.append({'key': 'Unitcode', 'value': unitcode}) try: command = RFX.rfx_subtype_1A_cmnd[ByteToHex(message[7])] except KeyError: command = '0x' + ByteToHex(message[7]) result.append({'key': 'Command', 'value': command}) signal = rfxdecode.decode_signal(message[8]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('signal_level', signal), ('id', sensor_id), ('unicode', unitcode), ('command', command)] return result, output_extra
def decode_0x10(message, subtype, seqnbr): """ 0x10 Lighting1 """ result = list() try: display_subtype = RFX.rfx_subtype_10[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = ByteToHex(message[4]) + ByteToHex(message[5]) + \ ByteToHex(message[6]) + ByteToHex(message[7]) result.append({'key': 'Id', 'value': sensor_id}) try: housecode = RFX.rfx_subtype_10_housecode[ByteToHex(message[4])] except KeyError: housecode = '0x' + ByteToHex(message[4]) result.append({'key': 'Housecode', 'value': housecode}) unitcode = int(ByteToHex(message[5]), 16) result.append({'key': 'Unitcode', 'value': unitcode}) try: command = RFX.rfx_subtype_10_cmnd[ByteToHex(message[6])] except KeyError: command = '0x' + ByteToHex(message[6]) result.append({'key': 'Command', 'value': command}) signal = rfxdecode.decode_signal(message[7]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('signal_level', signal), ('housecode', housecode), ('command', command), ('unitcode', unitcode)] return result, output_extra
def decode_0x16(message, subtype, seqnbr, id1, id2): """ 0x16 Chime """ result = list() try: display_subtype = RFX.rfx_subtype_16[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) if subtype == '00': try: sound = RFX.rfx_subtype_16_sound[ByteToHex(message[6])] except KeyError: sound = '0x' + ByteToHex(message[6]) elif subtype == '02' or subtype == '03' or subtype == '04': sound = None else: sound = '0x' + ByteToHex(message[6]) result.append({'key': 'Sound', 'value': sound}) signal = rfxdecode.decode_signal(message[7]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('id', sensor_id), ('sound', sound), ('signal_level', signal)] return result, output_extra
def decode_0x15(message, subtype, seqnbr, id1, id2): """ 0x15 Lighting6 Credit: Dimitri Clatot """ result = list() try: display_subtype = RFX.rfx_subtype_15[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) try: groupcode = RFX.rfx_subtype_15_groupcode[ByteToHex(message[6])] except KeyError: groupcode = '0x' + ByteToHex(message[6]) result.append({'key': 'Groupcode', 'value': groupcode}) unitcode = int(ByteToHex(message[7]), 16) result.append({'key': 'Unitcode', 'value': unitcode}) try: command = RFX.rfx_subtype_15_cmnd[ByteToHex(message[8])] except KeyError: command = '0x' + ByteToHex(message[8]) result.append({'key': 'Command', 'value': command}) command_seqnbr = ByteToHex(message[9]) result.append({'key': 'Command seqnbr', 'value': command_seqnbr}) seqnbr2 = ByteToHex(message[10]) result.append({'key': 'Seqnbr2', 'value': seqnbr2}) signal = rfxdecode.decode_signal(message[11]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('id', sensor_id), ('signal_level', signal), ('groupcode', groupcode), ('command', command), ('unitcode', unitcode), ('seqnbr', seqnbr2), ('command_seqnbr', command_seqnbr)] return result, output_extra
def decode_0x58(message, subtype, seqnbr, id1, id2): """ 0x58 Date/Time sensor """ result = list() try: display_subtype = RFX.rfx_subtype_58[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) date_yy = int(ByteToHex(message[6]), 16) date_mm = int(ByteToHex(message[7]), 16) date_dd = int(ByteToHex(message[8]), 16) date_string = "20%s-%s-%s" % (str(date_yy).zfill(2), str(date_mm).zfill(2), str(date_dd).zfill(2)) result.append({'key': 'Date (yy-mm-dd)', 'value': date_string}) date_dow = int(ByteToHex(message[9]), 16) result.append({'key': 'Day of week (1-7)', 'value': date_dow}) time_hr = int(ByteToHex(message[10]), 16) time_min = int(ByteToHex(message[11]), 16) time_sec = int(ByteToHex(message[12]), 16) time_string = "%s:%s:%s" % (str(time_hr), str(time_min), str(time_sec)) result.append({'key': 'Time', 'value': time_string}) signal = rfxdecode.decode_signal(message[13]) result.append({'key': 'Signal level', 'value': signal}) battery = rfxdecode.decode_battery(message[13]) result.append({'key': 'Battery', 'value': battery}) output_extra = [('id', sensor_id), ('time', time_string), ('date', date_string), ('day_of_week', date_dow), ('battery', battery), ('signal_level', signal)] return result, output_extra
def decode_0x59(message, subtype, seqnbr, id1, id2): """ 0x59 Current Sensor """ result = list() try: display_subtype = RFX.rfx_subtype_59[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) count = int(ByteToHex(message[6]), 16) result.append({'key': 'Counter', 'value': count}) channel1 = (int(ByteToHex(message[7]), 16) * 0x100 + int(ByteToHex(message[8]), 16)) * 0.1 result.append({'key': 'Channel #1', 'value': channel1, 'unit': 'A'}) channel2 = (int(ByteToHex(message[9]), 16) * 0x100 + int(ByteToHex(message[10]), 16)) * 0.1 result.append({'key': 'Channel #2', 'value': channel2, 'unit': 'A'}) channel3 = (int(ByteToHex(message[11]), 16) * 0x100 + int(ByteToHex(message[12]), 16)) * 0.1 result.append({'key': 'Channel #3', 'value': channel3, 'unit': 'A'}) signal = rfxdecode.decode_signal(message[13]) result.append({'key': 'Signal level', 'value': signal}) battery = rfxdecode.decode_battery(message[13]) result.append({'key': 'Battery', 'value': battery}) output_extra = [('id', sensor_id), ('counter', count), ('channel1', channel1), ('channel2', channel2), ('channel3', channel3), ('battery', battery), ('signal_level', signal)] return result, output_extra
def decode_0x13(message, subtype, seqnbr): """ 0x13 Lighting4 """ result = list() try: display_subtype = RFX.rfx_subtype_13[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) code = ByteToHex(message[4]) + ByteToHex(message[5]) + ByteToHex( message[6]) result.append({'key': 'Code', 'value': code}) code1 = dec2bin(int(ByteToHex(message[4]), 16)) code2 = dec2bin(int(ByteToHex(message[5]), 16)) code3 = dec2bin(int(ByteToHex(message[6]), 16)) code_bin = code1 + " " + code2 + " " + code3 result.append({'key': 'S1-S24', 'value': code_bin}) pulse = ((int(ByteToHex(message[7]), 16) * 256) + int(ByteToHex(message[8]), 16)) result.append({'key': 'Code', 'value': pulse, 'unit': 'usec'}) signal = rfxdecode.decode_signal(message[9]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('code', code), ('s1_s24', code_bin), ('pulse', pulse), ('signal', signal)] return result, output_extra
def decode_0x57(message, subtype, seqnbr, id1, id2): """ 0x57 UV Sensor """ result = list() try: display_subtype = RFX.rfx_subtype_57[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) ultra_violet = int(ByteToHex(message[6]), 16) * 10 result.append({'key': 'Ultra Violet', 'value': ultra_violet}) temperature = 'not implemented' if subtype == '03': temperature = rfxdecode.decode_temperature(message[6], message[8]) result.append({'key': 'Temperature', 'value': temperature, 'unit': 'C'}) signal = rfxdecode.decode_signal(message[9]) result.append({'key': 'Signal level', 'value': signal}) battery = rfxdecode.decode_battery(message[9]) result.append({'key': 'Battery', 'value': battery}) output_extra = [('id', sensor_id), ('ultra_violet', ultra_violet), ('temperature', temperature), ('battery', battery), ('signal_level', signal)] return result, output_extra
def decode_signal(message): """ Decode signal byte. """ signal = int(ByteToHex(message), 16) >> 4 return signal
def decode_0x14(message, subtype, seqnbr, id1, id2): """ 0x14 Lighting5 """ result = list() try: display_subtype = RFX.rfx_subtype_14[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 + ByteToHex(message[6]) result.append({'key': 'Id', 'value': sensor_id}) command_hex = ByteToHex(message[8]) level = 0 unitcode = 'Not used' try: if subtype == '00': command = RFX.rfx_subtype_14_cmnd0[command_hex] unitcode = int(ByteToHex(message[7]), 16) level = ByteToHex(message[9]) elif subtype == '01': command = RFX.rfx_subtype_14_cmnd1[command_hex] unitcode = int(ByteToHex(message[7]), 16) elif subtype == '02': command = RFX.rfx_subtype_14_cmnd2[command_hex] unitcode = int(ByteToHex(message[7]), 16) elif subtype == '03': command = RFX.rfx_subtype_14_cmnd3[command_hex] elif subtype == '04': command = RFX.rfx_subtype_14_cmnd4[command_hex] unitcode = int(ByteToHex(message[7]), 16) elif subtype == '05': command = RFX.rfx_subtype_14_cmnd5[command_hex] elif subtype == '06': unitcode = int(ByteToHex(message[7]), 16) try: command = RFX.rfx_subtype_14_cmnd5[command_hex] except KeyError: # if the value is between x06 and x84 it is 'select color' # This should be improved, as it will not catch unknown values command = 'Select Color' elif subtype == '11': unitcode = int(ByteToHex(message[7]), 16) command = RFX.rfx_subtype_14_cmnd11[command_hex] else: command = '0x' + command_hex except KeyError: command = '0x' + command_hex result.append({'key': 'Command', 'value': command}) result.append({'key': 'Level', 'value': level}) result.append({'key': 'Unitcode', 'value': unitcode}) signal = rfxdecode.decode_signal(message[10]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('id', sensor_id), ('unitcode', unitcode), ('command', command), ('level', level), ('signal_level', signal)] return result, output_extra
def decode_0x12(message, subtype, seqnbr): """ 0x12 Lighting3 """ result = list() try: display_subtype = RFX.rfx_subtype_12[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) system = ByteToHex(message[4]) result.append({'System': 'Command', 'value': system}) if testBit(int(ByteToHex(message[5]), 16), 0) == 1: channel = 1 elif testBit(int(ByteToHex(message[5]), 16), 1) == 2: channel = 2 elif testBit(int(ByteToHex(message[5]), 16), 2) == 4: channel = 3 elif testBit(int(ByteToHex(message[5]), 16), 3) == 8: channel = 4 elif testBit(int(ByteToHex(message[5]), 16), 4) == 16: channel = 5 elif testBit(int(ByteToHex(message[5]), 16), 5) == 32: channel = 6 elif testBit(int(ByteToHex(message[5]), 16), 6) == 64: channel = 7 elif testBit(int(ByteToHex(message[5]), 16), 7) == 128: channel = 8 elif testBit(int(ByteToHex(message[6]), 16), 0) == 1: channel = 9 elif testBit(int(ByteToHex(message[6]), 16), 1) == 2: channel = 10 else: channel = 255 result.append({'key': 'Channel', 'value': channel}) try: command = RFX.rfx_subtype_12_cmnd[ByteToHex(message[7])] except KeyError: command = '0x' + ByteToHex(message[7]) result.append({'key': 'Command', 'value': command}) battery = rfxdecode.decode_battery(message[8]) result.append({'key': 'Battery', 'value': battery}) signal = rfxdecode.decode_signal(message[8]) result.append({'key': 'Signal level', 'value': signal}) output_extra = [('battery', battery), ('signal', signal), ('system', system), ('command', command), ('channel', channel)] return result, output_extra
def decode_0x54(message, subtype, seqnbr, id1, id2, config_barometric=0): """ 0x54 Temperature, humidity and barometric sensors Credit: Jean-Baptiste Bodart """ result = list() try: display_subtype = RFX.rfx_subtype_54[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) temperature = rfxdecode.decode_temperature(message[6], message[7]) result.append({'key': 'Temperature', 'value': temperature, 'unit': 'C'}) humidity = int(ByteToHex(message[8]), 16) result.append({'key': 'Humidity', 'value': humidity, 'unit': '%'}) try: humidity_status = RFX.rfx_subtype_54_humstatus[ByteToHex(message[9])] except KeyError: humidity_status = '0x' + ByteToHex(message[9]) result.append({'key': 'Humidity Status', 'value': humidity_status}) barometric_high = ByteToHex(message[10]) barometric_low = ByteToHex(message[11]) barometric_high = clearBit(int(barometric_high, 16), 7) barometric_high = barometric_high << 8 barometric = barometric_high + int(barometric_low, 16) + int(config_barometric) result.append({ 'key': 'Barometric pressure', 'value': humidity_status, 'unit': 'hPa' }) try: forecast = RFX.rfx_subtype_54_forecast[ByteToHex(message[12])] except KeyError: forecast = '0x' + ByteToHex(message[12]) result.append({'key': 'Forecast Status', 'value': forecast}) signal = rfxdecode.decode_signal(message[13]) result.append({'key': 'Signal level', 'value': signal}) battery = rfxdecode.decode_battery(message[13]) result.append({'key': 'Battery', 'value': battery}) output_extra = [('battery', battery), ('signal_level', signal), ('id', sensor_id), ('forecast_status', forecast), ('humidity_status', humidity_status), ('humidity', humidity), ('barometric_pressure', barometric), ('temperature', temperature)] return result, output_extra
def decode_0x5a(message, subtype, seqnbr, id1, id2): """ 0x5A Energy sensor Credit: Jean-Michel ROY """ result = list() try: display_subtype = RFX.rfx_subtype_5A[subtype] except KeyError: display_subtype = '0x' + subtype result.append({'key': 'Subtype', 'value': display_subtype}) result.append({'key': 'Sequence number', 'value': seqnbr}) sensor_id = id1 + id2 result.append({'key': 'Id', 'value': sensor_id}) count = int(ByteToHex(message[6]), 16) result.append({'key': 'Count', 'value': count}) instant = int(ByteToHex(message[7]), 16) * 0x1000000 + \ int(ByteToHex(message[8]), 16) * 0x10000 + \ int(ByteToHex(message[9]), 16) * 0x100 + \ int(ByteToHex(message[10]), 16) result.append({'key': 'Instant usage', 'value': instant}) usage = int(( int(ByteToHex(message[11]), 16) * 0x10000000000 + \ int(ByteToHex(message[12]), 16) * 0x100000000 + \ int(ByteToHex(message[13]), 16) * 0x1000000 + \ int(ByteToHex(message[14]), 16) * 0x10000 + \ int(ByteToHex(message[15]), 16) * 0x100 + \ int(ByteToHex(message[16]), 16)) / 223.666) result.append({'key': 'Total usage', 'value': usage}) signal = rfxdecode.decode_signal(message[17]) result.append({'key': 'Signal level', 'value': signal}) battery = rfxdecode.decode_battery(message[17]) result.append({'key': 'Battery', 'value': battery}) output_extra = [('id', sensor_id), ('instant_usage', instant), ('total_usage', usage), ('battery', battery), ('signal_level', signal)] return result, output_extra
def decode_battery(message): """ Decode battery byte. """ battery = int(ByteToHex(message), 16) & 0xf return battery
def decode_0x01(message): """ 0x01 - Interface Message """ data = { 'packetlen': ByteToHex(message[0]), 'packettype': ByteToHex(message[1]), 'subtype': ByteToHex(message[2]), 'seqnbr': ByteToHex(message[3]), 'cmnd': ByteToHex(message[4]), 'msg1': ByteToHex(message[5]), 'msg2': ByteToHex(message[6]), 'msg3': ByteToHex(message[7]), 'msg4': ByteToHex(message[8]), 'msg5': ByteToHex(message[9]), 'msg6': ByteToHex(message[10]), 'msg7': ByteToHex(message[11]), 'msg8': ByteToHex(message[12]), 'msg9': ByteToHex(message[13]) } result = list() # Subtype if data['subtype'] == '00': result.append({'key': 'Subtype', 'value': 'Interface response'}) else: result.append({ 'key': 'Subtype', 'value': 'Unknown type (' + data['packettype'] + ')' }) # Seq result.append({'key': 'Sequence number', 'value': data['seqnbr']}) # Command try: result.append({ 'key': 'Response on command', 'value': RFX.rfx_cmnd[data['cmnd']] }) except KeyError: result.append({'key': 'Response on command', 'value': 'Invalid'}) # MSG 1 try: result.append({ 'key': 'Transceiver type', 'value': RFX.rfx_subtype_01_msg1[data['msg1']] }) except KeyError: result.append({'key': 'Transceiver type', 'value': 'Invalid'}) # MSG 2 result.append({'key': 'Firmware version', 'value': int(data['msg2'], 16)}) protocols = list() # ------------------------------------------------------ # MSG 3 protocols.append({ 'key': RFX.rfx_subtype_01_msg3['128'], 'value': bool(testBit(int(data['msg3'], 16), 7) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg3['64'], 'value': bool(testBit(int(data['msg3'], 16), 6) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg3['32'], 'value': bool(testBit(int(data['msg3'], 16), 5) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg3['16'], 'value': bool(testBit(int(data['msg3'], 16), 4) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg3['8'], 'value': bool(testBit(int(data['msg3'], 16), 3) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg3['4'], 'value': bool(testBit(int(data['msg3'], 16), 2) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg3['2'], 'value': bool(testBit(int(data['msg3'], 16), 1) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg3['1'], 'value': bool(testBit(int(data['msg3'], 16), 0) == 128) }) # # ------------------------------------------------------ # # MSG 4 protocols.append({ 'key': RFX.rfx_subtype_01_msg4['128'], 'value': bool(testBit(int(data['msg4'], 16), 7) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg4['64'], 'value': bool(testBit(int(data['msg4'], 16), 6) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg4['32'], 'value': bool(testBit(int(data['msg4'], 16), 5) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg4['16'], 'value': bool(testBit(int(data['msg4'], 16), 4) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg4['8'], 'value': bool(testBit(int(data['msg4'], 16), 3) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg4['4'], 'value': bool(testBit(int(data['msg4'], 16), 2) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg4['2'], 'value': bool(testBit(int(data['msg4'], 16), 1) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg4['1'], 'value': bool(testBit(int(data['msg4'], 16), 0) == 128) }) # # ------------------------------------------------------ # # MSG 5 protocols.append({ 'key': RFX.rfx_subtype_01_msg5['128'], 'value': bool(testBit(int(data['msg5'], 16), 7) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg5['64'], 'value': bool(testBit(int(data['msg5'], 16), 6) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg5['32'], 'value': bool(testBit(int(data['msg5'], 16), 5) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg5['16'], 'value': bool(testBit(int(data['msg5'], 16), 4) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg5['8'], 'value': bool(testBit(int(data['msg5'], 16), 3) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg5['4'], 'value': bool(testBit(int(data['msg5'], 16), 2) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg5['2'], 'value': bool(testBit(int(data['msg5'], 16), 1) == 128) }) protocols.append({ 'key': RFX.rfx_subtype_01_msg5['1'], 'value': bool(testBit(int(data['msg5'], 16), 0) == 128) }) result.append({'key': 'Protocols', 'value': protocols}) return result, dict()