Add support for Z-Wave

This commit is contained in:
Michael Zanetti 2022-07-08 10:25:25 +02:00
parent 3e1e7b5a01
commit a8b02a4869
44 changed files with 4654 additions and 12 deletions

3
debian/control vendored
View File

@ -28,7 +28,7 @@ Build-Depends: debhelper (>= 9.0.0),
qtconnectivity5-dev,
qtdeclarative5-dev,
libqt5serialport5-dev,
libqt5serialbus5-dev
libqt5serialbus5-dev,
Package: nymea
@ -61,6 +61,7 @@ Recommends: nymea-cli,
nymea-system-plugin-impl,
nymea-zeroconf-plugin-impl,
nymea-apikeysprovider-plugin-impl,
nymea-zwave-plugin-impl,
Description: An open source IoT server - daemon
The nymea daemon is a plugin based IoT (Internet of Things) server.
The server works like a translator for devices, things and services

View File

@ -0,0 +1,183 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavehardwareresourceimplementation.h"
#include "zwave/zwavemanager.h"
#include "zwave/zwavenetwork.h"
#include "loggingcategories.h"
Q_DECLARE_LOGGING_CATEGORY(dcZWave)
namespace nymeaserver
{
ZWaveHardwareResourceImplementation::ZWaveHardwareResourceImplementation(ZWaveManager *zwaveManager, QObject *parent):
ZWaveHardwareResource(parent),
m_zwaveManager(zwaveManager)
{
connect(m_zwaveManager, &ZWaveManager::networkStateChanged, this, &ZWaveHardwareResourceImplementation::onNetworkStateChanged);
connect(m_zwaveManager, &ZWaveManager::nodeInitialized, this, &ZWaveHardwareResourceImplementation::onNodeInitialized);
connect(m_zwaveManager, &ZWaveManager::nodeRemoved, this, &ZWaveHardwareResourceImplementation::onNodeRemoved);
// connect(m_zigbeeManager, &ZigbeeManager::availableChanged, this, &ZigbeeHardwareResourceImplementation::onZigbeeAvailableChanged);
}
bool ZWaveHardwareResourceImplementation::available() const
{
return m_zwaveManager->available();
}
bool ZWaveHardwareResourceImplementation::enabled() const
{
return m_zwaveManager->enabled();
}
void ZWaveHardwareResourceImplementation::setEnabled(bool enabled)
{
m_zwaveManager->setEnabled(enabled);
}
void ZWaveHardwareResourceImplementation::registerHandler(ZWaveHandler *handler, HandlerType type)
{
qCDebug(dcZWave()) << "Registering new Z-Wave handler" << handler->name() << "with type" << type;
m_handlers.insert(type, handler);
}
ZWaveNode *ZWaveHardwareResourceImplementation::claimNode(ZWaveHandler *handler, const QUuid &networkUuid, quint8 nodeId)
{
if (!m_handlers.values().contains(handler)) {
qCWarning(dcZWave()) << "Handler" << handler->name() << "is not registered. Not allowing node to be claimed.";
return nullptr;
}
ZWaveNetwork *network = m_zwaveManager->network(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Network" << networkUuid << "not found.";
return nullptr;
}
ZWaveNode *node = network->node(nodeId);
if (!node) {
qCWarning(dcZWave()) << "Node with ID" << nodeId << "not found in ZWave network" << networkUuid.toString();
return nullptr;
}
if (m_nodeHandlers.contains(node) && m_nodeHandlers.value(node) != handler) {
qCWarning(dcZWave()) << "Node with ID" << nodeId << "is already claimed by another handler (" << m_nodeHandlers.value(node)->name() << "). Not allowing node to be reclaimed.";
return nullptr;
}
m_nodeHandlers[node] = handler;
return node;
}
void ZWaveHardwareResourceImplementation::thingsLoaded()
{
m_thingsLoaded = true;
qCDebug(dcZWave) << "Things loaded. Checking for unhandled nodes...";
// We can assume here that all handled nodes have been claimed by plugins
// In case we started up and loaded new Z-Wave plugins, let's try to get all previously joined nodes handled now...
foreach (ZWaveNetwork *network, m_zwaveManager->networks()) {
foreach (ZWaveNode *node, network->nodes()) {
// Ignore the controller node
if (node->nodeId() == network->controllerNodeId())
continue;
if (!m_nodeHandlers.contains(node)) {
qCDebug(dcZWave()) << "Node" << node << "is not yet handled by any plugin. Trying to find a suitable plugin.";
handleNewNode(node);
}
}
}
}
void ZWaveHardwareResourceImplementation::onNetworkStateChanged(ZWaveNetwork *network)
{
// If the network is now ready and things have been loaded already, check if there are
// unclaimed nodes that might be handled now. This might happen if a node joins the network
// but no appropriate plugin had been installed at the time. If additional plugins have
// been installed now, such nodes might be handled by them now.
if (network->networkState() == ZWaveNetwork::ZWaveNetworkStateOnline && m_thingsLoaded) {
foreach (ZWaveNode *node, network->nodes()) {
// Ignore the controller node
if (node->nodeId() == network->controllerNodeId())
continue;
if (!m_nodeHandlers.contains(node)) {
handleNewNode(node);
}
}
}
}
void ZWaveHardwareResourceImplementation::onNodeInitialized(ZWaveNode *node)
{
if (!m_thingsLoaded) {
return;
}
handleNewNode(node);
}
void ZWaveHardwareResourceImplementation::onNodeRemoved(ZWaveNode *node)
{
qCDebug(dcZWave()) << "Node removed from the network";
ZWaveHandler *handler = m_nodeHandlers.value(node);
if (handler) {
handler->handleRemoveNode(node);
}
}
void ZWaveHardwareResourceImplementation::handleNewNode(ZWaveNode *node)
{
ZWaveNetwork *network = m_zwaveManager->network(node->networkUuid());
if (node->nodeId() == network->controllerNodeId()) {
// Not forwarding the controller node to plugins...
return;
}
qCDebug(dcZWave()) << "Node" << node->nodeId() << "added to the network:" << node->networkUuid().toString();
ZWaveHandler *handler = nullptr;
foreach (ZWaveHandler *tmp, m_handlers) {
if (tmp->handleNode(node)) {
handler = tmp;
m_nodeHandlers.insert(node, handler);
qCDebug(dcZWave()) << "Node" << node->nodeId() << "taken by handler" << handler->name();
break;
}
}
if (!handler) {
qCInfo(dcZWave()) << "No Z-Wave handler available to handle node" << node;
return;
}
}
}

View File

@ -0,0 +1,86 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEHARDWARERESOURCEIMPLEMENTATION_H
#define ZWAVEHARDWARERESOURCEIMPLEMENTATION_H
#include <QObject>
#include <QHash>
#include <QMultiMap>
#include "hardware/zwave/zwavehardwareresource.h"
class ZWaveNetwork;
namespace nymeaserver
{
class ZWaveManager;
class ZWaveHardwareResourceImplementation : public ZWaveHardwareResource
{
Q_OBJECT
public:
ZWaveHardwareResourceImplementation(ZWaveManager *zwaveManager, QObject *parent = nullptr);
bool available() const override;
bool enabled() const override;
void setEnabled(bool enabled) override;
void registerHandler(ZWaveHandler *handler, HandlerType type = HandlerTypeVendor) override;
ZWaveNode *claimNode(ZWaveHandler *handler, const QUuid &networkUuid, quint8 nodeId) override;
signals:
public slots:
void thingsLoaded();
private slots:
void onNetworkStateChanged(ZWaveNetwork *network);
void onNodeInitialized(ZWaveNode *node);
void onNodeRemoved(ZWaveNode *node);
void handleNewNode(ZWaveNode *node);
private:
bool m_available = false;
bool m_enabled = false;
ZWaveManager *m_zwaveManager = nullptr;
QMultiMap<ZWaveHardwareResource::HandlerType, ZWaveHandler*> m_handlers;
bool m_thingsLoaded = false;
QHash<ZWaveNode*, ZWaveHandler*> m_nodeHandlers;
};
}
#endif // ZWAVEHARDWARERESOURCEIMPLEMENTATION_H

View File

