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