about summary refs log tree commit diff
path: root/broadlink
diff options
context:
space:
mode:
Diffstat (limited to 'broadlink')
-rw-r--r--broadlink/__init__.py84
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)