@ -43,6 +43,7 @@
#include "hardware/network/mqtt/mqttproviderimplementation.h"
#include "hardware/i2c/i2cmanagerimplementation.h"
#include "hardware/zigbee/zigbeehardwareresourceimplementation.h"
#include "hardware/zwave/zwavehardwareresourceimplementation.h"
#include "hardware/modbus/modbusrtumanager.h"
#include "hardware/modbus/modbusrtuhardwareresourceimplementation.h"
@ -50,7 +51,7 @@
namespace nymeaserver {
HardwareManagerImplementation::HardwareManagerImplementation(Platform *platform, MqttBroker *mqttBroker, ZigbeeManager *zigbeeManager, ModbusRtuManager *modbusRtuManager, QObject *parent) :
HardwareManagerImplementation::HardwareManagerImplementation(Platform *platform, MqttBroker *mqttBroker, ZigbeeManager *zigbeeManager, ZWaveManager *zwaveManager, ModbusRtuManager *modbusRtuManager, QObject *parent) :
HardwareManager(parent),
m_platform(platform)
{
@ -77,6 +78,8 @@ HardwareManagerImplementation::HardwareManagerImplementation(Platform *platform,
m_zigbeeResource = new ZigbeeHardwareResourceImplementation(zigbeeManager, this);
m_zwaveResource = new ZWaveHardwareResourceImplementation(zwaveManager, this);
m_modbusRtuResource = new ModbusRtuHardwareResourceImplementation(modbusRtuManager, this);
m_networkDeviceDiscovery = new NetworkDeviceDiscoveryImpl(this);
@ -151,6 +154,11 @@ ZigbeeHardwareResource *HardwareManagerImplementation::zigbeeResource()
return m_zigbeeResource;
}
ZWaveHardwareResource *HardwareManagerImplementation::zwaveResource()
{
return m_zwaveResource;
}
ModbusRtuHardwareResource *HardwareManagerImplementation::modbusRtuResource()
{
return m_modbusRtuResource;
@ -164,6 +172,7 @@ NetworkDeviceDiscovery *HardwareManagerImplementation::networkDeviceDiscovery()
void HardwareManagerImplementation::thingsLoaded()
{
m_zigbeeResource->thingsLoaded();
m_zwaveResource->thingsLoaded();
}
}

View File

@ -43,6 +43,8 @@ class Platform;
class MqttBroker;
class ZigbeeManager;
class ZigbeeHardwareResourceImplementation;
class ZWaveManager;
class ZWaveHardwareResourceImplementation;
class ModbusRtuManager;
class ModbusRtuHardwareResourceImplementation;
class NetworkDeviceDiscoveryImpl;
@ -52,7 +54,7 @@ class HardwareManagerImplementation : public HardwareManager
Q_OBJECT
public:
explicit HardwareManagerImplementation(Platform *platform, MqttBroker *mqttBroker, ZigbeeManager *zigbeeManager, ModbusRtuManager *modbusRtuManager, QObject *parent = nullptr);
explicit HardwareManagerImplementation(Platform *platform, MqttBroker *mqttBroker, ZigbeeManager *zigbeeManager, ZWaveManager *zwaveManager, ModbusRtuManager *modbusRtuManager, QObject *parent = nullptr);
~HardwareManagerImplementation() override;
Radio433 *radio433() override;
@ -64,6 +66,7 @@ public:
MqttProvider *mqttProvider() override;
I2CManager *i2cManager() override;
ZigbeeHardwareResource *zigbeeResource() override;
ZWaveHardwareResource *zwaveResource() override;
ModbusRtuHardwareResource *modbusRtuResource() override;
NetworkDeviceDiscovery *networkDeviceDiscovery() override;
@ -84,6 +87,7 @@ private:
MqttProvider *m_mqttProvider = nullptr;
I2CManager *m_i2cManager = nullptr;
ZigbeeHardwareResourceImplementation *m_zigbeeResource = nullptr;
ZWaveHardwareResourceImplementation *m_zwaveResource = nullptr;
ModbusRtuHardwareResourceImplementation *m_modbusRtuResource = nullptr;
NetworkDeviceDiscoveryImpl *m_networkDeviceDiscovery = nullptr;

View File

@ -71,6 +71,7 @@
#include "systemhandler.h"
#include "usershandler.h"
#include "zigbeehandler.h"
#include "zwavehandler.h"
#include "modbusrtuhandler.h"
#include <QJsonDocument>
@ -607,6 +608,7 @@ void JsonRPCServerImplementation::setup()
registerHandler(new SystemHandler(NymeaCore::instance()->platform(), this));
registerHandler(new UsersHandler(NymeaCore::instance()->userManager(), this));
registerHandler(new ZigbeeHandler(NymeaCore::instance()->zigbeeManager(), this));
registerHandler(new ZWaveHandler(NymeaCore::instance()->zwaveManager(), this));
registerHandler(new ModbusRtuHandler(NymeaCore::instance()->modbusRtuManager(), this));
connect(NymeaCore::instance()->cloudManager(), &CloudManager::pairingReply, this, &JsonRPCServerImplementation::pairingFinished);

View File

@ -0,0 +1,386 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavehandler.h"
namespace nymeaserver
{
ZWaveHandler::ZWaveHandler(ZWaveManager *zwaveManager, QObject *parent):
JsonHandler(parent),
m_zwaveManager(zwaveManager)
{
registerEnum<ZWave::ZWaveError>();
registerObject<SerialPort, SerialPorts>();
registerEnum<ZWaveNetwork::ZWaveNetworkState>();
registerEnum<ZWaveNode::ZWaveNodeType>();
registerEnum<ZWaveNode::ZWaveNodeRole>();
registerEnum<ZWaveNode::ZWaveDeviceType>();
QVariantMap networkDescription;
networkDescription.insert("networkUuid", enumValueName(Uuid));
networkDescription.insert("serialPort", enumValueName(String));
networkDescription.insert("networkState", enumRef<ZWaveNetwork::ZWaveNetworkState>());
networkDescription.insert("homeId", enumValueName(Uint));
networkDescription.insert("isZWavePlus", enumValueName(Bool));
networkDescription.insert("isStaticUpdateController", enumValueName(Bool));
networkDescription.insert("isPrimaryController", enumValueName(Bool));
networkDescription.insert("isBridgeController", enumValueName(Bool));
networkDescription.insert("waitingForNodeAddition", enumValueName(Bool));
networkDescription.insert("waitingForNodeRemoval", enumValueName(Bool));
registerObject("ZWaveNetwork", networkDescription);
QVariantMap nodeDescription;
nodeDescription.insert("nodeId", enumValueName(Uint));
nodeDescription.insert("networkUuid", enumValueName(Uuid));
nodeDescription.insert("initialized", enumValueName(Bool));
nodeDescription.insert("reachable", enumValueName(Bool));
nodeDescription.insert("failed", enumValueName(Bool));
nodeDescription.insert("sleeping", enumValueName(Bool));
nodeDescription.insert("linkQuality", enumValueName(Uint));
nodeDescription.insert("securityMode", enumValueName(Uint));
nodeDescription.insert("nodeType", enumRef<ZWaveNode::ZWaveNodeType>());
nodeDescription.insert("role", enumRef<ZWaveNode::ZWaveNodeRole>());
nodeDescription.insert("deviceType", enumRef<ZWaveNode::ZWaveDeviceType>());
nodeDescription.insert("productType", enumValueName(Uint));
nodeDescription.insert("productId", enumValueName(Uint));
nodeDescription.insert("productName", enumValueName(String));
nodeDescription.insert("manufacturerId", enumValueName(Uint));
nodeDescription.insert("manufacturerName", enumValueName(String));
nodeDescription.insert("version", enumValueName(String));
nodeDescription.insert("isZWavePlusDevice", enumValueName(Bool));
nodeDescription.insert("isSecurityDevice", enumValueName(Bool));
nodeDescription.insert("isBeamingDevice", enumValueName(Bool));
registerObject("ZWaveNode", nodeDescription);
QVariantMap params, returns;
QString description;
params.clear(); returns.clear();
description = "Query if the Z-Wave subsystem is available at all.";
returns.insert("available", enumValueName(Bool));
registerMethod("IsZWaveAvailable", description, params, returns);
params.clear(); returns.clear();
description = "Get the list of available serial ports from the host system.";
returns.insert("serialPorts", objectRef<SerialPorts>());
registerMethod("GetSerialPorts", description, params, returns);
params.clear(); returns.clear();
description = "Get all the Z-Wave networks in the system.";
returns.insert("networks", QVariantList() << objectRef("ZWaveNetwork"));
registerMethod("GetNetworks", description, params, returns);
params.clear(); returns.clear();
description = "Add a new Z-Wave network with the given serial port.";
params.insert("serialPort", enumValueName(String));
returns.insert("o:networkUuid", enumValueName(Uuid));
returns.insert("zwaveError", enumRef<ZWave::ZWaveError>());
registerMethod("AddNetwork", description, params, returns);
params.clear(); returns.clear();
description = "Remove the given Z-Wave network from the system.";
params.insert("networkUuid", enumValueName(Uuid));
returns.insert("zwaveError", enumRef<ZWave::ZWaveError>());
registerMethod("RemoveNetwork", description, params, returns);
params.clear(); returns.clear();
description = "Start the node inclusion procedure for the given Z-Wave network.";
params.insert("networkUuid", enumValueName(Uuid));
returns.insert("zwaveError", enumRef<ZWave::ZWaveError>());
registerMethod("AddNode", description, params, returns);
params.clear(); returns.clear();
description = "Start the node removal procedure for the given Z-Wave network.";
params.insert("networkUuid", enumValueName(Uuid));
returns.insert("zwaveError", enumRef<ZWave::ZWaveError>());
registerMethod("RemoveNode", description, params, returns);
params.clear(); returns.clear();
description = "Cancel any running node inclusion or removal procedure for the given Z-Wave network.";
params.insert("networkUuid", enumValueName(Uuid));
returns.insert("zwaveError", enumRef<ZWave::ZWaveError>());
registerMethod("CancelPendingOperation", description, params, returns);
params.clear(); returns.clear();
description = "Remove the given failed node from the given Z-Wave network. This will not work if node is not marked as failed.";
params.insert("networkUuid", enumValueName(Uuid));
params.insert("nodeId", enumValueName(Uint));
returns.insert("zwaveError", enumRef<ZWave::ZWaveError>());
registerMethod("RemoveFailedNode", description, params, returns);
params.clear(); returns.clear();
description = "Factory reset the controller for the given Z-Wave network.";
params.insert("networkUuid", enumValueName(Uuid));
returns.insert("zwaveError", enumRef<ZWave::ZWaveError>());
registerMethod("FactoryResetNetwork", description, params, returns);
params.clear(); returns.clear();
description = "Get the list of nodes in a network";
params.insert("networkUuid", enumValueName(Uuid));
returns.insert("zwaveError", enumRef<ZWave::ZWaveError>());
returns.insert("o:nodes", QVariantList() << objectRef("ZWaveNode"));
registerMethod("GetNodes", description, params, returns);
// Notifications
params.clear();
description = "Emitted whenever a new Z-Wave network has been added to the system.";
params.insert("network", objectRef("ZWaveNetwork"));
registerNotification("NetworkAdded", description, params);
params.clear();
description = "Emitted whenever a Z-Wave network has been removed from the system.";
params.insert("networkUuid", enumValueName(Uuid));
registerNotification("NetworkRemoved", description, params);
params.clear();
description = "Emitted whenever a Z-Wave network changes.";
params.insert("network", objectRef("ZWaveNetwork"));
registerNotification("NetworkChanged", description, params);
params.clear();
description = "Emitted whenever a Z-Wave node is added.";
params.insert("networkUuid", enumValueName(Uuid));
params.insert("node", objectRef("ZWaveNode"));
registerNotification("NodeAdded", description, params);
params.clear();
description = "Emitted whenever a Z-Wave node has changed.";
params.insert("networkUuid", enumValueName(Uuid));
params.insert("node", objectRef("ZWaveNode"));
registerNotification("NodeChanged", description, params);
params.clear();
description = "Emitted whenever a Z-Wave node is removed.";
params.insert("networkUuid", enumValueName(Uuid));
params.insert("nodeId", enumValueName(Uint));
registerNotification("NodeRemoved", description, params);
connect(m_zwaveManager, &ZWaveManager::networkAdded, this, &ZWaveHandler::onNetworkAdded);
connect(m_zwaveManager, &ZWaveManager::networkChanged, this, &ZWaveHandler::onNetworkChanged);
connect(m_zwaveManager, &ZWaveManager::networkStateChanged, this, &ZWaveHandler::onNetworkChanged);
connect(m_zwaveManager, &ZWaveManager::networkRemoved, this, &ZWaveHandler::onNetworkRemoved);
connect(m_zwaveManager, &ZWaveManager::nodeAdded, this, &ZWaveHandler::onNodeAdded);
connect(m_zwaveManager, &ZWaveManager::nodeChanged, this, &ZWaveHandler::onNodeChanged);
connect(m_zwaveManager, &ZWaveManager::nodeRemoved, this, &ZWaveHandler::onNodeRemoved);
}
QString ZWaveHandler::name() const
{
return "ZWave";
}
JsonReply *ZWaveHandler::IsZWaveAvailable(const QVariantMap &params)
{
Q_UNUSED(params)
return createReply({{"available", m_zwaveManager->available()}});
}
JsonReply *ZWaveHandler::GetSerialPorts(const QVariantMap &params)
{
Q_UNUSED(params)
QVariantList portList;
foreach (const SerialPort &serialPort, m_zwaveManager->serialPorts()) {
portList << pack(serialPort);
}
return createReply({{"serialPorts", portList}});
}
JsonReply *ZWaveHandler::GetNetworks(const QVariantMap &params)
{
Q_UNUSED(params)
QVariantList networkList;
foreach (ZWaveNetwork *network, m_zwaveManager->networks()) {
networkList.append(packNetwork(network));
}
return createReply({{"networks", networkList}});
}
JsonReply *ZWaveHandler::AddNetwork(const QVariantMap &params)
{
QPair<ZWave::ZWaveError, QUuid> status = m_zwaveManager->createNetwork(params.value("serialPort").toString());
QVariantMap returns;
returns.insert("zwaveError", enumValueName(status.first));
if (status.first == ZWave::ZWaveErrorNoError) {
returns.insert("networkUuid", status.second);
}
return createReply(returns);
}
JsonReply *ZWaveHandler::RemoveNetwork(const QVariantMap &params)
{
QUuid networkUuid = params.value("networkUuid").toUuid();
ZWave::ZWaveError status = m_zwaveManager->removeNetwork(networkUuid);
return createReply({{"zwaveError", enumValueName(status)}});
}
JsonReply *ZWaveHandler::FactoryResetNetwork(const QVariantMap &params)
{
QUuid networkUuid = params.value("networkUuid").toUuid();
ZWave::ZWaveError status = m_zwaveManager->factoryResetNetwork(networkUuid);
return createReply({{"zwaveError", enumValueName(status)}});
}
JsonReply *ZWaveHandler::AddNode(const QVariantMap &params)
{
ZWaveReply *zwaveReply = m_zwaveManager->addNode(params.value("networkUuid").toUuid());
JsonReply *jsonReply = createAsyncReply("AddNode");
connect(zwaveReply, &ZWaveReply::finished, jsonReply, [jsonReply](ZWave::ZWaveError status) {
jsonReply->setData({{"zwaveError", enumValueName(status)}});
jsonReply->finished();
});
return jsonReply;
}
JsonReply *ZWaveHandler::GetNodes(const QVariantMap &params)
{
QUuid networkUuid = params.value("networkUuid").toUuid();
ZWaveNetwork *network = m_zwaveManager->network(networkUuid);
if (!network) {
return createReply({{"zwaveError", enumValueName(ZWave::ZWaveErrorNetworkUuidNotFound)}});
}
ZWaveNodes nodes = m_zwaveManager->network(networkUuid)->nodes();
QVariantList nodeList;
foreach (ZWaveNode *node, nodes) {
nodeList.append(packNode(node));
}
return createReply({
{"zwaveError", enumValueName(ZWave::ZWaveErrorNoError)},
{"nodes", nodeList}
});
}
JsonReply *ZWaveHandler::RemoveNode(const QVariantMap &params)
{
QUuid networkUuid = params.value("networkUuid").toUuid();
JsonReply *jsonReply = createAsyncReply("RemoveNode");
ZWaveReply *zwaveReply = m_zwaveManager->removeNode(networkUuid);
connect(zwaveReply, &ZWaveReply::finished, jsonReply, [jsonReply](ZWave::ZWaveError status) {
jsonReply->setData({{"zwaveError", enumValueName(status)}});
jsonReply->finished();
});
return jsonReply;
}
JsonReply *ZWaveHandler::RemoveFailedNode(const QVariantMap &params)
{
QUuid networkUuid = params.value("networkUuid").toUuid();
quint8 nodeId = params.value("nodeId").toUInt();
m_zwaveManager->removeFailedNode(networkUuid, nodeId);
return createReply({{"zwaveError", enumValueName(ZWave::ZWaveErrorNoError)}});
}
JsonReply *ZWaveHandler::CancelPendingOperation(const QVariantMap &params)
{
QUuid networkUuid = params.value("networkUuid").toUuid();
m_zwaveManager->cancelPendingOperation(networkUuid);
return createReply({{"zwaveError", enumValueName(ZWave::ZWaveErrorNoError)}});
}
void ZWaveHandler::onNetworkAdded(ZWaveNetwork *network)
{
emit NetworkAdded({{"network", packNetwork(network)}});
}
void ZWaveHandler::onNetworkChanged(ZWaveNetwork *network)
{
emit NetworkChanged({{"network", packNetwork(network)}});
}
void ZWaveHandler::onNetworkRemoved(const QUuid &networkUuid)
{
emit NetworkRemoved({{"networkUuid", networkUuid.toString()}});
}
void ZWaveHandler::onNodeAdded(ZWaveNode *node)
{
emit NodeAdded({{"networkUuid", node->networkUuid()}, {"node", packNode(node)}});
}
void ZWaveHandler::onNodeChanged(ZWaveNode *node)
{
emit NodeChanged({{"networkUuid", node->networkUuid()}, {"node", packNode(node)}});
}
void ZWaveHandler::onNodeRemoved(ZWaveNode *node)
{
emit NodeRemoved({{"networkUuid", node->networkUuid()}, {"nodeId", node->nodeId()}});
}
QVariantMap ZWaveHandler::packNetwork(ZWaveNetwork *network)
{
return {
{"networkUuid", network->networkUuid()},
{"serialPort", network->serialPort()},
{"networkState", enumValueName(network->networkState())},
{"homeId", network->homeId()},
{"isZWavePlus", network->isZWavePlus()},
{"isPrimaryController", network->isPrimaryController()},
{"isStaticUpdateController", network->isStaticUpdateController()},
{"isBridgeController", network->isBridgeController()},
{"waitingForNodeAddition", network->waitingForNodeAddition()},
{"waitingForNodeRemoval", network->waitingForNodeRemoval()}
};
}
QVariantMap ZWaveHandler::packNode(ZWaveNode *node)
{
return {
{"nodeId", node->nodeId()},
{"networkUuid", node->networkUuid()},
{"initialized", node->initialized()},
{"reachable", node->reachable()},
{"failed", node->failed()},
{"sleeping", node->sleeping()},
{"linkQuality", node->linkQuality()},
{"securityMode", node->securityMode()},
{"nodeType", enumValueName(node->nodeType())},
{"role", enumValueName(node->role())},
{"deviceType", enumValueName(node->deviceType())},
{"productType", node->productType()},
{"productId", node->productId()},
{"productName", node->productName()},
{"manufacturerId", node->manufacturerId()},
{"manufacturerName", node->manufacturerName()},
{"version", node->version()},
{"isZWavePlusDevice", node->isZWavePlusDevice()},
{"isSecurityDevice", node->isSecurityDevice()},
{"isBeamingDevice", node->isBeamingDevice()}
};
}
}

View File

@ -0,0 +1,92 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEHANDLER_H
#define ZWAVEHANDLER_H
#include "jsonrpc/jsonhandler.h"
#include "zwave/zwavemanager.h"
#include <QObject>
namespace nymeaserver
{
class ZWaveHandler : public JsonHandler
{
Q_OBJECT
public:
explicit ZWaveHandler(ZWaveManager *zwaveManager, QObject *parent = nullptr);
QString name() const override;
Q_INVOKABLE JsonReply *IsZWaveAvailable(const QVariantMap &params);
Q_INVOKABLE JsonReply *GetSerialPorts(const QVariantMap &params);
Q_INVOKABLE JsonReply *GetNetworks(const QVariantMap &params);
Q_INVOKABLE JsonReply *AddNetwork(const QVariantMap &params);
Q_INVOKABLE JsonReply *RemoveNetwork(const QVariantMap &params);
Q_INVOKABLE JsonReply *FactoryResetNetwork(const QVariantMap &params);
Q_INVOKABLE JsonReply *GetNodes(const QVariantMap &params);
Q_INVOKABLE JsonReply *AddNode(const QVariantMap &params);
Q_INVOKABLE JsonReply *RemoveNode(const QVariantMap &params);
Q_INVOKABLE JsonReply *RemoveFailedNode(const QVariantMap &params);
Q_INVOKABLE JsonReply *CancelPendingOperation(const QVariantMap &params);
signals:
void NetworkAdded(const QVariantMap &params);
void NetworkChanged(const QVariantMap &params);
void NetworkRemoved(const QVariantMap &params);
void NodeAdded(const QVariantMap &params);
void NodeChanged(const QVariantMap &params);
void NodeRemoved(const QVariantMap &params);
private slots:
void onNetworkAdded(ZWaveNetwork *network);
void onNetworkChanged(ZWaveNetwork *network);
void onNetworkRemoved(const QUuid &networkUuid);
void onNodeAdded(ZWaveNode *node);
void onNodeChanged(ZWaveNode *node);
void onNodeRemoved(ZWaveNode *node);
private:
QVariantMap packNetwork(ZWaveNetwork *network);
QVariantMap packNode(ZWaveNode *node);
private:
ZWaveManager *m_zwaveManager = nullptr;
};
}
#endif // ZWAVEHANDLER_H

View File

@ -60,6 +60,10 @@ RESOURCES += $$top_srcdir/icons.qrc \
HEADERS += nymeacore.h \
hardware/network/macaddressdatabasereplyimpl.h \
hardware/serialport/serialportmonitor.h \
hardware/zwave/zwavehardwareresourceimplementation.h \
zwave/zwavedevicedatabase.h \
zwave/zwavemanagerreply.h \
zwave/zwavenodeimplementation.h \
integrations/apikeysprovidersloader.h \
integrations/plugininfocache.h \
integrations/python/pyapikeystorage.h \
@ -74,6 +78,7 @@ HEADERS += nymeacore.h \
experiences/experiencemanager.h \
jsonrpc/modbusrtuhandler.h \
jsonrpc/zigbeehandler.h \
jsonrpc/zwavehandler.h \
ruleengine/ruleengine.h \
ruleengine/rule.h \
ruleengine/stateevaluator.h \
@ -159,12 +164,19 @@ HEADERS += nymeacore.h \
platform/platform.h \
zigbee/zigbeeadapter.h \
zigbee/zigbeeadapters.h \
zigbee/zigbeemanager.h
zigbee/zigbeemanager.h \
zwave/zwaveadapter.h \
zwave/zwavemanager.h \
zwave/zwavenetwork.h \
SOURCES += nymeacore.cpp \
hardware/network/macaddressdatabasereplyimpl.cpp \
hardware/serialport/serialportmonitor.cpp \
hardware/zwave/zwavehardwareresourceimplementation.cpp \
zwave/zwavedevicedatabase.cpp \
zwave/zwavemanagerreply.cpp \
zwave/zwavenodeimplementation.cpp \
integrations/apikeysprovidersloader.cpp \
integrations/plugininfocache.cpp \
integrations/thingmanagerimplementation.cpp \
@ -172,6 +184,7 @@ SOURCES += nymeacore.cpp \
experiences/experiencemanager.cpp \
jsonrpc/modbusrtuhandler.cpp \
jsonrpc/zigbeehandler.cpp \
jsonrpc/zwavehandler.cpp \
ruleengine/ruleengine.cpp \
ruleengine/rule.cpp \
ruleengine/stateevaluator.cpp \
@ -256,7 +269,10 @@ SOURCES += nymeacore.cpp \
platform/platform.cpp \
zigbee/zigbeeadapter.cpp \
zigbee/zigbeeadapters.cpp \
zigbee/zigbeemanager.cpp
zigbee/zigbeemanager.cpp \
zwave/zwaveadapter.cpp \
zwave/zwavemanager.cpp \
zwave/zwavenetwork.cpp \
versionAtLeast(QT_VERSION, 5.12.0) {
message("Building with JS plugin support")

View File

@ -53,6 +53,7 @@
#include "zigbee/zigbeemanager.h"
#include "zwave/zwavemanager.h"
#include "hardware/modbus/modbusrtumanager.h"
#include "hardware/serialport/serialportmonitor.h"
@ -108,17 +109,20 @@ void NymeaCore::init(const QStringList &additionalInterfaces) {
qCDebug(dcCore) << "Creating Server Manager";
m_serverManager = new ServerManager(m_platform, m_configuration, additionalInterfaces, this);
qCDebug(dcCore()) << "Create Serial Port Monitor";
m_serialPortMonitor = new SerialPortMonitor(this);
qCDebug(dcCore()) << "Create Zigbee Manager";
m_zigbeeManager = new ZigbeeManager(this);
qCDebug(dcCore()) << "Create Serial Port Monitor";
m_serialPortMonitor = new SerialPortMonitor(this);
qCDebug(dcCore()) << "Creating ZWave Manager";
m_zwaveManager = new ZWaveManager(m_serialPortMonitor, this);
qCDebug(dcCore()) << "Create Modbus RTU Manager";
m_modbusRtuManager = new ModbusRtuManager(m_serialPortMonitor, this);
qCDebug(dcCore) << "Creating Hardware Manager";
m_hardwareManager = new HardwareManagerImplementation(m_platform, m_serverManager->mqttBroker(), m_zigbeeManager, m_modbusRtuManager, this);
m_hardwareManager = new HardwareManagerImplementation(m_platform, m_serverManager->mqttBroker(), m_zigbeeManager, m_zwaveManager, m_modbusRtuManager, this);
qCDebug(dcCore) << "Creating Thing Manager (locale:" << m_configuration->locale() << ")";
m_thingManager = new ThingManagerImplementation(m_hardwareManager, m_configuration->locale(), this);
@ -660,6 +664,11 @@ ZigbeeManager *NymeaCore::zigbeeManager() const
return m_zigbeeManager;
}
ZWaveManager *NymeaCore::zwaveManager() const
{
return m_zwaveManager;
}
ModbusRtuManager *NymeaCore::modbusRtuManager() const
{
return m_modbusRtuManager;

View File

@ -67,6 +67,7 @@ class ExperienceManager;
class ScriptEngine;
class CloudManager;
class ZigbeeManager;
class ZWaveManager;
class ModbusRtuManager;
class SerialPortMonitor;
@ -109,6 +110,7 @@ public:
TagsStorage *tagsStorage() const;
Platform *platform() const;
ZigbeeManager *zigbeeManager() const;
ZWaveManager *zwaveManager() const;
ModbusRtuManager *modbusRtuManager() const;
static QStringList getAvailableLanguages();
@ -154,6 +156,7 @@ private:
System *m_system;
ExperienceManager *m_experienceManager;
ZigbeeManager *m_zigbeeManager;
ZWaveManager *m_zwaveManager;
SerialPortMonitor *m_serialPortMonitor;
ModbusRtuManager *m_modbusRtuManager;

View File

@ -0,0 +1,77 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwaveadapter.h"
ZWaveAdapter::ZWaveAdapter()
{
}
QString ZWaveAdapter::serialPort() const
{
return m_serialPort;
}
void ZWaveAdapter::setSerialPort(const QString &serialPort)
{
m_serialPort = serialPort;
}
ZWaveAdapters::ZWaveAdapters()
{
}
ZWaveAdapters::ZWaveAdapters(const QList<ZWaveAdapter> &other):
QList<ZWaveAdapter>(other)
{
}
bool ZWaveAdapters::hasSerialPort(const QString &serialPort)
{
foreach (const ZWaveAdapter &adapter, *this) {
if (adapter.serialPort() == serialPort) {
return true;
}
}
return false;
}
QVariant ZWaveAdapters::get(int index) const
{
return QVariant::fromValue(at(index));
}
void ZWaveAdapters::put(const QVariant &variant)
{
append(variant.value<ZWaveAdapter>());
}

View File

@ -0,0 +1,66 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEADAPTER_H
#define ZWAVEADAPTER_H
#include <QObject>
#include <QVariant>
class ZWaveAdapter
{
Q_GADGET
Q_PROPERTY(QString serialPort READ serialPort)
public:
ZWaveAdapter();
QString serialPort() const;
void setSerialPort(const QString &serialPort);
private:
QString m_serialPort;
};
class ZWaveAdapters: public QList<ZWaveAdapter>
{
Q_GADGET
Q_PROPERTY(int count READ count)
public:
ZWaveAdapters();
ZWaveAdapters(const QList<ZWaveAdapter> &other);
bool hasSerialPort(const QString &serialPort);
Q_INVOKABLE QVariant get(int index) const;
Q_INVOKABLE void put(const QVariant &variant);
};
#endif // ZWAVEADAPTER_H

View File

@ -0,0 +1,282 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavedevicedatabase.h"
#include <QDir>
#include <QFileInfo>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlResult>
#include "hardware/zwave/zwavenode.h"
#include "zwavenodeimplementation.h"
#include "logging/logvaluetool.h"
#include "loggingcategories.h"
Q_DECLARE_LOGGING_CATEGORY(dcZWave)
namespace nymeaserver
{
ZWaveDeviceDatabase::ZWaveDeviceDatabase(const QString &path, const QUuid &networkUuid):
m_path(path),
m_networkUuid(networkUuid)
{
}
bool ZWaveDeviceDatabase::initDB()
{
m_db.close();
QDir path(m_path);
if (!path.exists()) {
if (!path.mkpath(path.path())) {
qCCritical(dcZWave) << "Unable to create ZWave divce database path";
return false;
}
}
QString networkUuidString = m_networkUuid.toString().remove(QRegExp("[{}]"));
m_db = QSqlDatabase::addDatabase("QSQLITE", "ZWaveDevices-" + networkUuidString);
m_db.setDatabaseName(path.absoluteFilePath("zwave-network-" + networkUuidString + ".db"));
bool opened = m_db.open();
if (!opened) {
qCCritical(dcZWave()) << "Cannot open ZWave device DB at" << m_db.databaseName() << m_db.lastError();
return false;
}
if (!m_db.tables().contains("metadata")) {
qCDebug(dcZWave()) << "No \"metadata\" table in database. Creating it.";
m_db.exec("CREATE TABLE metadata (version INT);");
m_db.exec("INSERT INTO metadata (version) VALUES (1);");
if (m_db.lastError().isValid()) {
qCCritical(dcZWave()) << "Error creating metadata table in devie database. Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText();
return false;
}
}
if (!m_db.tables().contains("nodes")) {
qCDebug(dcZWave()) << "No \"nodes\" table in database. Creating it.";
m_db.exec("CREATE TABLE nodes "
"("
"nodeId INT PRIMARY KEY NOT NULL,"
"basicType INT,"
"deviceType INT,"
"plusDeviceType INT,"
"manufacturerId INT,"
"manufacturerName TEXT,"
"name TEXT,"
"productId INT,"
"productName TEXT,"
"productType INT,"
"isZWavePlus INT,"
"isSecure INT,"
"isBeaming INT,"
"version INT"
");");
if (m_db.lastError().isValid()) {
qCCritical(dcZWave()) << "Error creating nodes table in devices database. Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText();
return false;
}
}
if (!m_db.tables().contains("nodevalues")) {
qCDebug(dcZWave()) << "No \"nodevalues\" table in database. Creating it.";
m_db.exec("CREATE TABLE nodevalues "
"("
"valueId INT PRIMARY KEY NOT NULL,"
"nodeId INT,"
"valueGenre INT,"
"commandClass INT,"
"instance INT,"
"idx INT,"
"type INT,"
"value TEXT,"
"valueSelection INT,"
"description TEXT,"
"FOREIGN KEY (nodeId) REFERENCES nodes(nodeId)"
");");
if (m_db.lastError().isValid()) {
qCCritical(dcZWave()) << "Error creating nodevalues table in device database. Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText();
return false;
}
}
qCInfo(dcZWave()) << "Initialized devices DB successfully." << m_db.databaseName();
return true;
}
void ZWaveDeviceDatabase::removeDB()
{
m_db.close();
QFile::remove(m_db.databaseName());
}
void ZWaveDeviceDatabase::clearDB()
{
QSqlQuery query(m_db);
query.prepare("DELETE FROM nodes;");
if (!query.exec()) {
qCWarning(dcZWave) << "Error clearing node db:" << query.lastError().databaseText() << query.lastError().driverText();
qCDebug(dcZWave) << "Query was:" << query.executedQuery();
return;
}
}
void ZWaveDeviceDatabase::storeNode(ZWaveNode *node)
{
QSqlQuery query(m_db);
query.prepare("INSERT OR REPLACE INTO nodes(nodeId, basicType, deviceType, plusDeviceType, manufacturerId, manufacturerName, name, productId, productName, productType, isZWavePlus, isSecure, isBeaming, version) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
query.addBindValue(node->nodeId());
query.addBindValue(node->nodeType());
query.addBindValue(node->deviceType());
query.addBindValue(node->plusDeviceType());
query.addBindValue(node->manufacturerId());
query.addBindValue(node->manufacturerName());
query.addBindValue(node->name());
query.addBindValue(node->productId());
query.addBindValue(node->productName());
query.addBindValue(node->productType());
query.addBindValue(node->isZWavePlusDevice());
query.addBindValue(node->isSecurityDevice());
query.addBindValue(node->isBeamingDevice());
query.addBindValue(node->version());
if (!query.exec()) {
qCWarning(dcZWave) << "Error inserting node into db:" << query.lastError().databaseText() << query.lastError().driverText();
qCDebug(dcZWave) << "Query was:" << query.executedQuery();
return;
}
foreach (const ZWaveValue &value, node->values()) {
storeValue(node, value.id());
}
}
void ZWaveDeviceDatabase::removeNode(quint8 nodeId)
{
QSqlQuery query(m_db);
query.prepare("DELETE FROM nodes WHERE nodeId = ?;");
query.addBindValue(nodeId);
if (!query.exec()) {
qCWarning(dcZWave) << "Error removing node from db:" << query.lastError().databaseText() << query.lastError().driverText();
qCDebug(dcZWave) << "Query was:" << query.executedQuery();
return;
}
}
void ZWaveDeviceDatabase::storeValue(ZWaveNode *node, quint64 valueId)
{
ZWaveValue value = node->value(valueId);
QSqlQuery query(m_db);
query.prepare("INSERT OR REPLACE INTO nodevalues(valueId, nodeId, valueGenre, commandClass, instance, idx, type, value, valueSelection, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
query.addBindValue(value.id());
query.addBindValue(node->nodeId());
query.addBindValue(value.genre());
query.addBindValue(value.commandClass());
query.addBindValue(value.instance());
query.addBindValue(value.index());
query.addBindValue(value.type());
query.addBindValue(LogValueTool::serializeValue(value.value()));
query.addBindValue(value.valueListSelection());
query.addBindValue(value.description());
if (!query.exec()) {
qCWarning(dcZWave) << "Unable to store node value:" << query.lastError().databaseText();
}
}
void ZWaveDeviceDatabase::removeValue(ZWaveNode *node, quint64 valueId)
{
QSqlQuery query(m_db);
query.prepare("DELETE FROM nodevalues WHERE nodeId = ? AND valueId = ?;");
query.addBindValue(node->nodeId());
query.addBindValue(valueId);
if (!query.exec()) {
qCWarning(dcZWave) << "Unable to remove node value from DB:" << query.lastError().databaseText();
}
}
ZWaveNodes ZWaveDeviceDatabase::createNodes(ZWaveManager *manager)
{
ZWaveNodes ret;
QSqlQuery query(m_db);
query.prepare("SELECT * FROM nodes;");
if (!query.exec()) {
qCWarning(dcZWave()) << "Unable to query nodes from DB" << query.lastError().databaseText();
return ret;
}
while (query.next()) {
quint8 nodeId = query.value("nodeId").toUInt();
ZWaveNodeImplementation *node = new ZWaveNodeImplementation(manager, m_networkUuid, nodeId);
node->setNodeType(static_cast<ZWaveNode::ZWaveNodeType>(query.value("basicType").toInt()));
node->setDeviceType(static_cast<ZWaveNode::ZWaveDeviceType>(query.value("deviceType").toInt()));
node->setPlusDeviceType(static_cast<ZWaveNode::ZWavePlusDeviceType>(query.value("plusDeviceType").toInt()));
node->setManufacturerId(query.value("manufacturerId").toUInt());
node->setManufacturerName(query.value("manufacturerName").toString());
node->setName(query.value("name").toString());
node->setProductId(query.value("productId").toUInt());
node->setProductName(query.value("productName").toString());
node->setProductType(query.value("productType").toUInt());
node->setIsZWavePlusDevice(query.value("isZWavePlus").toBool());
node->setIsSecurityDevice(query.value("isSecure").toBool());
node->setIsBeamingDevice(query.value("isBeaming").toBool());
node->setVersion(query.value("version").toUInt());
QSqlQuery valueQuery(m_db);
valueQuery.prepare("SELECT * FROM nodevalues WHERE nodeId = ?;");
valueQuery.addBindValue(nodeId);
if (!valueQuery.exec()) {
qCWarning(dcZWave) << "Unable to query node values from DB" << query.lastError().databaseText();
continue;
}
while (valueQuery.next()) {
ZWaveValue value(
valueQuery.value("valueId").toULongLong(),
static_cast<ZWaveValue::Genre>(valueQuery.value("valueGenre").toInt()),
static_cast<ZWaveValue::CommandClass>(valueQuery.value("commandClass").toUInt()),
valueQuery.value("instance").toUInt(),
valueQuery.value("idx").toUInt(),
static_cast<ZWaveValue::Type>(valueQuery.value("type").toInt()),
valueQuery.value("description").toString());
value.setValue(LogValueTool::deserializeValue(valueQuery.value("value").toString()), valueQuery.value("valueSelection").toInt());
node->updateValue(value);
}
ret.append(node);
}
return ret;
}
}

View File

@ -0,0 +1,66 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEDEVICEDATABASE_H
#define ZWAVEDEVICEDATABASE_H
#include <QSqlDatabase>
#include "hardware/zwave/zwavenode.h"
namespace nymeaserver
{
class ZWaveManager;
class ZWaveDeviceDatabase
{
public:
explicit ZWaveDeviceDatabase(const QString &path, const QUuid &networkUuid);
bool initDB();
void removeDB();
void clearDB();
void storeNode(ZWaveNode *node);
void removeNode(quint8 nodeId);
void storeValue(ZWaveNode *node, quint64 valueId);
void removeValue(ZWaveNode *node, quint64 valueId);
ZWaveNodes createNodes(ZWaveManager *manager);
private:
QString m_path;
QUuid m_networkUuid;
QSqlDatabase m_db;
};
}
#endif // ZWAVEDEVICEDATABASE_H

View File

@ -0,0 +1,722 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavemanager.h"
#include "hardware/zwave/zwavebackend.h"
#include "zwavemanagerreply.h"
#include "zwave/zwavenodeimplementation.h"
#include "nymeasettings.h"
#include <QSerialPortInfo>
#include <QCoreApplication>
#include <QDir>
#include <QPluginLoader>
#include <QStringList>
namespace nymeaserver
{
ZWaveManager::ZWaveManager(SerialPortMonitor *serialPortMonitor, QObject *parent):
QObject(parent),
m_serialPortMonitor(serialPortMonitor)
{
qRegisterMetaType<ZWave::ZWaveError>();
qRegisterMetaType<ZWaveValue::Genre>();
qRegisterMetaType<ZWaveValue::CommandClass>();
#ifdef WITH_OPENZWAVE
m_backend = new OpenZWaveBackend(this);
#endif
if (!loadBackend()) {
qCInfo(dcZWave()) << "No Z-Wave backend found. Z-Wave support will be disabled.";
return;
}
loadZWaveNetworks();
connect(m_backend, &ZWaveBackend::networkStarted, this, &ZWaveManager::onNetworkStarted);
connect(m_backend, &ZWaveBackend::networkFailed, this, &ZWaveManager::onNetworkFailed);
connect(m_backend, &ZWaveBackend::waitingForNodeAdditionChanged, this, &ZWaveManager::onWaitingForNodeAdditionChanged);
connect(m_backend, &ZWaveBackend::waitingForNodeRemovalChanged, this, &ZWaveManager::onWaitingForNodeRemovalChanged);
connect(m_backend, &ZWaveBackend::nodeAdded, this, &ZWaveManager::onNodeAdded);
connect(m_backend, &ZWaveBackend::nodeInitialized, this, &ZWaveManager::onNodeInitialized);
connect(m_backend, &ZWaveBackend::nodeRemoved, this, &ZWaveManager::onNodeRemoved);
connect(m_backend, &ZWaveBackend::nodeDataChanged, this, &ZWaveManager::onNodeDataChanged);
connect(m_backend, &ZWaveBackend::nodeReachableStatus, this, &ZWaveManager::onNodeReachableStatus);
connect(m_backend, &ZWaveBackend::nodeFailedStatus, this, &ZWaveManager::onNodeFailedStatus);
connect(m_backend, &ZWaveBackend::nodeSleepStatus, this, &ZWaveManager::onNodeSleepStatus);
connect(m_backend, &ZWaveBackend::nodeLinkQualityStatus, this, &ZWaveManager::onNodeLinkQualityStatus);
connect(m_backend, &ZWaveBackend::valueAdded, this, &ZWaveManager::onValueAdded);
connect(m_backend, &ZWaveBackend::valueChanged, this, &ZWaveManager::onValueChanged);
connect(m_backend, &ZWaveBackend::valueRemoved, this, &ZWaveManager::onValueRemoved);
}
ZWaveManager::~ZWaveManager()
{
}
bool ZWaveManager::available() const
{
return m_backend != nullptr;
}
bool ZWaveManager::enabled() const
{
return true; // TODO
}
void ZWaveManager::setEnabled(bool enabled)
{
Q_UNUSED(enabled)
// TODO
}
SerialPorts ZWaveManager::serialPorts() const
{
SerialPorts serialPorts;
// FIXME: There should be a mechanism in SerialPortMonitor so that resources can claim a port and it won't show
// up any more in other resources.
foreach (const SerialPort &serialPort, m_serialPortMonitor->serialPorts()) {
bool used = false;
foreach (ZWaveNetwork *network, m_networks) {
if (network->serialPort() == serialPort.portName()) {
used = true;
}
}
if (!used) {
serialPorts.append(serialPort);
}
}
return serialPorts;
}
void ZWaveManager::loadZWaveNetworks()
{
NymeaSettings settings(NymeaSettings::SettingsRoleZWave);
qCDebug(dcZWave()) << "Loading ZWave networks from" << settings.fileName();
settings.beginGroup("Networks");
foreach (const QString &uuidString, settings.childGroups()) {
settings.beginGroup(uuidString);
QString serialPort = settings.value("serialPort").toString();
quint32 homeId = settings.value("homeId").toULongLong();
QString networkKey = settings.value("networkKey").toString();
quint8 controllerNodeId = settings.value("controllerNodeId").toUInt();
bool isZWavePlus = settings.value("isZWavePlus").toBool();
bool isPrimaryController = settings.value("isPrimaryController").toBool();
bool isStaticUpdateController = settings.value("isStaticUpdateController").toBool();
settings.endGroup(); // uuid
ZWaveNetwork *network = new ZWaveNetwork(QUuid(uuidString), serialPort, networkKey, this);
network->setHomeId(homeId);
network->setControllerNodeId(controllerNodeId);
network->setIsZWavePlus(isZWavePlus);
network->setIsPrimaryController(isPrimaryController);
network->setIsStaticUpdateController(isStaticUpdateController);
loadNetwork(network);
qCInfo(dcZWave) << "Loaded network" << uuidString << "with" << network->nodes().count() << "nodes";
foreach (ZWaveNode *node, network->nodes()) {
qCDebug(dcZWave) << node;
}
}
settings.endGroup(); // Networks
}
bool ZWaveManager::loadNetwork(ZWaveNetwork *network)
{
bool success = m_backend->startNetwork(network->networkUuid(), network->serialPort(), network->networkKey());
if (!success) {
return false;
}
ZWaveDeviceDatabase *db = new ZWaveDeviceDatabase(NymeaSettings::settingsPath(), network->networkUuid());
if (!db->initDB()) {
qCCritical(dcZWave()) << "Unable to initialize ZWave device database";
delete db;
return false;
}
m_networks.insert(network->networkUuid(), network);
m_dbs.insert(network->networkUuid(), db);
foreach (ZWaveNode *n, db->createNodes(this)) {
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(n);
node->setInitialized(true);
connect(node, &ZWaveNodeImplementation::nodeChanged, this, [this, node](){emit nodeChanged(node);});
network->addNode(node);
}
network->setNetworkState(ZWaveNetwork::ZWaveNetworkStateStarting);
emit networkStateChanged(network);
return true;
}
void ZWaveManager::storeNetwork(ZWaveNetwork *network)
{
NymeaSettings settings(NymeaSettings::SettingsRoleZWave);
settings.beginGroup("Networks");
settings.beginGroup(network->networkUuid().toString());
settings.setValue("serialPort", network->serialPort());
settings.setValue("homeId", network->homeId());
settings.setValue("networkKey", network->networkKey());
settings.setValue("controllerNodeId", network->controllerNodeId());
settings.setValue("isZWavePlus", network->isZWavePlus());
settings.setValue("isPrimaryController", network->isPrimaryController());
settings.setValue("isStaticUpdateController", network->isStaticUpdateController());
settings.endGroup();
settings.endGroup();
}
void ZWaveManager::onNetworkStarted(const QUuid &networkUuid)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a network started signal for a network we don't know:" << networkUuid.toString();
return;
}
network->setHomeId(m_backend->homeId(networkUuid));
network->setControllerNodeId(m_backend->controllerNodeId(networkUuid));
network->setIsPrimaryController(m_backend->isPrimaryController(networkUuid));
network->setIsStaticUpdateController(m_backend->isStaticUpdateController(networkUuid));
network->setIsBridgeController(m_backend->isBridgeController(networkUuid));
qCDebug(dcZWave()) << "Network started" << network->networkUuid().toString();
storeNetwork(network);
emit networkChanged(network);
network->setNetworkState(ZWaveNetwork::ZWaveNetworkStateOnline);
emit networkStateChanged(network);
foreach (ZWaveNode *n, network->nodes()) {
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(n);
if (node->failed() != m_backend->isNodeFailed(networkUuid, node->nodeId())) {
node->setFailed(m_backend->isNodeFailed(networkUuid, node->nodeId()));
emit nodeChanged(node);
}
qCDebug(dcZWave) << "Node" << node->productName() << "is failed:" << node->failed() << "awake:" << m_backend->isNodeAwake(networkUuid, node->nodeId());
}
}
void ZWaveManager::onNetworkFailed(const QUuid &networkUuid)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a network failed signal for a network we don't know:" << networkUuid.toString();
return;
}
qCWarning(dcZWave()).nospace() << "Failed to initialize adapter for network " << network->networkUuid().toString() << " at " << network->serialPort() << ". Retrying in 5 seconds...";
network->setNetworkState(ZWaveNetwork::ZWaveNetworkStateError);
emit networkStateChanged(network);
// As long as the network exists, keep retrying...
QTimer::singleShot(5000, network, [this, network]() {
qCInfo(dcZWave()) << "Retrying to initialize adapter for network" << network->networkUuid().toString() << "at" << network->serialPort();
network->setNetworkState(ZWaveNetwork::ZWaveNetworkStateStarting);
emit networkStateChanged(network);
if (!m_backend->startNetwork(network->networkUuid(), network->serialPort())) {
onNetworkFailed(network->networkUuid());
}
});
}
void ZWaveManager::onWaitingForNodeAdditionChanged(const QUuid &networkUuid, bool waitingForNodeAddition)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a network waiting for node addition changed signal for a network we don't know:" << networkUuid.toString();
return;
}
network->setWaitingForNodeAddition(waitingForNodeAddition);
emit networkChanged(network);
}
void ZWaveManager::onWaitingForNodeRemovalChanged(const QUuid &networkUuid, bool waitingForNodeRemoval)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a network waiting for node addition changed signal for a network we don't know:" << networkUuid.toString();
return;
}
network->setWaitingForNodeRemoval(waitingForNodeRemoval);
emit networkChanged(network);
}
void ZWaveManager::onNodeAdded(const QUuid &networkUuid, quint8 nodeId)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a node added signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(network->node(nodeId));
if (node) {
qCDebug(dcZWave()) << "Received a new node signal for a node we already know:" << nodeId;
return;
}
qCInfo(dcZWave()) << "New node with ID" << nodeId << "joined the network" << network->networkUuid();
node = new ZWaveNodeImplementation(this, network->networkUuid(), nodeId, this);
connect(node, &ZWaveNodeImplementation::nodeChanged, this, [this, node](){emit nodeChanged(node);});
network->addNode(node);
emit nodeAdded(node);
}
void ZWaveManager::onNodeInitialized(const QUuid &networkUuid, quint8 nodeId)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a node initialized signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(network->node(nodeId));
if (!node) {
qCWarning(dcZWave()) << "Received a node initialized signal for a node we don't know:" << nodeId;
return;
}
node->setReachable(true);
m_dbs.value(network->networkUuid())->storeNode(node);
if (!node->initialized()) {
node->setInitialized(true);
emit nodeInitialized(node);
}
qCInfo(dcZWave()) << "Node initialized:" << node->nodeId();
emit nodeChanged(node);
}
void ZWaveManager::onNodeDataChanged(const QUuid &networkUuid, quint8 nodeId)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a node names changed signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(network->node(nodeId));
if (!node) {
qCWarning(dcZWave()) << "Received a node names changed signal for a node we don't know:" << nodeId;
return;
}
qCDebug(dcZWave()) << "Node names changed for node" << nodeId << "in network" << network->networkUuid();
node->blockSignals(true);
node->setName(m_backend->nodeName(networkUuid, nodeId));
node->setNodeType(m_backend->nodeType(networkUuid, nodeId));
node->setRole(m_backend->nodeRole(networkUuid, nodeId));
node->setDeviceType(m_backend->nodeDeviceType(networkUuid, nodeId));
node->setManufacturerId(m_backend->nodeManufacturerId(networkUuid, nodeId));
node->setManufacturerName(m_backend->nodeManufacturerName(networkUuid, nodeId));
node->setProductId(m_backend->nodeProductId(networkUuid, nodeId));
node->setProductName(m_backend->nodeProductName(networkUuid, nodeId));
node->setProductType(m_backend->nodeProductType(networkUuid, nodeId));
node->setVersion(m_backend->nodeVersion(networkUuid, nodeId));
node->setIsZWavePlusDevice(m_backend->nodeIsZWavePlus(networkUuid, nodeId));
node->setIsSecurityDevice(m_backend->nodeIsSecureDevice(networkUuid, nodeId));
node->setSecurityMode(m_backend->nodeSecurityMode(networkUuid, nodeId));
node->setIsBeamingDevice(m_backend->nodeIsBeamingDevice(networkUuid, nodeId));
node->setPlusDeviceType(m_backend->nodePlusDeviceType(networkUuid, nodeId));
node->blockSignals(false);
emit nodeChanged(node);
m_dbs.value(network->networkUuid())->storeNode(node);
if (node->nodeId() == network->controllerNodeId()) {
network->setIsZWavePlus(m_backend->nodeIsZWavePlus(networkUuid, network->controllerNodeId()));
emit networkChanged(network);
}
}
void ZWaveManager::onNodeReachableStatus(const QUuid &networkUuid, quint8 nodeId, bool reachable)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a node reachable changed signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(network->node(nodeId));
if (!node) {
qCWarning(dcZWave()) << "Received a node reachable status signal for a node we don't know:" << nodeId;
return;
}
qCInfo(dcZWave()) << "Node" << nodeId << "in network" << network->networkUuid().toString() << "is" << (reachable ? "reachable" : "not reachable");
node->setReachable(reachable);
}
void ZWaveManager::onNodeFailedStatus(const QUuid &networkUuid, quint8 nodeId, bool failed)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a node failed status signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(network->node(nodeId));
if (!node) {
qCWarning(dcZWave()) << "Received a node reachable changed signal for a node we don't know:" << nodeId;
return;
}
qCInfo(dcZWave()) << "Node" << nodeId << "in network" << network->networkUuid().toString() << "is" << (failed ? "failed" : "ok");
node->setFailed(failed);
}
void ZWaveManager::onNodeSleepStatus(const QUuid &networkUuid, quint8 nodeId, bool sleeping)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a node sleep status signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(network->node(nodeId));
if (!node) {
qCWarning(dcZWave()) << "Received a node sleep signal for a node we don't know:" << nodeId;
return;
}
qCInfo(dcZWave()) << "Node" << nodeId << "in network" << network->networkUuid().toString() << "is" << (sleeping ? "sleeping" : "awake");
node->setSleeping(sleeping);
}
void ZWaveManager::onNodeLinkQualityStatus(const QUuid &networkUuid, quint8 nodeId, quint8 linkQuality)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a node link qlility status signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(network->node(nodeId));
if (!node) {
qCWarning(dcZWave()) << "Received a node link quality signal for a node we don't know:" << nodeId;
return;
}
qCInfo(dcZWave()) << "Link quality for node" << nodeId << "in network" << network->networkUuid().toString() << "is" << linkQuality;
node->setLinkQuality(linkQuality);
}
void ZWaveManager::onNodeRemoved(const QUuid &networkUuid, quint8 nodeId)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a node removed signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNode *node = network->node(nodeId);
if (!node) {
qCWarning(dcZWave()) << "Received a node removed signal for a node we don't know:" << nodeId;
return;
}
qCInfo(dcZWave()) << "Node" << nodeId << "removed from network" << network->networkUuid();
network->removeNode(nodeId);
m_dbs.value(network->networkUuid())->removeNode(nodeId);
emit nodeRemoved(node);
}
void ZWaveManager::onValueAdded(const QUuid &networkUuid, quint8 nodeId, const ZWaveValue &value)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave) << "Received a value added signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(network->node(nodeId));
if (!node) {
qCWarning(dcZWave) << "Received a value added signal for a node we don't know:" << nodeId;
return;
}
qCDebug(dcZWave()) << "Value added to node" << nodeId << value;
node->updateValue(value);
m_dbs.value(network->networkUuid())->storeValue(node, value.id());
}
void ZWaveManager::onValueChanged(const QUuid &networkUuid, quint8 nodeId, const ZWaveValue &value)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave) << "Received a value changed signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(network->node(nodeId));
if (!node) {
qCWarning(dcZWave) << "Received a value changed signal for a node we don't know:" << nodeId;
return;
}
qCDebug(dcZWave) << "Value changed for node" << node->nodeId() << value;
node->updateValue(value);
// node->setReachable(true);
m_dbs.value(network->networkUuid())->storeValue(node, value.id());
}
void ZWaveManager::onValueRemoved(const QUuid &networkUuid, quint8 nodeId, quint64 valueId)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "Received a value removed signal for a network we don't know:" << networkUuid.toString();
return;
}
ZWaveNodeImplementation *node = qobject_cast<ZWaveNodeImplementation*>(network->node(nodeId));
if (!node) {
qCWarning(dcZWave()) << "Received a value removed signal for a node we don't know:" << nodeId;
return;
}
node->removeValue(valueId);
m_dbs.value(network->networkUuid())->removeValue(node, valueId);
}
ZWaveNetworks ZWaveManager::networks() const
{
return m_networks.values();
}
ZWaveNetwork *ZWaveManager::network(const QUuid &networkUuid) const
{
return m_networks.value(networkUuid);
}
QPair<ZWave::ZWaveError, QUuid> ZWaveManager::createNetwork(const QString &serialPort)
{
if (!available()) {
qCWarning(dcZWave()) << "Z-Wave is not available.";
return qMakePair<ZWave::ZWaveError, QUuid>(ZWave::ZWaveErrorBackendError, QUuid());
}
QString networkKey = QUuid::createUuid().toString().remove(QRegExp("[{\\-}]*"));
ZWaveNetwork *network = new ZWaveNetwork(QUuid::createUuid(), serialPort, networkKey, this);
bool success = loadNetwork(network);
if (!success) {
delete network;
return qMakePair<ZWave::ZWaveError, QUuid>(ZWave::ZWaveErrorInUse, QUuid());
}
emit networkAdded(network);
storeNetwork(network);
return qMakePair<ZWave::ZWaveError, QUuid>(ZWave::ZWaveErrorNoError, network->networkUuid());
}
ZWave::ZWaveError ZWaveManager::removeNetwork(const QUuid &networkUuid)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
return ZWave::ZWaveErrorNetworkUuidNotFound;
}
bool status = m_backend->stopNetwork(networkUuid);
if (!status) {
return ZWave::ZWaveErrorBackendError;
}
foreach (ZWaveNode *node, network->nodes()) {
network->removeNode(node->nodeId());
emit nodeRemoved(node);
}
m_networks.remove(network->networkUuid());
ZWaveDeviceDatabase *db = m_dbs.take(network->networkUuid());
db->removeDB();
delete db;
network->deleteLater();
NymeaSettings settings(NymeaSettings::SettingsRoleZWave);
settings.beginGroup("Networks");
settings.remove(network->networkUuid().toString());
settings.endGroup();
emit networkRemoved(network->networkUuid());
return ZWave::ZWaveErrorNoError;
}
ZWave::ZWaveError ZWaveManager::factoryResetNetwork(const QUuid &networkUuid)
{
if (!m_networks.contains(networkUuid)) {
return ZWave::ZWaveErrorNetworkUuidNotFound;
}
qCInfo(dcZWave()) << "Resetting controller for network:" << networkUuid.toString();
ZWaveNetwork *network = m_networks.value(networkUuid);
foreach (ZWaveNode *node, network->nodes()) {
network->removeNode(node->nodeId());
emit nodeRemoved(node);
}
m_backend->factoryResetNetwork(networkUuid);
ZWaveDeviceDatabase *db = m_dbs.value(network->networkUuid());
db->clearDB();
network->setHomeId(0);
emit networkChanged(network);
network->setNetworkState(ZWaveNetwork::ZWaveNetworkStateStarting);
emit networkStateChanged(network);
storeNetwork(network);
qCInfo(dcZWave()) << "Controller reset succeeded";
return ZWave::ZWaveErrorNoError;
}
ZWaveReply *ZWaveManager::addNode(const QUuid &networkUuid)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
ZWaveManagerReply *reply = new ZWaveManagerReply(this);
if (!network) {
reply->finish(ZWave::ZWaveErrorNetworkUuidNotFound);
return reply;
}
ZWaveReply *backendReply = m_backend->addNode(network->networkUuid(), true);
connect(backendReply, &ZWaveReply::finished, reply, &ZWaveReply::finished);
qCDebug(dcZWave) << "Adding node to network" << networkUuid.toString();
return reply;
}
ZWaveReply* ZWaveManager::removeNode(const QUuid &networkUuid)
{
ZWaveManagerReply *reply = new ZWaveManagerReply(this);
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
reply->finish(ZWave::ZWaveErrorNetworkUuidNotFound);
return reply;
}
ZWaveReply *backendReply = m_backend->removeNode(networkUuid);
connect(backendReply, &ZWaveReply::finished, reply, &ZWaveManagerReply::finish);
return reply;
}
ZWaveReply* ZWaveManager::removeFailedNode(const QUuid &networkUuid, quint8 nodeId)
{
ZWaveManagerReply *reply = new ZWaveManagerReply(this);
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
reply->finish(ZWave::ZWaveErrorNetworkUuidNotFound);
return reply;
}
ZWaveNode *node = network->node(nodeId);
if (!node) {
reply->finish(ZWave::ZWaveErrorNodeIdNotFound);
return reply;
}
ZWaveReply *backendReply = m_backend->removeFailedNode(networkUuid, nodeId);
connect(backendReply, &ZWaveReply::finished, reply, &ZWaveManagerReply::finish);
return reply;
}
ZWaveReply* ZWaveManager::cancelPendingOperation(const QUuid &networkUuid)
{
ZWaveManagerReply *reply = new ZWaveManagerReply(this);
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
reply->finish(ZWave::ZWaveErrorNetworkUuidNotFound);
return reply;
}
ZWaveReply *backendReply = m_backend->cancelPendingOperation(networkUuid);
connect(backendReply, &ZWaveReply::finished, reply, &ZWaveManagerReply::finish);
return reply;
}
void ZWaveManager::setValue(const QUuid &networkUuid, quint8 nodeId, const ZWaveValue &value)
{
ZWaveNetwork *network = m_networks.value(networkUuid);
if (!network) {
qCWarning(dcZWave()) << "No network with UUID" << networkUuid;
return;
}
qCDebug(dcZWave) << "Setting value" << value.id() << "on node" << nodeId;
m_backend->setValue(network->networkUuid(), nodeId, value);
}
bool ZWaveManager::loadBackend()
{
QStringList searchDirs;
QByteArray envPath = qgetenv("NYMEA_ZWAVE_PLUGIN_PATH");
if (!envPath.isEmpty()) {
searchDirs << QString(envPath).split(':');
}
foreach (QString libraryPath, QCoreApplication::libraryPaths()) {
searchDirs << libraryPath.replace("qt5", "nymea").replace("plugins", "zwave");
}
foreach (QString libraryPath, QCoreApplication::libraryPaths()) {
searchDirs << libraryPath.replace("plugins", "nymea/zwave");
}
searchDirs << QCoreApplication::applicationDirPath() + "/../lib/nymea/zwave/";
searchDirs << QCoreApplication::applicationDirPath() + "/../zwave/";
searchDirs << QCoreApplication::applicationDirPath() + "/../../../zwave/";
foreach (const QString &path, searchDirs) {
QDir dir(path);
qCDebug(dcZWave) << "Loading Z-Wave backend from:" << dir.absolutePath();
foreach (const QString &entry, dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot)) {
QFileInfo fi(path + "/" + entry);
if (fi.isFile()) {
if (entry.startsWith("libnymea_zwaveplugin") && entry.endsWith(".so")) {
QPluginLoader loader;
loader.setFileName(path + "/" + entry);
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
if (!loader.load()) {
qCWarning(dcZWave) << loader.errorString();
continue;
}
m_backend = qobject_cast<ZWaveBackend*>(loader.instance());
if (!m_backend) {
qCWarning(dcZWave) << "Could not get plugin instance of" << loader.fileName();
loader.unload();
continue;
}
qCDebug(dcZWave()) << "Loaded Z-Wave backend:" << loader.fileName();
m_backend->setParent(this);
return true;
}
}
}
}
return false;
}
}

