|
1 | 1 | """ Orbivo S20. """ |
2 | 2 |
|
3 | 3 | import binascii |
| 4 | +import struct |
4 | 5 | import logging |
5 | 6 | import socket |
6 | 7 | import threading |
@@ -57,23 +58,36 @@ def _setup(): |
57 | 58 | udp.start() |
58 | 59 |
|
59 | 60 |
|
| 61 | +def _device_time(tab): |
| 62 | + ts = struct.unpack('<L', tab)[0] - 2208988800 |
| 63 | + return ts |
| 64 | + |
| 65 | + |
60 | 66 | def discover(timeout=DISCOVERY_TIMEOUT): |
61 | 67 | """ Discover devices on the local network. |
62 | 68 |
|
63 | 69 | :param timeout: Optional timeout in seconds. |
64 | 70 | :returns: Set of discovered host addresses. |
65 | 71 | """ |
66 | | - hosts = set() |
| 72 | + hosts = {} |
67 | 73 | payload = MAGIC + DISCOVERY |
68 | 74 | for _ in range(RETRIES): |
69 | 75 | _SOCKET.sendto(bytearray(payload), ('255.255.255.255', PORT)) |
70 | 76 | start = time.time() |
71 | 77 | while time.time() < start + timeout: |
72 | 78 | for host, data in _BUFFER.copy().items(): |
73 | | - if _is_discovery_response(data): |
74 | | - if host not in hosts: |
75 | | - _LOGGER.debug("Discovered device at %s", host) |
76 | | - hosts.add(host) |
| 79 | + if not _is_discovery_response(data): |
| 80 | + continue |
| 81 | + if host not in hosts: |
| 82 | + _LOGGER.debug("Discovered device at %s", host) |
| 83 | + entry = {} |
| 84 | + entry['mac'] = data[7:13] |
| 85 | + entry['imac'] = data[19:25] |
| 86 | + entry['next'] = 0 |
| 87 | + entry['st'] = int(data[-1]) |
| 88 | + entry['time'] = _device_time(data[37:41]) |
| 89 | + entry['serverTime'] = int(time.time()) |
| 90 | + hosts[host] = entry |
77 | 91 | return hosts |
78 | 92 |
|
79 | 93 |
|
@@ -113,13 +127,22 @@ class S20(object): |
113 | 127 |
|
114 | 128 | Protocol documentation: http://pastebin.com/LfUhsbcS |
115 | 129 | """ |
116 | | - def __init__(self, host): |
| 130 | + def __init__(self, host, mac = None): |
117 | 131 | """ Initialize S20 object. |
118 | 132 |
|
119 | 133 | :param host: IP or hostname of device. |
120 | 134 | """ |
121 | 135 | self.host = host |
122 | | - (self._mac, self._mac_reversed) = self._discover_mac() |
| 136 | + if not mac: |
| 137 | + (self._mac, self._mac_reversed) = self._discover_mac() |
| 138 | + else: |
| 139 | + if type(mac) is str: |
| 140 | + self._mac = binascii.a2b_hex(''.join(mac.split(':'))) |
| 141 | + else: |
| 142 | + self._mac = mac |
| 143 | + ba = bytearray(self._mac) |
| 144 | + ba.reverse() |
| 145 | + self._mac_reversed = bytes(ba) |
123 | 146 | self._subscribe() |
124 | 147 |
|
125 | 148 | @property |
|
0 commit comments