5959CARD_REQUEST_SEGMENT_DELAY_MS = 250
6060
6161
62- def prepareRequest (req , debug = False ):
62+ def _prepare_request (req , debug = False ):
6363 """Format the request string as a JSON object and add a newline."""
6464 req_json = json .dumps (req )
6565 if debug :
@@ -69,90 +69,20 @@ def prepareRequest(req, debug=False):
6969 return req_json
7070
7171
72- def serialReadByte (port ):
73- """Read a single byte from a Notecard."""
74- if sys .implementation .name == 'micropython' :
75- if not port .any ():
76- return None
77- elif sys .implementation .name == 'cpython' :
78- if port .in_waiting == 0 :
79- return None
80- return port .read (1 )
72+ def serial_lock (fn ):
73+ """Attempt to get a lock on the serial channel used for Notecard comms."""
8174
82-
83- def serialReset (port ):
84- """Send a reset command to a Notecard."""
85- for i in range (10 ):
86- try :
87- port .write (b'\n ' )
88- except :
89- continue
90- time .sleep (0.5 )
91- somethingFound = False
92- nonControlCharFound = False
93- while True :
94- data = serialReadByte (port )
95- if (data is None ) or (data == b'' ):
96- break
97- somethingFound = True
98- if data [0 ] >= 0x20 :
99- nonControlCharFound = True
100- if somethingFound and not nonControlCharFound :
101- break
75+ def decorator (self , * args , ** kwargs ):
76+ if use_serial_lock :
77+ try :
78+ with self .lock .acquire (timeout = 5 ):
79+ return fn (self , * args , ** kwargs )
80+ except Timeout :
81+ raise Exception ('Notecard in use' )
10282 else :
103- raise Exception ( "Notecard not responding" )
83+ return fn ( self , * args , ** kwargs )
10484
105-
106- def serialTransaction (port , req , debug , txn_manager = None ):
107- """Perform a single write to and read from a Notecard."""
108- req_json = prepareRequest (req , debug )
109-
110- transaction_timeout_secs = 30
111- if txn_manager :
112- txn_manager .start (transaction_timeout_secs )
113-
114- seg_off = 0
115- seg_left = len (req_json )
116- while True :
117- seg_len = seg_left
118- if seg_len > CARD_REQUEST_SEGMENT_MAX_LEN :
119- seg_len = CARD_REQUEST_SEGMENT_MAX_LEN
120-
121- port .write (req_json [seg_off :seg_off + seg_len ].encode ('utf-8' ))
122- seg_off += seg_len
123- seg_left -= seg_len
124- if seg_left == 0 :
125- break
126- time .sleep (CARD_REQUEST_SEGMENT_DELAY_MS / 1000 )
127-
128- if txn_manager :
129- txn_manager .stop ()
130-
131- rsp_json = port .readline ()
132- if debug :
133- print (rsp_json .rstrip ())
134-
135- rsp = json .loads (rsp_json )
136- return rsp
137-
138-
139- def serialCommand (port , req , debug ):
140- """Perform a single write to and read from a Notecard."""
141- req_json = prepareRequest (req , debug )
142-
143- seg_off = 0
144- seg_left = len (req_json )
145- while True :
146- seg_len = seg_left
147- if seg_len > CARD_REQUEST_SEGMENT_MAX_LEN :
148- seg_len = CARD_REQUEST_SEGMENT_MAX_LEN
149-
150- port .write (req_json [seg_off :seg_off + seg_len ].encode ('utf-8' ))
151- seg_off += seg_len
152- seg_left -= seg_len
153- if seg_left == 0 :
154- break
155- time .sleep (CARD_REQUEST_SEGMENT_DELAY_MS / 1000 )
85+ return decorator
15686
15787
15888class Notecard :
@@ -178,7 +108,7 @@ def __init__(self):
178108 self ._user_agent ['os_family' ] = os .uname ().machine
179109 self ._transaction_manager = None
180110
181- def _preprocessReq (self , req ):
111+ def _preprocess_req (self , req ):
182112 """Inspect the request for hub.set and add the User Agent."""
183113 if 'hub.set' in req .values ():
184114 # Merge the User Agent to send along with the hub.set request.
@@ -210,51 +140,83 @@ def SetTransactionPins(self, rtx_pin, ctx_pin):
210140class OpenSerial (Notecard ):
211141 """Notecard class for Serial communication."""
212142
143+ def _transmit (self , req ):
144+ req = self ._preprocess_req (req )
145+ req_json = _prepare_request (req , self ._debug )
146+
147+ transaction_timeout_secs = 30
148+ if self ._transaction_manager :
149+ self ._transaction_manager .start (transaction_timeout_secs )
150+
151+ seg_off = 0
152+ seg_left = len (req_json )
153+ while True :
154+ seg_len = seg_left
155+ if seg_len > CARD_REQUEST_SEGMENT_MAX_LEN :
156+ seg_len = CARD_REQUEST_SEGMENT_MAX_LEN
157+
158+ self .uart .write (req_json [seg_off :seg_off + seg_len ].encode ('utf-8' ))
159+ seg_off += seg_len
160+ seg_left -= seg_len
161+ if seg_left == 0 :
162+ break
163+ time .sleep (CARD_REQUEST_SEGMENT_DELAY_MS / 1000 )
164+
165+ if self ._transaction_manager :
166+ self ._transaction_manager .stop ()
167+
168+ def _read_byte (self ):
169+ """Read a single byte from the Notecard."""
170+ if sys .implementation .name == 'micropython' :
171+ if not self .uart .any ():
172+ return None
173+ elif sys .implementation .name == 'cpython' :
174+ if self .uart .in_waiting == 0 :
175+ return None
176+ return self .uart .read (1 )
177+
178+ @serial_lock
213179 def Command (self , req ):
214- """Perform a Notecard command and exit with no response."""
215- req = self ._preprocessReq (req )
180+ """Send a command to the Notecard. The Notecard response is ignored."""
216181 if 'cmd' not in req :
217182 raise Exception ("Please use 'cmd' instead of 'req'" )
218183
219- if use_serial_lock :
220- try :
221- self .lock .acquire (timeout = 5 )
222- serialCommand (self .uart , req , self ._debug )
223- except Timeout :
224- raise Exception ("Notecard in use" )
225- finally :
226- self .lock .release ()
227- else :
228- serialCommand (self .uart , req , self ._debug )
184+ self ._transmit (req )
229185
186+ @serial_lock
230187 def Transaction (self , req ):
231188 """Perform a Notecard transaction and return the result."""
232- req = self ._preprocessReq (req )
233- if use_serial_lock :
234- try :
235- self .lock .acquire (timeout = 5 )
236- return serialTransaction (self .uart , req , self ._debug ,
237- self ._transaction_manager )
238- except Timeout :
239- raise Exception ("Notecard in use" )
240- finally :
241- self .lock .release ()
242- else :
243- return serialTransaction (self .uart , req , self ._debug ,
244- self ._transaction_manager )
189+ self ._transmit (req )
190+
191+ rsp_json = self .uart .readline ()
192+ if self ._debug :
193+ print (rsp_json .rstrip ())
194+
195+ rsp = json .loads (rsp_json )
196+ return rsp
245197
198+ @serial_lock
246199 def Reset (self ):
247200 """Reset the Notecard."""
248- if use_serial_lock :
201+ for i in range ( 10 ) :
249202 try :
250- self .lock .acquire (timeout = 5 )
251- serialReset (self .uart )
252- except Timeout :
253- raise Exception ("Notecard in use" )
254- finally :
255- self .lock .release ()
256- else :
257- serialReset (self .uart )
203+ self .uart .write (b'\n ' )
204+ except :
205+ continue
206+ time .sleep (0.5 )
207+ somethingFound = False
208+ nonControlCharFound = False
209+ while True :
210+ data = self ._read_byte ()
211+ if (data is None ) or (data == b'' ):
212+ break
213+ somethingFound = True
214+ if data [0 ] >= 0x20 :
215+ nonControlCharFound = True
216+ if somethingFound and not nonControlCharFound :
217+ break
218+ else :
219+ raise Exception ('Notecard not responding' )
258220
259221 def __init__ (self , uart_id , debug = False ):
260222 """Initialize the Notecard before a reset."""
@@ -299,11 +261,11 @@ def _sendPayload(self, json):
299261
300262 def Command (self , req ):
301263 """Perform a Notecard command and exit with no response."""
302- req = self ._preprocessReq (req )
264+ req = self ._preprocess_req (req )
303265 if 'cmd' not in req :
304266 raise Exception ("Please use 'cmd' instead of 'req'" )
305267
306- req_json = prepareRequest (req , self ._debug )
268+ req_json = _prepare_request (req , self ._debug )
307269
308270 while not self .lock ():
309271 pass
@@ -315,9 +277,9 @@ def Command(self, req):
315277
316278 def Transaction (self , req ):
317279 """Perform a Notecard transaction and return the result."""
318- req = self ._preprocessReq (req )
280+ req = self ._preprocess_req (req )
319281
320- req_json = prepareRequest (req , self ._debug )
282+ req_json = _prepare_request (req , self ._debug )
321283 rsp_json = ""
322284
323285 while not self .lock ():
0 commit comments