def test_app(self): import cs # capture output to test on with self._capture_output() as (out, err): # augment cs.CSClient().get to return mock data cs.CSClient().get = unittest.mock.Mock( side_effect=self.mock_get_enabled) gps_probe = importlib.import_module('gps_probe') # Pull info out of stdout since this app uses the cs.py log # function. This means the logs are converted to prints and # go to stdout output = out.getvalue().strip() # if the test passed, stdout should have captured output self.assertIn('GPS Function is Enabled', output) self.assertIn('"nmea": [', output) self.assertIn('"fix": {', output) self.assertIn('"lastpos": {', output) with self._capture_output() as (out, err): # augment cs.CSClient().get to return mock data gps is disabled cs.CSClient().get = unittest.mock.Mock( side_effect=self.mock_get_disabled) importlib.reload(gps_probe) # Pull info out of stdout since this app uses the cs.py log # function. This means the logs are converted to prints and # go to stdout output = out.getvalue().strip() # if the test passed, stdout should have captured output self.assertIn('GPS Function is NOT Enabled', output)
def get_router_data(): system_id = cs.CSClient().get('/config/system/system_id').get('data', '') modem_temp = cs.CSClient().get('/status/system/modem_temperature').get('data', '') host_os = sys.platform router_data = {'host_os': host_os, 'system_id': system_id, 'modem_temp': modem_temp } return router_data
def putline(self, line): line = line + CRLF if self.debugging > 1: print('*put*', self.sanitize(line)) cs.CSClient().log('FTP', '{} {}'.format('*put*', self.sanitize(line))) self.sock.sendall(line.encode(self.encoding))
def publish_thread(): log.debug('Start publish_thread()') while True: try: gps_lastpos = cs.CSClient().get(settings.GPS_TOPIC).get('data') gps_pos = { 'longitude': gps_lastpos.get('longitude'), 'latitude': gps_lastpos.get('latitude') } # Single Topic Publish example # QOS 0: The client will deliver the message once, with no confirmation. publish.single(topic=settings.GPS_TOPIC, payload=json.dumps(gps_pos), qos=0, hostname=settings.MQTT_SERVER, port=settings.MQTT_PORT) time.sleep(1) # Multiple Topics Publish example modem_temp = cs.CSClient().get(settings.MODEM_TEMP_TOPIC).get( 'data', '') wan_connection_state = cs.CSClient().get( settings.WAN_CONNECTION_STATE_TOPIC).get('data') # Using tuples to define multiple messages, # the form must be: ("<topic>", "<payload>", qos, retain) # QOS 1: The client will deliver the message at least once, with confirmation required. # QOS 2: The client will deliver the message exactly once by using a four step handshake. msgs = [(settings.MODEM_TEMP_TOPIC, modem_temp, 1, False), (settings.WAN_CONNECTION_STATE_TOPIC, wan_connection_state, 2, False)] publish.multiple(msgs=msgs, hostname=settings.MQTT_SERVER, port=settings.MQTT_PORT) time.sleep(1) # Publish the package.ini file as an example file_name = 'package.ini' publish_file(file_name, os.path.join(os.getcwd(), file_name)) time.sleep(10) except Exception as ex: log.error('Exception in publish_thread(). ex: {}'.format(ex))
def getwelcome(self): '''Get the welcome message from the server. (this is read and squirreled away by connect())''' if self.debugging: print('*welcome*', self.sanitize(self.welcome)) cs.CSClient().log( 'FTP', '{} {}'.format('*welcome*', self.sanitize(self.welcome))) return self.welcome
def start_server(): # avoid 8080, as the router may have service on it. # Firewall rules will need to be changed in the router # to allow access on this port. server_address = ('', 9001) cs.CSClient().log(APP_NAME, "Starting Server: {}".format(server_address)) cs.CSClient().log(APP_NAME, "Web Message is: {}".format(WEB_MESSAGE)) httpd = HTTPServer(server_address, WebServerRequestHandler) # Use the line below to serve the index.html page that is in the # app directory. # httpd = HTTPServer(server_address, SimpleHTTPRequestHandler) try: httpd.serve_forever() except KeyboardInterrupt: cs.CSClient().log(APP_NAME, "Stopping Server, Key Board interrupt") return 0
def initializevalues(): log.debug('Initializing Graph values') try: # get the time router_time = cs.CSClient().get('/status/system/time/') router_time = int(router_time['data']) for i in range(50): # every loop, subtract 30 seconds from the time to populate the graph along the time axis rssi.insert(0, {"x": router_time - (i*30), "y": 0}) sinr.insert(0, {"x": router_time - (i*30), "y": 0}) except Exception as e: log.error('Exception during initializevalues()! exception: {}'.format(e))
def send_ftp_file(): cs.CSClient().log(APP_NAME, 'ftp_client send_ftp_file()...') # Create a temporary file to upload to an FTP server try: f = open(TEMP_FILE, 'w') f.write('This is a test!!') f.write('This is another test!!') f.close() except OSError as msg: cs.CSClient().log( APP_NAME, 'Failed to open file: {}. error: {}'.format(TEMP_FILE, msg)) try: # Connect to an FTP test server ftp = FTP('speedtest.tele2.net') # Login to the server reply = ftp.login('anonymous', 'anonymous') cs.CSClient().log(APP_NAME, 'FTP login reply: {}'.format(reply)) # Change to the proper directory for upload ftp.cwd('/upload/') # Open the file and upload it to the server fh = open(TEMP_FILE, 'rb') reply = ftp.storlines('STOR a.txt', fh) cs.CSClient().log(APP_NAME, 'FTP STOR reply: {}'.format(reply)) except Exception as e: cs.CSClient().log( APP_NAME, 'Something went wrong in start_router_app()! exception: {}'.format( e)) raise finally: if fh: fh.close()
def start_ftp_server(): cs.CSClient().log(APP_NAME, 'start_ftp_server()...') try: authorizer = DummyAuthorizer() # Define a new user having full r/w permissions and a read-only # anonymous user authorizer.add_user('user', '12345', FTP_DIR, perm='elradfmwM') authorizer.add_anonymous(FTP_DIR) # Instantiate FTP handler class handler = FTPHandler handler.authorizer = authorizer # Define a customized banner (string returned when client connects) handler.banner = "pyftpdlib based ftpd ready." # Instantiate FTP server class and listen on 0.0.0.0:2121. # Application can only use ports higher that 1024 and the port # will need to be allowed in the router firewall address = ('', 2121) server = FTPServer(address, handler) # set a limit for connections server.max_cons = 256 server.max_cons_per_ip = 5 # start ftp server cs.CSClient().log(APP_NAME, 'Starting FTP server...') server.serve_forever() # This will run the server in another thread # t = Thread(target=server.serve_forever()) # t.start() except Exception as e: cs.CSClient().log( APP_NAME, 'Something went wrong in start_ftp_server()! exception: {}'.format( e))
def getvalues(): log.debug('Starting getvalues to get current rssi/sinr values') global rssi, sinr # Get the RSSI get_rssi = cs.CSClient().get('/status/wan/devices/%s/diagnostics/DBM/' % primary_connection) get_rssi = float(get_rssi['data']) # Get the SINR get_sinr = cs.CSClient().get('/status/wan/devices/%s/diagnostics/SINR/' % primary_connection) # remove first entry in list and append SINR get_sinr = float(get_sinr['data']) # get the time router_time = cs.CSClient().get('/status/system/time/') router_time = int(router_time['data']) # remove the first entry in rssi and append rssi value to end rssi.pop(0) rssi.append({"x": router_time, "y": get_rssi}) # remove the first entry in sinr and append sinr value to end sinr.pop(0) sinr.append({"x": router_time, "y": get_sinr})
def post_to_server(): try: # The tree item to get from the router config store tree_item = '/status/system/sdk' start_time = datetime.datetime.now() # Get the item from the router config store tree_data = cs.CSClient().get(tree_item) cs.CSClient().log(APP_NAME, "{}: {}".format(tree_item, tree_data)) time_to_get = datetime.datetime.now() - start_time encode_start_time = datetime.datetime.now() # URL encode the tree_data params = urllib.parse.urlencode(tree_data) # UTF-8 encode the URL encoded data params = params.encode('utf-8') time_to_encode = datetime.datetime.now() - encode_start_time send_to_server_start_time = datetime.datetime.now() # Send a post request to a test server. It will respond with the data sent # in the request response = urllib.request.urlopen("http://httpbin.org/post", params) end_time = datetime.datetime.now() # Log the response code and the processing timing information. cs.CSClient().log( APP_NAME, "data sent, http response code: {}".format(response.code)) cs.CSClient().log( APP_NAME, 'Time to get data from router config store: {}'.format( time_to_get)) cs.CSClient().log(APP_NAME, 'Time to urlencode data: {}'.format(time_to_encode)) cs.CSClient().log( APP_NAME, 'Time to get reply from server: {}'.format( end_time - send_to_server_start_time)) cs.CSClient().log( APP_NAME, 'Time to get and send data in post request: {}'.format(end_time - start_time)) except Exception as ex: cs.CSClient().log(APP_NAME, 'Something went wrong! ex: {}'.format(ex))
def abort(self): '''Abort a file transfer. Uses out-of-band data. This does not follow the procedure from the RFC to send Telnet IP and Synch; that doesn't seem to work with the servers I've tried. Instead, just send the ABOR command as OOB data.''' line = b'ABOR' + B_CRLF if self.debugging > 1: print('*put urgent*', self.sanitize(line)) cs.CSClient().log( 'FTP', '{} {}'.format('*put urgent*', self.sanitize(line))) self.sock.sendall(line, MSG_OOB) resp = self.getmultiline() if resp[:3] not in {'426', '225', '226'}: raise error_proto(resp) return resp
def getresp(self): resp = self.getmultiline() if self.debugging: print('*resp*', self.sanitize(resp)) cs.CSClient().log('FTP', '{} {}'.format('*resp*', self.sanitize(resp))) self.lastresp = resp[:3] c = resp[:1] if c in {'1', '2', '3'}: return resp if c == '4': raise error_temp(resp) if c == '5': raise error_perm(resp) raise error_proto(resp)
def getline(self): line = self.file.readline(self.maxline + 1) if len(line) > self.maxline: raise Error("got more than %d bytes" % self.maxline) if self.debugging > 1: print('*get*', self.sanitize(line)) cs.CSClient().log('FTP', '{} {}'.format('*get*', self.sanitize(line))) if not line: raise EOFError if line[-2:] == CRLF: line = line[:-2] elif line[-1:] in CRLF: line = line[:-1] return line
def do_GET(self): # Log the Get request cs.CSClient().log(APP_NAME, 'Received Get request: {}'.format(self.path)) # Send response status code self.send_response(200) # Send headers self.send_header('Content-type', 'text/html') self.end_headers() # Send message back to client # Write content as utf-8 data self.wfile.write(bytes(WEB_MESSAGE, "utf8")) return
def retrlines(self, cmd, callback=None): """Retrieve data in line mode. A new port is created for you. Args: cmd: A RETR, LIST, or NLST command. callback: An optional single parameter callable that is called for each line with the trailing CRLF stripped. [default: print_line()] Returns: The response code. """ if callback is None: callback = print_line resp = self.sendcmd('TYPE A') with self.transfercmd(cmd) as conn, \ conn.makefile('r', encoding=self.encoding) as fp: while 1: line = fp.readline(self.maxline + 1) if len(line) > self.maxline: raise Error("got more than %d bytes" % self.maxline) if self.debugging > 2: print('*retr*', repr(line)) cs.CSClient().log( 'FTP', '{} {}'.format('*retr*', self.sanitize(line))) if not line: break if line[-2:] == CRLF: line = line[:-2] elif line[-1:] == '\n': line = line[:-1] callback(line) # shutdown ssl layer if _SSLSocket is not None and isinstance(conn, _SSLSocket): conn.unwrap() return self.voidresp()
def run_ping(): try: # Log the action for the app. cs.CSClient().log(APP_NAME, 'run_ping()...') ping_data = { 'host': 'www.google.com', # Can also be an IP address 'size': 64 } result = cs.CSClient().put('/control/ping/start', ping_data) cs.CSClient().log(APP_NAME, 'Start ping: {}'.format(result)) done = False ping_results = [] while not done: time.sleep(1) ping_data = cs.CSClient().get('/control/ping').get('data') # Need to collect the results as it is cleared when read. result = ping_data.get('result') if result != '': lines = result.split('\n') ping_results.extend(lines) status = ping_data.get('status') if status == 'done' or status == 'error': done = True # Now that the ping is done, log the results for line in ping_results: cs.CSClient().log(APP_NAME, 'Ping Results: {}'.format(line)) except Exception as ex: cs.CSClient().log(APP_NAME, 'Exception occurred! ex: {}'.format(ex))
hosts = ['208.67.220.220', '208.67.222.222', '8.8.8.8'] handlers = [logging.StreamHandler()] if sys.platform == 'linux2': # on router also use the syslog handlers.append(logging.handlers.SysLogHandler(address='/dev/log')) logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)s: %(message)s', datefmt='%b %d %H:%M:%S', handlers=handlers) log = logging.getLogger('ping-sdk') cstore = cs.CSClient() def is_time_between(begin_time, end_time, check_time=None): # If check time is not given, default to current UTC time check_time = check_time or datetime.now(timezone( timedelta(hours=-6))).time() if begin_time < end_time: return check_time >= begin_time and check_time <= end_time else: # crosses midnight return check_time >= begin_time or check_time <= end_time ''' CHANGE TIME RANGE HERE. ADD/REMOVE "or" STATEMENTS FOR MULTIPLE RANGES '''
import cs from time import sleep APP_NAME = 'E300_RUN_DARK' while 1: for i in range(0, 18): cs.CSClient().put('/control/gpio/LED_BAR_{}'.format(i), 0) sleep(5)
# A try/except is wrapped around the imports to catch an # attempt to import a file or library that does not exist # in NCOS. Very useful during app development if one is # adding python libraries. try: import cs import sys import traceback import argparse from app_logging import AppLogger except Exception as ex: # Output DEBUG logs indicating what import failed. Use the logging in the # CSClient since app_logging may not be loaded. cs.CSClient().log('app_template.py', 'Import failure: {}'.format(ex)) cs.CSClient().log('app_template.py', 'Traceback: {}'.format(traceback.format_exc())) sys.exit(-1) # Create an AppLogger for logging to syslog in NCOS. log = AppLogger() # Add functionality to execute when the app is started def start_router_app(): try: log.debug('start_router_app()') except Exception as e: log.error(
import cs # Used for logging or anytime the app name is needed APP_NAME = 'ibr1700_obdII' # MQTT Client MQTT_CLIENT_ID = cs.CSClient().get('/config/system/system_id').get('data', '') MQTT_LOGGING = False # MQTT Server settings MQTT_SERVER = '127.0.0.1' MQTT_PORT = 1883 # OBDII MQTT Topics VEHICLE_SPEED = 'OBDII/PIDS/VEHICLE_SPEED' ENGINE_SPEED = 'OBDII/PIDS/ENGINE_SPEED' THROTTLE_POSITION = 'OBDII/PIDS/THROTTLE_POSITION' ODOMETER = 'OBDII/PIDS/ODOMETER' FUEL_LEVEL = 'OBDII/PIDS/FUEL_LEVEL' ENGINE_COOLANT_TEMPERATURE = 'OBDII/PIDS/ENGINE_COOLANT_TEMPERATURE' IGNITION_STATUS = 'OBDII/PIDS/IGNITION_STATUS' MIL_STATUS = 'OBDII/PIDS/MIL_STATUS' FUEL_RATE = 'OBDII/PIDS/FUEL_RATE' PTO_STATUS = 'OBDII/PIDS/PTO_STATUS' SEATBELT_FASTENED = 'OBDII/PIDS/SEATBELT_FASTENED' MISFIRE_MONITOR = 'OBDII/PIDS/MISFIRE_MONITOR' FUEL_SYSTEM_MONITOR = 'OBDII/PIDS/FUEL_SYSTEM_MONITOR' COMPREHENSIVE_COMPONENT_MONITOR = 'OBDII/PIDS/COMPREHENSIVE_COMPONENT_MONITOR' CATALYST_MONITOR = 'OBDII/PIDS/CATALYST_MONITOR' HEATED_CATALYST_MONITOR = 'OBDII/PIDS/HEATED_CATALYST_MONITOR'
import os import sys import traceback import settings import json import time import ssl import paho.mqtt.client as mqtt import paho.mqtt.publish as publish from app_logging import AppLogger from threading import Thread except Exception as e: # Output logs indicating what import failed. cs.CSClient().log('mqtt_app.py', 'Import failure: {}'.format(e)) cs.CSClient().log('mqtt_app.py', 'Traceback: {}'.format(traceback.format_exc())) sys.exit(-1) # Create an AppLogger for logging to syslog in NCOS. log = AppLogger() # The mqtt_client for publishing to the broker mqtt_client = None # Called when the broker responds to our connection request. def on_connect(client, userdata, flags, rc): log.debug("MQTT Client connection results: {}".format( mqtt.connack_string(rc)))
''' Outputs a 'Hello World!' log every 10 seconds. ''' import cs import time APP_NAME = 'hello_world' # The main entry point for hello_world.py if __name__ == "__main__": while True: cs.CSClient().log(APP_NAME, 'Hello World!') time.sleep(10)
def checkChange(): while True: config_1 = cs.CSClient().get('/config/') log.debug( 'Saving current config for comparison, check diff in 20 seconds') time.sleep(20) config_2 = cs.CSClient().get('/config/') # Check the configs, if there's a difference save the old config to backup.json if config_1 != config_2: log.debug( 'Difference detected, saving backup of old config to /var/media/config_backups/' ) # Try and create folder in /var/media/ for configs if it doesnt exist. try: if not os.path.exists('/var/media/config_backups/'): try: os.makedirs('/var/media/config_backups/') except OSError as e: if e.errno != errno.EEXIST: raise except Exception as e: log.error('Exception creating /var/media/config_backups!' 'Is a usb stick attached? exception: {}'.format(e)) # save backup try: # dump our config to a json file json_file = json.dumps(config_1) # convert it to a python dictionary py_dict = json.loads(json_file) # grab just the data tree from it data = py_dict["data"] # create our config file. its a nested list/dict right now config_file = [{ "fw_info": { "major_version": 6, "minor_version": 6, "patch_version": 4, "build_version": 0 }, "config": {} }, []] # create a default user to override the hashed password default_user = [{ 'group': 'admin', 'username': '******', 'password': '******' }] # set the config tree in it to equal our data tree config_file[0]["config"] = data # add the default user config_file[0]["config"]["system"]["users"] = default_user # check how many files we have in our folder n = len(os.listdir('/var/media/config_backups/')) os.chdir('/var/media/config_backups/') # dump to json, uncomment this if you want a .json instead of a .bin # with open('backup{}.json'.format(n), 'w') as f: # json.dump(config_file, f) # dump to bin with open('backup{}.bin'.format(n), 'wb') as f: f.write(zlib.compress(json.dumps(config_file).encode())) except Exception as e: log.error('Exception during save! exception: {}'.format(e)) raise else: log.debug('No difference detected in configuration')
webserver.py runs a basic python web server to serve up the rssi/sinr graphs page ''' try: import cs import sys import traceback from http.server import BaseHTTPRequestHandler from app_logging import AppLogger except Exception as ex: # Output DEBUG logs indicating what import failed. Use the logging in the # CSClient since app_logging may not be loaded. cs.CSClient().log('getsignal.py', 'Import failure: {}'.format(ex)) cs.CSClient().log('getsignal.py', 'Traceback: {}'.format(traceback.format_exc())) sys.exit(-1) # Create an AppLogger for logging to syslog in NCOS. log = AppLogger() log.debug('Started webserver.py') class GetHandler(BaseHTTPRequestHandler): def do_GET(self): # serve the index.html file if self.path == '/': try:
try: import cs import sys import traceback import argparse import os import time import json import zlib from app_logging import AppLogger except Exception as ex: cs.CSClient().log('cpu_usage.py', 'Import failure: {}'.format(ex)) cs.CSClient().log('cpu_usage.py', 'Traceback: {}'.format(traceback.format_exc())) sys.exit(-1) log = AppLogger() def start_app(): """ Add functionality to execute when the app is started. """ try: log.info('start_app()') create_folder() create_csv() get_usage() except Exception as e:
def get_usage(): while True: usb_status = cs.CSClient().get('/status/usb/connection/state') system_id = cs.CSClient().get('/config/system/system_id') memory = cs.CSClient().get('/status/system/memory') load_avg = cs.CSClient().get('/status/system/load_avg') cpu = cs.CSClient().get('/status/system/cpu') if 'mounted' in usb_status['data']: try: os.chdir('/var/media/usage_data/') with open('usage_info.csv', 'a') as f: # write row to csv. f.write( str(system_id['data']) + ',' + str(time.asctime()) + ',' + str(('{:,.0f}'.format(memory['data']['memavailable'] / float(1 << 20)) + " MB")) + ',' + str(('{:,.0f}'.format(memory['data']['memfree'] / float(1 << 20)) + " MB")) + ',' + str(('{:,.0f}'.format(memory['data']['memtotal'] / float(1 << 20)) + " MB")) + ',' + str(load_avg['data']['15min']) + ',' + str(load_avg['data']['1min']) + ',' + str(load_avg['data']['5min']) + ',' + str( round( float(cpu['data']['nice']) + float(cpu['data']['system']) + float(cpu['data']['user']) * float(100))) + '%\n') log.info('Saved CPU and Memory usage info to CSV.\ Sleeping for 15 seconds.') except Exception as e: log.error('Exception during save! exception: {}'.format(e)) time.sleep(15) else: log.info('USB Mount Status: ' + str(usb_status['data']) + '. Is your usb drive plugged in and formatted to fat32?') # print results to info log. log.info('Mem Available :' + str(('{:,.0f}'.format(memory['data']['memavailable'] / float(1 << 20)) + " MB")) + ',' + 'Mem Free :' + str(('{:,.0f}'.format(memory['data']['memfree'] / float(1 << 20)) + " MB")) + ',' + 'Mem Total :' + str(('{:,.0f}'.format(memory['data']['memtotal'] / float(1 << 20)) + " MB")) + ',' + 'CPU Load :' + str( round( float(cpu['data']['nice']) + float(cpu['data']['system']) + float(cpu['data']['user']) * float(100))) + '%\n') time.sleep(15)
return True def data_logger_to_mqtt_reader(): client = mqtt.Client("Datalogger2Mqtt", protocol=mqtt.MQTTv311) #create new instance try: client.connect(broker_address, port=9898) #connect to broker except ConnectionRefusedError: return try: with serial.Serial('/dev/ttyUSB0', 9600, timeout=1) as ser: while True: line = ser.readline() chunks = line.decode("utf-8").split(",") if chunks and has_t1t2(chunks): d1temp = parse_temp(chunks[0]) d2temp = parse_temp(chunks[1]) data = {"d1temp": d1temp, "d2temp": d2temp} client.publish("measurement/", json.dumps(data)) except Exception as e: logger.debug("Exception is %s" % str(e)) finally: client.disconnect() if __name__ == "__main__": client = cs.CSClient() if modem_state(client, state='connected', sim='mdm-e152d8b2'): data_logger_to_mqtt_reader()
try: # Connect to an FTP test server ftp = FTP('speedtest.tele2.net') # Login to the server reply = ftp.login('anonymous', 'anonymous') cs.CSClient().log(APP_NAME, 'FTP login reply: {}'.format(reply)) # Change to the proper directory for upload ftp.cwd('/upload/') # Open the file and upload it to the server fh = open(TEMP_FILE, 'rb') reply = ftp.storlines('STOR a.txt', fh) cs.CSClient().log(APP_NAME, 'FTP STOR reply: {}'.format(reply)) except Exception as e: cs.CSClient().log(APP_NAME, 'Exception occurred! exception: {}'.format(e)) raise finally: if fh: fh.close() if __name__ == "__main__": cs.CSClient().log(APP_NAME, 'ftp_client main...') send_ftp_file()
def action(command): client = cs.CSClient() value = {'action': command, 'routes': route_map, 'server': 'hotspotServer'} client.put(path, value)