mirror of
https://github.com/eclipse/upm.git
synced 2025-03-15 04:57:30 +03:00
ozw: Initial implementation
This module was developed using the OpenZWave library (v1.3): http://www.openzwave.com/ It was developed using a collection of devices (switches and a multi-sensor) connected via an Aeon Z-Stick Gen5 USB dongle. It can be used to query (and, where appropriate, set) Values on Nodes connected to the ZWave network. Checks are made in src/ozw/CMakeLists.txt to ensure that the libopenzwave library is installed (via pkg-config). If not present, then neither the module, nor the example will be built. Signed-off-by: Jon Trulson <jtrulson@ics.com> Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
parent
287250b32d
commit
fd509c7d79
@ -157,6 +157,10 @@ add_executable (mcp9808-example mcp9808.cxx)
|
||||
add_executable (groveultrasonic-example groveultrasonic.cxx)
|
||||
add_executable (sx1276-lora-example sx1276-lora.cxx)
|
||||
add_executable (sx1276-fsk-example sx1276-fsk.cxx)
|
||||
# availability of libopenzwave is tested in src/ozw/CMakeLists.txt
|
||||
if (OPENZWAVE_FOUND)
|
||||
add_executable (ozw-example ozw.cxx)
|
||||
endif ()
|
||||
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/grove)
|
||||
@ -277,6 +281,10 @@ include_directories (${PROJECT_SOURCE_DIR}/src/dfrph)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/mcp9808)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/groveultrasonic)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/sx1276)
|
||||
if (OPENZWAVE_FOUND)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src/ozw)
|
||||
include_directories(${OPENZWAVE_INCLUDE_DIRS})
|
||||
endif ()
|
||||
|
||||
target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT})
|
||||
@ -435,3 +443,6 @@ target_link_libraries (mcp9808-example mcp9808 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (groveultrasonic-example groveultrasonic ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (sx1276-lora-example sx1276 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (sx1276-fsk-example sx1276 ${CMAKE_THREAD_LIBS_INIT})
|
||||
if (OPENZWAVE_FOUND)
|
||||
target_link_libraries (ozw-example ozw ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif ()
|
||||
|
141
examples/c++/ozw.cxx
Normal file
141
examples/c++/ozw.cxx
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "ozw.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
//! [Interesting]
|
||||
|
||||
string defaultDev = "/dev/ttyACM0";
|
||||
|
||||
// if an argument was specified, use it as the device instead
|
||||
if (argc > 1)
|
||||
defaultDev = string(argv[1]);
|
||||
|
||||
// Instantiate an OZW instance
|
||||
upm::OZW *sensor = new upm::OZW();
|
||||
|
||||
// The first thing to do is create options, then lock them when done.
|
||||
sensor->optionsCreate();
|
||||
sensor->optionsLock();
|
||||
|
||||
// Next, initialize it.
|
||||
cout << "Initializing, this may take awhile depending on your ZWave network"
|
||||
<< endl;
|
||||
|
||||
if (!sensor->init(defaultDev))
|
||||
{
|
||||
cerr << "Init failed." << endl;
|
||||
return 0;
|
||||
}
|
||||
cout << "Initialization complete" << endl;
|
||||
|
||||
cout << "Dumping nodes..." << endl;
|
||||
|
||||
sensor->dumpNodes();
|
||||
|
||||
// The following is example output of dumpNodes:
|
||||
//
|
||||
// Dumping nodes...
|
||||
// Node 1: Z-Stick Gen5
|
||||
// Node 2: Smart Switch 6
|
||||
// Index: 0, Type: bool, Label: Switch, Value: False
|
||||
// Index: 2, Type: float, Label: Energy, Value: 1.190 kWh
|
||||
// Index: 3, Type: float, Label: Previous Reading, Value: 1.190 kWh
|
||||
// Index: 4, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
// Index: 5, Type: float, Label: Power, Value: 0.000 W
|
||||
// Index: 6, Type: float, Label: Voltage, Value: 121.256 V
|
||||
// Index: 7, Type: float, Label: Current, Value: 0.000 A
|
||||
// Index: 8, Type: bool, Label: Exporting, Value: False
|
||||
// Index: 45, Type: list, Label: Day, Value: Friday
|
||||
// Index: 46, Type: byte, Label: Hour, Value: 5
|
||||
// Index: 47, Type: byte, Label: Minute, Value: 53
|
||||
// Node 3: Multi Sensor
|
||||
// Index: 0, Type: bool, Label: Sensor, Value: True
|
||||
// Index: 1, Type: float, Label: Temperature, Value: 72.8 F
|
||||
// Index: 2, Type: float, Label: Luminance, Value: 4 lux
|
||||
// Index: 3, Type: float, Label: Relative Humidity, Value: 22 %
|
||||
// Index: 17, Type: byte, Label: Battery Level, Value: 98 %
|
||||
// Node 5: Minimote
|
||||
// Node 6: Smart Energy Switch
|
||||
// Index: 0, Type: bool, Label: Switch, Value: False
|
||||
// Index: 2, Type: float, Label: Power, Value: 0.000 W
|
||||
// Index: 3, Type: float, Label: Energy, Value: 1.609 kWh
|
||||
// Index: 4, Type: float, Label: Previous Reading, Value: 1.609 kWh
|
||||
// Index: 5, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
// Index: 6, Type: float, Label: Power, Value: 0.000 W
|
||||
// Index: 7, Type: float, Label: Previous Reading, Value: 1.609 W
|
||||
// Index: 8, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
// Index: 9, Type: bool, Label: Exporting, Value: False
|
||||
// Node 7: Smart Energy Switch
|
||||
// Index: 0, Type: bool, Label: Switch, Value: False
|
||||
// Index: 2, Type: float, Label: Power, Value: 0.000 W
|
||||
// Index: 3, Type: float, Label: Energy, Value: 0.000 kWh
|
||||
// Index: 4, Type: float, Label: Previous Reading, Value: 0.000 kWh
|
||||
// Index: 5, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
// Index: 6, Type: float, Label: Power, Value: 0.000 W
|
||||
// Index: 7, Type: float, Label: Previous Reading, Value: 0.000 W
|
||||
// Index: 8, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
// Index: 9, Type: bool, Label: Exporting, Value: False
|
||||
//
|
||||
// So, with the above in mind:
|
||||
//
|
||||
// 1. Query the temperature on node 3 and print it out (as a
|
||||
// string), along with the units of measure:
|
||||
//
|
||||
// cout << "Temperature: " << sensor->getValueAsString(3, 1)
|
||||
// << " " << sensor->getValueUnits(3, 1) << endl;
|
||||
//
|
||||
// 2. query the same temperature as a float:
|
||||
//
|
||||
// float temperature = sensor->getValueAsFloat(3, 1);
|
||||
//
|
||||
// 3. Turn on the light plugged into the switch on Node 7, wait 5
|
||||
// seconds, then turn it back off again:
|
||||
//
|
||||
// cout << "Turning ON node 7" << endl;
|
||||
// sensor->setValueAsBool(7, 0, true);
|
||||
//
|
||||
// cout << "Sleeping for 5 seconds" << endl;
|
||||
// sleep(5);
|
||||
//
|
||||
// cout << "Turning OFF node 7" << endl;
|
||||
// sensor->setValueAsBool(7, 0, false);
|
||||
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
delete sensor;
|
||||
|
||||
return 0;
|
||||
}
|
128
examples/javascript/ozw.js
Normal file
128
examples/javascript/ozw.js
Normal file
@ -0,0 +1,128 @@
|
||||
/*jslint node:true, vars:true, bitwise:true, unparam:true */
|
||||
/*jshint unused:true */
|
||||
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
var sensorObj = require('jsupm_ozw');
|
||||
|
||||
|
||||
/************** Main code **************/
|
||||
// Instantiate an OZW instance
|
||||
var sensor = new sensorObj.OZW();
|
||||
|
||||
var defaultDev = "/dev/ttyACM0";
|
||||
|
||||
// if an argument was specified, use it as the device instead
|
||||
if (process.argv.length > 2)
|
||||
{
|
||||
defaultDev = process.argv[2];
|
||||
}
|
||||
|
||||
// The first thing to do is create options, then lock them when done.
|
||||
sensor.optionsCreate();
|
||||
sensor.optionsLock();
|
||||
|
||||
// Next, initialize it.
|
||||
console.log("Initializing, this may take awhile depending on your ZWave network");
|
||||
|
||||
if (!sensor.init(defaultDev))
|
||||
{
|
||||
console.log("Init failed.");
|
||||
process.exit(0);
|
||||
}
|
||||
console.log("Initialization complete");
|
||||
|
||||
console.log("Dumping nodes...");
|
||||
|
||||
sensor.dumpNodes();
|
||||
|
||||
// The following is example output of dumpNodes:
|
||||
//
|
||||
// Dumping nodes...
|
||||
// Node 1: Z-Stick Gen5
|
||||
// Node 2: Smart Switch 6
|
||||
// Index: 0, Type: bool, Label: Switch, Value: False
|
||||
// Index: 2, Type: float, Label: Energy, Value: 1.190 kWh
|
||||
// Index: 3, Type: float, Label: Previous Reading, Value: 1.190 kWh
|
||||
// Index: 4, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
// Index: 5, Type: float, Label: Power, Value: 0.000 W
|
||||
// Index: 6, Type: float, Label: Voltage, Value: 121.256 V
|
||||
// Index: 7, Type: float, Label: Current, Value: 0.000 A
|
||||
// Index: 8, Type: bool, Label: Exporting, Value: False
|
||||
// Index: 45, Type: list, Label: Day, Value: Friday
|
||||
// Index: 46, Type: byte, Label: Hour, Value: 5
|
||||
// Index: 47, Type: byte, Label: Minute, Value: 53
|
||||
// Node 3: Multi Sensor
|
||||
// Index: 0, Type: bool, Label: Sensor, Value: True
|
||||
// Index: 1, Type: float, Label: Temperature, Value: 72.8 F
|
||||
// Index: 2, Type: float, Label: Luminance, Value: 4 lux
|
||||
// Index: 3, Type: float, Label: Relative Humidity, Value: 22 %
|
||||
// Index: 17, Type: byte, Label: Battery Level, Value: 98 %
|
||||
// Node 5: Minimote
|
||||
// Node 6: Smart Energy Switch
|
||||
// Index: 0, Type: bool, Label: Switch, Value: False
|
||||
// Index: 2, Type: float, Label: Power, Value: 0.000 W
|
||||
// Index: 3, Type: float, Label: Energy, Value: 1.609 kWh
|
||||
// Index: 4, Type: float, Label: Previous Reading, Value: 1.609 kWh
|
||||
// Index: 5, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
// Index: 6, Type: float, Label: Power, Value: 0.000 W
|
||||
// Index: 7, Type: float, Label: Previous Reading, Value: 1.609 W
|
||||
// Index: 8, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
// Index: 9, Type: bool, Label: Exporting, Value: False
|
||||
// Node 7: Smart Energy Switch
|
||||
// Index: 0, Type: bool, Label: Switch, Value: False
|
||||
// Index: 2, Type: float, Label: Power, Value: 0.000 W
|
||||
// Index: 3, Type: float, Label: Energy, Value: 0.000 kWh
|
||||
// Index: 4, Type: float, Label: Previous Reading, Value: 0.000 kWh
|
||||
// Index: 5, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
// Index: 6, Type: float, Label: Power, Value: 0.000 W
|
||||
// Index: 7, Type: float, Label: Previous Reading, Value: 0.000 W
|
||||
// Index: 8, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
// Index: 9, Type: bool, Label: Exporting, Value: False
|
||||
//
|
||||
// So, with the above in mind:
|
||||
//
|
||||
// 1. Query the temperature on node 3 and print it out (as a
|
||||
// string), along with the units of measure:
|
||||
//
|
||||
// console.log("Temperature: " + sensor.getValueAsString(3, 1) +
|
||||
// " " + sensor.getValueUnits(3, 1));
|
||||
//
|
||||
// 2. query the same temperature as a float:
|
||||
//
|
||||
// var temperature = sensor.getValueAsFloat(3, 1);
|
||||
//
|
||||
// 3. Turn on the light plugged into the switch on Node 7
|
||||
//
|
||||
// console.log("Turning ON node 7");
|
||||
// sensor.setValueAsBool(7, 0, true);
|
||||
//
|
||||
|
||||
sensor = null;
|
||||
sensorObj.cleanUp();
|
||||
sensorObj = null;
|
||||
console.log("Exiting...");
|
||||
process.exit(0);
|
126
examples/python/ozw.py
Normal file
126
examples/python/ozw.py
Normal file
@ -0,0 +1,126 @@
|
||||
#!/usr/bin/python
|
||||
# Author: Jon Trulson <jtrulson@ics.com>
|
||||
# Copyright (c) 2015 Intel Corporation.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import time, sys, signal, atexit
|
||||
import pyupm_ozw as sensorObj
|
||||
|
||||
# Instantiate an OZW instance
|
||||
sensor = sensorObj.OZW()
|
||||
|
||||
# This function lets you run code on exit
|
||||
def exitHandler():
|
||||
print "Exiting"
|
||||
sys.exit(0)
|
||||
|
||||
# Register exit handlers
|
||||
atexit.register(exitHandler)
|
||||
|
||||
defaultDev = "/dev/ttyACM0"
|
||||
if (len(sys.argv) > 1):
|
||||
defaultDev = sys.argv[1]
|
||||
|
||||
# The first thing to do is create options, then lock them when done.
|
||||
sensor.optionsCreate()
|
||||
sensor.optionsLock()
|
||||
|
||||
# Next, initialize it.
|
||||
print "Initializing, this may take awhile depending on your ZWave network"
|
||||
|
||||
if (not sensor.init(defaultDev)):
|
||||
print "Init failed."
|
||||
sys.exit(1)
|
||||
|
||||
print "Initialization complete"
|
||||
|
||||
print "Dumping nodes..."
|
||||
|
||||
sensor.dumpNodes()
|
||||
|
||||
# The following is example output of dumpNodes:
|
||||
#
|
||||
# Dumping nodes...
|
||||
# Node 1: Z-Stick Gen5
|
||||
# Node 2: Smart Switch 6
|
||||
# Index: 0, Type: bool, Label: Switch, Value: False
|
||||
# Index: 2, Type: float, Label: Energy, Value: 1.190 kWh
|
||||
# Index: 3, Type: float, Label: Previous Reading, Value: 1.190 kWh
|
||||
# Index: 4, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
# Index: 5, Type: float, Label: Power, Value: 0.000 W
|
||||
# Index: 6, Type: float, Label: Voltage, Value: 121.256 V
|
||||
# Index: 7, Type: float, Label: Current, Value: 0.000 A
|
||||
# Index: 8, Type: bool, Label: Exporting, Value: False
|
||||
# Index: 45, Type: list, Label: Day, Value: Friday
|
||||
# Index: 46, Type: byte, Label: Hour, Value: 5
|
||||
# Index: 47, Type: byte, Label: Minute, Value: 53
|
||||
# Node 3: Multi Sensor
|
||||
# Index: 0, Type: bool, Label: Sensor, Value: True
|
||||
# Index: 1, Type: float, Label: Temperature, Value: 72.8 F
|
||||
# Index: 2, Type: float, Label: Luminance, Value: 4 lux
|
||||
# Index: 3, Type: float, Label: Relative Humidity, Value: 22 %
|
||||
# Index: 17, Type: byte, Label: Battery Level, Value: 98 %
|
||||
# Node 5: Minimote
|
||||
# Node 6: Smart Energy Switch
|
||||
# Index: 0, Type: bool, Label: Switch, Value: False
|
||||
# Index: 2, Type: float, Label: Power, Value: 0.000 W
|
||||
# Index: 3, Type: float, Label: Energy, Value: 1.609 kWh
|
||||
# Index: 4, Type: float, Label: Previous Reading, Value: 1.609 kWh
|
||||
# Index: 5, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
# Index: 6, Type: float, Label: Power, Value: 0.000 W
|
||||
# Index: 7, Type: float, Label: Previous Reading, Value: 1.609 W
|
||||
# Index: 8, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
# Index: 9, Type: bool, Label: Exporting, Value: False
|
||||
# Node 7: Smart Energy Switch
|
||||
# Index: 0, Type: bool, Label: Switch, Value: False
|
||||
# Index: 2, Type: float, Label: Power, Value: 0.000 W
|
||||
# Index: 3, Type: float, Label: Energy, Value: 0.000 kWh
|
||||
# Index: 4, Type: float, Label: Previous Reading, Value: 0.000 kWh
|
||||
# Index: 5, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
# Index: 6, Type: float, Label: Power, Value: 0.000 W
|
||||
# Index: 7, Type: float, Label: Previous Reading, Value: 0.000 W
|
||||
# Index: 8, Type: int32, Label: Interval, Value: 1521 seconds
|
||||
# Index: 9, Type: bool, Label: Exporting, Value: False
|
||||
#
|
||||
# So, with the above in mind:
|
||||
#
|
||||
# 1. Query the temperature on node 3 and print it out (as a
|
||||
# string), along with the units of measure:
|
||||
#
|
||||
# print "Temperature:", sensor.getValueAsString(3, 1),
|
||||
# sensor->getValueUnits(3, 1)
|
||||
#
|
||||
# 2. query the same temperature as a float:
|
||||
#
|
||||
# temperature = sensor.getValueAsFloat(3, 1)
|
||||
#
|
||||
# 3. Turn on the light plugged into the switch on Node 7, wait 5
|
||||
# seconds, then turn it back off again:
|
||||
#
|
||||
# print "Turning ON node 7"
|
||||
# sensor.setValueAsBool(7, 0, true)
|
||||
#
|
||||
# print "Sleeping for 5 seconds";
|
||||
# time.sleep(5)
|
||||
#
|
||||
# print "Turning OFF node 7"
|
||||
# sensor.setValueAsBool(7, 0, false);
|
||||
|
21
src/ozw/CMakeLists.txt
Normal file
21
src/ozw/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
set (libname "ozw")
|
||||
set (libdescription "upm module for the OpenZWave library interface")
|
||||
set (module_src ${libname}.cxx zwNode.cxx)
|
||||
set (module_h ${libname}.h)
|
||||
|
||||
pkg_search_module(OPENZWAVE libopenzwave)
|
||||
if (OPENZWAVE_FOUND)
|
||||
set (reqlibname "libopenzwave")
|
||||
include_directories(${OPENZWAVE_INCLUDE_DIRS})
|
||||
upm_module_init()
|
||||
add_dependencies(${libname} ${OPENZWAVE_LIBRARIES})
|
||||
target_link_libraries(${libname} ${OPENZWAVE_LIBRARIES})
|
||||
if (BUILDSWIG)
|
||||
if (BUILDSWIGNODE)
|
||||
swig_link_libraries (jsupm_${libname} ${OPENZWAVE_LIBRARIES} ${MRAA_LIBRARIES} ${NODE_LIBRARIES})
|
||||
endif()
|
||||
if (BUILDSWIGPYTHON)
|
||||
swig_link_libraries (pyupm_${libname} ${OPENZWAVE_LIBRARIES} ${PYTHON_LIBRARIES} ${MRAA_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
endif ()
|
12
src/ozw/javaupm_ozw.i
Normal file
12
src/ozw/javaupm_ozw.i
Normal file
@ -0,0 +1,12 @@
|
||||
%module javaupm_ozw
|
||||
%include "../upm.i"
|
||||
%include "cpointer.i"
|
||||
%include "typemaps.i"
|
||||
%include "arrays_java.i";
|
||||
%include "../java_buffer.i"
|
||||
|
||||
%{
|
||||
#include "ozw.h"
|
||||
%}
|
||||
|
||||
%include "ozw.h"
|
12
src/ozw/jsupm_ozw.i
Normal file
12
src/ozw/jsupm_ozw.i
Normal file
@ -0,0 +1,12 @@
|
||||
%module jsupm_ozw
|
||||
%include "../upm.i"
|
||||
%include "cpointer.i"
|
||||
%include "stdint.i"
|
||||
|
||||
%pointer_functions(float, floatp);
|
||||
|
||||
%include "ozw.h"
|
||||
%{
|
||||
#include "ozw.h"
|
||||
%}
|
||||
|
909
src/ozw/ozw.cxx
Normal file
909
src/ozw/ozw.cxx
Normal file
@ -0,0 +1,909 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "platform/Log.h"
|
||||
|
||||
#include "zwNode.h"
|
||||
|
||||
#include "ozw.h"
|
||||
|
||||
using namespace upm;
|
||||
using namespace std;
|
||||
using namespace OpenZWave;
|
||||
|
||||
|
||||
OZW::OZW()
|
||||
{
|
||||
m_mgrCreated = false;
|
||||
m_driverFailed = false;
|
||||
m_homeId = 0;
|
||||
|
||||
pthread_mutexattr_t mutexAttrib;
|
||||
pthread_mutexattr_init(&mutexAttrib);
|
||||
pthread_mutexattr_settype(&mutexAttrib, PTHREAD_MUTEX_RECURSIVE);
|
||||
|
||||
if (pthread_mutex_init(&m_nodeLock, &mutexAttrib))
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": pthread_mutex_init(nodeLock) failed");
|
||||
}
|
||||
|
||||
pthread_mutexattr_destroy(&mutexAttrib);
|
||||
|
||||
if (pthread_mutex_init(&m_initLock, NULL))
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": pthread_mutex_init(initLock) failed");
|
||||
}
|
||||
|
||||
// initialize our init conditional
|
||||
if (pthread_cond_init(&m_initCond, NULL))
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": pthread_cond_init() failed");
|
||||
}
|
||||
|
||||
setDebug(false);
|
||||
}
|
||||
|
||||
OZW::~OZW()
|
||||
{
|
||||
if (m_mgrCreated)
|
||||
{
|
||||
// remove the driver
|
||||
if (m_driverIsHID)
|
||||
Manager::Get()->RemoveDriver("HID");
|
||||
else
|
||||
Manager::Get()->RemoveDriver(m_devicePath);
|
||||
|
||||
// remove the notification handler
|
||||
Manager::Get()->RemoveWatcher(notificationHandler, this);
|
||||
|
||||
// now destroy Manager and Options. Options must be destroyed
|
||||
// after the Manager is destroyed.
|
||||
Manager::Destroy();
|
||||
Options::Destroy();
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(&m_nodeLock);
|
||||
pthread_mutex_destroy(&m_initLock);
|
||||
pthread_cond_destroy(&m_initCond);
|
||||
|
||||
// delete any nodes. This should be safe after deleting the node
|
||||
// mutex since the handler is no longer registered.
|
||||
for (zwNodeMap_t::iterator it = m_zwNodeMap.begin();
|
||||
it != m_zwNodeMap.end(); ++it)
|
||||
{
|
||||
// delete the zwNode pointer
|
||||
delete (*it).second;
|
||||
}
|
||||
// empty the map
|
||||
m_zwNodeMap.clear();
|
||||
}
|
||||
|
||||
void OZW::optionsCreate(std::string configPath,
|
||||
std::string userConfigDir,
|
||||
std::string cmdLine)
|
||||
{
|
||||
Options::Create(configPath, userConfigDir, cmdLine);
|
||||
}
|
||||
|
||||
void OZW::optionAddInt(std::string name, int val)
|
||||
{
|
||||
Options::Get()->AddOptionInt(name, val);
|
||||
}
|
||||
|
||||
void OZW::optionAddBool(std::string name, bool val)
|
||||
{
|
||||
Options::Get()->AddOptionBool(name, val);
|
||||
}
|
||||
|
||||
void OZW::optionAddString(std::string name, std::string val, bool append)
|
||||
{
|
||||
Options::Get()->AddOptionString(name, val, append);
|
||||
}
|
||||
|
||||
void OZW::optionsLock()
|
||||
{
|
||||
// lock the options if not already locked
|
||||
if (!Options::Get()->AreLocked())
|
||||
Options::Get()->Lock();
|
||||
}
|
||||
|
||||
bool OZW::init(string devicePath, bool isHID)
|
||||
{
|
||||
// make sure options are locked
|
||||
optionsLock();
|
||||
|
||||
pthread_mutex_lock(&m_initLock);
|
||||
|
||||
// the fun begins
|
||||
Manager::Create();
|
||||
|
||||
// add our event handler
|
||||
Manager::Get()->AddWatcher(notificationHandler, this);
|
||||
|
||||
// now add the driver
|
||||
m_devicePath = devicePath;
|
||||
if (isHID)
|
||||
{
|
||||
m_driverIsHID = true;
|
||||
Manager::Get()->AddDriver("HID",
|
||||
Driver::ControllerInterface_Hid);
|
||||
}
|
||||
else
|
||||
Manager::Get()->AddDriver(devicePath);
|
||||
|
||||
m_mgrCreated = true;
|
||||
|
||||
// now we block here waiting for the driver to get far enough along
|
||||
// (or fail) to proceed further
|
||||
pthread_cond_wait(&m_initCond, &m_initLock);
|
||||
|
||||
if (m_driverFailed)
|
||||
{
|
||||
throw std::runtime_error(std::string(__FUNCTION__) +
|
||||
": driver initialization failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OZW::notificationHandler(Notification const* notification, void *ctx)
|
||||
{
|
||||
upm::OZW *This = (upm::OZW *)ctx;
|
||||
|
||||
This->lockNodes();
|
||||
|
||||
if (This->m_debugging)
|
||||
fprintf(stderr, "### %s: homeId %08x, nodeId %d, type %x\n",
|
||||
__FUNCTION__,
|
||||
notification->GetHomeId(),
|
||||
notification->GetNodeId(),
|
||||
notification->GetType());
|
||||
|
||||
const uint32_t homeId = notification->GetHomeId();
|
||||
const uint8_t nodeId = notification->GetNodeId();
|
||||
|
||||
switch (notification->GetType())
|
||||
{
|
||||
|
||||
case Notification::Type_NodeAdded:
|
||||
case Notification::Type_NodeNew:
|
||||
{
|
||||
if (This->m_debugging)
|
||||
cerr << "### ### ADDING NODE: " << int(nodeId) << endl;
|
||||
zwNode *node = new zwNode(homeId, nodeId);
|
||||
This->m_zwNodeMap.insert(std::pair<uint8_t, zwNode *>(nodeId, node));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Notification::Type_NodeRemoved:
|
||||
{
|
||||
if (This->m_debugging)
|
||||
cerr << "### ### REMOVING NODE: " << int(nodeId) << endl;
|
||||
if (This->m_zwNodeMap.count(nodeId) != 0)
|
||||
{
|
||||
delete This->m_zwNodeMap[nodeId];
|
||||
This->m_zwNodeMap.erase(nodeId);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Notification::Type_ValueAdded:
|
||||
{
|
||||
if (This->m_debugging)
|
||||
cerr << "### ### VALUE ADDED " << endl;
|
||||
This->m_zwNodeMap[nodeId]->addValueID(notification->GetValueID());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Notification::Type_ValueRemoved:
|
||||
{
|
||||
if (This->m_debugging)
|
||||
cerr << "### ### VALUE DELETED " << endl;
|
||||
This->m_zwNodeMap[nodeId]->removeValueID(notification->GetValueID());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Notification::Type_ValueChanged:
|
||||
{
|
||||
// might be able to do something with this someday...
|
||||
break;
|
||||
}
|
||||
|
||||
case Notification::Type_DriverReset:
|
||||
{
|
||||
// all nodes deleted. According to OZW docs, this happens
|
||||
// when a driver is reset, instead of sending potentially
|
||||
// hundreds of ValueRemoved/NodeRemoved events.
|
||||
for (zwNodeMap_t::iterator it = This->m_zwNodeMap.begin();
|
||||
it != This->m_zwNodeMap.end(); ++it)
|
||||
{
|
||||
// delete the zwNode pointer
|
||||
delete (*it).second;
|
||||
}
|
||||
// empty the map
|
||||
This->m_zwNodeMap.clear();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Notification::Type_DriverReady:
|
||||
{
|
||||
if (This->m_debugging)
|
||||
fprintf(stderr, "### DriverReady, homeID = %08x\n", This->m_homeId);
|
||||
This->m_homeId = notification->GetHomeId();
|
||||
break;
|
||||
}
|
||||
|
||||
case Notification::Type_DriverFailed:
|
||||
{
|
||||
if (This->m_debugging)
|
||||
cerr << "### Driver FAILED" << endl;
|
||||
This->m_driverFailed = true;
|
||||
// wake up init()
|
||||
pthread_cond_broadcast(&(This->m_initCond));
|
||||
break;
|
||||
}
|
||||
|
||||
case Notification::Type_AwakeNodesQueried:
|
||||
case Notification::Type_AllNodesQueried:
|
||||
case Notification::Type_AllNodesQueriedSomeDead:
|
||||
{
|
||||
if (This->m_debugging)
|
||||
cerr << "### Awake/All/SomeDead complete" << endl;
|
||||
// wake up init()
|
||||
pthread_cond_broadcast(&(This->m_initCond));
|
||||
break;
|
||||
}
|
||||
|
||||
// might be able to do something with these someday too
|
||||
case Notification::Type_Notification:
|
||||
case Notification::Type_NodeNaming:
|
||||
case Notification::Type_NodeProtocolInfo:
|
||||
case Notification::Type_NodeQueriesComplete:
|
||||
case Notification::Type_PollingEnabled:
|
||||
case Notification::Type_PollingDisabled:
|
||||
case Notification::Type_NodeEvent:
|
||||
case Notification::Type_Group:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
This->unlockNodes();
|
||||
}
|
||||
|
||||
void OZW::dumpNodes(bool all)
|
||||
{
|
||||
// iterate through all the nodes and dump various info on them
|
||||
|
||||
lockNodes();
|
||||
|
||||
for (zwNodeMap_t::iterator it = m_zwNodeMap.begin();
|
||||
it != m_zwNodeMap.end(); ++it)
|
||||
{
|
||||
uint8_t nodeId = (*it).first;
|
||||
|
||||
cerr << "Node " << int(nodeId)
|
||||
<< ": "
|
||||
<< Manager::Get()->GetNodeProductName(m_homeId, nodeId)
|
||||
<< endl;
|
||||
(*it).second->dumpNode(all);
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
bool OZW::getValueID(int nodeId, int index, ValueID *vid)
|
||||
{
|
||||
// nodeId's are uint8_t's in OpenZWave, but we want to use int's to
|
||||
// avoid hassles when dealing with SWIG, so here we just throw away
|
||||
// everything except the first byte.
|
||||
nodeId &= 0xff;
|
||||
|
||||
lockNodes();
|
||||
|
||||
zwNodeMap_t::iterator it;
|
||||
|
||||
it = m_zwNodeMap.find(nodeId);
|
||||
|
||||
if (it == m_zwNodeMap.end())
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId
|
||||
<< " does not exist" << endl;
|
||||
unlockNodes();
|
||||
return false;
|
||||
}
|
||||
|
||||
// now get the ValueID
|
||||
if (!(*it).second->indexToValueID(index, vid))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Index " << index
|
||||
<< " for node " << nodeId
|
||||
<< " does not exist" << endl;
|
||||
unlockNodes();
|
||||
return false;
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
return true;
|
||||
}
|
||||
|
||||
string OZW::getValueAsString(int nodeId, int index)
|
||||
{
|
||||
// we have to play this game since there is no default ctor for ValueID
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
string rv;
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
Manager::Get()->GetValueAsString(vid, &rv);
|
||||
|
||||
unlockNodes();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
string OZW::getValueUnits(int nodeId, int index)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
string rv;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
rv = Manager::Get()->GetValueUnits(vid);
|
||||
|
||||
unlockNodes();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void OZW::setValueUnits(int nodeId, int index, string text)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
Manager::Get()->SetValueUnits(vid, text);
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
string OZW::getValueLabel(int nodeId, int index)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
string rv;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
rv = Manager::Get()->GetValueLabel(vid);
|
||||
|
||||
unlockNodes();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void OZW::setValueLabel(int nodeId, int index, string text)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
Manager::Get()->SetValueLabel(vid, text);
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
string OZW::getValueHelp(int nodeId, int index)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
string rv;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
rv = Manager::Get()->GetValueHelp(vid);
|
||||
|
||||
unlockNodes();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void OZW::setValueHelp(int nodeId, int index, string text)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
Manager::Get()->SetValueHelp(vid, text);
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
void OZW::setValueAsBool(int nodeId, int index, bool val)
|
||||
{
|
||||
if (isValueReadOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is ReadOnly" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->SetValue(vid, val))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not a bool type" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
void OZW::setValueAsByte(int nodeId, int index, uint8_t val)
|
||||
{
|
||||
if (isValueReadOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is ReadOnly" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->SetValue(vid, val))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not a byte type" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
void OZW::setValueAsFloat(int nodeId, int index, float val)
|
||||
{
|
||||
if (isValueReadOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is ReadOnly" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->SetValue(vid, val))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not a float type" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
void OZW::setValueAsInt32(int nodeId, int index, int32_t val)
|
||||
{
|
||||
if (isValueReadOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is ReadOnly" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->SetValue(vid, val))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not a int32 type" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
void OZW::setValueAsInt16(int nodeId, int index, int16_t val)
|
||||
{
|
||||
if (isValueReadOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is ReadOnly" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->SetValue(vid, val))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not a int16 type" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
void OZW::setValueAsBytes(int nodeId, int index, uint8_t *val, uint8_t len)
|
||||
{
|
||||
if (isValueReadOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is ReadOnly" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->SetValue(vid, val, len))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not a bytes type" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
void OZW::setValueAsString(int nodeId, int index, string val)
|
||||
{
|
||||
if (isValueReadOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is ReadOnly" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->SetValue(vid, val))
|
||||
{
|
||||
// this should always succeed, but for consistancy...
|
||||
cerr << __FUNCTION__ << ": Value is not a string type" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
void OZW::refreshValue(int nodeId, int index)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
Manager::Get()->RefreshValue(vid);
|
||||
|
||||
unlockNodes();
|
||||
}
|
||||
|
||||
int OZW::getValueMin(int nodeId, int index)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
int rv = 0;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
rv = Manager::Get()->GetValueMin(vid);
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
int OZW::getValueMax(int nodeId, int index)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
int rv = 0;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
rv = Manager::Get()->GetValueMax(vid);
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool OZW::isValueReadOnly(int nodeId, int index)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
bool rv = false;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
rv = Manager::Get()->IsValueReadOnly(vid);
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool OZW::isValueWriteOnly(int nodeId, int index)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
bool rv = false;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
rv = Manager::Get()->IsValueWriteOnly(vid);
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool OZW::isValueSet(int nodeId, int index)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
bool rv = false;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
rv = Manager::Get()->IsValueSet(vid);
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool OZW::isValuePolled(int nodeId, int index)
|
||||
{
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
bool rv = false;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
rv = Manager::Get()->IsValuePolled(vid);
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool OZW::getValueAsBool(int nodeId, int index)
|
||||
{
|
||||
if (isValueWriteOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is WriteOnly" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
bool rv = false;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->GetValueAsBool(vid, &rv))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not a bool type, returning "
|
||||
<< rv << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint8_t OZW::getValueAsByte(int nodeId, int index)
|
||||
{
|
||||
if (isValueWriteOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is WriteOnly" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
uint8_t rv = false;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->GetValueAsByte(vid, &rv))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not a byte type, returning "
|
||||
<< int(rv) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
float OZW::getValueAsFloat(int nodeId, int index)
|
||||
{
|
||||
if (isValueWriteOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is WriteOnly" << endl;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
float rv = 0.0;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->GetValueAsFloat(vid, &rv))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not a float type, returning "
|
||||
<< rv << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
int OZW::getValueAsInt32(int nodeId, int index)
|
||||
{
|
||||
if (isValueWriteOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is WriteOnly" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
int32_t rv = 0;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->GetValueAsInt(vid, &rv))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not an int32 type, returning "
|
||||
<< rv << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
return int(rv);
|
||||
}
|
||||
|
||||
int OZW::getValueAsInt16(int nodeId, int index)
|
||||
{
|
||||
if (isValueWriteOnly(nodeId, index))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Node " << nodeId << " index " << index
|
||||
<< " is WriteOnly" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ValueID vid(m_homeId, (uint64)0);
|
||||
|
||||
lockNodes();
|
||||
|
||||
int16_t rv = 0;
|
||||
if (getValueID(nodeId, index, &vid))
|
||||
{
|
||||
if (!Manager::Get()->GetValueAsShort(vid, &rv))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Value is not an int16 type, returning "
|
||||
<< rv << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unlockNodes();
|
||||
return int(rv);
|
||||
}
|
||||
|
||||
bool OZW::isNodeListeningDevice(int nodeId)
|
||||
{
|
||||
nodeId &= 0xff;
|
||||
|
||||
lockNodes();
|
||||
|
||||
bool rv = Manager::Get()->IsNodeListeningDevice(m_homeId, nodeId);
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool OZW::isNodeFrequentListeningDevice(int nodeId)
|
||||
{
|
||||
nodeId &= 0xff;
|
||||
|
||||
lockNodes();
|
||||
|
||||
bool rv = Manager::Get()->IsNodeFrequentListeningDevice(m_homeId, nodeId);
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool OZW::isNodeAwake(int nodeId)
|
||||
{
|
||||
nodeId &= 0xff;
|
||||
|
||||
lockNodes();
|
||||
|
||||
bool rv = Manager::Get()->IsNodeAwake(m_homeId, nodeId);
|
||||
|
||||
unlockNodes();
|
||||
return rv;
|
||||
}
|
||||
|
||||
void OZW::setDebug(bool enable)
|
||||
{
|
||||
m_debugging = enable;
|
||||
|
||||
// To bad the following does not seem to affect anything. The only
|
||||
// way I've found to control it is via the options.xml file.
|
||||
|
||||
// Log::SetLoggingState(enable);
|
||||
}
|
574
src/ozw/ozw.h
Normal file
574
src/ozw/ozw.h
Normal file
@ -0,0 +1,574 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "Manager.h"
|
||||
#include "Notification.h"
|
||||
#include "Options.h"
|
||||
#include "Driver.h"
|
||||
#include "Node.h"
|
||||
#include "Group.h"
|
||||
#include "platform/Log.h"
|
||||
|
||||
namespace upm {
|
||||
|
||||
/**
|
||||
* @brief OZW OpenZWave library
|
||||
* @defgroup ozw libupm-ozw
|
||||
* @ingroup uart wifi
|
||||
*/
|
||||
|
||||
/**
|
||||
* @library ozw
|
||||
* @sensor ozw
|
||||
* @comname UPM wrapper for the OpenZWave library
|
||||
* @type wifi
|
||||
* @man other
|
||||
* @con uart
|
||||
* @web http://www.openzwave.com/
|
||||
*
|
||||
* @brief UPM API for the OpenZWave library
|
||||
*
|
||||
* This module implements a wrapper around the OpenZWave library.
|
||||
* OpenZWave must be compiled and installed on your machine in order
|
||||
* to use this library.
|
||||
*
|
||||
* This module was developed with OpenZWave 1.3, and an Aeon Z-Stick
|
||||
* Gen5 configured as a Primary Controller. It provides the ability
|
||||
* to query and set various values that can be used to control ZWave
|
||||
* devices. It does not concern itself with configuration of
|
||||
* devices. It is assumed that you have already setup your ZWave
|
||||
* network using a tool like the OpenZWave control panel, and have
|
||||
* already configured your devices as appropriate.
|
||||
*
|
||||
* To avoid exposing some of the internals of OpenZWave, devices
|
||||
* (nodes) and their values, are accessed via a nodeId and a value
|
||||
* index number. The example will run dumpNodes() which will list
|
||||
* the currently connected devices and the values that are available
|
||||
* to them, along with an index number for that value. It is
|
||||
* through these values (nodeId and index) that you can query and
|
||||
* set device values.
|
||||
*
|
||||
* In addition to querying values from a device (such as state
|
||||
* (on/off), or temperature, etc), methods are provided to allow you
|
||||
* to control these devices to the extent they allow, for example,
|
||||
* using a ZWave connected switch to turn on a lamp.
|
||||
*
|
||||
* Since it's likely no two ZWave networks are going to be the same,
|
||||
* the example will just initialize OpenZWave and run the
|
||||
* dumpNodes() method to allow you to see what devices are present,
|
||||
* the values they support and their current content, along with the
|
||||
* per-node index number you can use to address them. There will be
|
||||
* commented out code examples showing you how to query or set a
|
||||
* specific value for a device.
|
||||
*
|
||||
* See the ozw example code comments for an example of the ouput of
|
||||
* running dumpNodes().
|
||||
*
|
||||
* In most of the methods below, You will need the NodeId (Node
|
||||
* number), and the Index number to access or otherwise affect these
|
||||
* values.
|
||||
*
|
||||
* @snippet openzwave.cxx Interesting
|
||||
*/
|
||||
|
||||
// forward declaration of private zwNode data
|
||||
class zwNode;
|
||||
|
||||
class OZW {
|
||||
public:
|
||||
|
||||
typedef std::map<uint8_t, zwNode *> zwNodeMap_t;
|
||||
|
||||
/**
|
||||
* OZW constructor
|
||||
*/
|
||||
OZW();
|
||||
|
||||
/**
|
||||
* OZW Destructor
|
||||
*/
|
||||
~OZW();
|
||||
|
||||
/**
|
||||
* Start configuration with basic options. This must be called
|
||||
* prior to init(), after the OZW() contructor is called.
|
||||
*
|
||||
* @param configPath Set the location of the OpenZWave config
|
||||
* directory, default is /etc/openzwave
|
||||
* @param userConfigDir Set the path to the user configuration
|
||||
* directory. This is the location of the zwcfg*.xml and
|
||||
* option.xml files for the user (probably created by the
|
||||
* OpenZWave Control Panel example application). The default is
|
||||
* the current directory ("").
|
||||
* @param cmdLine Specify command line formatted options to
|
||||
* OpenZWave. The default is "".
|
||||
*/
|
||||
void optionsCreate(std::string configPath="/etc/openzwave",
|
||||
std::string userConfigDir="",
|
||||
std::string cmdLine="");
|
||||
|
||||
/**
|
||||
* Add an integer Option. See the OpenZWave documentation for
|
||||
* valid values.
|
||||
*
|
||||
* @param name The name of the configuration option
|
||||
* @param val The value to set it to
|
||||
*/
|
||||
void optionAddInt(std::string name, int val);
|
||||
|
||||
/**
|
||||
* Add a boolean Option. See the OpenZWave documentation for
|
||||
* valid values.
|
||||
*
|
||||
* @param name The name of the configuration option
|
||||
* @param val The value to set it to
|
||||
*/
|
||||
void optionAddBool(std::string name, bool val);
|
||||
|
||||
/**
|
||||
* Add a string Option. See the OpenZWave documentation for valid
|
||||
* values.
|
||||
*
|
||||
* @param name The name of the configuration option
|
||||
* @param val The value to set it to
|
||||
* @append true to append to the option, false to override
|
||||
*/
|
||||
void optionAddString(std::string name, std::string val, bool append);
|
||||
|
||||
/**
|
||||
* Lock the Options. This must be called after all options have
|
||||
* been set, and before init() is called. If init() is called
|
||||
* without locking the Options, init() will lock them itself.
|
||||
* After the options have been locked, no further options can be
|
||||
* specified.
|
||||
*/
|
||||
void optionsLock();
|
||||
|
||||
/**
|
||||
* Initialize the ZWave network. This method will start a probe
|
||||
* of all defined devices on the ZWave network and query essential
|
||||
* information about them. This function will not return until
|
||||
* either initialization has failed, or has succeeded far enough
|
||||
* along for the following methods to work. Depending on the size
|
||||
* an complexity of the ZWave network, this may take anywhere from
|
||||
* seconds to several minutes to complete.
|
||||
*
|
||||
* All Options (via option*()) must have been specified before
|
||||
* this function is called. If the Options have not been locked
|
||||
* via optionsLock() prior to calling init(), this method will
|
||||
* lock them for you before proceeding.
|
||||
*
|
||||
* @param devicePath The device path for the ZWave controller,
|
||||
* typically something like /dev/ttyACM0, or similiar
|
||||
* @param isHID true if this is a HID device, false otherwise (ie:
|
||||
* a serial port like /dev/ttyACM0, /dev/ttyUSB0, etc). Default
|
||||
* is false.
|
||||
* @return true if init succeeded, false otherwise
|
||||
*/
|
||||
bool init(std::string devicePath, bool isHID=false);
|
||||
|
||||
/**
|
||||
* Dump information about all configured nodes and their values to
|
||||
* stdout. This is useful to determine what nodes are available,
|
||||
* and the index (used for querying and seting values for them).
|
||||
* In addition, it includes information about each value (type,
|
||||
* current value, etc).
|
||||
*
|
||||
* @param all set to true to dump information about all values
|
||||
* available for each node. If false, only information about
|
||||
* 'user' values (ignoring 'system' and 'configuration') are
|
||||
* output. The default is false ('user' values only).
|
||||
*/
|
||||
void dumpNodes(bool all=false);
|
||||
|
||||
/**
|
||||
* Return a string (which may be empty) indicating the Units of
|
||||
* measure for a given value. For example, querying a temperature
|
||||
* value may return "F" to indicate Fahrenheit.
|
||||
*
|
||||
* @param nodeId The node ID to query
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return A string containing the Unit of measure for the value
|
||||
*/
|
||||
std::string getValueUnits(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Set the text for the Units of measure for a value.
|
||||
*
|
||||
* @param nodeId The node ID to query
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param text The text to set
|
||||
*/
|
||||
void setValueUnits(int nodeId, int index, std::string text);
|
||||
|
||||
/**
|
||||
* Return a string (which may be empty) containing the
|
||||
* user-freindly Label for a value.
|
||||
*
|
||||
* @param nodeId The node ID to query
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return A string containing the Value's label
|
||||
*/
|
||||
std::string getValueLabel(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Set the text for a Value's label.
|
||||
*
|
||||
* @param nodeId The node ID to query
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param text The text to set
|
||||
*/
|
||||
void setValueLabel(int nodeId, int index, std::string text);
|
||||
|
||||
/**
|
||||
* Return a string (which may be empty) indicating the Help text
|
||||
* of a value, if available.
|
||||
*
|
||||
* @param nodeId The node ID to query
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return A string containing the Help text, if available
|
||||
*/
|
||||
std::string getValueHelp(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Set the text for a Value's help text.
|
||||
*
|
||||
* @param nodeId The node ID to query
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param text The text to set
|
||||
*/
|
||||
void setValueHelp(int nodeId, int index, std::string text);
|
||||
|
||||
/**
|
||||
* Set the contents of a Value to a string. This should always
|
||||
* succeed if the supplied content makes sense for a given value,
|
||||
* regardless of the value's actual type.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param val the content to assign to the value referenced by
|
||||
* nodeId, and index.
|
||||
*/
|
||||
void setValueAsString(int nodeId, int index, std::string val);
|
||||
|
||||
/**
|
||||
* Set the contents of a Value, to a bool. This will fail, and an
|
||||
* error message printed if the value type is not a boolean value.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param val the boolean content to assign to the value referenced
|
||||
* by nodeId, and index.
|
||||
*/
|
||||
void setValueAsBool(int nodeId, int index, bool val);
|
||||
|
||||
/**
|
||||
* Set the contents of a Value, to a byte. This will fail, and an
|
||||
* error message printed if the value type is not a byte value.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param val the byte content to assign to the value referenced
|
||||
* by nodeId, and index.
|
||||
*/
|
||||
void setValueAsByte(int nodeId, int index, uint8_t val);
|
||||
|
||||
/**
|
||||
* Set the contents of a Value, to a float. This will fail, and an
|
||||
* error message printed if the value type is not a float value.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param val the float content to assign to the value referenced
|
||||
* by nodeId, and index.
|
||||
*/
|
||||
void setValueAsFloat(int nodeId, int index, float val);
|
||||
|
||||
/**
|
||||
* Set the contents of a Value, to a 32 bit integer (int32). This
|
||||
* will fail, and an error message printed if the value type is
|
||||
* not an int32.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param val the int32 content to assign to the value referenced
|
||||
* by nodeId, and index.
|
||||
*/
|
||||
void setValueAsInt32(int nodeId, int index, int32_t val);
|
||||
|
||||
/**
|
||||
* Set the contents of a Value, to a 16 bit integer (int16). This
|
||||
* will fail, and an error message printed if the value type is
|
||||
* not an int16.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param val the int16 content to assign to the value referenced
|
||||
* by nodeId, and index.
|
||||
*/
|
||||
void setValueAsInt16(int nodeId, int index, int16_t val);
|
||||
|
||||
/**
|
||||
* Set the contents of a Value, to an array of bytes. This will
|
||||
* fail, and an error message printed if the value type is not
|
||||
* settable as an array of bytes.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param val the byte array content to assign to the value referenced
|
||||
* by nodeId, and index.
|
||||
* @param len The length of the byte array
|
||||
*/
|
||||
void setValueAsBytes(int nodeId, int index, uint8_t *val, uint8_t len);
|
||||
|
||||
/**
|
||||
* Get the minimum allowed value for a node's Value.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return The minumum allowed value
|
||||
*/
|
||||
int getValueMin(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Get the maximum allowed value for a node's Value.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return The maximum allowed value
|
||||
*/
|
||||
int getValueMax(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Test whether a value is read-only.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return true if the value is read-only, false otherwise
|
||||
*/
|
||||
bool isValueReadOnly(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Test whether a value is write only.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return true if the value is write-only, false otherwise
|
||||
*/
|
||||
bool isValueWriteOnly(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Test whether a value is really set on a node, and not a default
|
||||
* value chosen by the OpenZWave library.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return true if the value is really set, false if a default value is
|
||||
* being reported
|
||||
*/
|
||||
bool isValueSet(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Test whether a value is being manually polled by the OpenZWave
|
||||
* library. Most modern devices are never polled, rather they are
|
||||
* configured to report changing values to the controller on their
|
||||
* own at device specific intervals or when appropriate events
|
||||
* (depending the device) have occured.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return true if the value is being maually polled, false otherwise
|
||||
* being reported
|
||||
*/
|
||||
bool isValuePolled(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Return the content of a value as a string. This should always
|
||||
* succeed, regardless of the actual value type.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return A string representing the current contents of a value.
|
||||
*/
|
||||
std::string getValueAsString(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Return the content of a value as a booleang. This will fail,
|
||||
* and an error message printed if the value type is not boolean.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return A boolean representing the current contents of a value.
|
||||
*/
|
||||
bool getValueAsBool(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Return the content of a value as a byte. This will fail, and
|
||||
* an error message printed if the value type is not a byte.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return A byte representing the current contents of a value.
|
||||
*/
|
||||
uint8_t getValueAsByte(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Return the content of a value as a float. This will fail, and
|
||||
* an error message printed if the value type is not a floating
|
||||
* point value.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return A float representing the current contents of a value.
|
||||
*/
|
||||
float getValueAsFloat(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Return the content of a value as an int32. This will fail, and
|
||||
* an error message printed if the value type is not an int32.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return An int32 representing the current contents of a value.
|
||||
*/
|
||||
int getValueAsInt32(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Return the content of a value as an int16. This will fail, and
|
||||
* an error message printed if the value type is not an int16.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @return An int16 representing the current contents of a value.
|
||||
*/
|
||||
int getValueAsInt16(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Issue a refresh request for a value on a node. OpenZWave will
|
||||
* query the value and update it's internal state when the device
|
||||
* responds. Note, this happens asynchronously - it may take some
|
||||
* time before the current value is reported to OpenZWave by the
|
||||
* node. If the node is asleep, you may not get a current value
|
||||
* for some time (or at all, depending on the device). This
|
||||
* method will return immediately after the request has been
|
||||
* queued.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
*/
|
||||
void refreshValue(int nodeId, int index);
|
||||
|
||||
/**
|
||||
* Enable or disable some debugging output. Note, this will not
|
||||
* affect OpenZWave's own debugging, which is usually set in the
|
||||
* option.xml file.
|
||||
*
|
||||
* @param enable true to enable debugging, false otherwise
|
||||
*/
|
||||
void setDebug(bool enable);
|
||||
|
||||
/**
|
||||
* Determine if a node is a listening device -- in other words, the
|
||||
* node never sleeps.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @return true if the node never sleeps, false otherwise
|
||||
*/
|
||||
bool isNodeListeningDevice(int nodeId);
|
||||
|
||||
/**
|
||||
* Determine if a node is a frequent listening device -- in other
|
||||
* words, if the node is asleep, can it be woken by a beam.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @return true if the node is a frequent listening device, false
|
||||
* otherwise
|
||||
*/
|
||||
bool isNodeFrequentListeningDevice(int nodeId);
|
||||
|
||||
/**
|
||||
* Determine if a node is awake.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @return true if the node is awake, false otherwise
|
||||
*/
|
||||
bool isNodeAwake(int nodeId);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Based on a nodeId and a value index, lookup the corresponding
|
||||
* OpenZWave ValueID.
|
||||
*
|
||||
* @param nodeId The node ID
|
||||
* @param index The value index (see dumpNodes()) of the value to query.
|
||||
* @param A pointer to a ValueID that will be returned if successful
|
||||
* @return true of the nodeId and index was found, false otherwise
|
||||
*/
|
||||
bool getValueID(int nodeId, int index, OpenZWave::ValueID *vid);
|
||||
|
||||
/**
|
||||
* Lock the m_zwNodeMap mutex to protect against changes made to
|
||||
* the the the map by the OpenZWave notification handler. Always
|
||||
* lock this mutex when acessing anything in the zwNodeMap map.
|
||||
*/
|
||||
|
||||
void lockNodes() { pthread_mutex_lock(&m_nodeLock); };
|
||||
/**
|
||||
* Unlock the m_zwNodeMap mutex after lockNodes() has been called.
|
||||
*/
|
||||
void unlockNodes() { pthread_mutex_unlock(&m_nodeLock); };
|
||||
|
||||
private:
|
||||
uint32_t m_homeId;
|
||||
bool m_mgrCreated;
|
||||
bool m_driverFailed;
|
||||
bool m_debugging;
|
||||
|
||||
bool m_driverIsHID;
|
||||
std::string m_devicePath;
|
||||
|
||||
// our notification handler, called by OpenZWave for events on the
|
||||
// network.
|
||||
static void notificationHandler(OpenZWave::Notification
|
||||
const* notification,
|
||||
void *ctx);
|
||||
|
||||
// a map of added nodes
|
||||
zwNodeMap_t m_zwNodeMap;
|
||||
|
||||
// for coordinating access to the node list
|
||||
pthread_mutex_t m_nodeLock;
|
||||
|
||||
// We use these to determine init failure or success (if OpenZWave
|
||||
// has successfully queried essential data about the network).
|
||||
pthread_mutex_t m_initLock;
|
||||
pthread_cond_t m_initCond;
|
||||
};
|
||||
}
|
||||
|
||||
|
15
src/ozw/pyupm_ozw.i
Normal file
15
src/ozw/pyupm_ozw.i
Normal file
@ -0,0 +1,15 @@
|
||||
%module pyupm_ozw
|
||||
%include "../upm.i"
|
||||
%include "cpointer.i"
|
||||
|
||||
%include "stdint.i"
|
||||
|
||||
%feature("autodoc", "3");
|
||||
|
||||
%pointer_functions(float, floatp);
|
||||
|
||||
%include "ozw.h"
|
||||
%{
|
||||
#include "ozw.h"
|
||||
%}
|
||||
|
168
src/ozw/zwNode.cxx
Normal file
168
src/ozw/zwNode.cxx
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include "zwNode.h"
|
||||
|
||||
#include "Node.h"
|
||||
|
||||
using namespace upm;
|
||||
using namespace std;
|
||||
using namespace OpenZWave;
|
||||
|
||||
zwNode::zwNode(uint32_t homeId, uint8_t nodeId)
|
||||
{
|
||||
m_homeId = homeId;
|
||||
m_nodeId = nodeId;
|
||||
|
||||
m_vindex = 0;
|
||||
}
|
||||
|
||||
zwNode::~zwNode()
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t zwNode::nodeId()
|
||||
{
|
||||
return m_nodeId;
|
||||
}
|
||||
|
||||
uint32_t zwNode::homeId()
|
||||
{
|
||||
return m_homeId;
|
||||
}
|
||||
|
||||
void zwNode::addValueID(ValueID vid)
|
||||
{
|
||||
// We need to use insert since ValueID's default ctor is private
|
||||
m_values.insert(std::pair<int, ValueID>(m_vindex++, vid));
|
||||
}
|
||||
|
||||
void zwNode::removeValueID(ValueID vid)
|
||||
{
|
||||
//we have to get a little complicated here since we need to delete
|
||||
//the value id, but the map is indexed by m_vindex
|
||||
for (valueMap_t::iterator it = m_values.begin();
|
||||
it != m_values.end(); ++it)
|
||||
{
|
||||
if ((*it).second == vid)
|
||||
{
|
||||
m_values.erase((*it).first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool zwNode::indexToValueID(int index, ValueID *vid)
|
||||
{
|
||||
valueMap_t::iterator it;
|
||||
|
||||
it = m_values.find(index);
|
||||
|
||||
if (it == m_values.end())
|
||||
{
|
||||
// not found, return false
|
||||
return false;
|
||||
}
|
||||
else
|
||||
*vid = (*it).second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void zwNode::dumpNode(bool all)
|
||||
{
|
||||
for (valueMap_t::iterator it = m_values.begin();
|
||||
it != m_values.end(); ++it)
|
||||
{
|
||||
int vindex = (*it).first;
|
||||
ValueID vid = (*it).second;
|
||||
string label = Manager::Get()->GetValueLabel(vid);
|
||||
string valueAsStr;
|
||||
Manager::Get()->GetValueAsString(vid, &valueAsStr);
|
||||
string valueUnits = Manager::Get()->GetValueUnits(vid);
|
||||
ValueID::ValueType vType = vid.GetType();
|
||||
string vTypeStr;
|
||||
|
||||
switch (vType)
|
||||
{
|
||||
case ValueID::ValueType_Bool:
|
||||
vTypeStr = "bool";
|
||||
break;
|
||||
|
||||
case ValueID::ValueType_Byte:
|
||||
vTypeStr = "byte";
|
||||
break;
|
||||
|
||||
case ValueID::ValueType_Decimal:
|
||||
vTypeStr = "float";
|
||||
break;
|
||||
|
||||
case ValueID::ValueType_Int:
|
||||
vTypeStr = "int32";
|
||||
break;
|
||||
|
||||
case ValueID::ValueType_List:
|
||||
vTypeStr = "list";
|
||||
break;
|
||||
|
||||
case ValueID::ValueType_Schedule:
|
||||
vTypeStr = "schedule";
|
||||
break;
|
||||
|
||||
case ValueID::ValueType_Short:
|
||||
vTypeStr = "int16";
|
||||
break;
|
||||
|
||||
case ValueID::ValueType_String:
|
||||
vTypeStr = "string";
|
||||
break;
|
||||
|
||||
case ValueID::ValueType_Button:
|
||||
vTypeStr = "button";
|
||||
break;
|
||||
|
||||
case ValueID::ValueType_Raw:
|
||||
vTypeStr = "raw";
|
||||
break;
|
||||
|
||||
default:
|
||||
vTypeStr = "undefined";
|
||||
break;
|
||||
}
|
||||
|
||||
// by default we only want user values, unless 'all' is true
|
||||
if (all || (vid.GetGenre() == ValueID::ValueGenre_User))
|
||||
fprintf(stderr, "\t Index: %2d, Type: %s, Label: %s, Value: %s %s\n",
|
||||
vindex,
|
||||
vTypeStr.c_str(),
|
||||
label.c_str(),
|
||||
valueAsStr.c_str(),
|
||||
valueUnits.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
105
src/ozw/zwNode.h
Normal file
105
src/ozw/zwNode.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Manager.h"
|
||||
|
||||
namespace upm {
|
||||
|
||||
class zwNode {
|
||||
public:
|
||||
typedef std::map<int, OpenZWave::ValueID> valueMap_t;
|
||||
|
||||
/**
|
||||
* zwNode contructor.
|
||||
*
|
||||
* @param homeId the homeId os the network controller
|
||||
* @param nodeId the node index
|
||||
*/
|
||||
zwNode(uint32_t homeId, uint8_t nodeId);
|
||||
|
||||
~zwNode();
|
||||
|
||||
/**
|
||||
* get the nodeId
|
||||
*
|
||||
* @return The nodeId for this node
|
||||
*/
|
||||
uint8_t nodeId();
|
||||
|
||||
/**
|
||||
* get the homeId
|
||||
*
|
||||
* @return The homeId for this node
|
||||
*/
|
||||
uint32_t homeId();
|
||||
|
||||
/**
|
||||
* Add an OpenZWave ValueID and index to the value map,
|
||||
* incrementing m_vindex.
|
||||
*
|
||||
* @param vid The OpenZWave ValueID
|
||||
*/
|
||||
void addValueID(OpenZWave::ValueID vid);
|
||||
|
||||
/**
|
||||
* Remove an OpenZWave ValueID from the value map.
|
||||
*
|
||||
* @param vid The OpenZWave ValueID
|
||||
*/
|
||||
void removeValueID(OpenZWave::ValueID vid);
|
||||
|
||||
/**
|
||||
* Lookup and return a ValueID corresponding to an index.
|
||||
*
|
||||
* @param index the index to look up
|
||||
* @param vid The pointer to the returned ValueID, if it exists
|
||||
* @return true if the index was found, false otherwise
|
||||
*/
|
||||
bool indexToValueID(int index, OpenZWave::ValueID *vid);
|
||||
|
||||
/**
|
||||
* Dump various information about the ValueIDs stored in this
|
||||
* node.
|
||||
*
|
||||
* @param all true to dump all values, false to limit dumping only
|
||||
* 'user' values.
|
||||
*/
|
||||
void dumpNode(bool all=false);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
uint32_t m_homeId;
|
||||
uint8_t m_nodeId;
|
||||
|
||||
valueMap_t m_values;
|
||||
|
||||
// we increment this index for every ValueID we add
|
||||
unsigned int m_vindex;
|
||||
};
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user