View File

@ -0,0 +1,137 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEMANAGER_H
#define ZWAVEMANAGER_H
#include <QObject>
#include <QTimer>
#include "hardware/zwave/zwave.h"
#include "hardware/zwave/zwavereply.h"
#include "zwaveadapter.h"
#include "zwavenetwork.h"
#include "zwavedevicedatabase.h"
#include "hardware/zwave/zwavenode.h"
#include "hardware/serialport/serialportmonitor.h"
#include "loggingcategories.h"
Q_DECLARE_LOGGING_CATEGORY(dcZWave)
class ZWaveBackend;
namespace nymeaserver
{
class ZWaveNodeImplementation;
class ZWaveManager : public QObject
{
Q_OBJECT
public:
explicit ZWaveManager(SerialPortMonitor *serialPortMonitor, QObject *parent = nullptr);
~ZWaveManager();
bool available() const;
bool enabled() const;
void setEnabled(bool enabled);
SerialPorts serialPorts() const;
ZWaveNetworks networks() const;
ZWaveNetwork* network(const QUuid &networkUuid) const;
QPair<ZWave::ZWaveError, QUuid> createNetwork(const QString &serialPort);
ZWave::ZWaveError removeNetwork(const QUuid &networkUuid);
ZWave::ZWaveError factoryResetNetwork(const QUuid &networkUuid);
ZWaveReply* addNode(const QUuid &networkUuid);
ZWaveReply *removeNode(const QUuid &networkUuid);
ZWaveReply *removeFailedNode(const QUuid &networkUuid, quint8 nodeId);
ZWaveReply *cancelPendingOperation(const QUuid &networkUuid);
void setValue(const QUuid &networkUuid, quint8 nodeId, const ZWaveValue &value);
signals:
void networkAdded(ZWaveNetwork *network);
void networkChanged(ZWaveNetwork *network);
void networkStateChanged(ZWaveNetwork *network);
void networkRemoved(const QUuid &networkUuid);
void nodeAdded(ZWaveNode *node);
void nodeChanged(ZWaveNode *node);
void nodeInitialized(ZWaveNode *node);
void nodeRemoved(ZWaveNode *node);
private:
bool loadBackend();
void loadZWaveNetworks();
void setupNode(ZWaveNodeImplementation *node);
bool loadNetwork(ZWaveNetwork *network);
void storeNetwork(ZWaveNetwork *network);
private slots:
void onNetworkStarted(const QUuid &networkUuid);
void onNetworkFailed(const QUuid &networkUuid);
void onWaitingForNodeAdditionChanged(const QUuid &networkUuid, bool waitingForNodeAddition);
void onWaitingForNodeRemovalChanged(const QUuid &networkUuid, bool waitingForNodeRemoval);
void onNodeAdded(const QUuid &networkUuid, quint8 nodeId);
void onNodeInitialized(const QUuid &networkUuid, quint8 nodeId);
void onNodeRemoved(const QUuid &networkUuid, quint8 nodeId);
void onNodeDataChanged(const QUuid &networkUuid, quint8 nodeId);
void onNodeReachableStatus(const QUuid &networkUuid, quint8 nodeId, bool reachable);
void onNodeFailedStatus(const QUuid &networkUuid, quint8 nodeId, bool failed);
void onNodeSleepStatus(const QUuid &networkUuid, quint8 nodeId, bool sleeping);
void onNodeLinkQualityStatus(const QUuid &networkUuid, quint8 nodeId, quint8 linkQuality);
void onValueAdded(const QUuid &networkUuid, quint8 nodeId, const ZWaveValue &value);
void onValueChanged(const QUuid &networkUuid, quint8 nodeId, const ZWaveValue &value);
void onValueRemoved(const QUuid &networkUuid, quint8 nodeId, quint64 valueId);
private:
SerialPortMonitor *m_serialPortMonitor = nullptr;
ZWaveBackend *m_backend = nullptr;
QHash<QUuid, ZWaveNetwork*> m_networks;
ZWaveAdapters m_adapters;
QHash<QUuid, ZWaveDeviceDatabase*> m_dbs;
QTimer m_statsTimer;
};
}
#endif // ZWAVEMANAGER_H

