13 from threading
import Event
15 import import_gos_sdk_utils
19 from common.gos_http_server
import gos_ws_data_api
20 from common
import logger_configure
21 from common
import object_from_dict
22 from common
import issue_event
26 class http_server_data_api_client(object):
28 ''' ******************************************************************************************* ''' 29 def __init__(self, options):
30 self.logger = logger_configure(log_level=options.log_level, name=
'client')
32 self.ws_api = gos_ws_data_api(host=options.host,
33 logger=logger_configure(log_level=options.ws_log_level, name=
'ws_api'),
34 disconnect_callback=self._ws_disconnect_callback)
36 self.host = options.host
37 self.stop_event = Event()
38 self.stop_event.clear()
42 self.ws_api.register(
'sysinfo', self._sysinfo_client_stream_handler)
43 self.ws_api.register(
'version', self._version_client_stream_handler)
45 self.read_led_stream =
None 46 self.write_led_stream =
None 47 self.read_adc_stream =
None 48 self.read_time_stream =
None 51 if options.read_led_period:
52 self.read_led_stream = issue_event(handler=self._read_led_device_stream_handler,
55 period=options.read_led_period)
56 if options.write_led_period:
57 self.write_led_stream = issue_event(handler=self._write_led_device_stream_handler,
60 period=options.write_led_period)
61 if options.read_adc_period:
62 self.read_adc_stream = issue_event(handler=self._read_adc_device_stream_handler,
65 period=options.read_adc_period)
66 if options.read_time_period:
67 self.read_time_stream = issue_event(handler=self._read_time_device_stream_handler,
70 period=options.read_time_period)
73 ''' ******************************************************************************************* ''' 76 return not self.stop_event.is_set()
79 ''' ******************************************************************************************* ''' 80 def run_forever(self):
81 self._ws_try_connect()
82 self.stop_event.wait()
85 ''' ******************************************************************************************* ''' 88 if self.read_led_stream:
89 self.read_led_stream.stop()
90 if self.write_led_stream:
91 self.write_led_stream.stop()
92 if self.read_adc_stream:
93 self.read_adc_stream.stop()
94 if self.read_time_stream:
95 self.read_time_stream.stop()
98 ''' ******************************************************************************************* 99 Try to connect to device via websocket. 101 def _ws_try_connect(self):
102 issue_event(self._ws_try_connect_handler, name=
'WS Connect')
105 ''' ******************************************************************************************* ''' 106 def _ws_try_connect_handler(self):
109 self.logger.info(
'Attempting to connect to: %s' % self.ws_api.host)
111 self.logger.info(
'Connected')
113 except Exception
as e:
114 self.logger.warn(
'Failed to connect to websocket, err:%s' % e)
115 issue_event(self._ws_try_connect_handler, initial_delay=7, name=
'WS Connect')
119 self.logger.info(
'Listing device streams')
120 streams = self.ws_api.list()
121 stream_list =
', '.join(streams)
122 self.logger.info(
'Streams device is actively listing: %s' % stream_list)
124 except Exception
as e:
125 self.logger.warn(
'Failed to list device streams, err:%s' % e)
128 self.logger.info(
'Starting client stream polling loops')
129 if self.read_led_stream:
130 self.read_led_stream.start()
131 if self.write_led_stream:
132 self.write_led_stream.start()
133 if self.read_adc_stream:
134 self.read_adc_stream.start()
135 if self.read_time_stream:
136 self.read_time_stream.start()
139 ''' ******************************************************************************************* ''' 140 def _ws_disconnect_callback(self):
141 self.logger.warn(
'Websocket disconnected')
143 if self.read_led_stream:
144 self.read_led_stream.pause()
145 if self.write_led_stream:
146 self.write_led_stream.pause()
147 if self.read_adc_stream:
148 self.read_adc_stream.pause()
149 if self.read_time_stream:
150 self.read_time_stream.pause()
152 self._ws_try_connect()
162 ''' ########################################################################################## 164 The following are stream handlers the device reads/writes from/to the client 165 e.g.: device -> client 167 ########################################################################################## 172 ''' ******************************************************************************************* 173 This is called when the device writes the 'version' client stream. 174 See: websocket_periodic_write_version_stream_handler() in the example app. 176 def _version_client_stream_handler(self, stream, data):
177 self.logger.info(
'[Device->Client] Writing stream: %s\n%s' % (stream, data.pretty_str))
180 ''' ******************************************************************************************* 181 This is called when the device read the 'sysinfo' client stream. 182 See: websocket_periodic_read_sysinfo_stream_handler() in the example app. 184 def _sysinfo_client_stream_handler(self, stream, unused):
185 self.logger.info(
'[Device->Client] Reading stream: %s' % stream)
189 'timestamp':
'%s' % datetime.datetime.now(),
190 'platform' :
' '.join(platform.architecture()),
201 ''' ########################################################################################## 203 The following are periodically invoked by this client 204 to read/write device streams. 208 ########################################################################################## 211 ''' ******************************************************************************************* 212 This is call periodically when the client reads the device's 'led' stream. 213 See: led_stream_handler() in the example app 215 def _read_led_device_stream_handler(self):
216 self.logger.debug(
'[Client->Device] Reading stream: led')
219 response = self.ws_api.read(
'led')
220 self.logger.info(
'[Client->Device] Read stream: led\n%s' % response.pretty_str)
221 except Exception
as e:
222 self.logger.warn(
'[Client->Device] Failed to read stream, err:%s' % e)
225 ''' ******************************************************************************************* 226 This is call periodically when the client writes the device's 'led' stream. 227 See: led_stream_handler() in the example app 229 def _write_led_device_stream_handler(self):
230 self.logger.debug(
'[Client->Device] Writing stream: led')
235 'timestamp':
'%s' % datetime.datetime.now(),
238 self.ws_api.write(
'led', request, timeout=7)
239 self.logger.info(
'[Client->Device] Wrote stream: led')
240 except Exception
as e:
241 self.logger.warn(
'[Client->Device] Failed to write stream, err:%s' % e)
244 ''' ******************************************************************************************* 245 This is call periodically when the client reads the device's 'adc' stream. 246 See: adc_stream_handler() in the example app 248 def _read_adc_device_stream_handler(self):
249 self.logger.debug(
'[Client->Device] Reading stream: adc')
252 response = self.ws_api.read(
'adc')
253 self.logger.info(
'[Client->Device] Read stream: adc\n%s' % response.pretty_str)
254 except Exception
as e:
255 self.logger.warn(
'[Client->Device] Failed to read stream, err:%s' % e)
258 ''' ******************************************************************************************* 259 This is call periodically when the client reads the device's 'time' stream. 260 See: time_stream_handler() in the example app 262 def _read_time_device_stream_handler(self):
263 self.logger.debug(
'[Client->Device] Reading stream: time')
266 response = self.ws_api.read(
'time')
267 self.logger.info(
'[Client->Device] Read stream: time\n%s' % response.pretty_str)
268 except Exception
as e:
269 self.logger.warn(
'[Client->Device] Failed to read stream, err:%s' % e)
281 ''' ******************************************************************************************* ''' 282 if __name__ ==
"__main__":
283 parser = optparse.OptionParser(description=
'This is a test client for the network.http_server_stream example app')
285 parser.add_option(
'--host',
286 help=
'The IP address or hostname of the device running the example app. NOTE: The device must be on the same network as this PC')
287 parser.add_option(
'--log_level',
288 choices=[
'debug',
'info',
'warn',
'error'],
290 help=
'Client debugging log level')
291 parser.add_option(
'--ws_log_level',
292 choices=[
'debug',
'info',
'warn',
'error'],
294 help=
'Websocket debugging log level')
295 parser.add_option(
'--read_led_period', type=
'float', default=5.5, help=
'Period of the Client->Device read LED stream handler in seconds as a float [default %default]')
296 parser.add_option(
'--write_led_period', type=
'float', default=5.5, help=
'Period of the Client->Device write LED stream handler in seconds as a float [default %default]')
297 parser.add_option(
'--read_adc_period', type=
'float', default=5.5, help=
'Period of the Client->Device read ADC stream handler in seconds as a float [default %default]')
298 parser.add_option(
'--read_time_period', type=
'float', default=5.5, help=
'Period of the Client->Device read time stream handler in seconds as a float [default %default]')
300 options, _ = parser.parse_args()
304 sys.stdout.write(
'\n\nMust provide --host option\n')
308 client = http_server_data_api_client(options)
313 except KeyboardInterrupt: