diff --git a/README.md b/README.md index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fe4d578747e4d0ec17b6cabede7786462f347e79 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,5 @@ + +##### TO DO ###### + +- Change some methods to POST +- Classes for different devices diff --git a/backend-lab.py b/backend-lab.py index 0fb3cd6566d58cfd5a58089ca14151bcf2b3c5b0..0db8dc522f8937d5cab0d76642c9a5ff0219a613 100644 --- a/backend-lab.py +++ b/backend-lab.py @@ -43,7 +43,6 @@ class Backend(): ###### These dispatchers associate a method to a signal. the signals are generated by the library python-openzwave. ###### Once the signal is reveived. It's associated method is executed (see "_node_added" example below in "_network_started" method) dispatcher.connect(self._network_started, ZWaveNetwork.SIGNAL_NETWORK_STARTED) - dispatcher.connect(self._network_failed, ZWaveNetwork.SIGNAL_NETWORK_FAILED) dispatcher.connect(self._network_ready, ZWaveNetwork.SIGNAL_NETWORK_READY) ###### backend object attributes @@ -91,15 +90,7 @@ class Backend(): dispatcher.connect(self._node_added, ZWaveNetwork.SIGNAL_NODE_ADDED) dispatcher.connect(self._node_removed, ZWaveNetwork.SIGNAL_NODE_REMOVED) - dispatcher.connect(self._debug_node_naming, ZWaveNetwork.SIGNAL_NODE_NAMING) - dispatcher.connect(self._debug_node_new, ZWaveNetwork.SIGNAL_NODE_NEW) - dispatcher.connect(self._debug_node_protocol_info, ZWaveNetwork.SIGNAL_NODE_PROTOCOL_INFO) - - def _network_failed(self, network): - - # executed once the software representation has failed - print("network failed :(") def _network_ready(self, network): @@ -107,8 +98,6 @@ class Backend(): print("network : ready : %d nodes were found." % network.nodes_count) print("network : controller is : %s" % network.controller) -# dispatcher.connect(self._node_update, ZWaveNetwork.SIGNAL_NODE) - dispatcher.connect(self._node_event, ZWaveNetwork.SIGNAL_NODE_EVENT) dispatcher.connect(self._value_update, ZWaveNetwork.SIGNAL_VALUE) def _node_added(self, network, node): @@ -126,41 +115,6 @@ class Backend(): print('node removed: %s.' % node.name) self.node_removed = True - def _debug_node_naming(self, network, node): - - # executed when node is named - - print('node %s named: %s.' % (node.node_id, node.name)) - - def _debug_node_new(self, network, node_id): - - # executed when a new node is detected in the network - - print('New node is node: %s.' % node_id) - - def _debug_node_protocol_info(self, network, node): - - # executed when discovering the features of a new node - - print('node Protocol Info: %s.' % node.node_id) - - def _node_update(self, network, node): - - # executed when the nodes features are received : product_name, manufacturer_id, ... - print('node update: %s.' % node) - - def _node_event(self, network, node, signal, sender): - - # executed when the motion sensor's state is changed - - print('node event %s from node %s.' % (signal, node.node_id)) - if node.isReady and node.product_name == "MultiSensor 6": - values = node.get_values("All","User","All",True,"All") - for value in values.itervalues(): - if value.label == "Sensor": - motion_value = value.data - - print('motion sensor value is now %s' %motion_value) def _value_update(self, network, node, value): @@ -172,7 +126,7 @@ class Backend(): def ordered_nodes_dict(self): - #this method returns an ordered list of the network's nodes + #this method returns an ordered list of the network's nodes sorted by node's id return OrderedDict(sorted(self.network.nodes.items())) @@ -232,14 +186,9 @@ class Backend(): ######################################################################################################################### - - - - - - def network_preview(self): + def network_info(self): #### COMPLETE THIS METHOD ############## @@ -252,27 +201,27 @@ class Backend(): ########## Configuration of multisensors ################################################################################## ########################################################################################################################### - def set_sensor(self, Grp_interval, Grp_reports, Wakeup_interval): + def set_basic_nodes_configuration(self, Grp_interval, Grp_reports, Wakeup_interval): #### COMPLETE THIS METHOD ############## - return "this method configures the nodes whit a specific configuration set by us" + return "this method configures the nodes whit a specific configuration" - def network_nodesConfiguration(self): + def get_nodes_Configuration(self): #### COMPLETE THIS METHOD ############## - return "this method returns a html containing the configuration of the network's nodes" + return "this method returns a JSON that gives an overview of the network and it's nodes' configuration parameters (like the ID, Wake-up Interval, Group 1 Reports, Group 1 Interval ...)" - def set_node_config_param(self, n, param, value): + def set_node_config_parameter(self, n, param, value, size): #### COMPLETE THIS METHOD ############## - return "this method sets a configuration parameter to a precise value" + return "this method sets a configuration parameter to a given value" - def get_node_config_param(self, n, param): + def get_node_config_parameter(self, n, param): #### COMPLETE THIS METHOD ############## @@ -285,7 +234,7 @@ class Backend(): ############# SENSORS ################################################################################################# ####################################################################################################################### - def get_sensors(self): + def get_sensors_list(self): #### COMPLETE THIS METHOD ############## @@ -309,14 +258,14 @@ class Backend(): - def allMeasures(self, n): + def get_all_Measures(self, n): #### COMPLETE THIS METHOD ############## return "this method gets all the measures of a specific sensor node" - def temperature(self, n): + def get_temperature(self, n): #### HERE'S AN EXAMPLE OF A METHOD THAT GETS THE TEMPERATURE OF A SPECIFIC SENSOR NODE ############## @@ -329,7 +278,7 @@ class Backend(): return jsonify(controller = name, sensor = node.node_id, location = node.location, type = value.label.lower(), updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) return "Node not ready or wrong sensor node !" - def humidity(self, n): + def get_humidity(self, n): #### HERE'S AN EXAMPLE OF A METHOD THAT GETS THE HUMIDITY OF A SPECIFIC SENSOR NODE ############## @@ -342,28 +291,28 @@ class Backend(): return jsonify(controller = name, sensor = node.node_id, location = node.location, type = value.label.lower(), updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) return "Node not ready or wrong sensor node !" - def luminance(self, n): + def get_luminance(self, n): #### COMPLETE THIS METHOD ############## return "this method gets the luminance measure of a specific sensor node" - def motion(self, n): + def get_motion(self, n): #### COMPLETE THIS METHOD ############## return "this method this method gets the motion measure of a specific sensor node" - def battery(self, n): + def get_battery(self, n): #### COMPLETE THIS METHOD ############## return "this method this method gets the battery measure of a specific sensor node" - def get_nodes(self): + def get_nodes_list(self): #### COMPLETE THIS METHOD ############## @@ -398,7 +347,7 @@ class Backend(): return "this method gets the name of a specific sensor node" - def get_neighbors(self, n): + def get_neighbours_list(self, n): #### COMPLETE THIS METHOD ############## diff --git a/backend.py b/backend.py index bceb2db0400c8f6bbd4f0562d8bfcb5bcfbae409..1319e6746432500d8c37bdc5e44536910d1ae9bf 100644 --- a/backend.py +++ b/backend.py @@ -1,558 +1,512 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import sys -import time -import logging -import configpi - -from louie import dispatcher -from datetime import datetime -from flask import jsonify -from collections import OrderedDict - -from openzwave.network import ZWaveNetwork -from openzwave.option import ZWaveOption - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger('openzwave') - -started = False -name = configpi.name - -class Backend(): - - def __init__(self): - - ################### instanciation de l'objet backend ######################################################## - - - ###### options needed for python openzwave library like config files path, logging, - device = configpi.interface - options = ZWaveOption(device, config_path="/home/pi/git-repo/python-openzwave/openzwave/config", user_path=".", cmd_line="") - options.set_log_file("OZW.log") - options.set_append_log_file(False) - options.set_console_output(False) - options.set_save_log_level('Warning') - options.set_logging(True) - options.lock() - - # creation of the object network using the options entity already created - self.network = ZWaveNetwork(options, autostart=False) - - ###### These dispatchers associate a method to a signal. the signals are generated by the library python-openzwave. - ###### Once the signal is reveived. It's associated method is executed (see "_node_added" example below in "_network_started" method) - dispatcher.connect(self._network_started, ZWaveNetwork.SIGNAL_NETWORK_STARTED) - dispatcher.connect(self._network_failed, ZWaveNetwork.SIGNAL_NETWORK_FAILED) - dispatcher.connect(self._network_ready, ZWaveNetwork.SIGNAL_NETWORK_READY) - - ###### backend object attributes -# self.devices = OrderedDict() ### will contain the list of nodes in the network -# self.sensors = OrderedDict() ### will contain the list of sensors (only) in the network - self.node_added = False - self.node_removed = False - self.timestamps = {} ### will contain the time of the last values' update for each sensor - self.queryStages = { ### the diffrent stages that a node object gets through before being ready - "None" : 1, # Query process hasn't started for this node - "ProtocolInfo" : 2, # Retrieve protocol information - "Probe" : 3, # Ping device to see if alive - "WakeUp" : 4, # Start wake up process if a sleeping node - "ManufacturerSpecific1" : 5, # Retrieve manufacturer name and product ids if ProtocolInfo lets us - "NodeInfo" : 6, # Retrieve info about supported, controlled command classes - "SecurityReport" : 7, # Retrieve a list of Command Classes that require Security - "ManufacturerSpecific2" : 8, # Retrieve manufacturer name and product ids - "Versions" : 9, # Retrieve version information - "Instances" : 10, # Retrieve information about multiple command class instances - "Static" : 11, # Retrieve static information (doesn't change) - "Probe1" : 12, # Ping a device upon starting with configuration - "Associations" : 13, # Retrieve information about associations - "Neighbors" : 14, # Retrieve node neighbor list - "Session" : 15, # Retrieve session information (changes infrequently) - "Dynamic" : 16, # Retrieve dynamic information (changes frequently) - "Configuration" : 17, # Retrieve configurable parameter information (only done on request) - "Complete" : 18 # Query process is completed for this node - } - -####################################################################################################################### -############# NETWORK ################################################################################################# -####################################################################################################################### - - def _network_started(self, network): - - # executed once the software representation is started. the discovery of the network components has begun. they will be mapped into objects - - print("network started - %d nodes were found." % network.nodes_count) - - # these dispatchers associate a method to a signal. the signals are generated by the library python-openzwave. - # a signal may contain a number of parameters that are passed to the method associated to the signal. - # for exemple, the dispatcher below associates the signal "SIGNAL_NODE_ADDED" to the method "_node_added" that is implemented below (line 111). - # the signal "SIGNAL_NODE_ADDED" transports two parameters which are the objects network and node. - # once this signal is received, these two parameters will be passed to the method "_node_added" and the method will be executed. - - dispatcher.connect(self._node_added, ZWaveNetwork.SIGNAL_NODE_ADDED) - dispatcher.connect(self._node_removed, ZWaveNetwork.SIGNAL_NODE_REMOVED) - dispatcher.connect(self._debug_node_naming, ZWaveNetwork.SIGNAL_NODE_NAMING) - dispatcher.connect(self._debug_node_new, ZWaveNetwork.SIGNAL_NODE_NEW) - dispatcher.connect(self._debug_node_protocol_info, ZWaveNetwork.SIGNAL_NODE_PROTOCOL_INFO) - - def _network_failed(self, network): - - # executed once the software representation has failed - - print("network failed :(") - - def _network_ready(self, network): - - # executed once the software representation is ready - - print("network : ready : %d nodes were found." % network.nodes_count) - print("network : controller is : %s" % network.controller) -# dispatcher.connect(self._node_update, ZWaveNetwork.SIGNAL_NODE) - dispatcher.connect(self._node_event, ZWaveNetwork.SIGNAL_NODE_EVENT) - dispatcher.connect(self._value_update, ZWaveNetwork.SIGNAL_VALUE) - - def _node_added(self, network, node): - - # executed when node is added to the software representation. it's executed after the method "_debug_node_new" (see below) - - print('node added: %s.' % node.node_id) - self.timestamps["timestamp" + str(node.node_id)] = "None" - self.node_added = True - - def _node_removed(self, network, node): - - # executed when node is removed from the software representation - - print('node removed: %s.' % node.name) - self.node_removed = True - - def _debug_node_naming(self, network, node): - - # executed when node is named - - print('node %s named: %s.' % (node.node_id, node.name)) - - def _debug_node_new(self, network, node_id): - - # executed when a new node is detected in the network - - print('New node is node: %s.' % node_id) - - def _debug_node_protocol_info(self, network, node): - - # executed when discovering the features of a new node - - print('node Protocol Info: %s.' % node.node_id) - - def _node_update(self, network, node): - - # executed when the nodes features are received : product_name, manufacturer_id, ... - print('node update: %s.' % node) - - def _node_event(self, network, node, signal, sender): - - # executed when the motion sensor's state is changed - - print('node event %s from node %s.' % (signal, node.node_id)) - if node.isReady and node.product_name == "MultiSensor 6": - values = node.get_values("All","User","All",True,"All") - for value in values.itervalues(): - if value.label == "Sensor": - motion_value = value.data - - print('motion sensor value is now %s' %motion_value) - - def _value_update(self, network, node, value): - - # executed when a new value from a node is received - - print('Node %s: value update: %s is %s.' % (node.node_id, value.label, value.data)) - self.timestamps["timestamp" + str(node.node_id)] = int(time.time()) - - - def network_preview(self): - - # this method returns a JSON that lists all network nodes and gives some informations about each one of them like the ID, neighbors, ... - - result = {} - result ['Network Home ID'] = self.network.home_id_str - - for node in self.ordered_nodes_dict().itervalues(): -# result ['Node ID'] = "Node "+str(node.node_id) - info = {} - info ['Node ID'] = str(node.node_id) - info ['Node name'] = str(node.name) - info ['Node location'] = str(node.location) - info ['Product name'] = str(node.product_name) - info ['Is Ready'] = node.isReady - info ['Query Stage'] = node.getNodeQueryStage - info ['Query Stage (%)'] = str(self.queryStages[node.getNodeQueryStage]*100/18)+" %" - info ['Neighbours'] = ", ".join(str(s) for s in node.neighbors) - result ['Node '+str(node.node_id)] = info - return jsonify(result) - - -########################################################################################################################### -########## Configuration of multisensors ################################################################################## -########################################################################################################################### - - def set_sensor(self, Grp_interval, Grp_reports, Wakeup_interval): - - # this method configures the nodes whit a specific configuration set by us - - if self.network.state < self.network.STATE_STARTED: - return "Network Not Started" - for node in self.ordered_nodes_dict().itervalues(): - #print("Node %d" % node.node_id) - #print("Product name %s" % node.product_name) - - ########## A VOIR ########### - if node.isReady and node.product_name == "MultiSensor 6": - values = node.get_values("All","All","All",False,"All") - for value in values.itervalues(): - #print("%s %s %s" % (value.label, value.data, value.units)) - if value.label == "Group 1 Interval": - value.data = Grp_interval # Group 1 Reports sent every 240 seconds - if value.label == "Group 1 Reports": - value.data = Grp_reports # Group 1 Reports : Temperature, Luminance, Humidity and battery - if value.label == "Wake-up Interval": - value.data = Wakeup_interval # Node wakes up every 480 seconds to hear what the controller has to say (e.g configuration command) - #if value.label == "Group 2 Interval": - # value.data = 180 - #if value.label == "Group 2 Reports": - # value.data = 0 - #if value.label == "Group 3 Interval": - # value.data = 180 - #if value.label == "Group 3 Reports": - # value.data = 0 - return "Configuration of sensors send...<br/>Group 1 Interval = 240<br/>Group 1 Reports = 225<br/>Wake-up Interval = 480" - - def network_nodesConfiguration(self): - - # this method returns a html containing the configuration of the network's nodes - result = {} - result ['Network Home ID'] = self.network.home_id_str - for node in self.ordered_nodes_dict().itervalues(): - if node.isReady and node.node_id is not 1: - node.request_all_config_params() - values = node.get_values("All","All","All",False,"All") #Config + System pour Wake-up interval - nodeValues = {} - for value in values.itervalues(): - #nodeValues[cle] = {}... - #nodeValues[value.value_id]... - #nodeValues[valeur.label]... - nodeValues[int(value.index)] = value.data - print str(value.index)+" "+str(value.label)+" "+str(value.data)+" id:"+str(node.node_id) - info = {} - info ['Node ID'] = str(node.node_id) - info ['Wake-up Interval'] = str(nodeValues[0]) - info ['Enable Motion Sensor'] = str(nodeValues[4]) - info ['Group 1 Reports'] = str(nodeValues[101]) - info ['Group 1 Interval'] = str(nodeValues[111]) - info ['Group 2 Reports'] = str(nodeValues[102]) - info ['Group 2 Interval'] = str(nodeValues[112]) - info ['Group 3 Reports'] = str(nodeValues[103]) - info ['Group 3 Interval'] = str(nodeValues[113]) - - result ['Node '+str(node.node_id)] = info - return jsonify(result) - - - -################################################################################################################ -######################## START AND STOP THE SOFTWARE REPRESENTATION ############################################ -################################################################################################################ - - def start(self): - - # this method starts the software representation - global started - - - if started: - print "Already started" - return - started = True - self.network.start() - print "Z-Wave Network Starting..." - for i in range(0, 300): - if self.network.state == self.network.STATE_READY: - break - else: - time.sleep(1.0) - if not self.network.is_ready: - print "Network is not ready but continue anyway" - print "------------------------------------------------------------" - print "Nodes in network : %s" % self.network.nodes_count - print "------------------------------------------------------------" - - def stop(self): - - # this method stops the software representation - - global started - started = False - print "Stopping Z-Wave Network... " - self.network.stop() - - def reset(self): - #if self.network.nodes_count == 1: - self.network.controller.hard_reset() - return "Hard Reset Done" - #return "Cannot make Hard Reset while nodes included in network" - - - -####################################################################################################################### -############# SENSORS ################################################################################################# -####################################################################################################################### - - def get_sensors(self): - - # returns the list of sensors - sensors = OrderedDict() - for node in self.ordered_nodes_dict().iterkeys(): - if self.network.nodes[node].get_sensors(): - if self.network.nodes[node].isReady: - sensors[str(node)] = self.network.nodes[node].product_name - else: - sensors[str(node)] = "" - return sensors - - def addNode(self): - - # passes the controller to inclusion mode and gets it out of it after 20 seconds - - if self.network.state < self.network.STATE_STARTED: - return "Network not started" - self.node_added = False - result = self.network.controller.begin_command_add_device() - if result == True: - for x in range(1, 21): - time.sleep(1) - if x%2 == 0: - sys.stdout.write("+") - sys.stdout.flush() - if x == 20: - sys.stdout.write(" ! ") - sys.stdout.flush() - self.network.controller.cancel_command() - return "Too long to add a node ! Max. 20 seconds" - if self.node_added == True: - self.node_added = False - return "Added node success" - return "Added node failed \n" - - - def removeNode(self): - - # passes the controller to exclusion mode and gets it out of it after 20 seconds - - if self.network.state < self.network.STATE_STARTED: - return "Network not started" - self.node_removed = False - result = self.network.controller.begin_command_remove_device() - if result == True: - for x in range(1, 21): - time.sleep(1) - if x%2 == 0: - sys.stdout.write("-") - sys.stdout.flush() - if x == 20: - sys.stdout.write(" ! ") - sys.stdout.flush() - self.network.controller.cancel_command() - return "Too long to remove a node ! Max. 20 seconds" - if self.node_removed == True: - self.node_removed = False - return "Removed node success" - return "Removed node failed \n" - -########################### TO DO ################################################################################ - - def allMeasures(self, n): - for node in self.network.nodes.itervalues(): - if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: - values = node.get_values("All", "User", "All", True, False) - if len(node.location) < 3: - node.location = configpi.sensors[str(node.node_id)][:4] - measures = {} - measures['controller'] = name - measures['sensor'] = node.node_id - measures['location'] = str(node.location) - measures['updateTime'] = self.timestamps["timestamp"+str(node.node_id)] - for value in values.itervalues(): - if value.label == "Battery Level": - measures["battery"] = value.data - if value.label == "Sensor": - measures["motion"] = value.data - if value.label == "Temperature": - measures[value.label.lower()] = round(value.data, 1) - if value.label == "Relative Humidity": - measures[value.label.lower()[9:]] = int(value.data) - if value.label == "Luminance": - measures[value.label.lower()] = int(value.data) - return jsonify(measures) - return "Node not ready or wrong sensor node !" - - def temperature(self, n): - for node in self.network.nodes.itervalues(): - if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: - values = node.get_values(0x31, "User", "All", True, False) - for value in values.itervalues(): - if value.label == "Temperature": - val = round(value.data,1) - if len(node.location) < 3: - node.location = configpi.sensors[str(node.node_id)][:4] - return jsonify(controller = name, sensor = node.node_id, location = node.location, type = value.label.lower(), updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) - return "Node not ready or wrong sensor node !" - - def humidity(self, n): - for node in self.network.nodes.itervalues(): - if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: - values = node.get_values(0x31, "User", "All", True, False) - for value in values.itervalues(): - if value.label == "Relative Humidity": - val = int(value.data) - if len(node.location) < 3: - node.location = configpi.sensors[str(node.node_id)][:4] - return jsonify(controller = name, sensor = node.node_id, location = node.location, type = value.label.lower(), updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) - return "Node not ready or wrong sensor node !" - - def luminance(self, n): - for node in self.network.nodes.itervalues(): - if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: - values = node.get_values(0x31, "User", "All", True, False) - for value in values.itervalues(): - if value.label == "Luminance": - val = int(value.data) - if len(node.location) < 3: - node.location = configpi.sensors[str(node.node_id)][:4] - return jsonify(controller = name, sensor = node.node_id, location = node.location, type = value.label.lower(), updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) - return "Node not ready or wrong sensor node !" - - def motion(self, n): - for node in self.network.nodes.itervalues(): - if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: - values = node.get_values(0x30, "User", "All", True, False) - for value in values.itervalues(): - if value.label == "Sensor": - val = value.data - if len(node.location) < 3: - node.location = configpi.sensors[str(node.node_id)][:4] - return jsonify(controller = name, sensor = node.node_id, location = node.location, type = value.label.lower(), updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) - return "Node not ready or wrong sensor node !" - - def battery(self, n): - for node in self.network.nodes.itervalues(): - if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: - val = node.get_battery_level() - return jsonify(controller = name, sensor = node.node_id, location = node.location, type = "battery", updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) - return "Node not ready or wrong sensor node !" - - - -########################### END TO DO ###############################################################################################"" - - - - def set_node_config_param(self, n, param, value): - - # sets a configuration parameter to a precise value - - for node in self.network.nodes.itervalues(): - if node.node_id == n: - node.set_config_param(param, value) - return "Value for param " + str(param) + " is now " + str(value) - - def get_node_config_param(self, n, param): - - # gets the value of a configuration parameter - - for node in self.network.nodes.itervalues(): - if node.node_id == n: - node.get_config_param(param) - values = node.get_values("All","Config","All",False,"All") - for value in values.itervalues(): - if value.index == param: - return "Value for param " + str(param) + " is " + value.data - return "Get config param failed" - - """ - def get_values_for_multisensor_six(self): - for node in self.network.nodes.itervalues(): - if str(node.node_id) == str(6) and node.product_name == "Multi Sensor": - values = node.get_values(0x31, "User", "All", True, False) - return jsonify(values) - """ - -######################################################################################################################## -############# NODES ################################################################################################## -######################################################################################################################## -####### THESE METHODS ARE MADE FOR ALL TYPE OF NODES AND NOT ONLY SENSORS ############################################## -######################### result = {}############################################################################################### - - def ordered_nodes_dict(self): - - # returns an ordered list of the network's nodes - - return OrderedDict(sorted(self.network.nodes.items())) - - def get_nodes(self): - - # returns the list of nodes - nodes = OrderedDict() - for node in self.ordered_nodes_dict().iterkeys(): - #print("Node %d" % node.node_id) - #print("Product name %s" % node.product_name) - if self.network.nodes[node].isReady: - nodes[str(node)] = self.network.nodes[node].product_name - else: - nodes[str(node)] = "" - return nodes - - -############################### TO DO ################################################################################## - - def set_node_location(self, n, value): - for node in self.network.nodes.itervalues(): - if node.node_id == n : - temp = node.location - node.location = value - return "Node location updated from "+temp+" to "+value - return "Node not found" - - def set_node_name(self, n, value): - for node in self.network.nodes.itervalues(): - if node.node_id == n : - temp = node.name - node.name=value - configpi.sensors[str(node.node_id)] = value - return "Node name updated from "+temp+" to "+value - return "Node not found" - - def get_node_location(self, n): - for node in self.network.nodes.itervalues(): - if node.node_id == n : - temp = node.location - return "Node location is "+temp - return "Node not found" - - def get_node_name(self, n): - for node in self.network.nodes.itervalues(): - if node.node_id == n : - temp = node.name - return "Node name is "+temp - return "Node not found" - - def get_neighbors(self, n): - for node in self.network.nodes.itervalues(): - if node.node_id == n : - temp = ", ".join(str(s) for s in node.neighbors) - return " neighbors of the node "+str(n)+" by ID are : "+temp+" ." - return "Node not found" - - - - -########################## END TO DO ########################################################################################### +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import time +import logging +import configpi + +from louie import dispatcher +from datetime import datetime +from flask import jsonify +from collections import OrderedDict + +from openzwave.network import ZWaveNetwork +from openzwave.option import ZWaveOption + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger('openzwave') + +started = False +name = configpi.name + +class Backend(): + + def __init__(self): + + ################### instanciation de l'objet backend ######################################################## + + + ###### options needed for python openzwave library like config files path, logging, + device = configpi.interface + options = ZWaveOption(device, config_path="/home/pi/git-repo/python-openzwave/openzwave/config", user_path=".", cmd_line="") + options.set_log_file("OZW.log") + options.set_append_log_file(False) + options.set_console_output(False) + options.set_save_log_level('Warning') + options.set_logging(True) + options.lock() + + # creation of the object network using the options entity already created + self.network = ZWaveNetwork(options, autostart=False) + + ###### These dispatchers associate a method to a signal. the signals are generated by the library python-openzwave. + ###### Once the signal is received. It's associated method is executed (see "_node_added" example below in "_network_started" method) + dispatcher.connect(self._network_started, ZWaveNetwork.SIGNAL_NETWORK_STARTED) + dispatcher.connect(self._network_ready, ZWaveNetwork.SIGNAL_NETWORK_READY) + + ###### backend object attributes +# self.devices = OrderedDict() ### will contain the list of nodes in the network +# self.sensors = OrderedDict() ### will contain the list of sensors (only) in the network + self.node_added = False + self.node_removed = False + self.timestamps = {} ### will contain the time of the last values' update for each sensor + self.queryStages = { ### the diffrent stages that a node object gets through before being ready + "None" : 1, # Query process hasn't started for this node + "ProtocolInfo" : 2, # Retrieve protocol information + "Probe" : 3, # Ping device to see if alive + "WakeUp" : 4, # Start wake up process if a sleeping node + "ManufacturerSpecific1" : 5, # Retrieve manufacturer name and product ids if ProtocolInfo lets us + "NodeInfo" : 6, # Retrieve info about supported, controlled command classes + "SecurityReport" : 7, # Retrieve a list of Command Classes that require Security + "ManufacturerSpecific2" : 8, # Retrieve manufacturer name and product ids + "Versions" : 9, # Retrieve version information + "Instances" : 10, # Retrieve information about multiple command class instances + "Static" : 11, # Retrieve static information (doesn't change) + "Probe1" : 12, # Ping a device upon starting with configuration + "Associations" : 13, # Retrieve information about associations + "Neighbors" : 14, # Retrieve node neighbor list + "Session" : 15, # Retrieve session information (changes infrequently) + "Dynamic" : 16, # Retrieve dynamic information (changes frequently) + "Configuration" : 17, # Retrieve configurable parameter information (only done on request) + "Complete" : 18 # Query process is completed for this node + } + +####################################################################################################################### +############# LAUNCH ################################################################################################# +####################################################################################################################### + + def _network_started(self, network): + + # executed once the software representation is started. the discovery of the network components has begun. they will be mapped into objects + + print("network started - %d nodes were found." % network.nodes_count) + + # these dispatchers associate a method to a signal. the signals are generated by the library python-openzwave. + # a signal may contain a number of parameters that are passed to the method associated to the signal. + # for exemple, the dispatcher below associates the signal "SIGNAL_NODE_ADDED" to the method "_node_added" that is implemented below (line 111). + # the signal "SIGNAL_NODE_ADDED" transports two parameters which are the objects network and node. + # once this signal is received, these two parameters will be passed to the method "_node_added" and the method will be executed. + + dispatcher.connect(self._node_added, ZWaveNetwork.SIGNAL_NODE_ADDED) + dispatcher.connect(self._node_removed, ZWaveNetwork.SIGNAL_NODE_REMOVED) + + + + + def _network_ready(self, network): + + # executed once the software representation is ready + + print("network : ready : %d nodes were found." % network.nodes_count) + print("network : controller is : %s" % network.controller) + dispatcher.connect(self._value_update, ZWaveNetwork.SIGNAL_VALUE) + + def _node_added(self, network, node): + + # executed when node is added to the software representation. it's executed after the method "_debug_node_new" (see below) + + print('node added: %s.' % node.node_id) + self.timestamps["timestamp" + str(node.node_id)] = "None" + self.node_added = True + + def _node_removed(self, network, node): + + # executed when node is removed from the software representation + + print('node removed: %s.' % node.name) + self.node_removed = True + + + def _value_update(self, network, node, value): + + # executed when a new value from a node is received + + print('Node %s: value update: %s is %s.' % (node.node_id, value.label, value.data)) + self.timestamps["timestamp" + str(node.node_id)] = int(time.time()) + + +####################################################################################################################### +############# NETWORK ################################################################################################# +####################################################################################################################### + + + + def network_info(self): + + # this method returns a JSON that lists all network nodes and gives some informations about each one of them like the ID, neighbors, ... + + result = {} + result ['Network Home ID'] = self.network.home_id_str + + for node in self.ordered_nodes_dict().itervalues(): +# result ['Node ID'] = "Node "+str(node.node_id) + info = {} + info ['Node ID'] = str(node.node_id) + info ['Node name'] = str(node.name) + info ['Node location'] = str(node.location) + info ['Product name'] = str(node.product_name) + info ['Is Ready'] = node.isReady + info ['Query Stage'] = node.getNodeQueryStage + info ['Query Stage (%)'] = str(self.queryStages[node.getNodeQueryStage]*100/18)+" %" + info ['Neighbours'] = ", ".join(str(s) for s in node.neighbors) + result ['Node '+str(node.node_id)] = info + return jsonify(result) + + +########################################################################################################################### +########## Configuration of multisensors ################################################################################## +########################################################################################################################### + + def set_basic_nodes_configuration(self, Grp_interval, Grp_reports, Wakeup_interval): + + # this method configures the nodes whith a specific configuration + + if self.network.state < self.network.STATE_STARTED: + return "Network Not Started" + for node in self.ordered_nodes_dict().itervalues(): + #print("Node %d" % node.node_id) + #print("Product name %s" % node.product_name) + + if node.isReady and node.product_name == "MultiSensor 6": + values = node.get_values("All","All","All",False,"All") + for value in values.itervalues(): + + if value.label == "Group 1 Interval": + value.data = Grp_interval + if value.label == "Group 1 Reports": + value.data = Grp_reports # Group 1 Reports : Temperature, Luminance, Humidity and battery + if value.label == "Wake-up Interval": + value.data = Wakeup_interval + #if value.label == "Group 2 Interval": + # value.data = 180 + #if value.label == "Group 2 Reports": + # value.data = 0 + #if value.label == "Group 3 Interval": + # value.data = 180 + #if value.label == "Group 3 Reports": + # value.data = 0 + return "Configuration of sensors : Group 1 Interval = "+str(Grp_interval)+"; Group 1 Reports = "+str(Grp_reports)+"; Wake-on Interval = "+str(Wakeup_interval) + + def get_nodes_Configuration(self): + + # this method returns a JSON that gives an overview of the network and it's nodes' configuration parameters (like the ID, Wake-up Interval, Group 1 Reports, Group 1 Interval ...) + + + result = {} + result ['Network Home ID'] = self.network.home_id_str + for node in self.ordered_nodes_dict().itervalues(): + if node.isReady and node.node_id is not 1: + node.request_all_config_params() # Update of the software representation: retreive the last status of the Z-Wave network + values = node.get_values("All","All","All",False,"All") # Get Config + System values + nodeValues = {} + for value in values.itervalues(): + nodeValues[int(value.index)] = value.data + #print str(value.index)+" "+str(value.label)+" "+str(value.data)+" id:"+str(node.node_id) + info = {} + info ['Node ID'] = str(node.node_id) + info ['Wake-up Interval'] = str(nodeValues[0]) + info ['Enable Motion Sensor'] = str(nodeValues[4]) + info ['Group 1 Reports'] = str(nodeValues[101]) + info ['Group 1 Interval'] = str(nodeValues[111]) + info ['Group 2 Reports'] = str(nodeValues[102]) + info ['Group 2 Interval'] = str(nodeValues[112]) + info ['Group 3 Reports'] = str(nodeValues[103]) + info ['Group 3 Interval'] = str(nodeValues[113]) + + result ['Node '+str(node.node_id)] = info + return jsonify(result) + + + +################################################################################################################ +######################## START AND STOP THE SOFTWARE REPRESENTATION ############################################ +################################################################################################################ + + def start(self): + + # this method starts the software representation + global started + + + if started: + print "Already started" + return + started = True + self.network.start() + print "Z-Wave Network Starting..." + for i in range(0, 300): + if self.network.state == self.network.STATE_READY: + break + else: + time.sleep(1.0) + if not self.network.is_ready: + print "Network is not ready but continue anyway" + print "------------------------------------------------------------" + print "Nodes in network : %s" % self.network.nodes_count + print "------------------------------------------------------------" + + def stop(self): + + # this method stops the software representation + + global started + started = False + print "Stopping Z-Wave Network... " + self.network.stop() + + def reset(self): + if self.network.nodes_count == 1: + self.network.controller.hard_reset() + return "Hard Reset Done" + return "Cannot make Hard Reset while nodes included in network" + + + +####################################################################################################################### +############# SENSORS ################################################################################################# +####################################################################################################################### + + def get_sensors_list(self): + + # returns the list of sensors + sensors = OrderedDict() + for node in self.ordered_nodes_dict().iterkeys(): + if self.network.nodes[node].get_sensors(): + if self.network.nodes[node].isReady: + sensors[str(node)] = self.network.nodes[node].product_name + else: + sensors[str(node)] = "" + return jsonify(sensors) + + def addNode(self): + + # passes the controller to inclusion mode and gets it out of it after 20 seconds + + if self.network.state < self.network.STATE_STARTED: + return "Network not started" + self.node_added = False + result = self.network.controller.begin_command_add_device() + if result == True: + for x in range(1, 21): + time.sleep(1) + if x%2 == 0: + sys.stdout.write("+") + sys.stdout.flush() + if x == 20: + sys.stdout.write(" ! ") + sys.stdout.flush() + self.network.controller.cancel_command() + return "Too long to add a node ! Max. 20 seconds" + if self.node_added == True: + self.node_added = False + return "Added node success" + return "Added node failed \n" + + + def removeNode(self): + + # passes the controller to exclusion mode and gets it out of it after 20 seconds + + if self.network.state < self.network.STATE_STARTED: + return "Network not started" + self.node_removed = False + result = self.network.controller.begin_command_remove_device() + if result == True: + for x in range(1, 21): + time.sleep(1) + if x%2 == 0: + sys.stdout.write("-") + sys.stdout.flush() + if x == 20: + sys.stdout.write(" ! ") + sys.stdout.flush() + self.network.controller.cancel_command() + return "Too long to remove a node ! Max. 20 seconds" + if self.node_removed == True: + self.node_removed = False + return "Removed node success" + return "Removed node failed \n" + + + def get_all_Measures(self, n): + for node in self.network.nodes.itervalues(): + if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: + values = node.get_values("All", "User", "All", True, False) + # if len(node.location) < 3: + # node.location = configpi.sensors[str(node.node_id)][:4] + measures = {} + measures['controller'] = name + measures['sensor'] = node.node_id + measures['location'] = str(node.location) + measures['updateTime'] = self.timestamps["timestamp"+str(node.node_id)] + for value in values.itervalues(): + if value.label == "Battery Level": + measures["battery"] = value.data + if value.label == "Sensor": + measures["motion"] = value.data + if value.label == "Temperature": + measures[value.label.lower()] = round(value.data, 1) + if value.label == "Relative Humidity": + measures[value.label.lower()[9:]] = int(value.data) + if value.label == "Luminance": + measures[value.label.lower()] = int(value.data) + return jsonify(measures) + return "Node not ready or wrong sensor node !" + + + def get_temperature(self, n): + for node in self.network.nodes.itervalues(): + if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: + values = node.get_values(0x31, "User", "All", True, False) + for value in values.itervalues(): + if value.label == "Temperature": + val = round(value.data,1) + # if len(node.location) < 3: + # node.location = configpi.sensors[str(node.node_id)][:4] + return jsonify(controller = name, sensor = node.node_id, location = node.location, type = value.label.lower(), updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) + return "Node not ready or wrong sensor node !" + + def get_humidity(self, n): + for node in self.network.nodes.itervalues(): + if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: + values = node.get_values(0x31, "User", "All", True, False) + for value in values.itervalues(): + if value.label == "Relative Humidity": + val = int(value.data) + # if len(node.location) < 3: + # node.location = configpi.sensors[str(node.node_id)][:4] + return jsonify(controller = name, sensor = node.node_id, location = node.location, type = value.label.lower(), updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) + return "Node not ready or wrong sensor node !" + + def get_luminance(self, n): + for node in self.network.nodes.itervalues(): + if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: + values = node.get_values(0x31, "User", "All", True, False) + for value in values.itervalues(): + if value.label == "Luminance": + val = int(value.data) + # if len(node.location) < 3: + # node.location = configpi.sensors[str(node.node_id)][:4] + return jsonify(controller = name, sensor = node.node_id, location = node.location, type = value.label.lower(), updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) + return "Node not ready or wrong sensor node !" + + def get_motion(self, n): + for node in self.network.nodes.itervalues(): + if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: + values = node.get_values(0x30, "User", "All", True, False) + for value in values.itervalues(): + if value.label == "Sensor": + val = value.data + # if len(node.location) < 3: + # node.location = configpi.sensors[str(node.node_id)][:4] + return jsonify(controller = name, sensor = node.node_id, location = node.location, type = value.label.lower(), updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) + return "Node not ready or wrong sensor node !" + + def get_battery(self, n): + for node in self.network.nodes.itervalues(): + if node.node_id == n and node.isReady and n != 1 and "timestamp"+str(node.node_id) in self.timestamps: + val = node.get_battery_level() + return jsonify(controller = name, sensor = node.node_id, location = node.location, type = "battery", updateTime = self.timestamps["timestamp"+str(node.node_id)], value = val) + return "Node not ready or wrong sensor node !" + + + +########################### END TO DO ###############################################################################################"" + + + + def set_node_config_parameter(self, n, param, value, size): + + # sets a configuration parameter to a given value + + for node in self.network.nodes.itervalues(): + if node.node_id == n: + node.set_config_param(param, value, size) + return "Value for param " + str(param) + " is now " + str(value) + + def get_node_config_parameter(self, n, param): + + # gets the value of a configuration parameter + + for node in self.network.nodes.itervalues(): + if node.node_id == n: + node.request_config_param(param) + values = node.get_values("All","Config","All",False,"All") + for value in values.itervalues(): + if value.index == param: + return "Value for param " + str(param) + " is " + str(value.data) + return "Get config param failed" + + + +######################################################################################################################## +############# NODES ################################################################################################## +######################################################################################################################## +####### THESE METHODS ARE MADE FOR ALL TYPE OF NODES AND NOT ONLY SENSORS ############################################## +######################### result = {}############################################################################ + + def ordered_nodes_dict(self): + + # returns an ordered list of the network's nodes sorted by node's id + + return OrderedDict(sorted(self.network.nodes.items())) + + def get_nodes_list(self): + + # returns the list of nodes + nodes = OrderedDict() + for node in self.ordered_nodes_dict().iterkeys(): + #print("Node %d" % node.node_id) + #print("Product name %s" % node.product_name) + if self.network.nodes[node].isReady: + nodes[str(node)] = self.network.nodes[node].product_name + else: + nodes[str(node)] = "" + return jsonify(nodes) + + +############################### TO DO ################################################################################## + + def set_node_location(self, n, value): + for node in self.network.nodes.itervalues(): + if node.node_id == n : + temp = node.location + node.location = value + return "Node location updated from "+temp+" to "+value + return "Node not found" + + def set_node_name(self, n, value): + for node in self.network.nodes.itervalues(): + if node.node_id == n : + temp = node.name + node.name=value + configpi.sensors[str(node.node_id)] = value + return "Node name updated from "+temp+" to "+value + return "Node not found" + + def get_node_location(self, n): + for node in self.network.nodes.itervalues(): + if node.node_id == n : + temp = node.location + return "Node location is "+temp + return "Node not found" + + def get_node_name(self, n): + for node in self.network.nodes.itervalues(): + if node.node_id == n : + temp = node.name + return "Node name is "+temp + return "Node not found" + + def get_neighbours_list(self, n): + for node in self.network.nodes.itervalues(): + if node.node_id == n : + temp = ", ".join(str(s) for s in node.neighbors) + return " neighbors of the node "+str(n)+" by ID are : "+temp+" ." + return "Node not found" + + + + +########################## END TO DO ########################################################################################### diff --git a/flask-main.py b/flask-main.py old mode 100755 new mode 100644 index 6dbce47591ad540ec6fae6efdb576940c7cc9427..cb77551deee3843fcb95cb2ac2f6a021e64c4cca --- a/flask-main.py +++ b/flask-main.py @@ -27,16 +27,41 @@ def index(): ####################################################################################################################### """ -@api {get} /network/preview get_network_config -@apiName get_network_config +@api {get} /network/info get_network_info +@apiName get_network_info @apiGroup User -@apiSuccess {JSON} Table Network's Information. -@apiSuccessExample {json} Example data on success: + + +@apiSuccess {String} Network_Home_ID Network's ID + +@apiSuccess {JSON} Node_<Number> A JSON containing node's information (for each node). See below + +@apiSuccess {boolean} Is_Ready Node status + +@apiSuccess {String[]} Neighbours Node's neighbours + +@apiSuccess {Number} Node_ID Node's ID + +@apiSuccess {String} Node_location Node's location + +@apiSuccess {String} Node_name Node's name + +@apiSuccess {String} Product_name Node's product name + +@apiSuccess {String} Query_stage Query Stage + +@apiSuccess {Number} Query_stage_(%) Query Stage (percentage) + + + + + +@apiSuccessExample {json} Example of result in case of success: { - "Network Home ID": "0xe221b13f", - "Node 1": { +"Network Home ID": "0xe221b13f", +"Node 1": { "Is Ready": true, "Neighbours": "2", "Node ID": "1", @@ -46,7 +71,7 @@ def index(): "Query Stage": "Complete", "Query Stage (%)": "100 %" }, - "Node 2": { +"Node 2": { "Is Ready": true, "Neighbours": "1", "Node ID": "2", @@ -58,45 +83,73 @@ def index(): } } -@apiDescription Gets the configuration of the Z-Wave network in a JSON format + + +@apiDescription Gets information about the Z-Wave network in a JSON format """ -@app.route('/network/preview', strict_slashes=False) -def network_preview(): - return backend.network_preview() +@app.route('/network/info', strict_slashes=False) +def network_info(): + return backend.network_info() """ -@api {get} /network/configureNodes/<int:Group_interval>/<int:Group_reports>/<int:Wake-up_interval> set_nodes_configuration -@apiName set_nodes_configuration +@api {get} /network/configureNodes/<int:Group_interval>/<int:Group_reports>/<int:Wake-up_interval> set_sensor +@apiName set_sensor @apiGroup Admin -@apiParam {Number} Group_Interval Number of seconds between measurements transmissions -@apiParam {Number} Group_Reports a Number identifying measurements sent -@apiParam {Number} Wake-up_Interval Number of seconds between two node's wake-ups +@apiParam {Number} Group_Interval Number of seconds between two successive transfers of measures +@apiParam {Number} Group_Reports Number identifying measures sent by the sensor +@apiParam {Number} Wake-up_Interval Number of seconds between two node's wake-ups @apiSuccess {String} Message Description of the new nodes' configuration. -@apiDescription Configure all nodes of the network with a predefined configuration +@apiDescription Configure all nodes of the network with a predefined configuration. This methods configures only Group 1. All measurements (temperature, luminosity, motion and humidity) must be retrieved from the sensors after a given period of time (Group_Interval Number). """ @app.route('/network/configureNodes/<int:Grp_interval>/<int:Grp_reports>/<int:Wakeup_interval>', strict_slashes=False) def network_configureNodes(Grp_interval,Grp_reports,Wakeup_interval): # configure all the nodes of the network with a specific configuration - return backend.set_sensor(Grp_interval,Grp_reports,Wakeup_interval) + return backend.set_basic_nodes_configuration(Grp_interval,Grp_reports,Wakeup_interval) """ -@api {get} /network/nodesConfiguration Nodes configuration -@apiName Networks' Nodes configuration +@api {get} /network/get_nodes_Configuration get_nodes_Configuration +@apiName get_nodes_Configuration @apiGroup Admin -@apiSuccess {JSON} Table Describing of the nodes' configuration. -@apiSuccessExample {json} Example data on success: + + +@apiSuccess {String} Network_Home_ID Network's ID + +@apiSuccess {JSON} Node_<Number> A JSON containing node's informations that are detailed above (for each node except the controller) + +@apiSuccess {String} Enable_Motion_Sensor Motion sensor level + +@apiSuccess {Number} Group1_Interval Number of seconds between two Group1 measurements transmissions + +@apiSuccess {Number} Group1_Reports A number specifying measurements sent in this group (set to 241 to send all measurements on this group) + +@apiSuccess {Number} Group2_Interval Number of seconds between two Group2 measurements transmissions + +@apiSuccess {Number} Group2_Reports A number specifying measurements sent in this group (set to 0 because no measurements will be sent on this group) + +@apiSuccess {Number} Group3_Interval Number of seconds between two Group3 measurements transmissions + +@apiSuccess {Number} Group3_Reports A number specifying measurements sent in this group (set to 0 because no measurements will be sent on this group) + +@apiSuccess {Number} Node_ID Node's ID + +@apiSuccess {Number} Wake_up_Interval Number of seconds between two wake-ups + + + + +@apiSuccessExample {json} Example of result in case of success: { - "Network Home ID": "0xe221b13f", - "Node 2": { +"Network Home ID": "0xe221b13f", +"Node 2": { "Enable Motion Sensor": "Enabled level 5 (maximum sensitivity", "Group 1 Interval": "3600", "Group 1 Reports": "241", @@ -105,18 +158,17 @@ def network_configureNodes(Grp_interval,Grp_reports,Wakeup_interval): "Group 3 Interval": "3600", "Group 3 Reports": "0", "Node ID": "2", - "Wake-up Interval": "240" + "Wake-up Interval": "3600" } } - -@apiDescription Gets a html with the list of nodes and their configuration parameters +@apiDescription Gets the list of nodes and their configuration parameters in a JSON format. For each node, the system should provide the following information: Node ID, Motion sensor level, Wake_up_Interval and the report and interval of each group (there are three groups). See details in the documentation of the sensor: Aeon Labs MultiSensor 6 (Z-wave MultiSensor). """ -@app.route('/network/nodesConfiguration', strict_slashes=False) -def network_nodesConfiguration(): +@app.route('/network/get_nodes_Configuration', strict_slashes=False) +def get_nodes_Configuration(): # gets a html with the list of nodes with their config parameters - return backend.network_nodesConfiguration() ######## a revoir + return backend.get_nodes_Configuration() ######## a revoir @@ -164,13 +216,13 @@ def stop(): """ -@api {get} /network/reset Reset Network +@api {get} /network/reset reset @apiName Reset Network @apiGroup Admin @apiSuccess {String} Message Confirmation that the Z-Wave Network has been reset -@apiDescription Resets the network's controller +@apiDescription Resets the network's controller. Do not call this method before excluding (removing) the sensors connected to the controller. """ @@ -186,31 +238,27 @@ def reset(): ### THESE METHODS WERE SPECIALLY MADE FOR SENSOR NODES ################################################################# ####################################################################################################################### """ -@api {get} /sensors get_sensors -@apiName get_sensors +@api {get} /get_sensors_list get_sensors_list +@apiName get_sensors_list @apiGroup User -@apiSuccess {String[]} List List of all sensor nodes in the network +@apiSuccess {String[]} JSON List of all sensor nodes in the network i a JSON format @apiDescription Lists all sensors nodes in the network. The controller is excluded. """ -@app.route('/sensors', strict_slashes=False) -def sensors(): - # returns a list of all sensors in the network (only sensors) - sensors = backend.get_sensors() - if type(sensors) is str: - return sensors - sensors_list = "" - for key, val in sensors.items(): - sensors_list += str(key) + "=" + str(val) + "\n" - return Response(sensors_list, mimetype="text/plain") +@app.route('/get_sensors_list', strict_slashes=False) +def get_sensors_list(): + # returns a list of all sensors in the network in a JSON format(only sensors) + return backend.get_sensors_list() + + """ -@api {get} /sensors/<node_id>/all_measures get_all_measures_sensor +@api {get} /sensors/<node_id>/get_all_measures get_all_measures_sensor @apiName get_all_measures_sensor @apiGroup User @@ -226,7 +274,7 @@ def sensors(): @apiSuccess {String} motion motion state (true or false) @apiSuccess {Number} updateTime Timestamp at the measures' reception -@apiSuccessExample {json} Example data on success: +@apiSuccessExample {json} Example of result in case of success: { "battery": 100, "controller": "Pi lab1", @@ -238,18 +286,18 @@ def sensors(): "temperature": 30.0, "updateTime": 1454682568 } -@apiDescription Gets all reasures of a given sensor in a JSON format +@apiDescription Gets all measures of a given sensor, in a JSON format """ -@app.route('/sensors/<int:node>/all_measures', strict_slashes=False) +@app.route('/sensors/<int:node>/get_all_measures', strict_slashes=False) def get_all_measures(node): - return backend.allMeasures(node) + return backend.get_all_Measures(node) """ -@api {get} /sensors/<node_id>/temperature get_temperature +@api {get} /sensors/<node_id>/get_temperature get_temperature @apiName get_temperature @apiGroup User @@ -262,7 +310,7 @@ def get_all_measures(node): @apiSuccess {Number} value Temperature level (C) @apiSuccess {Number} updateTime Timestamp of the measure -@apiSuccessExample {json} Example data on success: +@apiSuccessExample {json} Example of result in case of success: { "controller": "Pi lab1", "location": "Room A401", @@ -275,14 +323,14 @@ def get_all_measures(node): """ -@app.route('/sensors/<int:node>/temperature', strict_slashes=False) +@app.route('/sensors/<int:node>/get_temperature', strict_slashes=False) def get_temperature(node): - return backend.temperature(node) + return backend.get_temperature(node) """ -@api {get} /sensors/<node_id>/humidity get_humidity +@api {get} /sensors/<node_id>/get_humidity get_humidity @apiName get_humidity @apiGroup User @@ -295,7 +343,7 @@ def get_temperature(node): @apiSuccess {Number} value humidity level (%) @apiSuccess {Number} updateTime Timestamp at the measures' reception -@apiSuccessExample {json} Example data on success: +@apiSuccessExample {json} Example of result in case of success: { "controller": "Pi lab1", "location": "Room A401", @@ -308,14 +356,14 @@ def get_temperature(node): """ -@app.route('/sensors/<int:node>/humidity', strict_slashes=False) +@app.route('/sensors/<int:node>/get_humidity', strict_slashes=False) def get_humidity(node): - return backend.humidity(node) + return backend.get_humidity(node) """ -@api {get} /sensors/<node_id>/luminance get_luminance +@api {get} /sensors/<node_id>/get_luminance get_luminance @apiName get_luminance @apiGroup User @@ -328,7 +376,7 @@ def get_humidity(node): @apiSuccess {Number} value luminance level (lux) @apiSuccess {Number} updateTime Timestamp at the measures' reception -@apiSuccessExample {json} Example data on success: +@apiSuccessExample {json} Example of result in case of success: { "controller": "Pi lab1", "location": "Room A401", @@ -341,14 +389,14 @@ def get_humidity(node): """ -@app.route('/sensors/<int:node>/luminance', strict_slashes=False) +@app.route('/sensors/<int:node>/get_luminance', strict_slashes=False) def get_luminance(node): - return backend.luminance(node) + return backend.get_luminance(node) """ -@api {get} /sensors/<node_id>/motion get_motion +@api {get} /sensors/<node_id>/get_motion get_motion @apiName get_motion @apiGroup User @@ -361,7 +409,7 @@ def get_luminance(node): @apiSuccess {Number} value motion state (boolean) @apiSuccess {Number} updateTime Timestamp at the measures' reception -@apiSuccessExample {json} Example data on success: +@apiSuccessExample {json} Example of result in case of success: { "controller": "Pi lab1", "location": "Room A401", @@ -374,22 +422,23 @@ def get_luminance(node): """ -@app.route('/sensors/<int:node>/motion', strict_slashes=False) +@app.route('/sensors/<int:node>/get_motion', strict_slashes=False) def get_motion(node): - return backend.motion(node) + return backend.get_motion(node) """ -@api {get} /sensors/<node_id>/set/<parameter>/to/<value> set_parameter +@api {get} /sensors/<node_id>/set_parameter/<parameter>/to/<value> set_parameter @apiName set_parameter @apiGroup Admin @apiParam {Number} node_id Sensor's unique ID -@apiParam {Number} parameter Parameter's unique index -@apiParam {Number} value new value of the parameter +@apiParam {Number} parameter Parameter's unique index (See sensor manual) +@apiParam {Number} value new value of the parameter +@apiParam {Number} size size of value of the parameter (See sensor manual) @apiSuccess {String} parameter parameter's new value @@ -397,15 +446,15 @@ def get_motion(node): """ -@app.route('/sensors/<int:node>/set/<int:param>/to/<int:value>', strict_slashes=False) -def set_config_param(node, param, value): +@app.route('/sensors/<int:node>/set_parameter/<int:param>/to/<int:value>/<int:size>', strict_slashes=False) +def set_config_param(node, param, value, size): # sets a config parameter of a sensor node - return backend.set_node_config_param(node, param, value) + return backend.set_node_config_parameter(node, param, value, size) """ -@api {get} /sensors/<node_id>/get/<parameter> get_parameter +@api {get} /sensors/<node_id>/get_parameter/<parameter> get_parameter @apiName get_parameter @apiGroup Admin @@ -418,10 +467,10 @@ def set_config_param(node, param, value): """ -@app.route('/sensors/<int:node>/get/<int:param>', strict_slashes=False) +@app.route('/sensors/<int:node>/get_parameter/<int:param>', strict_slashes=False) def get_config_param(node, param): # gets a config parameter of a sensor node - return backend.get_node_config_param(node, param) + return backend.get_node_config_parameter(node, param) @@ -432,26 +481,21 @@ def get_config_param(node, param): ######################################################################################################################## ### THESE METHODS ARE SPECIALLY MADE FOR ALL TYPES OF NODES ############################################################ """ -@api {get} /nodes get_nodes -@apiName get_nodes +@api {get} /get_nodes_list get_nodes_list +@apiName get_nodes_list @apiGroup User -@apiSuccess {String[]} List List of all nodes in the network +@apiSuccess {String[]} JSON List of all nodes in the network in a JSON format @apiDescription Lists all nodes in the network """ -@app.route('/nodes', strict_slashes=False) +@app.route('/get_nodes_list', strict_slashes=False) def nodes(): - # gets a list of all nodes in the network ans not only sensors - nodes = backend.get_nodes() - if type(nodes) is str: - return nodes - nodes_list = "" - for key, val in nodes.items(): - nodes_list += str(key) + "=" + str(val) + "\n" - return Response(nodes_list, mimetype="text/plain") + # gets a list of all nodes in the network in a JSON format + return backend.get_nodes_list() + @@ -462,7 +506,7 @@ def nodes(): @apiSuccess {String} Message Node added successfully -@apiDescription Adds Node to the network +@apiDescription Adds Node to the network. The node can not be a controller. """ @@ -493,7 +537,7 @@ def remove_node(): ############# TO DO #################################################################################################### """ -@api {get} /nodes/<node_id>/battery get_battery_level +@api {get} /nodes/<node_id>/get_battery get_battery_level @apiName get_battery_level @apiGroup User @@ -506,7 +550,7 @@ def remove_node(): @apiSuccess {Number} value battery level (%) @apiSuccess {Number} updateTime Timestamp at the measures' reception -@apiSuccessExample {json} Example data on success: +@apiSuccessExample {json} Example of result in case of success: { "controller": "Pi lab1", "location": "Room A401", @@ -515,18 +559,18 @@ def remove_node(): "updateTime": 1454684168, "value": 100 } -@apiDescription Gets the battery level of a sensor in a JSON format +@apiDescription Gets the battery level of a given sensor, in a JSON format """ -@app.route('/nodes/<int:node>/battery', strict_slashes=False) +@app.route('/nodes/<int:node>/get_battery', strict_slashes=False) def get_battery(node): - return backend.battery(node) + return backend.get_battery(node) """ -@api {get} /nodes/<node_id>/setLocationTo/<value> set_location +@api {get} /nodes/<node_id>/set_location/<value> set_location @apiName set_location @apiGroup Admin @@ -539,14 +583,14 @@ def get_battery(node): """ -@app.route('/nodes/<int:node>/setLocationTo/<value>', strict_slashes=False) +@app.route('/nodes/<int:node>/set_location/<value>', strict_slashes=False) def set_node_location(node, value): return backend.set_node_location(node, value) """ -@api {get} /nodes/<node_id>/setNameTo/<value> set_name +@api {get} /nodes/<node_id>/set_name/<value> set_name @apiName set_name @apiGroup User @@ -559,14 +603,14 @@ def set_node_location(node, value): """ -@app.route('/nodes/<int:node>/setNameTo/<value>', strict_slashes=False) +@app.route('/nodes/<int:node>/set_name/<value>', strict_slashes=False) def set_node_name(node, value): return backend.set_node_name(node, value) """ -@api {get} /nodes/<node_id>/getLocation get_location +@api {get} /nodes/<node_id>/get_location get_location @apiName get_location @apiGroup User @@ -578,14 +622,14 @@ def set_node_name(node, value): """ -@app.route('/nodes/<int:node>/getLocation', strict_slashes=False) +@app.route('/nodes/<int:node>/get_location', strict_slashes=False) def get_node_location(node): return backend.get_node_location(node) """ -@api {get} /nodes/<node_id>/getName get_name +@api {get} /nodes/<node_id>/get_name get_name @apiName get_name @apiGroup User @@ -597,14 +641,14 @@ def get_node_location(node): """ -@app.route('/nodes/<int:node>/getName', strict_slashes=False) +@app.route('/nodes/<int:node>/get_name', strict_slashes=False) def get_node_name(node): return backend.get_node_name(node) """ -@api {get} /nodes/<node_id>/neighbors get_neighbours +@api {get} /nodes/<node_id>/get_neighbours get_neighbours @apiName get_neighbours @apiGroup User @@ -616,9 +660,9 @@ def get_node_name(node): """ -@app.route('/nodes/<int:node>/neighbors', strict_slashes=False) -def get_neighbors(node): - return backend.get_neighbors(node) +@app.route('/nodes/<int:node>/get_neighbours', strict_slashes=False) +def get_neighbours_list(node): + return backend.get_neighbours_list(node) @@ -636,7 +680,7 @@ if __name__ == '__main__': file_handler.setFormatter(Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')) app.logger.addHandler(file_handler) - app.run(host='::', debug=False, use_reloader=False, port=5000) + app.run(host='::', debug=False, use_reloader=False) except KeyboardInterrupt: backend.stop()