View File

@ -0,0 +1,47 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavemanagerreply.h"
namespace nymeaserver
{
ZWaveManagerReply::ZWaveManagerReply(QObject *parent)
: ZWaveReply{parent}
{
}
void ZWaveManagerReply::finish(ZWave::ZWaveError status)
{
ZWaveReply::finish(status);
}
}

View File

@ -0,0 +1,57 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEMANAGERREPLY_H
#define ZWAVEMANAGERREPLY_H
#include <QObject>
#include "hardware/zwave/zwavereply.h"
namespace nymeaserver
{
class ZWaveManagerReply : public ZWaveReply
{
Q_OBJECT
friend class ZWaveManager;
public:
explicit ZWaveManagerReply(QObject *parent = nullptr);
private slots:
void finish(ZWave::ZWaveError status) override;
signals:
};
}
#endif // ZWAVEMANAGERREPLY_H

View File

@ -0,0 +1,210 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavenetwork.h"
ZWaveNetwork::ZWaveNetwork(const QUuid &networkUuid, const QString &serialPort, const QString &networkKey, QObject *parent):
QObject(parent),
m_networkUuid(networkUuid),
m_serialPort(serialPort),
m_networkKey(networkKey)
{
}
QUuid ZWaveNetwork::networkUuid() const
{
return m_networkUuid;
}
QString ZWaveNetwork::serialPort() const
{
return m_serialPort;
}
ZWaveNetwork::ZWaveNetworkState ZWaveNetwork::networkState() const
{
return m_networkState;
}
quint32 ZWaveNetwork::homeId() const
{
return m_homeId;
}
QString ZWaveNetwork::networkKey() const
{
return m_networkKey;
}
quint8 ZWaveNetwork::controllerNodeId() const
{
return m_controllerNodeId;
}
ZWaveNodes ZWaveNetwork::nodes() const
{
return m_nodes.values();
}
void ZWaveNetwork::setHomeId(quint32 homeId)
{
m_homeId = homeId;
}
void ZWaveNetwork::setControllerNodeId(quint8 controllerNodeId)
{
if (m_controllerNodeId != controllerNodeId) {
m_controllerNodeId = controllerNodeId;
emit controllerNodeIdChanged(controllerNodeId);
}
}
bool ZWaveNetwork::isZWavePlus() const
{
return m_isZWavePlus;
}
void ZWaveNetwork::setIsZWavePlus(bool isZWavePlus)
{
if (m_isZWavePlus != isZWavePlus) {
m_isZWavePlus = isZWavePlus;
isZWavePlusChanged(isZWavePlus);
}
}
bool ZWaveNetwork::isPrimaryController() const
{
return m_isPrimaryController;
}
void ZWaveNetwork::setIsPrimaryController(bool isPrimaryController)
{
if (m_isPrimaryController != isPrimaryController) {
m_isPrimaryController = isPrimaryController;
emit isPrimaryControllerChanged(isPrimaryController);
}
}
bool ZWaveNetwork::isStaticUpdateController() const
{
return m_isStaticUpdateController;
}
bool ZWaveNetwork::waitingForNodeAddition() const
{
return m_waitingForNodeAddition;
}
bool ZWaveNetwork::waitingForNodeRemoval() const
{
return m_waitingForNodeRemoval;
}
void ZWaveNetwork::setIsStaticUpdateController(bool isStaticUpdateController)
{
if (m_isStaticUpdateController != isStaticUpdateController) {
m_isStaticUpdateController = isStaticUpdateController;
emit isStaticUpdateControllerChanged(isStaticUpdateController);
}
}
bool ZWaveNetwork::isBridgeController() const
{
return m_isBridgeController;
}
void ZWaveNetwork::setIsBridgeController(bool isBridgeController)
{
if (m_isBridgeController != isBridgeController) {
m_isBridgeController = isBridgeController;
emit isBridgeControllerChanged(isBridgeController);
}
}
ZWaveNode *ZWaveNetwork::node(quint8 nodeId) const
{
return m_nodes.value(nodeId);
}
void ZWaveNetwork::addNode(ZWaveNode *node)
{
node->setParent(this);
m_nodes.insert(node->nodeId(), node);
emit nodeAdded(node);
}
void ZWaveNetwork::removeNode(quint8 nodeId)
{
m_nodes.take(nodeId)->deleteLater();
emit nodeRemoved(nodeId);
}
void ZWaveNetwork::setNetworkState(ZWaveNetworkState networkState)
{
if (m_networkState != networkState) {
m_networkState = networkState;
emit networkStateChanged(m_networkState);
}
}
void ZWaveNetwork::setWaitingForNodeAddition(bool waitingForNodeAddition)
{
if (m_waitingForNodeAddition != waitingForNodeAddition) {
m_waitingForNodeAddition = waitingForNodeAddition;
emit waitingForNodeAdditionChanged(waitingForNodeAddition);
}
}
void ZWaveNetwork::setWaitingForNodeRemoval(bool waitingForNodeRemoval)
{
if (m_waitingForNodeRemoval != waitingForNodeRemoval) {
m_waitingForNodeRemoval = waitingForNodeRemoval;
emit waitingForNodeRemovalChanged(waitingForNodeRemoval);
}
}
ZWaveNetworks::ZWaveNetworks()
{
}
ZWaveNetworks::ZWaveNetworks(const ZWaveNetworks &other):
QList<ZWaveNetwork*>(other)
{
}
ZWaveNetworks::ZWaveNetworks(const QList<ZWaveNetwork *> &other):
QList<ZWaveNetwork*>(other)
{
}

