diff --git a/backend-lab.py b/backend-lab.py new file mode 100644 index 0000000000000000000000000000000000000000..0fb3cd6566d58cfd5a58089ca14151bcf2b3c5b0 --- /dev/null +++ b/backend-lab.py @@ -0,0 +1,409 @@ +#!/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)] = "No Measurement received yet" + 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 ordered_nodes_dict(self): + + #this method returns an ordered list of the network's nodes + + return OrderedDict(sorted(self.network.nodes.items())) + + +################################################################################################################ +######################## 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.is_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): + + # this method resets the controller node + self.network.controller.hard_reset() + return "Hard Reset Done" + + + + + + + + +######################################################################################################################### +############## YOUR WORK STARTS HERE #################################################################################### +######################################################################################################################### +######################################################################################################################### + + + + + + + + + + def network_preview(self): + + #### COMPLETE THIS METHOD ############## + + return "this method returns a JSON that lists all network nodes and gives some informations about each one of them like the ID, neighbors, ..." + + + + +########################################################################################################################### +########## Configuration of multisensors ################################################################################## +########################################################################################################################### + + def set_sensor(self, Grp_interval, Grp_reports, Wakeup_interval): + + #### COMPLETE THIS METHOD ############## + + return "this method configures the nodes whit a specific configuration set by us" + + def network_nodesConfiguration(self): + + #### COMPLETE THIS METHOD ############## + + return "this method returns a html containing the configuration of the network's nodes" + + + def set_node_config_param(self, n, param, value): + + #### COMPLETE THIS METHOD ############## + + return "this method sets a configuration parameter to a precise value" + + + def get_node_config_param(self, n, param): + + #### COMPLETE THIS METHOD ############## + + return "this method gets the value of a configuration parameter" + + + + +####################################################################################################################### +############# SENSORS ################################################################################################# +####################################################################################################################### + + def get_sensors(self): + + #### COMPLETE THIS METHOD ############## + + return "this method returns the list of sensors" + + + def addNode(self): + + #### COMPLETE THIS METHOD ############## + + return "this method passes the controller to inclusion mode and gets it out of it after 20 seconds " + + + + + def removeNode(self): + + #### COMPLETE THIS METHOD ############## + + return "this method passes the controller to exclusion mode and gets it out of it after 20 seconds " + + + + def allMeasures(self, n): + + #### COMPLETE THIS METHOD ############## + + return "this method gets all the measures of a specific sensor node" + + + def temperature(self, n): + + #### HERE'S AN EXAMPLE OF A METHOD THAT GETS THE TEMPERATURE OF A SPECIFIC SENSOR NODE ############## + + for node in self.network.nodes.itervalues(): + if node.node_id == n and node.isReady and n != 1 : + values = node.get_values(0x31, "User", "All", True, False) + for value in values.itervalues(): + if value.label == "Temperature": + val = round(value.data,1) + 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): + + #### HERE'S AN EXAMPLE OF A METHOD THAT GETS THE HUMIDITY OF A SPECIFIC SENSOR NODE ############## + + for node in self.network.nodes.itervalues(): + if node.node_id == n and node.isReady and n != 1 : + values = node.get_values(0x31, "User", "All", True, False) + for value in values.itervalues(): + if value.label == "Relative Humidity": + val = int(value.data) + 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): + + #### COMPLETE THIS METHOD ############## + + return "this method gets the luminance measure of a specific sensor node" + + + def motion(self, n): + + #### COMPLETE THIS METHOD ############## + + return "this method this method gets the motion measure of a specific sensor node" + + + def battery(self, n): + + #### COMPLETE THIS METHOD ############## + + return "this method this method gets the battery measure of a specific sensor node" + + + def get_nodes(self): + + #### COMPLETE THIS METHOD ############## + + return "this method returns the list of nodes " + + + def set_node_location(self, n, value): + + #### COMPLETE THIS METHOD ############## + + return " this method sets the location of a specific sensor node" + + + def set_node_name(self, n, value): + + #### COMPLETE THIS METHOD ############## + + return "this method sets the name of a specific sensor node" + + + def get_node_location(self, n): + + #### COMPLETE THIS METHOD ############## + + return "this method gets the location of a specific sensor node" + + + def get_node_name(self, n): + + #### COMPLETE THIS METHOD ############## + + return "this method gets the name of a specific sensor node" + + + def get_neighbors(self, n): + + #### COMPLETE THIS METHOD ############## + + return "this method gets the list of neighbours of a specific sensor node" + + + +