From 9996c252f702760df218382713e05b34cf0ead1e Mon Sep 17 00:00:00 2001 From: BAN <32472039+GGBBB2000@users.noreply.github.com> Date: Tue, 8 Jan 2019 16:47:31 +0900 Subject: [PATCH 1/5] Update __init__.py --- broadlink/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/broadlink/__init__.py b/broadlink/__init__.py index 02a8e2a..14c1a3b 100644 --- a/broadlink/__init__.py +++ b/broadlink/__init__.py @@ -41,7 +41,8 @@ def gendevice(devtype, host, mac): 0x2797, # RM2 Pro Plus HYC 0x27a1, # RM2 Pro Plus R1 0x27a6, # RM2 Pro PP - 0x278f # RM Mini Shate + 0x278f, # RM Mini Shate + 0x27c2 # RM Mini 3 ], a1: [0x2714], # A1 mp1: [0x4EB5, # MP1 From c393cf6079ccaa24afd61a8e81c051251198f73b Mon Sep 17 00:00:00 2001 From: Pim van den Berg Date: Wed, 16 Jan 2019 09:34:20 +0100 Subject: [PATCH 2/5] broadlink_cli: python3 support --- cli/broadlink_cli | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/cli/broadlink_cli b/cli/broadlink_cli index 54f02a0..a4d9a20 100755 --- a/cli/broadlink_cli +++ b/cli/broadlink_cli @@ -102,11 +102,11 @@ if args.host or args.device: if args.convert: data = bytearray.fromhex(''.join(args.data)) durations = to_microseconds(data) - print format_durations(durations) + print(format_durations(durations)) if args.temperature: - print dev.check_temperature() + print(dev.check_temperature()) if args.energy: - print dev.get_energy() + print(dev.get_energy()) if args.sensors: try: data = dev.check_sensors() @@ -114,7 +114,7 @@ if args.sensors: data = {} data['temperature'] = dev.check_temperature() for key in data: - print "{} {}".format(key, data[key]) + print("{} {}".format(key, data[key])) if args.send: data = durations_to_broadlink(parse_durations(' '.join(args.data))) \ if args.durations else bytearray.fromhex(''.join(args.data)) @@ -122,7 +122,7 @@ if args.send: if args.learn or args.learnfile: dev.enter_learning() data = None - print "Learning..." + print("Learning...") timeout = 30 while (data is None) and (timeout > 0): time.sleep(2) @@ -133,51 +133,51 @@ if args.learn or args.learnfile: if args.durations \ else ''.join(format(x, '02x') for x in bytearray(data)) if args.learn: - print learned + print(learned) if args.learnfile: - print "Saving to {}".format(args.learnfile) + print("Saving to {}".format(args.learnfile)) with open(args.learnfile, "w") as text_file: text_file.write(learned) else: - print "No data received..." + print("No data received...") if args.check: if dev.check_power(): - print '* ON *' + print('* ON *') else: - print '* OFF *' + print('* OFF *') if args.checknl: if dev.check_nightlight(): - print '* ON *' + print('* ON *') else: - print '* OFF *' + print('* OFF *') if args.turnon: dev.set_power(True) if dev.check_power(): - print '== Turned * ON * ==' + print('== Turned * ON * ==') else: - print '!! Still OFF !!' + print('!! Still OFF !!') if args.turnoff: dev.set_power(False) if dev.check_power(): - print '!! Still ON !!' + print('!! Still ON !!') else: - print '== Turned * OFF * ==' + print('== Turned * OFF * ==') if args.turnnlon: dev.set_nightlight(True) if dev.check_nightlight(): - print '== Turned * ON * ==' + print('== Turned * ON * ==') else: - print '!! Still OFF !!' + print('!! Still OFF !!') if args.turnnloff: dev.set_nightlight(False) if dev.check_nightlight(): - print '!! Still ON !!' + print('!! Still ON !!') else: - print '== Turned * OFF * ==' + print('== Turned * OFF * ==') if args.switch: if dev.check_power(): dev.set_power(False) - print '* Switch to OFF *' + print('* Switch to OFF *') else: dev.set_power(True) - print '* Switch to ON *' + print('* Switch to ON *') From 77f11c8d49255d6f41c35f0aefb87d648af66cfd Mon Sep 17 00:00:00 2001 From: gpenverne Date: Fri, 10 May 2019 20:19:09 +0200 Subject: [PATCH 3/5] Allow string mac address in constructor --- broadlink/__init__.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/broadlink/__init__.py b/broadlink/__init__.py index 14c1a3b..3d54414 100644 --- a/broadlink/__init__.py +++ b/broadlink/__init__.py @@ -143,7 +143,7 @@ def discover(timeout=None, local_ip_address=None): class device: def __init__(self, host, mac, devtype, timeout=10): self.host = host - self.mac = mac + self.mac = mac.encode() if isinstance(mac, str) else mac self.devtype = devtype self.timeout = timeout self.count = random.randrange(0xffff) @@ -577,19 +577,19 @@ class hysen(device): self.type = "Hysen heating controller" # Send a request - # input_payload should be a bytearray, usually 6 bytes, e.g. bytearray([0x01,0x06,0x00,0x02,0x10,0x00]) + # input_payload should be a bytearray, usually 6 bytes, e.g. bytearray([0x01,0x06,0x00,0x02,0x10,0x00]) # Returns decrypted payload # New behaviour: raises a ValueError if the device response indicates an error or CRC check fails # The function prepends length (2 bytes) and appends CRC def send_request(self,input_payload): - + from PyCRC.CRC16 import CRC16 crc = CRC16(modbus_flag=True).calculate(bytes(input_payload)) # first byte is length, +2 for CRC16 request_payload = bytearray([len(input_payload) + 2,0x00]) request_payload.extend(input_payload) - + # append CRC request_payload.append(crc & 0xFF) request_payload.append((crc >> 8) & 0xFF) @@ -599,9 +599,9 @@ class hysen(device): # check for error err = response[0x22] | (response[0x23] << 8) - if err: + if err: raise ValueError('broadlink_response_error',err) - + response_payload = bytearray(self.decrypt(bytes(response[0x38:]))) # experimental check on CRC in response (first 2 bytes are len, and trailing bytes are crc) @@ -611,9 +611,9 @@ class hysen(device): crc = CRC16(modbus_flag=True).calculate(bytes(response_payload[2:response_payload_len])) if (response_payload[response_payload_len] == crc & 0xFF) and (response_payload[response_payload_len+1] == (crc >> 8) & 0xFF): return response_payload[2:response_payload_len] - else: + else: raise ValueError('hysen_response_error','CRC check on response failed') - + # Get current room temperature in degrees celsius def get_temp(self): @@ -627,7 +627,7 @@ class hysen(device): # Get full status (including timer schedule) def get_full_status(self): - payload = self.send_request(bytearray([0x01,0x03,0x00,0x00,0x00,0x16])) + payload = self.send_request(bytearray([0x01,0x03,0x00,0x00,0x00,0x16])) data = {} data['remote_lock'] = payload[3] & 1 data['power'] = payload[4] & 1 @@ -653,11 +653,11 @@ class hysen(device): data['min'] = payload[20] data['sec'] = payload[21] data['dayofweek'] = payload[22] - + weekday = [] for i in range(0, 6): weekday.append({'start_hour':payload[2*i + 23], 'start_minute':payload[2*i + 24],'temp':payload[i + 39]/2.0}) - + data['weekday'] = weekday weekend = [] for i in range(6, 8): @@ -694,7 +694,7 @@ class hysen(device): # For backwards compatibility only. Prefer calling set_mode directly. Note this function invokes loop_mode=0 and sensor=0. def switch_to_auto(self): self.set_mode(auto_mode=1, loop_mode=0) - + def switch_to_manual(self): self.set_mode(auto_mode=0, loop_mode=0) From 852cbc24734bf3f7ac03080aa37374276f7a2856 Mon Sep 17 00:00:00 2001 From: Bartosz Fenski Date: Sat, 18 May 2019 09:07:25 +0200 Subject: [PATCH 4/5] adding base64 output (#239) base64 output useful when working with Home-Assistant --- cli/broadlink_cli | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/broadlink_cli b/cli/broadlink_cli index a4d9a20..9317cd1 100755 --- a/cli/broadlink_cli +++ b/cli/broadlink_cli @@ -134,6 +134,7 @@ if args.learn or args.learnfile: else ''.join(format(x, '02x') for x in bytearray(data)) if args.learn: print(learned) + print("Base64: " + base64.b64encode(learned.decode("hex"))) if args.learnfile: print("Saving to {}".format(args.learnfile)) with open(args.learnfile, "w") as text_file: From 0db317962348907096a29bb8d3b85c6c1d0ee35e Mon Sep 17 00:00:00 2001 From: ninstein Date: Thu, 7 Feb 2019 04:31:47 +0800 Subject: [PATCH 5/5] Update __init__.py add new device: TMall OEM SPMini3 --- broadlink/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/broadlink/__init__.py b/broadlink/__init__.py index 3d54414..98b6ba5 100644 --- a/broadlink/__init__.py +++ b/broadlink/__init__.py @@ -26,6 +26,7 @@ def gendevice(devtype, host, mac): 0x2728, # SPMini2 0x2733, 0x273e, # OEM branded SPMini 0x7530, 0x7918, # OEM branded SPMini2 + 0x7D0D, # TMall OEM SPMini3 0x2736 # SPMiniPlus ], rm: [0x2712, # RM2