View File

@ -0,0 +1,141 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVENETWORK_H
#define ZWAVENETWORK_H
#include <QObject>
#include <QUuid>
#include <QHash>
#include "hardware/zwave/zwavenode.h"
namespace nymeaserver {
class ZWaveManager;
}
class ZWaveNetwork : public QObject
{
Q_OBJECT
Q_PROPERTY(QUuid networkUuid READ networkUuid CONSTANT)
Q_PROPERTY(QString serialPort READ serialPort CONSTANT)
Q_PROPERTY(ZWaveNetworkState networkSate READ networkState NOTIFY networkStateChanged)
Q_PROPERTY(quint32 homeId READ homeId NOTIFY networkStateChanged)
Q_PROPERTY(quint8 controllerNodeId READ controllerNodeId NOTIFY controllerNodeIdChanged)
Q_PROPERTY(bool isZWavePlus READ isZWavePlus NOTIFY isZWavePlusChanged)
Q_PROPERTY(bool isPrimaryController READ isPrimaryController NOTIFY isPrimaryControllerChanged)
Q_PROPERTY(bool isStaticUpdateController READ isStaticUpdateController NOTIFY isStaticUpdateControllerChanged)
Q_PROPERTY(bool isBridgeController READ isBridgeController NOTIFY isBridgeControllerChanged)
Q_PROPERTY(bool waitingForNodeAddition READ waitingForNodeAddition NOTIFY waitingForNodeAdditionChanged)
Q_PROPERTY(bool waitingForNodeRemoval READ waitingForNodeRemoval NOTIFY waitingForNodeRemovalChanged)
friend class nymeaserver::ZWaveManager;
public:
enum ZWaveNetworkState {
ZWaveNetworkStateOffline,
ZWaveNetworkStateStarting,
ZWaveNetworkStateOnline,
ZWaveNetworkStateError
};
Q_ENUM(ZWaveNetworkState)
explicit ZWaveNetwork(const QUuid &networkUuid, const QString &serialPort, const QString &networkKey, QObject *parent = nullptr);
QUuid networkUuid() const;
QString serialPort() const;
quint32 homeId() const;
QString networkKey() const;
quint8 controllerNodeId() const;
ZWaveNetworkState networkState() const;
bool isZWavePlus() const;
bool isPrimaryController() const;
bool isStaticUpdateController() const;
bool isBridgeController() const;
bool waitingForNodeAddition() const;
bool waitingForNodeRemoval() const;
ZWaveNodes nodes() const;
ZWaveNode *node(quint8 nodeId) const;
signals:
void networkStateChanged(ZWaveNetworkState state);
void nodeAdded(ZWaveNode *node);
void nodeRemoved(quint8 nodeId);
void controllerNodeIdChanged(quint8 controllerNodeId);
void isZWavePlusChanged(bool isZWavePlus);
void isPrimaryControllerChanged(bool isPrimaryController);
void isBridgeControllerChanged(bool isBridgeController);
void isStaticUpdateControllerChanged(bool isStaticUpdateController);
void waitingForNodeAdditionChanged(bool waitingForNodeAddition);
void waitingForNodeRemovalChanged(bool waitingForNodeRemoval);
private:
void addNode(ZWaveNode *node);
void removeNode(quint8 nodeId);
void setHomeId(quint32 homeId);
void setControllerNodeId(quint8 controllerNodeId);
void setIsZWavePlus(bool isZWavePlus);
void setIsPrimaryController(bool isPrimaryController);
void setIsStaticUpdateController(bool isStaticUpdateController);
void setIsBridgeController(bool isBridgeController);
void setNetworkState(ZWaveNetworkState networkState);
void setWaitingForNodeAddition(bool waitingForNodeAddition);
void setWaitingForNodeRemoval(bool waitingForNodeRemoval);
private:
QUuid m_networkUuid;
QString m_serialPort;
quint32 m_homeId = 0;
QString m_networkKey;
quint8 m_controllerNodeId = 0;
bool m_isZWavePlus = false;
bool m_isPrimaryController = false;
bool m_isStaticUpdateController = false;
bool m_isBridgeController = false;
bool m_waitingForNodeAddition = false;
bool m_waitingForNodeRemoval = false;
ZWaveNetworkState m_networkState = ZWaveNetworkStateOffline;
QHash<quint8, ZWaveNode*> m_nodes;
};
class ZWaveNetworks: public QList<ZWaveNetwork*>
{
Q_GADGET
public:
ZWaveNetworks();
ZWaveNetworks(const ZWaveNetworks &other);
ZWaveNetworks(const QList<ZWaveNetwork *> &other);
};
Q_DECLARE_METATYPE(ZWaveNetworks)
#endif // ZWAVENETWORK_H

View File

