From a0d26f2635ca3a993f43d4bd438422c5e84d9f48 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Sun, 15 Oct 2017 12:50:36 +0200 Subject: [PATCH] added UDP output and changed Vendor to UDP commander --- udpcommander/devicepluginudpcommander.cpp | 79 ++++++++++++++++------ udpcommander/devicepluginudpcommander.h | 2 + udpcommander/devicepluginudpcommander.json | 58 ++++++++++++++++ 3 files changed, 118 insertions(+), 21 deletions(-) diff --git a/udpcommander/devicepluginudpcommander.cpp b/udpcommander/devicepluginudpcommander.cpp index 3ac4064e..9f8f9600 100644 --- a/udpcommander/devicepluginudpcommander.cpp +++ b/udpcommander/devicepluginudpcommander.cpp @@ -1,6 +1,7 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2015 Simon Stürz * + * Copyright (C) 2017 Bernhard Trinnes * * * * This file is part of nymea. * * * @@ -70,34 +71,68 @@ DevicePluginUdpCommander::DevicePluginUdpCommander() DeviceManager::DeviceSetupStatus DevicePluginUdpCommander::setupDevice(Device *device) { // check port - bool portOk = false; - int port = device->paramValue(commanderPortParamTypeId).toInt(&portOk); - if (!portOk || port <= 0 || port > 65535) { - qCWarning(dcUdpCommander) << device->name() << ": invalid port:" << device->paramValue(commanderPortParamTypeId).toString() << "."; - return DeviceManager::DeviceSetupStatusFailure; + if ((device->deviceClassId() == udpInputDeviceClassId) || (device->deviceClassId() == udpOutputDeviceClassId)) { + bool portOk = false; + int port = device->paramValue(portParamTypeId).toInt(&portOk); + if (!portOk || port <= 0 || port > 65535) { + qCWarning(dcUdpCommander) << device->name() << ": invalid port:" << device->paramValue(portParamTypeId).toString() << "."; + return DeviceManager::DeviceSetupStatusFailure; + } + + QUdpSocket *udpSocket = new QUdpSocket(this); + + if (!udpSocket->bind(QHostAddress::Any, port)) { + qCWarning(dcUdpCommander) << device->name() << "can't bind to port" << port << "."; + delete udpSocket; + return DeviceManager::DeviceSetupStatusFailure; + } + + connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); + m_commanderList.insert(udpSocket, device); + + return DeviceManager::DeviceSetupStatusSuccess; } + return DeviceManager::DeviceSetupStatusFailure; +} - QUdpSocket *udpSocket = new QUdpSocket(this); - if (!udpSocket->bind(QHostAddress::Any, port)) { - qCWarning(dcUdpCommander) << device->name() << "can't bind to port" << port << "."; - delete udpSocket; - return DeviceManager::DeviceSetupStatusFailure; +DeviceManager::DeviceError DevicePluginUdpCommander::executeAction(Device *device, const Action &action) { + + if (device->deviceClassId() == udpOutputDeviceClassId) { + + if (action.actionTypeId() == outputDataActionTypeId) { + QUdpSocket *udpSocket = m_commanderList.key(device); + int port = device->paramValue(portParamTypeId).toInt(); + QHostAddress address = QHostAddress(device->paramValue(ipv4AddressParamTypeId).toString()); + QByteArray data = action.param(outputDataAreaParamTypeId).value().toByteArray(); + qDebug(dcUdpCommander()) << "Send UDP datagram:" << data << "address:" << address.toIPv4Address() << "port:" << port; + udpSocket->writeDatagram(data, address, port); + + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorActionTypeNotFound; } - - connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); - m_commanderList.insert(udpSocket, device); - - return DeviceManager::DeviceSetupStatusSuccess; + return DeviceManager::DeviceErrorDeviceClassNotFound; } void DevicePluginUdpCommander::deviceRemoved(Device *device) { - QUdpSocket *socket = m_commanderList.key(device); - m_commanderList.remove(socket); + if (device->deviceClassId() == udpInputDeviceClassId) { - socket->close(); - socket->deleteLater(); + QUdpSocket *socket = m_commanderList.key(device); + m_commanderList.remove(socket); + + socket->close(); + socket->deleteLater(); + } + if (device->deviceClassId() == udpOutputDeviceClassId) { + + QUdpSocket *socket = m_commanderList.key(device); + m_commanderList.remove(socket); + + socket->close(); + socket->deleteLater(); + } } void DevicePluginUdpCommander::readPendingDatagrams() @@ -114,8 +149,10 @@ void DevicePluginUdpCommander::readPendingDatagrams() socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); } - if (datagram == device->paramValue(commanderCommandParamTypeId).toByteArray() || - datagram == device->paramValue(commanderCommandParamTypeId).toByteArray() + "\n") { + device->setStateValue(inputDataStateTypeId, datagram); + + if (datagram == device->paramValue(commandParamTypeId).toByteArray() || + datagram == device->paramValue(commandParamTypeId).toByteArray() + "\n") { qCDebug(dcUdpCommander) << device->name() << " got command from" << sender.toString() << senderPort; emit emitEvent(Event(commanderCommandReceivedEventTypeId, device->id())); socket->writeDatagram("OK\n", sender, senderPort); diff --git a/udpcommander/devicepluginudpcommander.h b/udpcommander/devicepluginudpcommander.h index 01c56c55..bb90e5af 100644 --- a/udpcommander/devicepluginudpcommander.h +++ b/udpcommander/devicepluginudpcommander.h @@ -1,6 +1,7 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2015 Simon Stürz * + * Copyright (C) 2017 Bernhard Trinnes * * * * This file is part of nymea. * * * @@ -41,6 +42,7 @@ public: DeviceManager::DeviceSetupStatus setupDevice(Device *device) override; void deviceRemoved(Device *device) override; + DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; private: QHash m_commanderList; diff --git a/udpcommander/devicepluginudpcommander.json b/udpcommander/devicepluginudpcommander.json index e3824887..71eceeb9 100644 --- a/udpcommander/devicepluginudpcommander.json +++ b/udpcommander/devicepluginudpcommander.json @@ -33,6 +33,17 @@ "inputType": "TextLine" } ], + "stateTypes":[ + { + "id": "065a1a0a-d324-4ae6-a461-bef8143e8795", + "idName": "inputData", + "name": "Input Data", + "type": "QString", + "defaultValue": "", + "eventTypeName": "input data changed", + "index": 0 + } + ], "eventTypes": [ { "id": "5fecbba3-ffbb-456b-872c-a2f571c681cb", @@ -40,6 +51,53 @@ "displayName": "command received" } ] + }, + { + "id": "31b00639-8904-4522-84ed-54c46a54c63c", + "name": "UDP Output", + "idName": "udpOutput", + "deviceIcon": "Network", + "basicTags": [ + "Service", + "Sensor" + ], + "createMethods": ["user"], + "paramTypes": [ + { + "id": "1843adcb-e377-44d1-8d70-ab4f9eeb32ec", + "idName": "port", + "name": "port", + "index": 0, + "type": "int" + }, + { + "id": "ea1be9fc-9a9b-44ba-a28d-e021aef4f046", + "idName": "ipv4Address", + "name": "IPv4 Address", + "type": "QString", + "index": 1, + "inputType": "IPv4Address", + "defaultValue": "127.0.0.1" + } + ], + "actionTypes": [ + { + "id": "6bc52462-b192-46a4-a6df-92cc5a479c89", + "idName": "outputData", + "name": "Send Data", + "index": 0, + "paramTypes": [ + { + "id": "6604c852-6b24-4707-b8e5-1ddd8032efcc", + "idName": "outputDataArea", + "name": "Data", + "type": "QString", + "index": 0, + "inputType": "TextArea" + } + ] + } + ] } ] }