diff options
Diffstat (limited to 'broadlink')
-rw-r--r-- | broadlink/__init__.py | 84 |
1 files changed, 74 insertions, 10 deletions
diff --git a/broadlink/__init__.py b/broadlink/__init__.py index ffbfd3ad2b1e..37a7fcbec26c 100644 --- a/broadlink/__init__.py +++ b/broadlink/__init__.py @@ -5,6 +5,7 @@ from Crypto.Cipher import AES import time import random import socket +import threading def gendevice(devtype, host, mac): if devtype == 0: # SP1 @@ -45,6 +46,8 @@ def gendevice(devtype, host, mac): return rm(host=host, mac=mac) elif devtype == 0x2714: # A1 return a1(host=host, mac=mac) + elif devtype == 0x4EB5: # MP1 + return mp1(host=host, mac=mac) else: return device(host=host, mac=mac) @@ -139,6 +142,7 @@ class device: self.cs.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) self.cs.bind(('',0)) self.type = "Unknown" + self.lock = threading.Lock() def auth(self): payload = bytearray(0x50) @@ -229,19 +233,79 @@ class device: packet[0x21] = checksum >> 8 starttime = time.time() - while True: - try: - self.cs.sendto(packet, self.host) - self.cs.settimeout(1) - response = self.cs.recvfrom(1024) - break - except socket.timeout: - if (time.time() - starttime) < self.timeout: - pass - raise + with self.lock: + while True: + try: + self.cs.sendto(packet, self.host) + self.cs.settimeout(1) + response = self.cs.recvfrom(1024) + break + except socket.timeout: + if (time.time() - starttime) < self.timeout: + pass + raise return bytearray(response[0]) +class mp1(device): + def __init__ (self, host, mac): + device.__init__(self, host, mac) + self.type = "MP1" + + def set_power_mask(self, sid_mask, state): + """Sets the power state of the smart power strip.""" + + packet = bytearray(16) + packet[0x00] = 0x0d + packet[0x02] = 0xa5 + packet[0x03] = 0xa5 + packet[0x04] = 0x5a + packet[0x05] = 0x5a + packet[0x06] = 0xb2 + ((sid_mask<<1) if state else sid_mask) + packet[0x07] = 0xc0 + packet[0x08] = 0x02 + packet[0x0a] = 0x03 + packet[0x0d] = sid_mask + packet[0x0e] = sid_mask if state else 0 + + response = self.send_packet(0x6a, packet) + + err = response[0x22] | (response[0x23] << 8) + + def set_power(self, sid, state): + """Sets the power state of the smart power strip.""" + sid_mask = 0x01 << (sid - 1) + return self.set_power_mask(sid_mask, state) + + def check_power(self): + """Returns the power state of the smart power strip.""" + packet = bytearray(16) + packet[0x00] = 0x0a + packet[0x02] = 0xa5 + packet[0x03] = 0xa5 + packet[0x04] = 0x5a + packet[0x05] = 0x5a + packet[0x06] = 0xae + packet[0x07] = 0xc0 + packet[0x08] = 0x01 + + response = self.send_packet(0x6a, packet) + err = response[0x22] | (response[0x23] << 8) + if err == 0: + aes = AES.new(bytes(self.key), AES.MODE_CBC, bytes(self.iv)) + payload = aes.decrypt(bytes(response[0x38:])) + if type(payload[0x4]) == int: + state = payload[0x0e] + else: + state = ord(payload[0x0e]) + data = {} + data['s1'] = bool(state & 0x01) + data['s2'] = bool(state & 0x02) + data['s3'] = bool(state & 0x04) + data['s4'] = bool(state & 0x08) + return data + + class sp1(device): def __init__ (self, host, mac): device.__init__(self, host, mac) |