@ -0,0 +1,382 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavenodeimplementation.h"
#include <QUuid>
#include <QDebug>
#include "zwavemanager.h"
namespace nymeaserver
{
nymeaserver::ZWaveNodeImplementation::ZWaveNodeImplementation(ZWaveManager *manager, const QUuid &networkUuid, quint8 nodeId, QObject *parent):
ZWaveNode{parent},
m_manager(manager),
m_networkUuid(networkUuid),
m_nodeId(nodeId)
{
}
QUuid ZWaveNodeImplementation::networkUuid() const
{
return m_networkUuid;
}
quint8 ZWaveNodeImplementation::nodeId() const
{
return m_nodeId;
}
ZWaveNodeImplementation::ZWaveNodeType ZWaveNodeImplementation::nodeType() const
{
return m_nodeType;
}
void ZWaveNodeImplementation::setNodeType(ZWaveNodeType nodeType)
{
if (m_nodeType != nodeType) {
m_nodeType = nodeType;
emit nodeTypeChanged();
emit nodeChanged();
}
}
ZWaveNode::ZWaveNodeRole ZWaveNodeImplementation::role() const
{
return m_role;
}
void ZWaveNodeImplementation::setRole(ZWaveNodeRole role)
{
if (m_role != role) {
m_role = role;
emit roleChanged();
emit nodeChanged();
}
}
ZWaveNodeImplementation::ZWaveDeviceType ZWaveNodeImplementation::deviceType() const
{
return m_deviceType;
}
void ZWaveNodeImplementation::setDeviceType(ZWaveDeviceType deviceType)
{
if (m_deviceType != deviceType) {
m_deviceType = deviceType;
emit deviceTypeChanged();
emit nodeChanged();
}
}
ZWaveNode::ZWavePlusDeviceType ZWaveNodeImplementation::plusDeviceType() const
{
return m_plusDeviceType;
}
void ZWaveNodeImplementation::setPlusDeviceType(ZWavePlusDeviceType plusDeviceType)
{
if (m_plusDeviceType != plusDeviceType) {
m_plusDeviceType = plusDeviceType;
emit plusDeviceTypeChanged();
emit nodeChanged();
}
}
quint16 ZWaveNodeImplementation::manufacturerId() const
{
return m_manufacturerId;
}
void ZWaveNodeImplementation::setManufacturerId(quint16 manufacturerId)
{
if (m_manufacturerId != manufacturerId) {
m_manufacturerId = manufacturerId;
emit manufacturerIdChanged();
emit nodeChanged();
}
}
QString ZWaveNodeImplementation::manufacturerName() const
{
return m_manufacturerName;
}
void ZWaveNodeImplementation::setManufacturerName(const QString &manufacturerName)
{
if (m_manufacturerName != manufacturerName) {
m_manufacturerName = manufacturerName;
emit manufacturerNameChanged();
emit nodeChanged();
}
}
QString ZWaveNodeImplementation::name() const
{
return m_name;
}
void ZWaveNodeImplementation::setName(const QString &name)
{
if (m_name != name) {
m_name = name;
emit nameChanged();
emit nodeChanged();
}
}
quint16 ZWaveNodeImplementation::productId() const
{
return m_productId;
}
void ZWaveNodeImplementation::setProductId(quint16 productId)
{
if (m_productId != productId) {
m_productId = productId;
emit productIdChanged();
emit nodeChanged();
}
}
QString ZWaveNodeImplementation::productName() const
{
return m_productName;
}
void ZWaveNodeImplementation::setProductName(const QString &productName)
{
if (m_productName != productName) {
m_productName = productName;
emit productNameChanged();
emit nodeChanged();
}
}
quint16 ZWaveNodeImplementation::productType() const
{
return m_productType;
}
void ZWaveNodeImplementation::setProductType(quint16 productType)
{
if (m_productType != productType) {
m_productType = productType;
emit productTypeChanged();
emit nodeChanged();
}
}
quint8 ZWaveNodeImplementation::version() const
{
return m_version;
}
void ZWaveNodeImplementation::setVersion(quint8 version)
{
if (m_version != version) {
m_version = version;
emit versionChanged();
emit nodeChanged();
}
}
bool ZWaveNodeImplementation::isZWavePlusDevice() const
{
return m_isZWavePlusDevice;
}
void ZWaveNodeImplementation::setIsZWavePlusDevice(bool isZWavePlusDevice)
{
if (m_isZWavePlusDevice != isZWavePlusDevice) {
m_isZWavePlusDevice = isZWavePlusDevice;
emit isZWavePlusDeviceChanged();
emit nodeChanged();
}
}
bool ZWaveNodeImplementation::isSecurityDevice() const
{
return m_isSecurityDevice;
}
void ZWaveNodeImplementation::setIsSecurityDevice(bool isSecurityDevice)
{
if (m_isSecurityDevice != isSecurityDevice) {
m_isSecurityDevice = isSecurityDevice;
emit isSecurityDeviceChanged();
emit nodeChanged();
}
}
bool ZWaveNodeImplementation::isBeamingDevice() const
{
return m_isBeamingDevice;
}
void ZWaveNodeImplementation::setIsBeamingDevice(bool isBeamingDevice)
{
if (m_isBeamingDevice != isBeamingDevice) {
m_isBeamingDevice = isBeamingDevice;
emit isBeamingDeviceChanged();
emit nodeChanged();
}
}
void ZWaveNodeImplementation::updateValue(const ZWaveValue &value)
{
if (m_values.contains(value.id())) {
m_values[value.id()] = value;
emit valueChanged(value);
} else {
m_values.insert(value.id(), value);
emit valueAdded(value);
}
}
void ZWaveNodeImplementation::removeValue(quint64 id)
{
if (m_values.contains(id)) {
emit valueRemoved(m_values.take(id));
}
}
QList<ZWaveValue> ZWaveNodeImplementation::values() const
{
return m_values.values();
}
ZWaveValue ZWaveNodeImplementation::value(quint64 valueId) const
{
return m_values.value(valueId);
}
ZWaveValue ZWaveNodeImplementation::value(ZWaveValue::Genre genre, ZWaveValue::CommandClass commandClass, quint8 instance, quint16 index, ZWaveValue::Type type) const
{
foreach (const ZWaveValue &value, m_values) {
if (value.genre() == genre && value.commandClass() == commandClass && value.instance() == instance && value.index() == index && value.type() == type) {
return value;
}
}
return ZWaveValue();
}
void ZWaveNodeImplementation::setValue(const ZWaveValue &value)
{
m_manager->setValue(m_networkUuid, m_nodeId, value);
}
bool ZWaveNodeImplementation::reachable() const
{
return m_reachable;
}
void ZWaveNodeImplementation::setReachable(bool reachable)
{
if (m_reachable != reachable) {
m_reachable = reachable;
emit reachableChanged(reachable);
emit nodeChanged();
}
}
bool ZWaveNodeImplementation::initialized() const
{
return m_initialized;
}
void ZWaveNodeImplementation::setInitialized(bool initialized)
{
if (m_initialized != initialized) {
m_initialized = initialized;
emit initializedChanged(initialized);
emit nodeChanged();
}
}
bool ZWaveNodeImplementation::failed() const
{
return m_failed;
}
void ZWaveNodeImplementation::setFailed(bool failed)
{
if (m_failed != failed) {
m_failed = failed;
emit failedChanged(failed);
emit nodeChanged();
}
}
bool ZWaveNodeImplementation::sleeping() const
{
return m_sleeping;
}
void ZWaveNodeImplementation::setSleeping(bool sleeping)
{
if (m_sleeping != sleeping) {
m_sleeping = sleeping;
emit sleepingChanged(sleeping);
emit nodeChanged();
}
}
quint8 ZWaveNodeImplementation::linkQuality() const
{
return m_linkQuality;
}
void ZWaveNodeImplementation::setLinkQuality(quint8 linkQuality)
{
if (m_linkQuality != linkQuality) {
m_linkQuality = linkQuality;
emit linkQualityChanged(linkQuality);
emit nodeChanged();
}
}
quint8 ZWaveNodeImplementation::securityMode() const
{
return m_securityMode;
}
void ZWaveNodeImplementation::setSecurityMode(quint8 securityMode)
{
if (m_securityMode != securityMode) {
m_securityMode = securityMode;
emit securityModeChanged(securityMode);
emit nodeChanged();
}
}
}

View File

@ -0,0 +1,159 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVENODEIMPLEMENTATION_H
#define ZWAVENODEIMPLEMENTATION_H
#include "hardware/zwave/zwavenode.h"
namespace nymeaserver
{
class ZWaveManager;
class ZWaveNodeImplementation: public ZWaveNode
{
Q_OBJECT
public:
explicit ZWaveNodeImplementation(ZWaveManager *manager, const QUuid &networkUuid, quint8 nodeId, QObject *parent = nullptr);
QUuid networkUuid() const override;
quint8 nodeId() const override;
ZWaveNodeType nodeType() const override;
void setNodeType(ZWaveNodeType nodeType);
ZWaveNodeRole role() const override;
void setRole(ZWaveNodeRole role);
bool reachable() const override;
void setReachable(bool reachable);
bool initialized() const override;
void setInitialized(bool initialized);
bool failed() const override;
void setFailed(bool failed);
bool sleeping() const override;
void setSleeping(bool sleeping);
quint8 linkQuality() const override;
void setLinkQuality(quint8 linkQuality);
quint8 securityMode() const override;
void setSecurityMode(quint8 securityMode);
ZWaveDeviceType deviceType() const override;
void setDeviceType(ZWaveDeviceType deviceType);
ZWavePlusDeviceType plusDeviceType() const override;
void setPlusDeviceType(ZWavePlusDeviceType plusDeviceType);
quint16 manufacturerId() const override;
void setManufacturerId(quint16 manufacturerId);
QString manufacturerName() const override;
void setManufacturerName(const QString &manufacturerName);
QString name() const override;
void setName(const QString &name);
quint16 productId() const override;
void setProductId(quint16 productId);
QString productName() const override;
void setProductName(const QString &productName);
quint16 productType() const override;
void setProductType(quint16 productType);
quint8 version() const override;
void setVersion(quint8 version);
bool isZWavePlusDevice() const override;
void setIsZWavePlusDevice(bool isZWavePlusDevice);
bool isSecurityDevice() const override;
void setIsSecurityDevice(bool isSecurityDevice);
bool isBeamingDevice() const override;
void setIsBeamingDevice(bool isBeamingDevice);
QList<ZWaveValue> values() const override;
ZWaveValue value(quint64 valueId) const override;
ZWaveValue value(ZWaveValue::Genre genre, ZWaveValue::CommandClass commandClass, quint8 instance, quint16 index, ZWaveValue::Type type) const override;
void updateValue(const ZWaveValue &value);
void removeValue(quint64 id);
void setValue(const ZWaveValue &value) override;
signals:
// For convenience, emitted when anything in the node changes
void nodeChanged();
private:
nymeaserver::ZWaveManager *m_manager = nullptr;
QUuid m_networkUuid;
quint8 m_nodeId;
bool m_initialized = false;
bool m_reachable = false;
bool m_failed = false;
bool m_sleeping = false;
quint8 m_linkQuality = 0;
quint8 m_securityMode = 0;
ZWaveNodeType m_nodeType = ZWaveNodeTypeUnknown;
ZWaveNodeRole m_role = ZWaveNodeRoleUnknown;
ZWaveDeviceType m_deviceType = ZWaveDeviceTypeUnknown;
ZWavePlusDeviceType m_plusDeviceType = ZWavePlusDeviceTypeUnknown;
quint16 m_manufacturerId;
QString m_manufacturerName;
QString m_name;
quint16 m_productId;
QString m_productName;
quint16 m_productType;
quint8 m_version;
bool m_isZWavePlusDevice = false;
bool m_isSecurityDevice = false;
bool m_isBeamingDevice = false;
QHash<quint64, ZWaveValue> m_values;
};
}
#endif // ZWAVENODEIMPLEMENTATION_H

View File

@ -0,0 +1,39 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwave.h"
#include "loggingcategories.h"
NYMEA_LOGGING_CATEGORY(dcZWave, "ZWave")
ZWave::ZWave()
{
}

View File

@ -0,0 +1,54 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVE_H
#define ZWAVE_H
#include <QObject>
class ZWave
{
Q_GADGET
public:
enum ZWaveError {
ZWaveErrorNoError,
ZWaveErrorInUse,
ZWaveErrorNetworkUuidNotFound,
ZWaveErrorNodeIdNotFound,
ZWaveErrorTimeout,
ZWaveErrorBackendError
};
Q_ENUM(ZWaveError)
private:
ZWave();
};
#endif // ZWAVE_H

View File

@ -0,0 +1,47 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavebackend.h"
ZWaveBackend::ZWaveBackend(QObject *parent)
: QObject{parent}
{
}
void ZWaveBackend::startReply(ZWaveReply *reply, int timeout)
{
reply->start(timeout);
}
void ZWaveBackend::finishReply(ZWaveReply *reply, ZWave::ZWaveError error)
{
reply->finish(error);
}

View File

