| /* |
| * 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; |
| }; |
| } |
| |
| |