diff --git a/src/energenie/encoder.py b/src/energenie/encoder.py index d4afa25..366a176 100644 --- a/src/energenie/encoder.py +++ b/src/energenie/encoder.py @@ -4,6 +4,53 @@ ALL_SOCKETS = 0 +# The preamble is now stored in the payload, +# this is more predictable than using the radio sync feature +PREAMBLE = [0x80, 0x00, 0x00, 0x00] + +# This generates a 20*4 bit address i.e. 10 bytes +# The number generated is always the same +# This is the random 'Energenie address prefix' +# The switch number is encoded in the payload +# 0000 00BA gets encoded as: +# 128 64 32 16 8 4 2 1 +# 1 B B 0 1 A A 0 +#payload = [] +#for i in range(10): +# j = i + 5 +# payload.append(8 + (j&1) * 6 + 128 + (j&2) * 48) +#dumpPayloadAsHex(payload) + +#this is just a fixed address generator, from the C code +#payload = [] +#for i in range(10): +# j = i + 5 +# payload.append(8 + (j&1) * 6 + 128 + (j&2) * 48) +#dumpPayloadAsHex(payload) +# binary = 0110 1100 0110 1100 0110 +# hex = 6 C 6 C 6 + +DEFAULT_ADDR = 0x6C6C6 + +# 5 6 7 8 9 10 11 12 13 14 +# 1(01) 1(10) 1(11) 0(00) 0(01) 0(10) 0(11) 1(00) 1(01) 1(10) +DEFAULT_ADDR_ENC = [0x8e, 0xe8, 0xee, 0x88, 0x8e, 0xe8, 0xee, 0x88, 0x8e, 0xe8] + +# D0=high, D1=high, D2-high, D3=high (S1 on) sent as:(D0D1D2D3) +# 128 64 32 16 8 4 2 1 128 64 32 16 8 4 2 1 +# 1 B B 0 1 A A 0 1 B B 0 1 A A 0 +# 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 + +SW1_ON_ENC = [0xEE, 0xEE] # 1111 sent as 1111 + +# D0=high, D1=high, D2=high, D3=low (S1 off) +# 128 64 32 16 8 4 2 1 128 64 32 16 8 4 2 1 +# 1 B B 0 1 A A 0 1 B B 0 1 A A 0 +# 1 1 1 0 1 1 1 0 1 1 1 0 1 0 0 0 + +SW1_OFF_ENC = [0xEE, 0xE8] # 1110 sent as 0111 + + def ashex(payload): line = "" for b in payload: @@ -14,46 +61,20 @@ def build_relay_msg(relayState=False): """Temporary test code to prove we can turn the relay on or off""" - # This generates a 20*4 bit address i.e. 10 bytes - # The number generated is always the same - # Presumably this is the random 'Energenie address prefix' - # The switch number is encoded in the payload + payload = PREAMBLE - # Looks like: 0000 00BA gets encoded as: - # 128 64 32 16 8 4 2 1 - # 1 B B 0 1 A A 0 - - #payload = [] - #for i in range(10): - # j = i + 5 - # payload.append(8 + (j&1) * 6 + 128 + (j&2) * 48) - #dumpPayloadAsHex(payload) - # - # 5 6 7 8 9 10 11 12 13 14 - # 1(01) 1(10) 1(11) 0(00) 0(01) 0(10) 0(11) 1(00) 1(01) 1(10) - payload = [0x8e, 0xe8, 0xee, 0x88, 0x8e, 0xe8, 0xee, 0x88, 0x8e, 0xe8] - - #TODO: This is taken from the C code, it might be wrong - #(the D bit order seems reversed compared to the pdf spec) if relayState: # ON - # D0=high, D1=high, D2-high, D3=high (S1 on) - # 128 64 32 16 8 4 2 1 128 64 32 16 8 4 2 1 - # 1 B B 0 1 A A 0 1 B B 0 1 A A 0 - # 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 - payload += [0xEE, 0xEE] # 1111 + payload += SW1_ON_ENC else: # OFF - # D0=high, D1=high, D2=high, D3=low (S1 off) - # 128 64 32 16 8 4 2 1 128 64 32 16 8 4 2 1 - # 1 B B 0 1 A A 0 1 B B 0 1 A A 0 - # 1 1 1 0 1 1 1 0 1 1 1 0 1 0 0 0 - payload += [0xEE, 0xE8] # 1110 + payload += SW1_OFF_ENC return payload def build_test_message(pattern): - payload = [0x8E, 0xE8, 0xEE, 0x88, 0x8E, 0xE8, 0xEE, 0x88, 0x8E, 0xE8] + """build a test message for a D3D2D1D0 control patter""" + payload = PREAMBLE + DEFAULT_ADDR_ENC pattern &= 0x0F control = encode_bits(pattern, 4) payload += control @@ -65,44 +86,15 @@ #print("build: state:%s, device:%d, house:%s" % (str(state), device_address, str(house_address))) if house_address == None: - #this is just a fixed address generator, from the C code - #payload = [] - #for i in range(10): - # j = i + 5 - # payload.append(8 + (j&1) * 6 + 128 + (j&2) * 48) - #dumpPayloadAsHex(payload) - # binary = 0110 1100 0110 1100 0110 - # hex = 6 C 6 C 6 - house_address = 0x6C6C6 + house_address = DEFAULT_ADDR - payload = encode_bits((house_address & 0x0F0000) >> 16, 4) + payload = [] + PREAMBLE + payload += encode_bits((house_address & 0x0F0000) >> 16, 4) payload += encode_bits((house_address & 0x00FF00) >> 8, 8) payload += encode_bits((house_address & 0x0000FF), 8) - #TODO: D3210 are the other way round in the message?? - #This is correct as presented by the PDF from Energenie though. - #the relay test code above proves that bit position 0 is the on/off command - #so the next 3 bits are just like extra address bits - # Turn switch request into a 4 bit switch command, and add to payload - # D 3210 - # 0000 UNUSED - # 0001 UNUSED - # 0010 UNUSED - # 0011 All off (3) - # 0100 socket 4 off (4) - # 0101 socket 3 off (5) - # 0110 socket 2 off (6) - # 0111 socket 1 off (7) - # 1000 UNUSED - # 1001 UNUSED - # 1010 UNUSED - # 1011 All on (3) - # 1100 socket 4 on (4) - # 1101 socket 3 on (5) - # 1110 socket 2 on (6) - # 1111 socket 1 on (7) - - # Coded as per the (working) C code would be: + # Coded as per the (working) C code, as it is transmitted D0D1D2D3: + # D 0123 # b 3210 # 0000 UNUSED 0 # 0001 UNUSED 1 @@ -138,6 +130,7 @@ bits |= 0x02 payload += encode_bits(bits, 4) + #print("encoded as:%s" % ashex(payload)) return payload @@ -168,7 +161,7 @@ #print(" shift %d bits %d" % (shift, bits)) encoded.append(ENCODER[bits]) shift -= 2 - #print(" returns:%s" % ashex(modulated)) + #print(" returns:%s" % ashex(encoded)) return encoded diff --git a/src/energenie/encoder_test.py b/src/energenie/encoder_test.py index 927061e..2967bd6 100644 --- a/src/energenie/encoder_test.py +++ b/src/energenie/encoder_test.py @@ -33,7 +33,9 @@ tests = [ALL_ON, ALL_OFF, ONE_ON, ONE_OFF, TWO_ON, TWO_OFF, THREE_ON, THREE_OFF, FOUR_ON, FOUR_OFF, MYHOUSE_ALL_ON] for t in tests: + print('') print(ashex(t)) # END + diff --git a/src/legacy.py b/src/legacy.py index 9eae880..1f6aab7 100644 --- a/src/legacy.py +++ b/src/legacy.py @@ -8,7 +8,14 @@ import time -from energenie import encoder, radio +from energenie import encoder +# moving over to the new, faster, C radio driver +from energenie import radio2 as radio + +# How many times to repeat messages +# Present version of driver limits to 8 +# but this restriction will be lifted soon +REPEATS = 8 #----- TEST APPLICATION ------------------------------------------------------- @@ -54,10 +61,9 @@ print("Press the LEARN button on any switch %d for 5 secs until LED flashes" % switch_no) raw_input("press ENTER when LED is flashing") - for i in range(8): - print("ON") - radio.transmit(ON_MSGS[switch_no]) - time.sleep(1) + print("ON") + radio.send_payload(ON_MSGS[switch_no], REPEATS) + time.sleep(1) print("Device should now be programmed") @@ -65,10 +71,10 @@ for i in range(4): time.sleep(1) print("OFF") - radio.transmit(OFF_MSGS[switch_no]) + radio.send_payload(OFF_MSGS[switch_no], REPEATS) time.sleep(1) print("ON") - radio.transmit(ON_MSGS[switch_no]) + radio.send_payload(ON_MSGS[switch_no], REPEATS) print("Test completed") @@ -80,25 +86,24 @@ # switch_no 0 is ALL, then 1=1, 2=2, 3=3, 4=4 # ON print("switch %d ON" % switch_no) - radio.transmit(ON_MSGS[switch_no]) + radio.send_payload(ON_MSGS[switch_no], REPEATS) time.sleep(2) # OFF print("switch %d OFF" % switch_no) - radio.transmit(OFF_MSGS[switch_no]) + radio.send_payload(OFF_MSGS[switch_no], REPEATS) time.sleep(2) def switch1_loop(): """Repeatedly turn switch 1 ON then OFF""" while True: - print("Switch 1 ON repeatedly") - while True: - radio.transmit(ON_MSGS[1]) + print("Switch 1 ON") + radio.send_payload(ON_MSGS[1], REPEATS) + time.sleep(1) - #print("Switch 1 OFF") - #for i in range(50): - # radio.transmit(OFF_MSGS[1]) - ##time.sleep(1) + print("Switch 1 OFF") + radio.send_payload(OFF_MSGS[1], REPEATS) + time.sleep(1) def pattern_test(): @@ -108,7 +113,7 @@ p = int(p, 16) msg = encoder.build_test_message(p) print("pattern %s payload %s" % (str(hex(p)), encoder.ashex(msg))) - radio.transmit(msg) + radio.send_payload(msg, REPEATS) if __name__ == "__main__": @@ -117,7 +122,7 @@ print("radio init") radio.init() print("radio as OOK") - radio.transmitter(ook=True) + radio.modulation(ook=True) try: #pattern_test()