diff --git a/plugins/deviceplugins/eq-3/deviceplugineq-3.cpp b/plugins/deviceplugins/eq-3/deviceplugineq-3.cpp index b07f142b..59ef9db7 100644 --- a/plugins/deviceplugins/eq-3/deviceplugineq-3.cpp +++ b/plugins/deviceplugins/eq-3/deviceplugineq-3.cpp @@ -34,6 +34,7 @@ StateTypeId dateTimeStateTypeId = StateTypeId("78aed123-ca8e-4e11-a823-52043c4a4 DevicePluginEQ3::DevicePluginEQ3() { m_cubeDiscovery = new MaxCubeDiscovery(this); + connect(m_cubeDiscovery,SIGNAL(cubesDetected(QList)),this,SLOT(discoveryDone(QList))); } @@ -116,7 +117,6 @@ QPair DevicePluginEQ3::discoverDevices(cons return report(DeviceManager::DeviceErrorDeviceClassNotFound); } - QPair DevicePluginEQ3::setupDevice(Device *device) { qDebug() << "setupDevice" << device->params(); @@ -129,15 +129,28 @@ QPair DevicePluginEQ3::setupDevice(De } MaxCube *cube = new MaxCube(this,device->paramValue("serial number").toString(),QHostAddress(device->paramValue("host address").toString()),device->paramValue("port").toInt()); - connect(cube,SIGNAL(cubeConnectionStatusChanged(bool)),this,SLOT(cubeConnectionStatusChanged(bool))); - m_cubes.insert(cube,device); + connect(cube,SIGNAL(cubeConnectionStatusChanged(bool)),this,SLOT(cubeConnectionStatusChanged(bool))); + cube->connectToCube(); return reportDeviceSetup(DeviceManager::DeviceSetupStatusAsync); } +void DevicePluginEQ3::deviceRemoved(Device *device) +{ + if (!m_cubes.values().contains(device)) { + return; + } + + MaxCube *cube = m_cubes.key(device); + cube->disconnectFromCube(); + qDebug() << "remove cube " << cube->serialNumber(); + m_cubes.remove(cube); + cube->deleteLater(); +} + void DevicePluginEQ3::guhTimer() { foreach (MaxCube *cube, m_cubes.keys()) { @@ -156,7 +169,7 @@ void DevicePluginEQ3::cubeConnectionStatusChanged(const bool &connected) MaxCube *cube = static_cast(sender()); Device *device; if (m_cubes.contains(cube)) { - device = m_cubes.take(cube); + device = m_cubes.value(cube); device->setName("Max! Cube " + cube->serialNumber()); emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess, QString()); } @@ -173,7 +186,7 @@ void DevicePluginEQ3::discoveryDone(const QList &cubeList) params.append(hostParam); Param portParam("port", cube->port()); params.append(portParam); - Param firmwareParam("firmware version", QString::number(cube->firmware())); + Param firmwareParam("firmware version", cube->firmware()); params.append(firmwareParam); Param serialNumberParam("serial number", cube->serialNumber()); params.append(serialNumberParam); diff --git a/plugins/deviceplugins/eq-3/deviceplugineq-3.h b/plugins/deviceplugins/eq-3/deviceplugineq-3.h index c26ede57..786795ee 100644 --- a/plugins/deviceplugins/eq-3/deviceplugineq-3.h +++ b/plugins/deviceplugins/eq-3/deviceplugineq-3.h @@ -47,6 +47,8 @@ public: QPair discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override; QPair setupDevice(Device *device) override; + void deviceRemoved(Device *device) override; + void guhTimer() override; diff --git a/plugins/deviceplugins/eq-3/eq-3.pro b/plugins/deviceplugins/eq-3/eq-3.pro index 8d0f868d..ac7c4e53 100644 --- a/plugins/deviceplugins/eq-3/eq-3.pro +++ b/plugins/deviceplugins/eq-3/eq-3.pro @@ -9,12 +9,14 @@ SOURCES += \ maxcubediscovery.cpp \ maxcube.cpp \ maxdevice.cpp \ - room.cpp \ + room.cpp \ + livemessage.cpp HEADERS += \ deviceplugineq-3.h \ maxcubediscovery.h \ maxcube.h \ maxdevice.h \ - room.h \ + room.h \ + livemessage.h diff --git a/plugins/deviceplugins/eq-3/livemessage.cpp b/plugins/deviceplugins/eq-3/livemessage.cpp new file mode 100644 index 00000000..254d5757 --- /dev/null +++ b/plugins/deviceplugins/eq-3/livemessage.cpp @@ -0,0 +1,170 @@ +#include "livemessage.h" + +LiveMessage::LiveMessage(QObject *parent) : + QObject(parent) +{ +} + +QByteArray LiveMessage::rfAddress() const +{ + return m_rfAddress; +} + +void LiveMessage::setRfAddress(const QByteArray &rfAddress) +{ + m_rfAddress = rfAddress; +} + +bool LiveMessage::informationValid() const +{ + return m_informationValid; +} + +void LiveMessage::setInformationValid(const bool &informationValid) +{ + m_informationValid = informationValid; +} + +bool LiveMessage::errorOccured() const +{ + return m_errorOccured; +} + +void LiveMessage::setErrorOccured(const bool &errorOccured) +{ + m_errorOccured = errorOccured; +} + +bool LiveMessage::isAnswereToCommand() const +{ + return m_isAnswerToCommand; +} + +void LiveMessage::setIsAnswereToCommand(const bool &isAnswereToCommand) +{ + m_isAnswerToCommand = isAnswereToCommand; +} + +bool LiveMessage::initialized() const +{ + return m_initialized; +} + +void LiveMessage::setInitialized(const bool &initialized) +{ + m_initialized = initialized; +} + +bool LiveMessage::batteryLow() const +{ + return m_batteryLow; +} + +void LiveMessage::setBatteryLow(const bool &batteryLow) +{ + m_batteryLow = batteryLow; +} + +bool LiveMessage::linkStatusOK() const +{ + return m_linkStatusOK; +} + +void LiveMessage::setLinkStatusOK(const bool &linkStatusOK) +{ + m_linkStatusOK = linkStatusOK; +} + +bool LiveMessage::panelLocked() const +{ + return m_panelLocked; +} + +void LiveMessage::setPanelLocked(const bool &panelLocked) +{ + m_panelLocked = panelLocked; +} + +bool LiveMessage::gatewayKnown() const +{ + return m_gatewayKnown; +} + +void LiveMessage::setGatewayKnown(const bool &gatewayKnown) +{ + m_gatewayKnown = gatewayKnown; +} + +bool LiveMessage::dtsActive() const +{ + return m_dtsActive; +} + +void LiveMessage::setDtsActive(const bool &dtsActive) +{ + m_dtsActive = dtsActive; +} + +int LiveMessage::deviceMode() const +{ + return m_deviceMode; +} + +void LiveMessage::setDeviceMode(const int &deviceMode) +{ + m_deviceMode = deviceMode; + + switch (deviceMode) { + case Auto: + m_deviceModeString = "Auto"; + break; + case Manual: + m_deviceModeString = "Manuel"; + break; + case Temporary: + m_deviceModeString = "Temporary"; + break; + case Boost: + m_deviceModeString = "Boost"; + break; + default: + m_deviceModeString = "-"; + break; + } + +} + +QString LiveMessage::deviceModeString() const +{ + return m_deviceModeString; +} + +int LiveMessage::valvePosition() const +{ + return m_valvePosition; +} + +void LiveMessage::setValvePosition(const int &valvePosition) +{ + m_valvePosition = valvePosition; +} + +double LiveMessage::setpointTemperature() const +{ + return m_setpointTemperature; +} + +void LiveMessage::setSetpointTemperatre(const double &setpointTemperature) +{ + m_setpointTemperature = setpointTemperature; +} + +QDateTime LiveMessage::dateTime() const +{ + return m_dateTime; +} + +void LiveMessage::setDateTime(const QDateTime dateTime) +{ + m_dateTime = dateTime; +} diff --git a/plugins/deviceplugins/eq-3/livemessage.h b/plugins/deviceplugins/eq-3/livemessage.h new file mode 100644 index 00000000..d60fc7b3 --- /dev/null +++ b/plugins/deviceplugins/eq-3/livemessage.h @@ -0,0 +1,89 @@ +#ifndef LIVEMESSAGE_H +#define LIVEMESSAGE_H + +#include +#include + +class LiveMessage : public QObject +{ + Q_OBJECT +public: + explicit LiveMessage(QObject *parent = 0); + + enum DeviceMode{ + Auto = 0, + Manual = 1, + Temporary = 2, + Boost = 3 + }; + + QByteArray rfAddress() const; + void setRfAddress(const QByteArray & rfAddress); + + bool informationValid() const; + void setInformationValid(const bool &informationValid); + + bool errorOccured() const; + void setErrorOccured(const bool &errorOccured); + + bool isAnswereToCommand() const; + void setIsAnswereToCommand(const bool &isAnswereToCommand); + + bool initialized() const; + void setInitialized(const bool &initialized); + + bool batteryLow() const; + void setBatteryLow(const bool &batteryLow); + + bool linkStatusOK() const; + void setLinkStatusOK(const bool &linkStatusOK); + + bool panelLocked() const; + void setPanelLocked(const bool &panelLocked); + + bool gatewayKnown() const; + void setGatewayKnown(const bool &gatewayKnown); + + bool dtsActive() const; + void setDtsActive(const bool &dtsActive); + + int deviceMode() const; + void setDeviceMode(const int &deviceMode); + + QString deviceModeString() const; + + int valvePosition() const; + void setValvePosition(const int &valvePosition); + + double setpointTemperature() const; + void setSetpointTemperatre(const double &setpointTemperature); + + QDateTime dateTime() const; + void setDateTime(const QDateTime dateTime); + + +private: + + QByteArray m_rfAddress; + bool m_informationValid; + bool m_errorOccured; + bool m_isAnswerToCommand; + bool m_initialized; + bool m_batteryLow; + bool m_linkStatusOK; + bool m_panelLocked; + bool m_gatewayKnown; + bool m_dtsActive; + int m_deviceMode; + QString m_deviceModeString; + int m_valvePosition; + double m_setpointTemperature; + QDateTime m_dateTime; + +signals: + +public slots: + +}; + +#endif // LIVEMESSAGE_H diff --git a/plugins/deviceplugins/eq-3/maxcube.cpp b/plugins/deviceplugins/eq-3/maxcube.cpp index 69cde312..a56ee510 100644 --- a/plugins/deviceplugins/eq-3/maxcube.cpp +++ b/plugins/deviceplugins/eq-3/maxcube.cpp @@ -21,6 +21,9 @@ MaxCube::MaxCube(QObject *parent, QString serialNumber, QHostAddress hostAdress, quint16 port): QTcpSocket(parent), m_serialNumber(serialNumber), m_hostAddress(hostAdress), m_port(port) { + + m_cubeInitialized = false; + connect(this,SIGNAL(connected()),this,SLOT(connected())); connect(this,SIGNAL(disconnected()),this,SLOT(disconnected())); connect(this,SIGNAL(readyRead()),this,SLOT(readData())); @@ -29,76 +32,91 @@ MaxCube::MaxCube(QObject *parent, QString serialNumber, QHostAddress hostAdress, connect(this,SIGNAL(cubeDataAvailable(QByteArray)),this,SLOT(processCubeData(QByteArray))); } -QString MaxCube::serialNumber() +QString MaxCube::serialNumber() const { return m_serialNumber; } -void MaxCube::setSerialNumber(QString serialNumber) +void MaxCube::setSerialNumber(const QString &serialNumber) { m_serialNumber = serialNumber; } -QByteArray MaxCube::rfAddress() +QByteArray MaxCube::rfAddress() const { return m_rfAddress; } -void MaxCube::setRfAddress(QByteArray rfAddress) +void MaxCube::setRfAddress(const QByteArray &rfAddress) { m_rfAddress = rfAddress; } -int MaxCube::firmware() +int MaxCube::firmware() const { return m_firmware; } -void MaxCube::setFirmware(int firmware) +void MaxCube::setFirmware(const int &firmware) { m_firmware = firmware; } -QHostAddress MaxCube::hostAddress() +QHostAddress MaxCube::hostAddress() const { return m_hostAddress; } -void MaxCube::setHostAddress(QHostAddress hostAddress) +void MaxCube::setHostAddress(const QHostAddress &hostAddress) { m_hostAddress = hostAddress; } -quint16 MaxCube::port() +quint16 MaxCube::port() const { return m_port; } -void MaxCube::setPort(quint16 port) +void MaxCube::setPort(const quint16 &port) { m_port = port; } -QByteArray MaxCube::httpConnectionId() +QByteArray MaxCube::httpConnectionId() const { return m_httpConnectionId; } -void MaxCube::setHttpConnectionId(QByteArray httpConnectionId) +void MaxCube::setHttpConnectionId(const QByteArray &httpConnectionId) { m_httpConnectionId = httpConnectionId; } -int MaxCube::freeMemorySlots() +int MaxCube::freeMemorySlots() const { return m_freeMemorySlots; } -void MaxCube::setFreeMemorySlots(int freeMemorySlots) +void MaxCube::setFreeMemorySlots(const int &freeMemorySlots) { m_freeMemorySlots = freeMemorySlots; } +QDateTime MaxCube::cubeDateTime() const +{ + return m_cubeDateTime; +} + +void MaxCube::setCubeDateTime(const QDateTime &cubeDateTime) +{ + m_cubeDateTime = cubeDateTime; +} + +bool MaxCube::portalEnabeld() const +{ + return m_portalEnabeld; +} + QList MaxCube::deviceList() { return m_deviceList; @@ -127,18 +145,20 @@ bool MaxCube::sendData(QByteArray data) return true; } -void MaxCube::parseHelloMessage(QByteArray data) +void MaxCube::decodeHelloMessage(QByteArray data) { - QList list = data.split(','); m_cubeDateTime = calculateDateTime(list.at(7),list.at(8)); + + m_rfAddress = list.at(1); + m_firmware = list.at(2).toInt(); + qDebug() << "===================================================="; - qDebug() << "HELLO message:"; + qDebug() << " HELLO message:"; qDebug() << "===================================================="; qDebug() << " serial number | " << list.at(0); qDebug() << " RF address (hex) | " << list.at(1); qDebug() << " firmware | " << QString::number(list.at(2).toInt()); - qDebug() << " ? | " << list.at(3); qDebug() << " HTTP connection id | " << list.at(4); qDebug() << " duty cycle (hex) | " << list.at(5); qDebug() << " free memory slots (hex) | " << list.at(6); @@ -148,19 +168,13 @@ void MaxCube::parseHelloMessage(QByteArray data) qDebug() << " NTP counter | " << list.at(10); } -void MaxCube::parseMetadataMessage(QByteArray data) +void MaxCube::decodeMetadataMessage(QByteArray data) { QList list = data.left(data.length()-2).split(','); QByteArray dataDecoded = QByteArray::fromBase64(list.at(2)); qDebug() << "===================================================="; - qDebug() << "METADATA message:"; + qDebug() << " METADATA message:"; qDebug() << "===================================================="; - // qDebug() << " Index | " << list.at(0); - // qDebug() << " Count | " << list.at(1); - // qDebug() << " Data Base64 encoded | " << list.at(2); - // qDebug() << " Data Base64 decoded | " << dataDecoded; - // qDebug() << " Data Base64 decoded hex | " << dataDecoded.toHex(); - // parse room list int roomCount = dataDecoded.toHex().mid(4,2).toInt(0,16); @@ -200,8 +214,8 @@ void MaxCube::parseMetadataMessage(QByteArray data) int deviceNameLenght = deviceRawData.mid(28,2).toInt(0,16); device->setDeviceName(QByteArray::fromHex(deviceRawData.mid(30,deviceNameLenght*2))); device->setRoomId(deviceRawData.mid(30 + deviceNameLenght*2,2).toInt(0,16)); - deviceRawData = deviceRawData.right(deviceRawData.length() - (30 + deviceNameLenght*2)); - //qDebug() << "rawdata left :" << deviceRawData; + + deviceRawData = deviceRawData.right(deviceRawData.length() - (32 + deviceNameLenght*2)); m_deviceList.append(device); } @@ -214,132 +228,292 @@ void MaxCube::parseMetadataMessage(QByteArray data) qDebug() << " Serial Number| " << device->serialNumber(); qDebug() << " Device Type String | " << device->deviceTypeString(); qDebug() << " RF address (hex) | " << device->rfAddress(); - //qDebug() << " Device Type | " << device->deviceType(); qDebug() << " Room ID | " << device->roomId(); qDebug() << "-------------------------|-------------------------"; } + + // set room data for each device + foreach (MaxDevice *device, m_deviceList) { + foreach (Room * room, m_roomList) { + if(device->roomId() == room->roomId()){ + device->setRoomName(room->roomName()); + } + } + } + + emit deviceListReady(m_deviceList); + m_cubeInitialized = true; } -void MaxCube::parseConfigMessage(QByteArray data) +void MaxCube::decodeConfigMessage(QByteArray data) { QList list = data.split(','); + if(list.count() < 2){ + return; + } QByteArray rfAddress = list.at(0); QByteArray dataRaw = QByteArray::fromBase64(list.at(1)).toHex(); - //int lengthData = dataRaw.left(2).toInt(0,16); - //QByteArray rfAddress = dataRaw.mid(2,6); + int lengthData = dataRaw.left(2).toInt(0,16); + if(rfAddress != dataRaw.mid(2,6)){ + qDebug() << "ERROR: rf addresses not equal!"; + } int deviceType = dataRaw.mid(8,2).toInt(0,16); - int roomId = dataRaw.mid(10,2).toInt(0,16); //QByteArray unknown = dataRaw.mid(12,6); QByteArray serialNumber = QByteArray::fromHex(dataRaw.mid(16,20)); qDebug() << "===================================================="; - qDebug() << "CONFIG message:"; + qDebug() << " CONFIG message:"; qDebug() << "===================================================="; - qDebug() << " device Type | " << deviceTypeString(deviceType); qDebug() << " Serial Number | " << serialNumber; + qDebug() << " device Type | " << deviceTypeString(deviceType); qDebug() << " RF address (hex) | " << rfAddress; - qDebug() << " Room ID | " << roomId; + qDebug() << " data length | " << lengthData; qDebug() << "-------------------------|-------------------------"; switch (deviceType) { case MaxDevice::DeviceCube:{ - qDebug() << QByteArray::fromHex(dataRaw.mid(dataRaw.length() - 32)); + + m_portalEnabeld = (bool)dataRaw.mid(36,2).toInt(0,16); + + qDebug() << " portal enabled | " << m_portalEnabeld; + qDebug() << " portal URL | " << QString(QByteArray::fromHex(dataRaw.mid(170,68))); + qDebug() << " time zone | " << QString(QByteArray::fromHex(dataRaw.mid(428,6))); + qDebug() << " summer/winter time | " << QString(QByteArray::fromHex(dataRaw.mid(452,8))); break; } - case MaxDevice::DeviceEcoButton: - break; - case MaxDevice::DeviceWallThermostat: - break; - case MaxDevice::DeviceRadiatorThermostatPlus: - break; case MaxDevice::DeviceRadiatorThermostat:{ - double confortTemp = dataRaw.mid(36,2).toInt(0,16)/2; - double ecoTemp = dataRaw.mid(38,2).toInt(0,16)/2; - double maxSetPointTemp = dataRaw.mid(40,2).toInt(0,16)/2; - double minSetPointTemp = dataRaw.mid(42,2).toInt(0,16)/2; - double offsetTemp = (dataRaw.mid(44,2).toInt(0,16) / 2 ) - 3.5; - double windowOpenTemp = dataRaw.mid(46,2).toInt(0,16)/2; + int roomId = dataRaw.mid(10,2).toInt(0,16); + int firmware = dataRaw.mid(12,2).toInt(0,16); + double confortTemp = (double)dataRaw.mid(36,2).toInt(0,16) / 2.0; + double ecoTemp = (double)dataRaw.mid(38,2).toInt(0,16) / 2.0; + double maxSetPointTemp = (double)dataRaw.mid(40,2).toInt(0,16) / 2.0; + double minSetPointTemp = (double)dataRaw.mid(42,2).toInt(0,16) / 2.0; + double offsetTemp = (double)(dataRaw.mid(44,2).toInt(0,16) / 2.0 ) - 3.5; + double windowOpenTemp = (double)dataRaw.mid(46,2).toInt(0,16)/2.0; int windowOpenDuration = dataRaw.mid(48,2).toInt(0,16); // boost code - QByteArray boostDurationCode = QByteArray::number(dataRaw.mid(50,2).toInt(0,16),2); - qDebug() << boostDurationCode; - int boostDuration = boostDurationCode.left(3).toInt(0,2); - if(boostDuration = 7){ - boostDuration = 30; - }else{ - boostDuration *= 5; - } - int valveValue = boostDurationCode.right(5).toInt(0,2); - // day of week an time - QByteArray dowTime = QByteArray::number(dataRaw.mid(52,2).toInt(0,16),2); - double valveMaximumSettings = dataRaw.mid(54,2).toInt(0,16)*(double)100/255; - double valveOffset = dataRaw.mid(56,2).toInt(0,16)*(double)100/255; + QByteArray boostDurationCode = fillBin(QByteArray::number(dataRaw.mid(50,2).toInt(0,16),2),8); + int boostDuration = boostDurationCode.left(3).toInt(0,2) * 5; + int valveValue = boostDurationCode.right(5).toInt(0,2) * 5; - qDebug() << " Serial Number | " << serialNumber; - qDebug() << " Confort Temp. | " << confortTemp; - qDebug() << " Eco Temp. | " << ecoTemp; - qDebug() << " Max. Set Point Temp. | " << maxSetPointTemp; - qDebug() << " Min. Set Point Temp. | " << minSetPointTemp; - qDebug() << " Temp. Offset | " << offsetTemp; - qDebug() << " Window Open Temp. | " << windowOpenTemp; - qDebug() << " Window Open Duration | " << windowOpenDuration; + // day of week an time + QByteArray dowTime = fillBin(QByteArray::number(dataRaw.mid(52,2).toInt(0,16),2),8); + QString weekDay = weekDayString(dowTime.left(3).toInt(0,2)); + QTime time = QTime(dowTime.right(5).toInt(0,2),0); + + double valveMaximumSettings = (double)dataRaw.mid(54,2).toInt(0,16)*(double)100.0/255.0; + double valveOffset = (double)dataRaw.mid(56,2).toInt(0,16)*100.0/255.0; + + qDebug() << " Room ID | " << roomId; + qDebug() << " firmware | " << firmware; + qDebug() << " Confort Temp. | " << confortTemp << "C"; + qDebug() << " Eco Temp. | " << ecoTemp << "C"; + qDebug() << " Max. Set Point Temp. | " << maxSetPointTemp << "C"; + qDebug() << " Min. Set Point Temp. | " << minSetPointTemp << "C"; + qDebug() << " Temp. Offset | " << offsetTemp << "C"; + qDebug() << " Window Open Temp. | " << windowOpenTemp << "C"; + qDebug() << " Window Open Duration | " << windowOpenDuration << "min"; + qDebug() << " Boost code | " << boostDurationCode; qDebug() << " Boost Duration | " << boostDuration << "min"; qDebug() << " Valve value | " << valveValue << "%"; - qDebug() << " Day of week and time | " << dowTime; + qDebug() << " dow code | " << dowTime; + qDebug() << " disclaiming run day | " << weekDay; + qDebug() << " disclaiming run time | " << time.toString("HH:mm"); qDebug() << " Valve Maximum Settings | " << valveMaximumSettings << "%"; qDebug() << " Valve Offset | " << valveOffset << "%"; parseWeeklyProgram(dataRaw.right(dataRaw.length() - 58)); break; } + case MaxDevice::DeviceRadiatorThermostatPlus: + break; + case MaxDevice::DeviceWallThermostat:{ + int roomId = dataRaw.mid(10,2).toInt(0,16); + int firmware = dataRaw.mid(12,2).toInt(0,16); + double confortTemp = (double)dataRaw.mid(36,2).toInt(0,16) / 2.0; + double ecoTemp = (double)dataRaw.mid(38,2).toInt(0,16)/2.0; + double maxSetPointTemp = (double)dataRaw.mid(40,2).toInt(0,16)/2.0; + double minSetPointTemp = (double)dataRaw.mid(42,2).toInt(0,16)/2.0; + + qDebug() << " Room ID | " << roomId; + qDebug() << " firmware | " << firmware; + qDebug() << " Confort Temp. | " << confortTemp; + qDebug() << " Eco Temp. | " << ecoTemp; + qDebug() << " Max. Set Point Temp. | " << maxSetPointTemp; + qDebug() << " Min. Set Point Temp. | " << minSetPointTemp; + + parseWeeklyProgram(dataRaw.right(dataRaw.length() - 44)); + break; + } + case MaxDevice::DeviceEcoButton: + break; + case MaxDevice::DeviceWindowContact: + break; default: qWarning() << "unknown device type: " << deviceType; break; } } -void MaxCube::parseDevicelistMessage(QByteArray data) +void MaxCube::decodeDevicelistMessage(QByteArray data) { - QList list = data.split(','); qDebug() << "===================================================="; - qDebug() << "DEVICELIST message:"; + qDebug() << " LIVE message:"; qDebug() << "===================================================="; - foreach (const QByteArray &code, list) { - QByteArray rawData = QByteArray::fromBase64(code).toHex(); - qDebug() << " Code | " << rawData.toBase64(); - qDebug() << " Code (Hex) | " << rawData; - qDebug() << " Length of data | " << rawData.left(2).toInt(0,16); - qDebug() << " RF address (hex) | " << rawData.mid(2,6); - qDebug() << " Initialization | " << QByteArray::number(rawData.mid(10,2).toInt(0,16),2); - qDebug() << " Battery, ... , | " << QByteArray::number(rawData.mid(12,2).toInt(0,16),2); - qDebug() << " Valve Position | " << QByteArray::number(rawData.mid(14,2).toInt(0,16),2) << "%"; - qDebug() << " Temperatur Setpoint | " << (double)rawData.mid(16,2).toInt(0,16) / 2.0 << "%"; - QDateTime dateTime = calculateDateTime(rawData.mid(18,4), rawData.mid(22,2)); - qDebug() << " Cube date | " << dateTime.date().toString("dd.MM.yyyy"); - qDebug() << " Cube time | " << dateTime.time().toString("HH:mm"); + //qDebug() << data; + QByteArray rawDataAll = QByteArray::fromBase64(data).toHex(); + qDebug() << rawDataAll; + + QList deviceMessageList = splitMessage(rawDataAll); + + foreach (QByteArray rawData, deviceMessageList) { + + LiveMessage message; + message.setRfAddress(rawData.mid(0,6)); + + MaxDevice *device = getDeviceTypeFromRFAddress(message.rfAddress()); + + switch (device->deviceType()) { + case MaxDevice::DeviceWallThermostat:{ + QByteArray unknown = rawData.mid(6,2); + + QByteArray initCode = fillBin(QByteArray::number(rawData.mid(8,2).toInt(0,16),2),8); + message.setInformationValid((bool)initCode.mid(3,1).toInt()); + message.setErrorOccured((bool)initCode.mid(4,1).toInt()); + message.setIsAnswereToCommand((bool)initCode.mid(5,1).toInt()); + message.setInitialized((bool)initCode.mid(6,1).toInt()); + + QByteArray statusCode = fillBin(QByteArray::number(rawData.mid(10,2).toInt(0,16),2),8); + message.setBatteryLow((bool)statusCode.mid(0,1).toInt()); + message.setLinkStatusOK(!(bool)statusCode.mid(1,1).toInt()); + message.setPanelLocked((bool)statusCode.mid(2,1).toInt()); + message.setGatewayKnown((bool)statusCode.mid(3,1).toInt()); + message.setDtsActive((bool)statusCode.mid(4,1).toInt()); + message.setDeviceMode(statusCode.right(2).toInt(0,2)); + + message.setValvePosition((double)rawData.mid(12,2).toInt(0,16)); + message.setSetpointTemperatre((double)rawData.mid(14,2).toInt(0,16)/ 2.0); + message.setDateTime(calculateDateTime(rawData.mid(18,4), rawData.mid(22,2))); + + qDebug() << " raw data | " << rawData; + qDebug() << " device type | " << device->deviceTypeString(); + qDebug() << " device name | " << device->deviceName(); + qDebug() << " RF address (hex) | " << message.rfAddress(); + qDebug() << " unknown | " << unknown; + qDebug() << " initCode | " << initCode; + qDebug() << " information valid | " << message.informationValid(); + qDebug() << " error occured | " << message.errorOccured(); + qDebug() << " is answere to a command | " << message.isAnswereToCommand(); + qDebug() << " initialized | " << message.initialized(); + qDebug() << " statusCode | " << statusCode; + qDebug() << " battery low | " << message.batteryLow(); + qDebug() << " link status OK | " << message.linkStatusOK(); + qDebug() << " panel locked | " << message.panelLocked(); + qDebug() << " gateway known | " << message.gatewayKnown(); + qDebug() << " DST settings active | " << message.dtsActive(); + qDebug() << " device mode | " << message.deviceModeString(); + qDebug() << " unknown | " << rawData.right(rawData.length() - 12); + qDebug() << " measured temp. 0b | " << fillBin(QByteArray::number(rawData.left(2).toInt(0,16),2),8); + qDebug() << "-------------------------|-------------------------"; + + + + emit liveMessageReady(message); + break; + } + case MaxDevice::DeviceRadiatorThermostat:{ + QByteArray unknown = rawData.mid(6,2); + + QByteArray initCode = fillBin(QByteArray::number(rawData.mid(8,2).toInt(0,16),2),8); + message.setInformationValid((bool)initCode.mid(3,1).toInt()); + message.setErrorOccured((bool)initCode.mid(4,1).toInt()); + message.setIsAnswereToCommand((bool)initCode.mid(5,1).toInt()); + message.setInitialized((bool)initCode.mid(6,1).toInt()); + + QByteArray statusCode = fillBin(QByteArray::number(rawData.mid(10,2).toInt(0,16),2),8); + message.setBatteryLow((bool)statusCode.mid(0,1).toInt()); + message.setLinkStatusOK(!(bool)statusCode.mid(1,1).toInt()); + message.setPanelLocked((bool)statusCode.mid(2,1).toInt()); + message.setGatewayKnown((bool)statusCode.mid(3,1).toInt()); + message.setDtsActive((bool)statusCode.mid(4,1).toInt()); + message.setDeviceMode(statusCode.right(2).toInt(0,2)); + + message.setValvePosition((double)rawData.mid(12,2).toInt(0,16)); + message.setSetpointTemperatre((double)rawData.mid(14,2).toInt(0,16)/ 2.0); + message.setDateTime(calculateDateTime(rawData.mid(18,4), rawData.mid(22,2))); + + qDebug() << " raw data | " << rawData; + qDebug() << " device type | " << device->deviceTypeString(); + qDebug() << " device name | " << device->deviceName(); + qDebug() << " RF address (hex) | " << message.rfAddress(); + qDebug() << " unknown | " << unknown; + qDebug() << " information valid | " << message.informationValid(); + qDebug() << " error occured | " << message.errorOccured(); + qDebug() << " is answere to a command | " << message.isAnswereToCommand(); + qDebug() << " initialized | " << message.initialized(); + qDebug() << " battery low | " << message.batteryLow(); + qDebug() << " link status OK | " << message.linkStatusOK(); + qDebug() << " panel locked | " << message.panelLocked(); + qDebug() << " gateway known | " << message.gatewayKnown(); + qDebug() << " DST settings active | " << message.dtsActive(); + qDebug() << " device mode | " << message.deviceModeString(); + qDebug() << " valve position | " << message.valvePosition() << "%"; + qDebug() << " Temperatur Setpoint | " << message.setpointTemperature() << " deg C"; + qDebug() << " unknown | " << rawData.right(rawData.length() - 12); + qDebug() << "-------------------------|-------------------------"; + + emit liveMessageReady(message); + break; + } + case MaxDevice::DeviceWindowContact:{ + QByteArray windowOpenRawData = fillBin(QByteArray::number(rawData.mid(10,2).toInt(0,16),2),8); + bool windowOpen = (bool)windowOpenRawData.mid(5,1).toInt(); + + qDebug() << " raw data | " << rawData; + qDebug() << " device type | " << device->deviceTypeString(); + qDebug() << " device name | " << device->deviceName(); + qDebug() << " RF address (hex) | " << message.rfAddress(); + qDebug() << " window open code | " << windowOpenRawData; + qDebug() << " window open | " << windowOpen; + break; + } + default: + break; + } } } void MaxCube::parseWeeklyProgram(QByteArray data) { - for(int i=0; i<7; i++){ + for(int i=0; i < 7; i++){ QByteArray dayData = data.left(52); - qDebug() << dayData; + //qDebug() << weekDayString(i); + for(int i = 0; i < 52; i+=4){ + QByteArray element = fillBin(QByteArray::number(dayData.mid(i,4).toInt(0,16),2),16); + int minutes = element.right(9).toInt(0,2) * 5; + int hours = (minutes / 60) % 24; + minutes = minutes % 60; + QTime time = QTime(hours,minutes); + //qDebug() << (double)element.left(7).toInt(0,2) / 2 << "\t" << "deg. until" << "\t" << time.toString("HH:mm"); + } + + data = data.right(data.length() - 52); } - qDebug() << "data left" << data; + if(!data.isEmpty()){ + qDebug() << " ? | " << data; + } } -void MaxCube::parseNewDeviceFoundMessage(QByteArray data) +void MaxCube::decodeNewDeviceFoundMessage(QByteArray data) { if(data.isEmpty()){ return; } qDebug() << "===================================================="; - qDebug() << "NEW DEVICE message:"; + qDebug() << " NEW DEVICE message:"; qDebug() << "===================================================="; - qDebug() << " Serial Number | " << QByteArray::fromBase64(data); } @@ -385,9 +559,70 @@ QString MaxCube::deviceTypeString(int deviceType) return deviceTypeString; } +QString MaxCube::weekDayString(int weekDay) +{ + QString weekDayString; + + switch (weekDay) { + case Monday: + weekDayString = "Monday"; + break; + case Tuesday: + weekDayString = "Tuesday"; + break; + case Wednesday: + weekDayString = "Wednesday"; + break; + case Thursday: + weekDayString = "Thursday"; + break; + case Friday: + weekDayString = "Friday"; + break; + case Saturday: + weekDayString = "Saturday"; + break; + case Sunday: + weekDayString = "Sunday"; + break; + default: + weekDayString = "-"; + break; + } + + return weekDayString; +} + QByteArray MaxCube::fillBin(QByteArray data, int dataLength) { + QByteArray zeros; + for(int i = 0; i < dataLength - data.length(); i++){ + zeros.append("0"); + } + data = zeros.append(data); + return data; +} +QList MaxCube::splitMessage(QByteArray data) +{ + QList messageList; + while(!data.isEmpty()){ + int length = data.left(2).toInt(0,16)*2; + messageList.append(data.mid(2,length)); + data = data.right(data.length() - (length+2)); + } + qDebug() << messageList; + return messageList; +} + +MaxDevice *MaxCube::getDeviceTypeFromRFAddress(QByteArray rfAddress) +{ + foreach (MaxDevice *device, m_deviceList){ + if(device->rfAddress() == rfAddress){ + return device; + } + } + return NULL; } void MaxCube::connected() @@ -398,6 +633,7 @@ void MaxCube::connected() void MaxCube::disconnected() { + m_cubeInitialized = false; qDebug() << "-> disconnected from cube " << m_serialNumber << m_hostAddress.toString(); emit cubeConnectionStatusChanged(false); } @@ -422,28 +658,35 @@ void MaxCube::processCubeData(const QByteArray &data) { //qDebug() << "data" << data; if(data.startsWith("H")){ - parseHelloMessage(data.right(data.length() -2 )); + decodeHelloMessage(data.right(data.length() -2 )); return; } // METADATA message if(data.startsWith("M")){ - parseMetadataMessage(data.right(data.length() -2 )); + decodeMetadataMessage(data.right(data.length() -2 )); return; } // CONFIG message if(data.startsWith("C")){ - parseConfigMessage(data.right(data.length() -2 )); + QList dataList = data.split('\r'); + foreach (QByteArray dataElement, dataList) { + if(dataElement.startsWith("C")){ + decodeConfigMessage(dataElement.right(dataElement.length() -2 )); + } + if(dataElement.startsWith("\nC")){ + decodeConfigMessage(dataElement.right(dataElement.length() -3 )); + } + } return; } - // DEVICELIST message + // LIVE message if(data.startsWith("L")){ - //customRequest("g:"); - parseDevicelistMessage(data.right(data.length() -2 )); + decodeDevicelistMessage(data.right(data.length() -2 )); return; } // NEWDEVICEFOUND message if(data.startsWith("N")){ - parseNewDeviceFoundMessage(data.right(data.length() -2)); + decodeNewDeviceFoundMessage(data.right(data.length() -2)); return; } // ACK message @@ -469,11 +712,8 @@ void MaxCube::disablePairingMode() void MaxCube::refresh() { - qDebug() << "refresh cube " << m_serialNumber; - if(isWritable()){ + if(m_cubeInitialized){ write("l:\r\n"); - }else{ - qDebug() << "ERROR: could not send to " << m_hostAddress.toString(); } } diff --git a/plugins/deviceplugins/eq-3/maxcube.h b/plugins/deviceplugins/eq-3/maxcube.h index 434b9d5a..6afe3f58 100644 --- a/plugins/deviceplugins/eq-3/maxcube.h +++ b/plugins/deviceplugins/eq-3/maxcube.h @@ -26,6 +26,7 @@ #include "maxdevice.h" #include "room.h" +#include "livemessage.h" class MaxCube : public QTcpSocket { @@ -33,30 +34,42 @@ class MaxCube : public QTcpSocket public: MaxCube(QObject *parent = 0, QString serialNumber = QString(), QHostAddress hostAdress = QHostAddress(), quint16 port = 0); + enum WeekDay{ + Saturday = 0, + Sunday = 1, + Monday = 2, + Tuesday = 3, + Wednesday = 4, + Thursday = 5, + Friday = 6 + }; + // cube data access functions - QString serialNumber(); - void setSerialNumber(QString serialNumber); + QString serialNumber() const; + void setSerialNumber(const QString &serialNumber); - QByteArray rfAddress(); - void setRfAddress(QByteArray rfAddress); + QByteArray rfAddress() const; + void setRfAddress(const QByteArray &rfAddress); - int firmware(); - void setFirmware(int firmware); + int firmware() const; + void setFirmware(const int &firmware); - QHostAddress hostAddress(); - void setHostAddress(QHostAddress hostAddress); + QHostAddress hostAddress() const; + void setHostAddress(const QHostAddress &hostAddress); - quint16 port(); - void setPort(quint16 port); + quint16 port() const; + void setPort(const quint16 &port); - QByteArray httpConnectionId(); - void setHttpConnectionId(QByteArray httpConnectionId); + QByteArray httpConnectionId() const; + void setHttpConnectionId(const QByteArray &httpConnectionId); - int freeMemorySlots(); - void setFreeMemorySlots(int freeMemorySlots); + int freeMemorySlots() const; + void setFreeMemorySlots(const int &freeMemorySlots); - QDateTime cubeDateTime(); - void setCubeDateTime(QDateTime cubeDateTime); + QDateTime cubeDateTime() const; + void setCubeDateTime(const QDateTime &cubeDateTime); + + bool portalEnabeld() const; QList deviceList(); QList roomList(); @@ -65,6 +78,7 @@ public: void disconnectFromCube(); bool sendData(QByteArray data); + private: // cube data QString m_serialNumber; @@ -75,25 +89,34 @@ private: QByteArray m_httpConnectionId; int m_freeMemorySlots; QDateTime m_cubeDateTime; + bool m_portalEnabeld; QList m_roomList; QList m_deviceList; - void parseHelloMessage(QByteArray data); - void parseMetadataMessage(QByteArray data); - void parseConfigMessage(QByteArray data); - void parseDevicelistMessage(QByteArray data); + bool m_cubeInitialized; + + void decodeHelloMessage(QByteArray data); + void decodeMetadataMessage(QByteArray data); + void decodeConfigMessage(QByteArray data); + void decodeDevicelistMessage(QByteArray data); void parseWeeklyProgram(QByteArray data); - void parseNewDeviceFoundMessage(QByteArray data); + void decodeNewDeviceFoundMessage(QByteArray data); QDateTime calculateDateTime(QByteArray dateRaw, QByteArray timeRaw); QString deviceTypeString(int deviceType); + QString weekDayString(int weekDay); + QByteArray fillBin(QByteArray data, int dataLength); + QList splitMessage(QByteArray data); + MaxDevice *getDeviceTypeFromRFAddress(QByteArray rfAddress); signals: void cubeDataAvailable(const QByteArray &data); void cubeACK(); void cubeConnectionStatusChanged(const bool &connected); + void deviceListReady(QList maxDeviceList); + void liveMessageReady(const LiveMessage &liveMessage); private slots: void connected(); diff --git a/plugins/deviceplugins/eq-3/maxcubediscovery.cpp b/plugins/deviceplugins/eq-3/maxcubediscovery.cpp index b944fe78..3b6aafad 100644 --- a/plugins/deviceplugins/eq-3/maxcubediscovery.cpp +++ b/plugins/deviceplugins/eq-3/maxcubediscovery.cpp @@ -35,14 +35,10 @@ MaxCubeDiscovery::MaxCubeDiscovery(QObject *parent) : void MaxCubeDiscovery::detectCubes() { - qDebug() << "===================================================="; - qDebug() << " searching for cubes...."; - m_cubeList.clear(); // broadcast the hello message, every cube should respond with a 26 byte message m_udpSocket->writeDatagram("eQ3Max*.**********I", QHostAddress::Broadcast, m_port); - m_timeout->start(1500); } @@ -63,6 +59,7 @@ void MaxCubeDiscovery::readData() QByteArray rfAddress = data.mid(21,3).toHex(); int firmware = data.mid(24,2).toHex().toInt(); qint16 port; + // set port depending on the firmware if(firmware < 109){ port= 80; @@ -72,16 +69,6 @@ void MaxCubeDiscovery::readData() MaxCube *cube = new MaxCube(this, serialNumber, sender, port); cube->setRfAddress(rfAddress); - qDebug() << "===================================================="; - qDebug() << " cube detected..."; - qDebug() << "===================================================="; - qDebug() << " serial number | " << cube->serialNumber(); - qDebug() << " host address | " << cube->hostAddress().toString(); - qDebug() << " port | " << QString::number(cube->port()); - qDebug() << " rf address | " << cube->rfAddress(); - qDebug() << " firmware | " << QString::number(cube->firmware()); - qDebug() << "===================================================="; - m_cubeList.append(cube); } } diff --git a/plugins/deviceplugins/eq-3/maxdevice.cpp b/plugins/deviceplugins/eq-3/maxdevice.cpp index d688eb0b..e9c4c6f7 100644 --- a/plugins/deviceplugins/eq-3/maxdevice.cpp +++ b/plugins/deviceplugins/eq-3/maxdevice.cpp @@ -23,12 +23,12 @@ MaxDevice::MaxDevice(QObject *parent) : { } -int MaxDevice::deviceType() +int MaxDevice::deviceType() const { return m_deviceType; } -void MaxDevice::setDeviceType(int deviceType) +void MaxDevice::setDeviceType(const int &deviceType) { m_deviceType = deviceType; @@ -57,58 +57,58 @@ void MaxDevice::setDeviceType(int deviceType) } } -QString MaxDevice::deviceTypeString() +QString MaxDevice::deviceTypeString() const { return m_deviceTypeString; } -QByteArray MaxDevice::rfAddress() +QByteArray MaxDevice::rfAddress() const { return m_rfAddress; } -void MaxDevice::setRfAddress(QByteArray rfAddress) +void MaxDevice::setRfAddress(const QByteArray &rfAddress) { m_rfAddress = rfAddress; } -QString MaxDevice::serialNumber() +QString MaxDevice::serialNumber() const { return m_serialNumber; } -void MaxDevice::setSerialNumber(QString serialNumber) +void MaxDevice::setSerialNumber(const QString &serialNumber) { m_serialNumber = serialNumber; } -QString MaxDevice::deviceName() +QString MaxDevice::deviceName() const { return m_deviceName; } -void MaxDevice::setDeviceName(QString deviceName) +void MaxDevice::setDeviceName(const QString &deviceName) { m_deviceName = deviceName; } -int MaxDevice::roomId() +int MaxDevice::roomId() const { return m_roomId; } -void MaxDevice::setRoomId(int roomId) +void MaxDevice::setRoomId(const int &roomId) { m_roomId = roomId; } -Room *MaxDevice::room() +QString MaxDevice::roomName() const { - return m_room; + return m_roomName; } -void MaxDevice::setRoom(Room *room) +void MaxDevice::setRoomName(const QString &roomName) { - m_room = room; + m_roomName = roomName; } diff --git a/plugins/deviceplugins/eq-3/maxdevice.h b/plugins/deviceplugins/eq-3/maxdevice.h index cb25c8d9..bc27f061 100644 --- a/plugins/deviceplugins/eq-3/maxdevice.h +++ b/plugins/deviceplugins/eq-3/maxdevice.h @@ -38,25 +38,26 @@ public: DeviceEcoButton = 5 }; - int deviceType(); - void setDeviceType(int deviceType); + int deviceType() const; + void setDeviceType(const int &deviceType); - QString deviceTypeString(); + QString deviceTypeString() const; - QByteArray rfAddress(); - void setRfAddress(QByteArray rfAddress); + QByteArray rfAddress() const; + void setRfAddress(const QByteArray &rfAddress); - QString serialNumber(); - void setSerialNumber(QString serialNumber); + QString serialNumber() const; + void setSerialNumber(const QString &serialNumber); - QString deviceName(); - void setDeviceName(QString deviceName); + QString deviceName() const; + void setDeviceName(const QString &deviceName); - int roomId(); - void setRoomId(int roomId); + int roomId() const; + void setRoomId(const int &roomId); + + QString roomName() const; + void setRoomName(const QString &roomName); - Room *room(); - void setRoom(Room *room); private: int m_deviceType; QString m_deviceTypeString; @@ -64,7 +65,7 @@ private: QString m_serialNumber; QString m_deviceName; int m_roomId; - Room *m_room; + QString m_roomName; bool m_batteryOk; signals: diff --git a/plugins/deviceplugins/eq-3/room.cpp b/plugins/deviceplugins/eq-3/room.cpp index db388a0e..08254c59 100644 --- a/plugins/deviceplugins/eq-3/room.cpp +++ b/plugins/deviceplugins/eq-3/room.cpp @@ -23,32 +23,32 @@ Room::Room(QObject *parent) : { } -int Room::roomId() +int Room::roomId() const { return m_roomId; } -void Room::setRoomId(int roomId) +void Room::setRoomId(const int &roomId) { m_roomId = roomId; } -QString Room::roomName() +QString Room::roomName() const { return m_roomName; } -void Room::setRoomName(QString roomName) +void Room::setRoomName(const QString &roomName) { m_roomName = roomName; } -QByteArray Room::groupRfAddress() +QByteArray Room::groupRfAddress() const { return m_groupRfAddress; } -void Room::setGroupRfAddress(QByteArray groupRfAddress) +void Room::setGroupRfAddress(const QByteArray &groupRfAddress) { m_groupRfAddress = groupRfAddress; } diff --git a/plugins/deviceplugins/eq-3/room.h b/plugins/deviceplugins/eq-3/room.h index 03e9b8da..52c55393 100644 --- a/plugins/deviceplugins/eq-3/room.h +++ b/plugins/deviceplugins/eq-3/room.h @@ -27,14 +27,14 @@ class Room : public QObject public: explicit Room(QObject *parent = 0); - int roomId(); - void setRoomId(int roomId); + int roomId() const; + void setRoomId(const int &roomId); - QString roomName(); - void setRoomName(QString roomName); + QString roomName() const; + void setRoomName(const QString &roomName); - QByteArray groupRfAddress(); - void setGroupRfAddress(QByteArray groupRfAddress); + QByteArray groupRfAddress() const; + void setGroupRfAddress(const QByteArray &groupRfAddress); private: int m_roomId; diff --git a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp index deb42f00..da15d8db 100644 --- a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp +++ b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp @@ -447,8 +447,15 @@ QPair DevicePluginOpenweathermap::discoverD QPair DevicePluginOpenweathermap::setupDevice(Device *device) { + foreach (Device *deviceListDevice, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) { + if(deviceListDevice->paramValue("id").toString() == device->paramValue("id").toString()){ + return reportDeviceSetup(DeviceManager::DeviceSetupStatusFailure,QString("Location " + device->paramValue("location").toString() + "allready in added")); + } + } + m_openweaher->update(device->paramValue("id").toString()); - return reportDeviceSetup(); + + return reportDeviceSetup(DeviceManager::DeviceSetupStatusSuccess); } DeviceManager::HardwareResources DevicePluginOpenweathermap::requiredHardware() const @@ -514,6 +521,7 @@ void DevicePluginOpenweathermap::weatherDataReady(const QByteArray &data) foreach (Device *device, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) { if(device->paramValue("id").toString() == dataMap.value("id").toString()){ + device->setName("Weather from openweathermap.org for " + device->paramValue("location").toString()); if(dataMap.contains("clouds")){ int cloudiness = dataMap.value("clouds").toMap().value("all").toInt();