3
3
import logging
4
4
import re
5
5
import serial
6
+ import socket
6
7
from functools import wraps
7
8
from serial_asyncio import create_serial_connection
8
9
from threading import RLock
13
14
EOL = b'\r '
14
15
LEN_EOL = len (EOL )
15
16
TIMEOUT = 2 # Number of seconds before serial operation timeout
16
- SYSTEM_POWER = None
17
+ PORT = 4001
18
+ SOCKET_RECV = 2048
17
19
18
20
class ZoneStatus (object ):
19
21
def __init__ (self ,
@@ -53,6 +55,7 @@ def from_string(cls, string: str):
53
55
else :
54
56
return False
55
57
58
+
56
59
class Blackbird (object ):
57
60
"""
58
61
Monoprice blackbird amplifier interface
@@ -134,13 +137,14 @@ def _format_lock_status() -> bytes:
134
137
return '%9961.\r ' .encode ()
135
138
136
139
137
- def get_blackbird (port_url ):
140
+ def get_blackbird (url , use_serial = True ):
138
141
"""
139
142
Return synchronous version of Blackbird interface
140
143
:param port_url: serial port, i.e. '/dev/ttyUSB0'
141
144
:return: synchronous implementation of Blackbird interface
142
145
"""
143
146
lock = RLock ()
147
+ print (serial )
144
148
145
149
def synchronized (func ):
146
150
@wraps (func )
@@ -150,44 +154,76 @@ def wrapper(*args, **kwargs):
150
154
return wrapper
151
155
152
156
class BlackbirdSync (Blackbird ):
153
- def __init__ (self , port_url ):
154
- self ._port = serial .serial_for_url (port_url , do_not_open = True )
155
- self ._port .baudrate = 9600
156
- self ._port .stopbits = serial .STOPBITS_ONE
157
- self ._port .bytesize = serial .EIGHTBITS
158
- self ._port .parity = serial .PARITY_NONE
159
- self ._port .timeout = TIMEOUT
160
- self ._port .write_timeout = TIMEOUT
161
- self ._port .open ()
157
+ def __init__ (self , url ):
158
+ """
159
+ Initialize the client.
160
+ """
161
+ if use_serial :
162
+ self ._port = serial .serial_for_url (url , do_not_open = True )
163
+ self ._port .baudrate = 9600
164
+ self ._port .stopbits = serial .STOPBITS_ONE
165
+ self ._port .bytesize = serial .EIGHTBITS
166
+ self ._port .parity = serial .PARITY_NONE
167
+ self ._port .timeout = TIMEOUT
168
+ self ._port .write_timeout = TIMEOUT
169
+ self ._port .open ()
170
+
171
+ else :
172
+ self .host = url
173
+ self .port = PORT
174
+ self .socket = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
175
+ self .socket .settimeout (TIMEOUT )
176
+ self .socket .connect ((self .host , self .port ))
177
+
178
+ # Clear login message
179
+ self .socket .recv (SOCKET_RECV )
162
180
163
181
def _process_request (self , request : bytes , skip = 0 ):
164
182
"""
183
+ Send data to socket
165
184
:param request: request that is sent to the blackbird
166
185
:param skip: number of bytes to skip for end of transmission decoding
167
186
:return: ascii string returned by blackbird
168
187
"""
169
188
_LOGGER .debug ('Sending "%s"' , request )
170
- # clear
171
- self ._port .reset_output_buffer ()
172
- self ._port .reset_input_buffer ()
173
- # send
174
- self ._port .write (request )
175
- self ._port .flush ()
176
- # receive
177
- result = bytearray ()
178
- while True :
179
- c = self ._port .read (1 )
180
- if c is None :
181
- break
182
- if not c :
183
- raise serial .SerialTimeoutException (
184
- 'Connection timed out! Last received bytes {}' .format ([hex (a ) for a in result ]))
185
- result += c
186
- if len (result ) > skip and result [- LEN_EOL :] == EOL :
187
- break
188
- ret = bytes (result )
189
- _LOGGER .debug ('Received "%s"' , ret )
190
- return ret .decode ('ascii' )
189
+
190
+ if use_serial :
191
+ # clear
192
+ self ._port .reset_output_buffer ()
193
+ self ._port .reset_input_buffer ()
194
+ # send
195
+ self ._port .write (request )
196
+ self ._port .flush ()
197
+ # receive
198
+ result = bytearray ()
199
+ while True :
200
+ c = self ._port .read (1 )
201
+ if c is None :
202
+ break
203
+ if not c :
204
+ raise serial .SerialTimeoutException (
205
+ 'Connection timed out! Last received bytes {}' .format ([hex (a ) for a in result ]))
206
+ result += c
207
+ if len (result ) > skip and result [- LEN_EOL :] == EOL :
208
+ break
209
+ ret = bytes (result )
210
+ _LOGGER .debug ('Received "%s"' , ret )
211
+ return ret .decode ('ascii' )
212
+
213
+ else :
214
+ self .socket .send (request )
215
+
216
+ response = ''
217
+
218
+ while True :
219
+
220
+ data = self .socket .recv (SOCKET_RECV )
221
+ response += data .decode ('ascii' )
222
+
223
+ if EOL in data and len (response ) > skip :
224
+ break
225
+
226
+ return response
191
227
192
228
@synchronized
193
229
def zone_status (self , zone : int ):
@@ -224,7 +260,7 @@ def lock_status(self):
224
260
# Report system locking status
225
261
return LockStatus .from_string (self ._process_request (_format_lock_status ()))
226
262
227
- return BlackbirdSync (port_url )
263
+ return BlackbirdSync (url )
228
264
229
265
230
266
@asyncio .coroutine
0 commit comments