# Copyright 2020 Espressif Systems (Shanghai) PTE LTD # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import json import re import os import time import requests import base64 from pathlib import Path try: from rmaker_lib import session, node, device, service,\ serverconfig, configmanager from rmaker_lib.exceptions import NetworkError, InvalidJSONError, SSLError,\ RequestTimeoutError from rmaker_lib.logger import log from rmaker_tools.rmaker_claim.claim import claim except ImportError as err: print("Failed to import ESP Rainmaker library. " + str(err)) raise err MAX_HTTP_CONNECTION_RETRIES = 5 def get_nodes(vars=None): """ List all nodes associated with the user. :param vars: No Parameters passed, defaults to `None` :type vars: dict | None :raises Exception: If there is an HTTP issue while getting nodes :return: None on Success :rtype: None """ try: s = session.Session() nodes = s.get_nodes() except Exception as get_nodes_err: log.error(get_nodes_err) else: if len(nodes.keys()) == 0: print('User is not associated with any nodes.') return for key in nodes.keys(): print(nodes[key].get_nodeid()) return def get_node_config(vars=None): """ Shows the configuration of the node. :param vars: `nodeid` as key - Node ID for the node, defaults to `None` :type vars: dict | None :raises Exception: If there is an HTTP issue while getting node config :return: None on Success :rtype: None """ try: n = node.Node(vars['nodeid'], session.Session()) node_config = n.get_node_config() except Exception as get_nodes_err: log.error(get_nodes_err) else: print(json.dumps(node_config, indent=4)) return node_config def get_node_status(vars=None): """ Shows the online/offline status of the node. :param vars: `nodeid` as key - Node ID for the node, defaults to `None` :type vars: dict | None :raises Exception: If there is an HTTP issue while getting node status :return: None on Success :rtype: None """ try: n = node.Node(vars['nodeid'], session.Session()) node_status = n.get_node_status() except Exception as get_node_status_err: log.error(get_node_status_err) else: print(json.dumps(node_status, indent=4)) return def set_params(vars=None): """ Set parameters of the node. :param vars: `nodeid` as key - Node ID for the node,\n `data` as key - JSON data containing parameters to be set `or`\n `filepath` as key - Path of the JSON file containing parameters to be set,\n defaults to `None` :type vars: dict | None :raises Exception: If there is an HTTP issue while setting params or JSON format issue in HTTP response :return: None on Success :rtype: None """ log.info('Setting params of the node with nodeid : ' + vars['nodeid']) if 'data' in vars: data = vars['data'] if 'filepath' in vars: filepath = vars['filepath'] if data is not None: log.debug('Setting node parameters using JSON data.') # Trimming white spaces except the ones between two strings data = re.sub(r"(? 0: try: # If session is expired then to initialise the new session # internet connection is required. if not curr_session: curr_session = session.Session() if not node_object: node_object = node.Node(node_id, curr_session) log.info("Creating service object...") if not service_obj: service_obj = service.Service() log.info("Checking service " + service.OTA_SERVICE_TYPE + " in node config...") print("Checking " + service.OTA_SERVICE_TYPE + " in node config...") if not service_config and not service_name: service_config, service_name = service_obj.verify_service_exists(node_object, service.OTA_SERVICE_TYPE) if not service_config: log.error(service.OTA_SERVICE_TYPE + " not found.") break log.info("Checking service " + service.OTA_SERVICE_TYPE + " in config...Success") log.debug("Service config received: " + str(service_config) + " Service name received: " + str(service_name)) print("Uploading OTA Firmware Image...This may take time...") log.info("Uploading OTA Firmware Image...This may take time...") if not status and not response: # Upload OTA Firwmare Image status, response = service_obj.upload_ota_image(node_object, img_name, base64_fw_img) if status: break except SSLError: log.error(SSLError()) break except (NetworkError, RequestTimeoutError) as conn_err: print(conn_err) log.warn(conn_err) except Exception as node_init_err: log.error(node_init_err) break time.sleep(5) retries -= 1 if retries: print("Retries left:", retries) log.info("Retries left: " + str(retries)) if node_object is None: log.error('Initialising new session...Failed\n') return if not status or not 'success' in status: print("\n") log.error("OTA Upgrade...Failed") log.debug('OTA Upgrade...Failed ' 'status: ' + str(status) + ' response: ' + str(response)) return log.info('Upload OTA Firmware Image Request...Success') log.debug("Upload OTA Firmware Image Request - Status: " + json.dumps(status) + " Response: " + json.dumps(response)) retries = MAX_HTTP_CONNECTION_RETRIES ota_start_status = None node_params = None service_read_params = None service_write_params = None ota_status = None while retries > 0: try: if 'image_url' in response: param_url_to_set = response["image_url"] if not service_read_params and not service_write_params: log.info("Getting service params from node config") service_read_params, service_write_params = service_obj.get_service_params(service_config) log.debug("Service params received with read properties: " + str(service_read_params) + " Service params received with write properties: " + str(service_write_params)) log.info("Getting node params...") if not node_params: node_params = node_object.get_node_params() log.debug("Node params received: " + json.dumps(node_params)) print("Setting the OTA URL parameter...") if not ota_start_status: ota_start_status = service_obj.start_ota(node_object, node_params, service_name, service_write_params, param_url_to_set) log.debug("OTA status received: " + str(ota_start_status)) if not ota_start_status: log.error("Failed to start OTA service...Exiting...") break print("Getting OTA Status...") if not ota_status: ota_status = service_obj.check_ota_status(node_object, service_name, service_read_params) break except SSLError: log.error(SSLError()) break except (NetworkError, RequestTimeoutError) as conn_err: print(conn_err) log.warn(conn_err) except Exception as node_init_err: log.error(node_init_err) break time.sleep(5) retries -= 1 if retries: print("Retries left:", retries) log.info("Retries left: " + str(retries)) if ota_status in [None, False]: log.error("OTA Upgrade...Failed") log.debug('OTA Upgrade...Failed ' 'ota_status: ' + str(ota_status)) except KeyError as key_err: log.error("Key Error: " + str(key_err)) except Exception as ota_err: log.error(ota_err) return