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