@ -0,0 +1,116 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEBACKEND_H
#define ZWAVEBACKEND_H
#include "zwave.h"
#include "zwavereply.h"
#include "zwavenode.h"
#include "zwavevalue.h"
#include <QObject>
#include <QUuid>
class ZWaveBackend : public QObject
{
Q_OBJECT
public:
explicit ZWaveBackend(QObject *parent = nullptr);
virtual ~ZWaveBackend() = default;
virtual bool startNetwork(const QUuid &networkUuid, const QString &serialPort, const QString &networkKey = QString()) = 0;
virtual bool stopNetwork(const QUuid &networkUuid) = 0;
virtual quint32 homeId(const QUuid &networkUuid) = 0;
virtual quint8 controllerNodeId(const QUuid &networkUuid) = 0;
virtual bool isPrimaryController(const QUuid &networkUuid) = 0;
virtual bool isStaticUpdateController(const QUuid &networkUuid) = 0;
virtual bool isBridgeController(const QUuid &networkUuid) = 0;
virtual bool factoryResetNetwork(const QUuid &networkUuid) = 0;
virtual ZWaveReply* addNode(const QUuid &networkUuid, bool useSecurity) = 0;
virtual ZWaveReply* removeNode(const QUuid &networkUuid) = 0;
virtual ZWaveReply* removeFailedNode(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual ZWaveReply* cancelPendingOperation(const QUuid &networkUuid) = 0;
virtual bool isNodeAwake(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual bool isNodeFailed(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual QString nodeName(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual ZWaveNode::ZWaveNodeType nodeType(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual ZWaveNode::ZWaveDeviceType nodeDeviceType(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual ZWaveNode::ZWaveNodeRole nodeRole(const QUuid &networkUiid, quint8 nodeId) = 0;
virtual quint8 nodeSecurityMode(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual quint16 nodeManufacturerId(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual QString nodeManufacturerName(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual quint16 nodeProductId(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual QString nodeProductName(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual quint16 nodeProductType(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual quint8 nodeVersion(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual bool nodeIsZWavePlus(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual ZWaveNode::ZWavePlusDeviceType nodePlusDeviceType(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual bool nodeIsBeamingDevice(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual bool nodeIsSecureDevice(const QUuid &networkUuid, quint8 nodeId) = 0;
virtual bool setValue(const QUuid &networkUuid, quint8 nodeId, const ZWaveValue &value) = 0;
signals:
void networkStarted(const QUuid &networkUuid);
void networkFailed(const QUuid &networkUuid);
void waitingForNodeAdditionChanged(const QUuid &networkUuid, bool waitingForNodeAddition);
void waitingForNodeRemovalChanged(const QUuid &networkUuid, bool waitingForNodeRemoval);
void nodeAdded(const QUuid &networkUuid, quint8 nodeId);
void nodeRemoved(const QUuid &networkUuid, quint8 nodeId);
void nodeInitialized(const QUuid &networkUuid, quint8 nodeId);
void nodeDataChanged(const QUuid &networkUuid, quint8 nodeId);
void nodeReachableStatus(const QUuid &networkUuid, quint8 nodeId, bool reachable);
void nodeFailedStatus(const QUuid &networkUuid, quint8 nodeId, bool failed);
void nodeSleepStatus(const QUuid &networkUuid, quint8 nodeId, bool sleeping);
void nodeLinkQualityStatus(const QUuid &networkUuid, quint8 nodeId, quint8 linkQuality);
void valueAdded(const QUuid &networkUuid, quint8 nodeId, const ZWaveValue &value);
void valueChanged(const QUuid &networkUuid, quint8 nodeId, const ZWaveValue &value);
void valueRemoved(const QUuid &networkUuid, quint8 nodeId, quint64 valueId);
protected:
void startReply(ZWaveReply *reply, int timeout = 5000);
void finishReply(ZWaveReply *reply, ZWave::ZWaveError error = ZWave::ZWaveErrorNoError);
};
Q_DECLARE_INTERFACE(ZWaveBackend, "io.nymea.ZWaveBackend")
#endif // ZWAVEBACKEND_H

View File

@ -0,0 +1,36 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavehandler.h"
ZWaveHandler::ZWaveHandler()
{
}

View File

@ -0,0 +1,48 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEHANDLER_H
#define ZWAVEHANDLER_H
#include "hardware/zwave/zwavenode.h"
class ZWaveHandler
{
public:
explicit ZWaveHandler();
virtual ~ZWaveHandler() = default;
virtual QString name() const = 0;
virtual bool handleNode(ZWaveNode *node) = 0;
virtual void handleRemoveNode(ZWaveNode *node) = 0;
};
#endif // ZWAVEHANDLER_H

View File

@ -0,0 +1,37 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavehardwareresource.h"
ZWaveHardwareResource::ZWaveHardwareResource(QObject *parent)
: HardwareResource("ZWave hardware resource", parent)
{
}

View File

@ -0,0 +1,59 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEHARDWARERESOURCE_H
#define ZWAVEHARDWARERESOURCE_H
#include <QObject>
#include "zwavehandler.h"
#include "zwavenode.h"
#include "hardwareresource.h"
class ZWaveHardwareResource : public HardwareResource
{
Q_OBJECT
public:
enum HandlerType {
HandlerTypeBranding,
HandlerTypeVendor,
HandlerTypeCatchAll
};
Q_ENUM(HandlerType)
explicit ZWaveHardwareResource(QObject *parent = nullptr);
virtual void registerHandler(ZWaveHandler *handler, HandlerType type = HandlerTypeVendor) = 0;
virtual ZWaveNode* claimNode(ZWaveHandler *hanlder, const QUuid &networkUuid, quint8 nodeId) = 0;
};
#endif // ZWAVEHARDWARERESOURCE_H

View File

@ -0,0 +1,116 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavenode.h"
#include <QDebug>
ZWaveNode::ZWaveNode(QObject *parent):
QObject{parent}
{
}
QDebug operator<<(QDebug debug, ZWaveNode *node)
{
debug.nospace().noquote() << "\nNode ID: " << node->nodeId() << (node->name().isEmpty() ? "" : ", " + node->name()) << " Z-Wave Version: " << node->version() << (node->isZWavePlusDevice() ? "+" : "") << "\n"
<< "├ Type: " << node->nodeType() << "\n"
<< "├ Role: " << node->role() << "\n"
<< "├ DeviceType: " << node->deviceType() << ", Plus DeviceType: " << node->plusDeviceType() << "\n"
<< "├ Manufacturer: " << node->manufacturerName() << " (" << QString("0x%1").arg(node->manufacturerId(), 4, 16, QChar('0')) << ")\n"
<< "├ Product: " << node->productName() << " (" << QString("0x%1").arg(node->productId(), 4, 16, QChar('0')) << "), Product type: " << QString("0x%1").arg(node->productType(), 4, 16, QChar('0')) << "\n";
QMap<int,QList<ZWaveValue>> byInstance;
foreach (const ZWaveValue &value, node->values()) {
byInstance[value.instance()].append(value);
}
for (int i = 0; i < byInstance.count(); i++) {
int instance = byInstance.keys().at(i);
bool isLastInstance = i == byInstance.count() - 1;
if (isLastInstance) {
debug.nospace().noquote() << "└ Instance: " << instance << "\n";
} else {
debug.nospace().noquote() << "├ Instance: " << instance << "\n";
}
QMap<ZWaveValue::Genre, QList<ZWaveValue>> byGenre;
foreach (const ZWaveValue &value, byInstance[instance]) {
byGenre[value.genre()].append(value);
}
QString instancePrefix = (isLastInstance ? " " : "");
for (int j = 0; j < byGenre.count(); j++) {
ZWaveValue::Genre genre = byGenre.keys().at(j);
bool isLastGenre = j == byGenre.count() - 1;
if (isLastGenre) {
debug.nospace().noquote() << instancePrefix << "" << genre << "\n";
} else {
debug.nospace().noquote() << instancePrefix << "" << genre << "\n";
}
QList<ZWaveValue> sorted = byGenre[genre];
std::sort(sorted.begin(), sorted.end(), [](const ZWaveValue &left, const ZWaveValue &right){
return left.index() < right.index();
});
QString genrePrefix = instancePrefix + (isLastGenre ? " " : "");
for (int k = 0; k < sorted.count(); k++) {
const ZWaveValue &value = sorted.at(k);
bool isLastIndex = k == sorted.count() - 1;
if (isLastIndex) {
debug.nospace().noquote() << genrePrefix << "└ Index: " << value.index() << ", ID: " << value.id() << "\n";
} else {
debug.nospace().noquote() << genrePrefix << "├ Index: " << value.index() << ", ID: " << value.id() << "\n";
}
QString indexPrefix = genrePrefix + (isLastIndex ? " " : "");
debug.nospace().noquote() << indexPrefix << "├ Types: " << value.type() << ", " << value.commandClass() << "\n";
if (value.type() == ZWaveValue::TypeList) {
debug.nospace().noquote() << indexPrefix << "├ Value: " << value.value().toStringList() << "\n";
debug.nospace().noquote() << indexPrefix << "│ └ Selection: " << value.valueListSelection() << " (" << value.value().toList().at(value.valueListSelection()).toString() << ")\n";
} else {
debug.nospace().noquote() << indexPrefix << "├ Value: " << value.value().toString() << "\n";
}
QStringList descriptionLines = value.description().trimmed().split("\n");
for (int l = 0; l < descriptionLines.count(); l++) {
bool isFirstDescription = l == 0;
bool isLastDescription = l == descriptionLines.count() - 1;
QString line = descriptionLines.at(l);
if (isFirstDescription) {
debug.nospace().noquote() << indexPrefix << "└ Description: " << line.trimmed() << "\n";
} else if (isLastDescription) {
debug.nospace().noquote() << indexPrefix << "" << line.trimmed() << "\n";
} else {
debug.nospace().noquote() << indexPrefix << "" << line.trimmed() << "\n";
}
}
}
}
}
return debug;
}

View File

@ -0,0 +1,225 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVENODE_H
#define ZWAVENODE_H
#include <QObject>
#include <QUuid>
#include "zwavevalue.h"
class ZWaveNode : public QObject
{
Q_OBJECT
public:
enum ZWaveNodeType {
ZWaveNodeTypeUnknown = 0x00,
ZWaveNodeTypeController = 0x01,
ZWaveNodeTypeStaticController = 0x02,
ZWaveNodeTypeSlave = 0x03,
ZWaveNodeTypeRoutingSlave = 0x04,
};
Q_ENUM(ZWaveNodeType)
enum ZWaveNodeRole {
ZWaveNodeRoleUnknown = -0x01,
ZWaveNodeRoleCentralController = 0x00,
ZWaveNodeRoleSubController = 0x01,
ZWaveNodeRolePortableController = 0x02,
ZWaveNodeRolePortableReportingController = 0x03,
ZWaveNodeRolePortableSlave = 0x04,
ZWaveNodeRoleAlwaysOnSlabe = 0x05,
ZWaveNodeRoleReportingSleepingSlave = 0x06,
ZWaveNodeRoleListeningSleepingSlave = 0x07
};
Q_ENUM(ZWaveNodeRole)
enum ZWaveDeviceType {
ZWaveDeviceTypeUnknown = 0x0000,
ZWaveDeviceTypeCentralController = 0x0100,
ZWaveDeviceTypeDisplaySimple = 0x0200,
ZWaveDeviceTypeDoorLockKeypad = 0x0300,
ZWaveDeviceTypeFanSwitch = 0x0400,
ZWaveDeviceTypeGateway = 0x0500,
ZWaveDeviceTypeLightDimmerSwitch = 0x0600,
ZWaveDeviceTypeOnOffPowerSwitch = 0x0700,
ZWaveDeviceTypePowerStrip = 0x0800,
ZWaveDeviceTypeRemoteControlAV = 0x0900,
ZWaveDeviceTypeRemoteControlMultiPurpose = 0x0a00,
ZWaveDeviceTypeRemoteControlSimple = 0x0b00,
ZWaveDeviceTypeKeyFob = 0x0b01,
ZWaveDeviceTypeSensorNotification = 0x0c00,
ZWaveDeviceTypeSmokeAlarmSensor = 0x0c01,
ZWaveDeviceTypeCOAlarmSensor = 0x0c02,
ZWaveDeviceTypeCO2AlarmSensor = 0x0c03,
ZWaveDeviceTypeHeatAlarmSensor = 0x0c04,
ZWaveDeviceTypeWaterAlarmSensor = 0x0c05,
ZWaveDeviceTypeAccessControlSensor = 0x0c06,
ZWaveDeviceTypeHomeSecuritySensor = 0x0c07,
ZWaveDeviceTypePowerManagementSensor = 0x0c08,
ZWaveDeviceTypeSystemSensor = 0x0c09,
ZWaveDeviceTypeEmergencyAlarmSensor = 0x0c0a,
ZWaveDeviceTypeClockSensor = 0x0c0b,
ZWaveDeviceTypeMultiDeviceAlarmSensor = 0x0cff,
ZWaveDeviceTypeMultilevelSensor = 0x0d00,
ZWaveDeviceTypeAirTemperatureSensor = 0x0d01,
ZWaveDeviceTypeGeneralPurposeSensor = 0x0d02,
ZWaveDeviceTypeLuminanceSensor = 0x0d03,
ZWaveDeviceTypePowerSensor = 0x0d04,
ZWaveDeviceTypeHumiditySensor = 0x0d05,
ZWaveDeviceTypeVelocitySensor = 0x0d06,
ZWaveDeviceTypeDirectionSensor = 0x0d07,
ZWaveDeviceTypeAtmosphericPressureSensor = 0x0d08,
ZWaveDeviceTypeBarometricPressureSensor = 0x0d09,
ZWaveDeviceTypeSolarRadiationSensor = 0x0d0a,
ZWaveDeviceTypeDewPointSensor = 0x0d0b,
ZWaveDeviceTypeRainRateSensor = 0x0d0c,
ZWaveDeviceTypeTideLevelSensor = 0x0d0d,
ZWaveDeviceTypeWeightSensor = 0x0d0e,
ZWaveDeviceTypeVoltageSensor = 0x0d0f,
ZWaveDeviceTypeCurrentSensor = 0x0d10,
ZWaveDeviceTypeCO2LevelSensor = 0x0d11,
ZWaveDeviceTypeAirFlowSensor = 0x0d12,
ZWaveDeviceTypeTankCapacitySensor = 0x0d13,
ZWaveDeviceTypeDistanceSensor = 0x0d14,
ZWaveDeviceTypeAnglePositionSensor = 0x0d15,
ZWaveDeviceTypeRotationSensor = 0x0d16,
ZWaveDeviceTypeWaterTemperatureSensor = 0x0d17,
ZWaveDeviceTypeSoilTemperatureSensor = 0x0d18,
ZWaveDeviceTypeSeismicIntensitySensor = 0x0d19,
ZWaveDeviceTypeSeismicMagnitudeSensor = 0x0d1a,
ZWaveDeviceTypeUltraVioletSensor = 0x0d1b,
ZWaveDeviceTypeElectricalResistivitySensor = 0x0d1c,
ZWaveDeviceTypeElectricalConductivitySensor = 0x0d1d,
ZWaveDeviceTypeLoudnessSensor = 0x0d1e,
ZWaveDeviceTypeMoistureSensor = 0x0d1f,
ZWaveDeviceTypeFrequencySensor = 0x0d20,
ZWaveDeviceTypeTimeSensor = 0x0d21,
ZWaveDeviceTypeTargetTemperatureSensor = 0x0d22,
ZWaveDeviceTypeMultiDeviceSensor = 0x0dff,
ZWaveDeviceTypeSetTopBox = 0x0e00,
ZWaveDeviceTypeSiren = 0x0f00,
ZWaveDeviceTypeSubEnergyMeter = 0x1000,
ZWaveDeviceTypeSubSystemController = 0x1100,
ZWaveDeviceTypeThermostatHVAC = 0x1200,
ZWaveDeviceTypeThermostatSetback = 0x1300,
ZWaveDeviceTypeTV = 0x1400,
ZWaveDeviceTypeValveOpenClose = 0x1500,
ZWaveDeviceTypeWallController = 0x1600,
ZWaveDeviceTypeWholeHomeMeterSimple = 0x1700,
ZWaveDeviceTypeWindowCoveringNoPosEndpoint = 0x1800,
ZWaveDeviceTypeWindowCoveringEndpointAware = 0x1900,
ZWaveDeviceTypeWindowCoveringPositionEndpointAware = 0x1a00,
};
Q_ENUM(ZWaveDeviceType)
enum ZWavePlusDeviceType {
ZWavePlusDeviceTypeUnknown = 0x00
};
Q_ENUM(ZWavePlusDeviceType)
explicit ZWaveNode(QObject *parent = nullptr);
virtual ~ZWaveNode() = default;
virtual QUuid networkUuid() const = 0;
virtual quint8 nodeId() const = 0;
virtual bool initialized() const = 0;
virtual bool reachable() const = 0;
virtual bool failed() const = 0;
virtual bool sleeping() const = 0;
virtual quint8 linkQuality() const = 0;
virtual quint8 securityMode() const = 0;
virtual ZWaveNodeType nodeType() const = 0;
virtual ZWaveNodeRole role() const = 0;
virtual ZWaveDeviceType deviceType() const = 0;
virtual quint16 manufacturerId() const = 0;
virtual QString manufacturerName() const = 0;
virtual QString name() const = 0;
virtual quint16 productId() const = 0;
virtual QString productName() const = 0;
virtual quint16 productType() const = 0;
virtual quint8 version() const = 0;
virtual bool isZWavePlusDevice() const = 0;
virtual bool isSecurityDevice() const = 0;
virtual bool isBeamingDevice() const = 0;
virtual ZWavePlusDeviceType plusDeviceType() const = 0;
virtual QList<ZWaveValue> values() const = 0;
virtual ZWaveValue value(quint64 valueId) const = 0;
virtual ZWaveValue value(ZWaveValue::Genre genre, ZWaveValue::CommandClass commandClass, quint8 instance, quint16 index, ZWaveValue::Type type) const = 0;
virtual void setValue(const ZWaveValue &value) = 0;
signals:
void initializedChanged(bool initialized);
void reachableChanged(bool reachable);
void failedChanged(bool failed);
void sleepingChanged(bool failed);
void linkQualityChanged(quint8 linkQuality);
void securityModeChanged(quint8 securityMode);
void nodeTypeChanged();
void roleChanged();
void deviceTypeChanged();
void plusDeviceTypeChanged();
void manufacturerIdChanged();
void manufacturerNameChanged();
void nameChanged();
void productIdChanged();
void productNameChanged();
void productTypeChanged();
void versionChanged();
void isZWavePlusDeviceChanged();
void isSecurityDeviceChanged();
void isBeamingDeviceChanged();
void valueAdded(const ZWaveValue &value);
void valueChanged(const ZWaveValue &value);
void valueRemoved(const ZWaveValue &value);
};
class ZWaveNodes: public QList<ZWaveNode*>
{
public:
ZWaveNodes() = default;
ZWaveNodes(const ZWaveNodes &other): QList<ZWaveNode*>(other) {}
ZWaveNodes(const QList<ZWaveNode*> &other): QList<ZWaveNode*>(other) {}
};
QDebug operator<<(QDebug debug, ZWaveNode *node);
#endif // ZWAVENODE_H

View File

@ -0,0 +1,63 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavereply.h"
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(dcZWave)
ZWaveReply::ZWaveReply(QObject *parent)
: QObject{parent}
{
connect(&m_timer, &QTimer::timeout, this, [this](){
qCWarning(dcZWave) << "ZWaveReply timed out...";
finish(ZWave::ZWaveErrorTimeout);
});
connect(this, &ZWaveReply::finished, this, &ZWaveReply::deleteLater);
}
void ZWaveReply::start(int timeout)
{
m_timer.start(timeout);
}
void ZWaveReply::finish(ZWave::ZWaveError status)
{
if (m_finished) {
qCWarning(dcZWave) << "Reply already finished. Not finishing a second time.";
return;
}
m_finished = true;
m_timer.stop();
// Delaying for one event loop pass to give the user chance to connect even if the reply is finished before returning
QTimer::singleShot(0, this, [this, status](){
emit finished(status);
});
}

View File

@ -0,0 +1,58 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEREPLY_H
#define ZWAVEREPLY_H
#include "zwave.h"
#include <QObject>
#include <QTimer>
class ZWaveReply : public QObject
{
Q_OBJECT
friend class ZWaveBackend;
public:
explicit ZWaveReply(QObject *parent = nullptr);
virtual ~ZWaveReply() = default;
signals:
void finished(ZWave::ZWaveError status);
protected slots:
virtual void start(int timeout = 15);
virtual void finish(ZWave::ZWaveError status);
private:
QTimer m_timer;
bool m_finished = false;
};
#endif // ZWAVEREPLY_H

View File

@ -0,0 +1,124 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "zwavevalue.h"
#include <QDebug>
ZWaveValue::ZWaveValue()
{
}
ZWaveValue::ZWaveValue(quint64 id, Genre genre, CommandClass commandClass, quint8 instance, quint16 index, Type type, const QString &description):
m_id(id),
m_genre(genre),
m_commandClass(commandClass),
m_instance(instance),
m_index(index),
m_type(type),
m_description(description)
{
}
quint64 ZWaveValue::id() const
{
return m_id;
}
ZWaveValue::Genre ZWaveValue::genre() const
{
return m_genre;
}
ZWaveValue::CommandClass ZWaveValue::commandClass() const
{
return m_commandClass;
}
quint8 ZWaveValue::instance() const
{
return m_instance;
}
quint16 ZWaveValue::index() const
{
return m_index;
}
ZWaveValue::Type ZWaveValue::type() const
{
return m_type;
}
QVariant ZWaveValue::value() const
{
return m_value;
}
int ZWaveValue::valueListSelection() const
{
return m_listSelection;
}
void ZWaveValue::selectListValue(int selection)
{
m_listSelection = selection;
}
void ZWaveValue::setValue(const QVariant &value, int listSelection)
{
m_value = value;
m_listSelection = listSelection;
}
QString ZWaveValue::description() const
{
return m_description;
}
bool ZWaveValue::isValid() const
{
return m_value.isValid();
}
QDebug operator<<(QDebug debug, ZWaveValue value)
{
debug.nospace() << "Value(ID: " << value.id() << ", "
<< "Ins: " << value.instance() << ", "
<< value.genre() << ", "
<< "Idx: " << value.index() << ", "
<< value.type() << ", "
<< value.commandClass() << ", "
<< "Value: " << value.value()
<< (value.type() == ZWaveValue::TypeList ? QString(" Selection: %1").arg(value.valueListSelection()) : "" ) << ")";
return debug;
}

View File

@ -0,0 +1,167 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ZWAVEVALUE_H
#define ZWAVEVALUE_H
#include <QObject>
#include <QVariant>
class ZWaveValue
{
Q_GADGET
public:
enum Genre {
GenreUnknown = -1,
GenreBasic = 0,
GenreUser,
GenreConfig,
GenreSystem,
};
Q_ENUM(Genre)
enum CommandClass {
CommandClassNoOperation = 0x00,
CommandClassBasic = 0x20,
CommandClassApplicationStatus = 0x22,
CommandClassSwitchBinary = 0x25,
CommandClassSwitchMultilevel = 0x26,
CommandClassSwitchAll = 0x27,
CommandClassSceneActuatorConf = 0x2c,
CommandClassSceneActivation = 0x2b,
CommandClassSceneControllerConf = 0x2d,
CommandClassSensorBinary = 0x30,
CommandClassSensorMultilevel = 0x31,
CommandClassMeter = 0x32,
CommandClassSwitchColor = 0x33,
CommandClassMeterPulse = 0x35,
CommandClassMeterTableMonitor = 0x3d,
CommandClassThermostatMode = 0x40,
CommandClassThermostatOperatingState = 0x42,
CommandClassThermostatSetPoint = 0x43,
CommandClassThermostatFanMode = 0x44,
CommandClassThermostatFanState = 0x45,
CommandClassClimateControlSchedule = 0x46,
CommandClassDoorLockLogging = 0x4C,
CommandClassScheduleEntryLock = 0x4e,
CommandClassBasicWindowCovering = 0x50,
CommandClassCRC16 = 0x56,
CommandClassAssociationGroupInformation = 0x59,
CommandClassDeviceResetLocally = 0x5a,
CommandClassCentralScene = 0x5b,
CommandClassZWavePlusInfo = 0x5e,
CommandClassMultiChannel = 0x60,
CommandClassDoorLock = 0x62,
CommandClassUserCode = 0x63,
CommandClassBarrierOperator = 0x66,
CommandClassSupervision = 0x6c,
CommandClassEntryControl = 0x6f,
CommandClassConfiguration = 0x70,
CommandClassAlarm = 0x71,
CommandClassManufacturerSpecific = 0x72,
CommandClassPowerLevel = 0x73,
CommandClassProtection = 0x75,
CommandClassNodeNaming = 0x77,
CommandClassSoundSwitch = 0x79,
CommandClassFirmwareUpdate = 0x7a,
CommandClassBattery = 0x80,
CommandClassClock = 0x81,
CommandClassWakeup = 0x84,
CommandClassAssociation = 0x85,
CommandClassVersion = 0x86,
CommandClassIndicator = 0x87,
CommandClassProprietary = 0x88,
CommandClassTime = 0x8a,
CommandClassTimeParameters = 0x8b,
CommandClassMultiChannelAssociation = 0x8e,
CommandClassMultiCmd = 0x8f,
CommandClassManufacturerProprietary = 0x91,
CommandClassSimpleAV = 0x94,
CommandClassSecurity = 0x98,
CommandClassAlarmSensor = 0x9c,
CommandClassSensorConfiguration = 0x9e,
CommandClassSecurityS2 = 0x9f,
};
Q_ENUM(CommandClass)
enum Type {
TypeUnknown = -1,
TypeBool = 0,
TypeByte,
TypeDecimal,
TypeInt,
TypeList,
TypeSchedule,
TypeShort,
TypeString,
TypeButton,
TypeRaw,
TypeBitSet,
};
Q_ENUM(Type)
ZWaveValue();
ZWaveValue(quint64 id, Genre genre, ZWaveValue::CommandClass commandClass, quint8 instance, quint16 index, Type type, const QString &description);
quint64 id() const;
Genre genre() const;
CommandClass commandClass() const;
quint8 instance() const;
quint16 index() const;
Type type() const;
QVariant value() const;
void setValue(const QVariant &value, int listSelection = -1);
int valueListSelection() const;
void selectListValue(int selection);
QString description() const;
bool isValid() const;
private:
quint64 m_id = 0;
Genre m_genre = GenreUnknown;
CommandClass m_commandClass = CommandClassNoOperation;
quint8 m_instance = 0;
quint8 m_index = 0;
Type m_type = TypeUnknown;
QVariant m_value;
int m_listSelection = -1;
QString m_description;
};
Q_DECLARE_METATYPE(ZWaveValue::Genre)
Q_DECLARE_METATYPE(ZWaveValue::Type)
QDebug operator<<(QDebug debug, ZWaveValue value);
#endif // ZWAVEVALUE_H

View File

@ -43,6 +43,7 @@ class BluetoothLowEnergyManager;
class MqttProvider;
class I2CManager;
class ZigbeeHardwareResource;
class ZWaveHardwareResource;
class HardwareResource;
class ModbusRtuHardwareResource;
class NetworkDeviceDiscovery;
@ -65,6 +66,7 @@ public:
virtual MqttProvider *mqttProvider() = 0;
virtual I2CManager *i2cManager() = 0;
virtual ZigbeeHardwareResource *zigbeeResource() = 0;
virtual ZWaveHardwareResource *zwaveResource() = 0;
virtual ModbusRtuHardwareResource *modbusRtuResource() = 0;
virtual NetworkDeviceDiscovery *networkDeviceDiscovery() = 0;

View File

@ -19,6 +19,13 @@ HEADERS += \
hardware/modbus/modbusrtureply.h \
hardware/zigbee/zigbeehandler.h \
hardware/zigbee/zigbeehardwareresource.h \
hardware/zwave/zwave.h \
hardware/zwave/zwavereply.h \
hardware/zwave/zwavehandler.h \
hardware/zwave/zwavehardwareresource.h \
hardware/zwave/zwavenode.h \
hardware/zwave/zwavevalue.h \
hardware/zwave/zwavebackend.h \
integrations/browseractioninfo.h \
integrations/browseritemactioninfo.h \
integrations/browseritemresult.h \
@ -124,6 +131,13 @@ SOURCES += \
hardware/modbus/modbusrtuhardwareresource.cpp \
hardware/zigbee/zigbeehandler.cpp \
hardware/zigbee/zigbeehardwareresource.cpp \
hardware/zwave/zwave.cpp \
hardware/zwave/zwavereply.cpp \
hardware/zwave/zwavehandler.cpp \
hardware/zwave/zwavehardwareresource.cpp \
hardware/zwave/zwavenode.cpp \
hardware/zwave/zwavevalue.cpp \
hardware/zwave/zwavebackend.cpp \
integrations/browseractioninfo.cpp \
integrations/browseritemactioninfo.cpp \
integrations/browseritemresult.cpp \

View File

@ -129,6 +129,9 @@ NymeaSettings::NymeaSettings(const SettingsRole &role, QObject *parent):
case SettingsRoleModbusRtu:
fileName = "modbusrtu.conf";
break;
case SettingsRoleZWave:
fileName = "zwave.conf";
break;
}
m_settings = new QSettings(basePath + settingsPrefix + fileName, QSettings::IniFormat, this);
}

View File

@ -52,7 +52,8 @@ public:
SettingsRoleMqttPolicies,
SettingsRoleIOConnections,
SettingsRoleZigbee,
SettingsRoleModbusRtu
SettingsRoleModbusRtu,
SettingsRoleZWave
};
Q_ENUM(SettingsRole)

View File

@ -5,7 +5,7 @@ NYMEA_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"
# define protocol versions
JSON_PROTOCOL_VERSION_MAJOR=6
JSON_PROTOCOL_VERSION_MINOR=0
JSON_PROTOCOL_VERSION_MINOR=1
JSON_PROTOCOL_VERSION="$${JSON_PROTOCOL_VERSION_MAJOR}.$${JSON_PROTOCOL_VERSION_MINOR}"
LIBNYMEA_API_VERSION_MAJOR=7
LIBNYMEA_API_VERSION_MINOR=3

View File

@ -1,4 +1,4 @@
6.0
6.1
{
"enums": {
"BasicType": [
@ -381,6 +381,115 @@
"WirelessModeInfrastructure",
"WirelessModeAccessPoint"
],
"ZWaveDeviceType": [
"ZWaveDeviceTypeUnknown",
"ZWaveDeviceTypeCentralController",
"ZWaveDeviceTypeDisplaySimple",
"ZWaveDeviceTypeDoorLockKeypad",
"ZWaveDeviceTypeFanSwitch",
"ZWaveDeviceTypeGateway",
"ZWaveDeviceTypeLightDimmerSwitch",
"ZWaveDeviceTypeOnOffPowerSwitch",
"ZWaveDeviceTypePowerStrip",
"ZWaveDeviceTypeRemoteControlAV",
"ZWaveDeviceTypeRemoteControlMultiPurpose",
"ZWaveDeviceTypeRemoteControlSimple",
"ZWaveDeviceTypeKeyFob",
"ZWaveDeviceTypeSensorNotification",
"ZWaveDeviceTypeSmokeAlarmSensor",
"ZWaveDeviceTypeCOAlarmSensor",
"ZWaveDeviceTypeCO2AlarmSensor",
"ZWaveDeviceTypeHeatAlarmSensor",
"ZWaveDeviceTypeWaterAlarmSensor",
"ZWaveDeviceTypeAccessControlSensor",
"ZWaveDeviceTypeHomeSecuritySensor",
"ZWaveDeviceTypePowerManagementSensor",
"ZWaveDeviceTypeSystemSensor",
"ZWaveDeviceTypeEmergencyAlarmSensor",
"ZWaveDeviceTypeClockSensor",
"ZWaveDeviceTypeMultiDeviceAlarmSensor",
"ZWaveDeviceTypeMultilevelSensor",
"ZWaveDeviceTypeAirTemperatureSensor",
"ZWaveDeviceTypeGeneralPurposeSensor",
"ZWaveDeviceTypeLuminanceSensor",
"ZWaveDeviceTypePowerSensor",
"ZWaveDeviceTypeHumiditySensor",
"ZWaveDeviceTypeVelocitySensor",
"ZWaveDeviceTypeDirectionSensor",
"ZWaveDeviceTypeAtmosphericPressureSensor",
"ZWaveDeviceTypeBarometricPressureSensor",
"ZWaveDeviceTypeSolarRadiationSensor",
"ZWaveDeviceTypeDewPointSensor",
"ZWaveDeviceTypeRainRateSensor",
"ZWaveDeviceTypeTideLevelSensor",
"ZWaveDeviceTypeWeightSensor",
"ZWaveDeviceTypeVoltageSensor",
"ZWaveDeviceTypeCurrentSensor",
"ZWaveDeviceTypeCO2LevelSensor",
"ZWaveDeviceTypeAirFlowSensor",
"ZWaveDeviceTypeTankCapacitySensor",
"ZWaveDeviceTypeDistanceSensor",
"ZWaveDeviceTypeAnglePositionSensor",
"ZWaveDeviceTypeRotationSensor",
"ZWaveDeviceTypeWaterTemperatureSensor",
"ZWaveDeviceTypeSoilTemperatureSensor",
"ZWaveDeviceTypeSeismicIntensitySensor",
"ZWaveDeviceTypeSeismicMagnitudeSensor",
"ZWaveDeviceTypeUltraVioletSensor",
"ZWaveDeviceTypeElectricalResistivitySensor",
"ZWaveDeviceTypeElectricalConductivitySensor",
"ZWaveDeviceTypeLoudnessSensor",
"ZWaveDeviceTypeMoistureSensor",
"ZWaveDeviceTypeFrequencySensor",
"ZWaveDeviceTypeTimeSensor",
"ZWaveDeviceTypeTargetTemperatureSensor",
"ZWaveDeviceTypeMultiDeviceSensor",
"ZWaveDeviceTypeSetTopBox",
"ZWaveDeviceTypeSiren",
"ZWaveDeviceTypeSubEnergyMeter",
"ZWaveDeviceTypeSubSystemController",
"ZWaveDeviceTypeThermostatHVAC",
"ZWaveDeviceTypeThermostatSetback",
"ZWaveDeviceTypeTV",
"ZWaveDeviceTypeValveOpenClose",
"ZWaveDeviceTypeWallController",
"ZWaveDeviceTypeWholeHomeMeterSimple",
"ZWaveDeviceTypeWindowCoveringNoPosEndpoint",
"ZWaveDeviceTypeWindowCoveringEndpointAware",
"ZWaveDeviceTypeWindowCoveringPositionEndpointAware"
],
"ZWaveError": [
"ZWaveErrorNoError",
"ZWaveErrorInUse",
"ZWaveErrorNetworkUuidNotFound",
"ZWaveErrorNodeIdNotFound",
"ZWaveErrorTimeout",
"ZWaveErrorBackendError"
],
"ZWaveNetworkState": [
"ZWaveNetworkStateOffline",
"ZWaveNetworkStateStarting",
"ZWaveNetworkStateOnline",
"ZWaveNetworkStateError"
],
"ZWaveNodeRole": [
"ZWaveNodeRoleUnknown",
"ZWaveNodeRoleCentralController",
"ZWaveNodeRoleSubController",
"ZWaveNodeRolePortableController",
"ZWaveNodeRolePortableReportingController",
"ZWaveNodeRolePortableSlave",
"ZWaveNodeRoleAlwaysOnSlabe",
"ZWaveNodeRoleReportingSleepingSlave",
"ZWaveNodeRoleListeningSleepingSlave"
],
"ZWaveNodeType": [
"ZWaveNodeTypeUnknown",
"ZWaveNodeTypeController",
"ZWaveNodeTypeStaticController",
"ZWaveNodeTypeSlave",
"ZWaveNodeTypeRoutingSlave"
],
"ZigbeeError": [
"ZigbeeErrorNoError",
"ZigbeeErrorAdapterNotAvailable",
@ -1907,6 +2016,120 @@
"error": "$ref:UserError"
}
},
"ZWave.AddNetwork": {
"description": "Add a new Z-Wave network with the given serial port.",
"params": {
"serialPort": "String"
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"o:networkUuid": "Uuid",
"zwaveError": "$ref:ZWaveError"
}
},
"ZWave.AddNode": {
"description": "Start the node inclusion procedure for the given Z-Wave network.",
"params": {
"networkUuid": "Uuid"
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"zwaveError": "$ref:ZWaveError"
}
},
"ZWave.CancelPendingOperation": {
"description": "Cancel any running node inclusion or removal procedure for the given Z-Wave network.",
"params": {
"networkUuid": "Uuid"
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"zwaveError": "$ref:ZWaveError"
}
},
"ZWave.FactoryResetNetwork": {
"description": "Factory reset the controller for the given Z-Wave network.",
"params": {
"networkUuid": "Uuid"
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"zwaveError": "$ref:ZWaveError"
}
},
"ZWave.GetNetworks": {
"description": "Get all the Z-Wave networks in the system.",
"params": {
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"networks": [
"$ref:ZWaveNetwork"
]
}
},
"ZWave.GetNodes": {
"description": "Get the list of nodes in a network",
"params": {
"networkUuid": "Uuid"
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"o:nodes": [
"$ref:ZWaveNode"
],
"zwaveError": "$ref:ZWaveError"
}
},
"ZWave.GetSerialPorts": {
"description": "Get the list of available serial ports from the host system.",
"params": {
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"serialPorts": "$ref:SerialPorts"
}
},
"ZWave.IsZWaveAvailable": {
"description": "Query if the Z-Wave subsystem is available at all.",
"params": {
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"available": "Bool"
}
},
"ZWave.RemoveFailedNode": {
"description": "Remove the given failed node from the given Z-Wave network. This will not work if node is not marked as failed.",
"params": {
"networkUuid": "Uuid",
"nodeId": "Uint"
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"zwaveError": "$ref:ZWaveError"
}
},
"ZWave.RemoveNetwork": {
"description": "Remove the given Z-Wave network from the system.",
"params": {
"networkUuid": "Uuid"
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"zwaveError": "$ref:ZWaveError"
}
},
"ZWave.RemoveNode": {
"description": "Start the node removal procedure for the given Z-Wave network.",
"params": {
"networkUuid": "Uuid"
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"zwaveError": "$ref:ZWaveError"
}
},
"Zigbee.AddNetwork": {
"description": "Create a new ZigBee network for the given 'serialPort', 'baudRate' and 'backend'. The serial ports can be fetched from the available adapters. See 'GetAdapters' for more information. The available backends can be fetched using the 'GetAvailableBackends' method.",
"params": {
@ -2442,6 +2665,45 @@
"username": "String"
}
},
"ZWave.NetworkAdded": {
"description": "Emitted whenever a new Z-Wave network has been added to the system.",
"params": {
"network": "$ref:ZWaveNetwork"
}
},
"ZWave.NetworkChanged": {
"description": "Emitted whenever a Z-Wave network changes.",
"params": {
"network": "$ref:ZWaveNetwork"
}
},
"ZWave.NetworkRemoved": {
"description": "Emitted whenever a Z-Wave network has been removed from the system.",
"params": {
"networkUuid": "Uuid"
}
},
"ZWave.NodeAdded": {
"description": "Emitted whenever a Z-Wave node is added.",
"params": {
"networkUuid": "Uuid",
"node": "$ref:ZWaveNode"
}
},
"ZWave.NodeChanged": {
"description": "Emitted whenever a Z-Wave node has changed.",
"params": {
"networkUuid": "Uuid",
"node": "$ref:ZWaveNode"
}
},
"ZWave.NodeRemoved": {
"description": "Emitted whenever a Z-Wave node is removed.",
"params": {
"networkUuid": "Uuid",
"nodeId": "Uint"
}
},
"Zigbee.AdapterAdded": {
"description": "Emitted whenever a new ZigBee adapter or serial port has been detected in the system.",
"params": {
@ -2944,6 +3206,40 @@
"r:o:currentAccessPoint": "$ref:WirelessAccessPoint",
"r:state": "$ref:NetworkDeviceState"
},
"ZWaveNetwork": {
"homeId": "Uint",
"isBridgeController": "Bool",
"isPrimaryController": "Bool",
"isStaticUpdateController": "Bool",
"isZWavePlus": "Bool",
"networkState": "$ref:ZWaveNetworkState",
"networkUuid": "Uuid",
"serialPort": "String",
"waitingForNodeAddition": "Bool",
"waitingForNodeRemoval": "Bool"
},
"ZWaveNode": {
"deviceType": "$ref:ZWaveDeviceType",
"failed": "Bool",
"initialized": "Bool",
"isBeamingDevice": "Bool",
"isSecurityDevice": "Bool",
"isZWavePlusDevice": "Bool",
"linkQuality": "Uint",
"manufacturerId": "Uint",
"manufacturerName": "String",
"networkUuid": "Uuid",
"nodeId": "Uint",
"nodeType": "$ref:ZWaveNodeType",
"productId": "Uint",
"productName": "String",
"productType": "Uint",
"reachable": "Bool",
"role": "$ref:ZWaveNodeRole",
"securityMode": "Uint",
"sleeping": "Bool",
"version": "String"
},
"ZigbeeAdapter": {
"r:backend": "String",
"r:baudRate": "Int",

View File

@ -680,7 +680,7 @@ void TestJSONRPC::enableDisableNotifications_legacy()
QStringList expectedNamespaces;
if (enabled == "true") {
expectedNamespaces << "NetworkManager" << "Integrations" << "System" << "Rules" << "Logging" << "Tags" << "AppData" << "JSONRPC" << "Configuration" << "Scripts" << "Users" << "Zigbee" << "ModbusRtu";
expectedNamespaces << "NetworkManager" << "Integrations" << "System" << "Rules" << "Logging" << "Tags" << "AppData" << "JSONRPC" << "Configuration" << "Scripts" << "Users" << "Zigbee" << "ZWave" << "ModbusRtu";
}
std::sort(expectedNamespaces.begin(), expectedNamespaces.end());