diff --git a/libguh/hardware/upnpdiscovery/upnpdevice.cpp b/libguh/hardware/upnpdiscovery/upnpdevice.cpp index 79d09714..beda733a 100644 --- a/libguh/hardware/upnpdiscovery/upnpdevice.cpp +++ b/libguh/hardware/upnpdiscovery/upnpdevice.cpp @@ -42,67 +42,137 @@ QUrl UpnpDevice::location() return m_location; } +void UpnpDevice::setLocation(const QUrl &location) +{ + m_location = location; +} + QHostAddress UpnpDevice::hostAddress() const { return m_hostAddress; } +void UpnpDevice::setHostAddress(const QHostAddress &hostAddress) +{ + m_hostAddress = hostAddress; +} + int UpnpDevice::port() const { return m_port; } +void UpnpDevice::setPort(const int &port) +{ + m_port = port; +} + QString UpnpDevice::deviceType() const { return m_deviceType; } +void UpnpDevice::setDeviceType(const QString &deviceType) +{ + m_deviceType = deviceType; +} + QString UpnpDevice::friendlyName() const { return m_friendlyName; } +void UpnpDevice::setFriendlyName(const QString &friendlyName) +{ + m_friendlyName = friendlyName; +} + QString UpnpDevice::manufacturer() const { return m_manufacturer; } +void UpnpDevice::setManufacturer(const QString &manufacturer) +{ + m_manufacturer = manufacturer; +} + QUrl UpnpDevice::manufacturerURL() const { return m_manufacturerURL; } +void UpnpDevice::setManufacturerURL(const QUrl &manufacturerURL) +{ + m_manufacturerURL = manufacturerURL; +} + QString UpnpDevice::modelDescription() const { return m_modelDescription; } +void UpnpDevice::setModelDescription(const QString &modelDescription) +{ + m_modelDescription = modelDescription; +} + QString UpnpDevice::modelName() const { return m_modelName; } +void UpnpDevice::setModelName(const QString &modelName) +{ + m_modelName = modelName; +} + QString UpnpDevice::modelNumber() const { return m_modelNumber; } +void UpnpDevice::setModelNumber(const QString &modelNumber) +{ + m_modelNumber = modelNumber; +} + QUrl UpnpDevice::modelURL() const { return m_modelURL; } +void UpnpDevice::setModelURL(const QUrl &modelURL) +{ + m_modelURL = modelURL; +} + QString UpnpDevice::serialNumber() const { return m_serialNumber; } +void UpnpDevice::setSerialNumber(const QString &serialNumber) +{ + m_serialNumber = serialNumber; +} + QString UpnpDevice::uuid() const { return m_uuid; } +void UpnpDevice::setUuid(const QString &uuid) +{ + m_uuid = uuid; +} + QString UpnpDevice::upc() const { return m_upc; } + +void UpnpDevice::setUpc(const QString &upc) +{ + m_upc = upc; +} diff --git a/libguh/hardware/upnpdiscovery/upnpdevice.h b/libguh/hardware/upnpdiscovery/upnpdevice.h index d86dfec3..0bd68e23 100644 --- a/libguh/hardware/upnpdiscovery/upnpdevice.h +++ b/libguh/hardware/upnpdiscovery/upnpdevice.h @@ -30,20 +30,46 @@ public: explicit UpnpDevice(QObject *parent = 0, UpnpDeviceDescriptor upnpDeviceDescriptor = UpnpDeviceDescriptor()); QUrl location(); - QHostAddress hostAddress() const; - int port() const; - QString deviceType() const; - QString friendlyName() const; - QString manufacturer() const; - QUrl manufacturerURL() const; - QString modelDescription() const; - QString modelName() const; - QString modelNumber() const; - QUrl modelURL() const; - QString serialNumber() const; - QString uuid() const; - QString upc() const; + void setLocation(const QUrl &location); + QHostAddress hostAddress() const; + void setHostAddress(const QHostAddress &hostAddress); + + int port() const; + void setPort(const int &port); + + QString deviceType() const; + void setDeviceType(const QString & deviceType); + + QString friendlyName() const; + void setFriendlyName(const QString &friendlyName); + + QString manufacturer() const; + void setManufacturer(const QString &manufacturer); + + QUrl manufacturerURL() const; + void setManufacturerURL(const QUrl & manufacturerURL); + + QString modelDescription() const; + void setModelDescription(const QString & modelDescription); + + QString modelName() const; + void setModelName(const QString & modelName); + + QString modelNumber() const; + void setModelNumber(const QString &modelNumber); + + QUrl modelURL() const; + void setModelURL(const QUrl &modelURL); + + QString serialNumber() const; + void setSerialNumber(const QString &serialNumber); + + QString uuid() const; + void setUuid(const QString &uuid); + + QString upc() const; + void setUpc(const QString &upc); private: QUrl m_location; diff --git a/plugins/deviceplugins/wemo/devicepluginwemo.cpp b/plugins/deviceplugins/wemo/devicepluginwemo.cpp index 82cbb9f6..011d54c3 100644 --- a/plugins/deviceplugins/wemo/devicepluginwemo.cpp +++ b/plugins/deviceplugins/wemo/devicepluginwemo.cpp @@ -51,48 +51,46 @@ #include +DeviceClassId wemoSwitchDeviceClassId = DeviceClassId("69d97d3b-a8e6-42f3-afc0-ca8a53eb7cce"); + +StateTypeId powerStateTypeId = StateTypeId("7166c4f6-f68c-4188-8f7c-2205d72a5a6d"); +StateTypeId reachableStateTypeId = StateTypeId("ec2f5b49-585c-4455-a233-b7aa4c608dbc"); +ActionTypeId powerActionTypeId = ActionTypeId("269f25eb-d0b7-4144-b9ef-801f4ff3e90c"); +ActionTypeId rediscoverActionTypeId = ActionTypeId("269cf3b8-d4dd-42e9-8309-6cb3ca8842df"); + DevicePluginWemo::DevicePluginWemo() { -// m_discovery = new WemoDiscovery(this); - -// connect(m_discovery,SIGNAL(discoveryDone(QList)),this,SLOT(discoveryDone(QList))); } DeviceManager::DeviceError DevicePluginWemo::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) { - Q_UNUSED(params) - if(deviceClassId != wemoSwitchDeviceClassId){ + Q_UNUSED(params); + if (deviceClassId != wemoSwitchDeviceClassId) { return DeviceManager::DeviceErrorDeviceClassNotFound; } - - m_discovery->discover(2000); - + upnpDiscover("upnp:rootdevice"); return DeviceManager::DeviceErrorAsync; } DeviceManager::DeviceSetupStatus DevicePluginWemo::setupDevice(Device *device) { - if(device->deviceClassId() == wemoSwitchDeviceClassId){ + if (device->deviceClassId() == wemoSwitchDeviceClassId) { foreach (WemoSwitch *wemoSwitch, m_wemoSwitches.keys()) { - if(wemoSwitch->serialNumber() == device->paramValue("serial number").toString()){ - qWarning() << wemoSwitch->serialNumber() << " already exists..."; + if (wemoSwitch->serialNumber() == device->paramValue("serial number").toString()) { + qWarning() << "WeMo Switch " << wemoSwitch->serialNumber() << " allready added..."; return DeviceManager::DeviceSetupStatusFailure; } } + UpnpDeviceDescriptor upnpDeviceDescriptor; + upnpDeviceDescriptor.setFriendlyName(device->paramValue("name").toString()); + upnpDeviceDescriptor.setHostAddress(QHostAddress(device->paramValue("host address").toString())); + upnpDeviceDescriptor.setPort(device->paramValue("port").toInt()); + upnpDeviceDescriptor.setSerialNumber(device->paramValue("serial number").toString()); + device->setName("WeMo Switch (" + device->paramValue("serial number").toString() + ")"); - WemoSwitch *wemoSwitch = new WemoSwitch(this); - wemoSwitch->setName(device->paramValue("name").toString()); - wemoSwitch->setUuid(device->paramValue("uuid").toString()); - wemoSwitch->setPort(device->paramValue("port").toInt()); - wemoSwitch->setModelName(device->paramValue("model").toString()); - wemoSwitch->setHostAddress(QHostAddress(device->paramValue("host address").toString())); - wemoSwitch->setModelDescription(device->paramValue("model description").toString()); - wemoSwitch->setSerialNumber(device->paramValue("serial number").toString()); - wemoSwitch->setLocation(QUrl(device->paramValue("location").toString())); - wemoSwitch->setManufacturer(device->paramValue("manufacturer").toString()); - wemoSwitch->setDeviceType(device->paramValue("device type").toString()); + WemoSwitch *wemoSwitch = new WemoSwitch(this, upnpDeviceDescriptor); connect(wemoSwitch,SIGNAL(stateChanged()),this,SLOT(wemoSwitchStateChanged())); connect(wemoSwitch,SIGNAL(setPowerFinished(bool,ActionId)),this,SLOT(setPowerFinished(bool,ActionId))); @@ -101,27 +99,35 @@ DeviceManager::DeviceSetupStatus DevicePluginWemo::setupDevice(Device *device) wemoSwitch->refresh(); return DeviceManager::DeviceSetupStatusSuccess; } - return DeviceManager::DeviceSetupStatusSuccess; + return DeviceManager::DeviceSetupStatusFailure; } DeviceManager::HardwareResources DevicePluginWemo::requiredHardware() const { - return DeviceManager::HardwareResourceTimer; + return DeviceManager::HardwareResourceTimer | DeviceManager::HardwareResourceUpnpDisovery; } DeviceManager::DeviceError DevicePluginWemo::executeAction(Device *device, const Action &action) { - if(device->deviceClassId() == wemoSwitchDeviceClassId){ - if(action.actionTypeId() == powerActionTypeId){ + if (device->deviceClassId() == wemoSwitchDeviceClassId) { + if (action.actionTypeId() == powerActionTypeId) { WemoSwitch *wemoSwitch = m_wemoSwitches.key(device); - wemoSwitch->setPower(action.param("power").value().toBool(),action.id()); - - return DeviceManager::DeviceErrorAsync; - }else{ - return DeviceManager::DeviceErrorActionTypeNotFound; + if (wemoSwitch->reachable()) { + // setPower returns false, if the curent powerState == new powerState + if (wemoSwitch->setPower(action.param("power").value().toBool(), action.id())) { + return DeviceManager::DeviceErrorAsync; + } else { + return DeviceManager::DeviceErrorNoError; + } + } else { + return DeviceManager::DeviceErrorHardwareNotAvailable; + } + } else if (action.actionTypeId() == rediscoverActionTypeId) { + upnpDiscover("upnp:rootdevice"); + return DeviceManager::DeviceErrorNoError; } + return DeviceManager::DeviceErrorActionTypeNotFound; } - return DeviceManager::DeviceErrorDeviceClassNotFound; } @@ -133,8 +139,8 @@ void DevicePluginWemo::deviceRemoved(Device *device) WemoSwitch *wemoSwitch= m_wemoSwitches.key(device); qDebug() << "remove wemo swich " << wemoSwitch->serialNumber(); - wemoSwitch->deleteLater(); m_wemoSwitches.remove(wemoSwitch); + wemoSwitch->deleteLater(); } void DevicePluginWemo::guhTimer() @@ -144,33 +150,64 @@ void DevicePluginWemo::guhTimer() } } -void DevicePluginWemo::discoveryDone(QList deviceList) +void DevicePluginWemo::upnpDiscoveryFinished(const QList &upnpDeviceDescriptorList) { QList deviceDescriptors; - foreach (WemoSwitch *device, deviceList) { - DeviceDescriptor descriptor(wemoSwitchDeviceClassId, "WeMo Switch", device->serialNumber()); - ParamList params; - params.append(Param("name", device->name())); - params.append(Param("uuid", device->uuid())); - params.append(Param("port", device->port())); - params.append(Param("model", device->modelName())); - params.append(Param("model description", device->modelDescription())); - params.append(Param("serial number", device->serialNumber())); - params.append(Param("host address", device->hostAddress().toString())); - params.append(Param("location", device->location().toString())); - params.append(Param("manufacturer", device->manufacturer())); - params.append(Param("device type", device->deviceType())); - descriptor.setParams(params); - deviceDescriptors.append(descriptor); + foreach (UpnpDeviceDescriptor upnpDeviceDescriptor, upnpDeviceDescriptorList) { + if (upnpDeviceDescriptor.friendlyName() == "WeMo Switch") { + if (!verifyExistingDevices(upnpDeviceDescriptor)) { + DeviceDescriptor descriptor(wemoSwitchDeviceClassId, "WemoSwitch", upnpDeviceDescriptor.serialNumber()); + ParamList params; + params.append(Param("name", upnpDeviceDescriptor.friendlyName())); + params.append(Param("host address", upnpDeviceDescriptor.hostAddress().toString())); + params.append(Param("port", upnpDeviceDescriptor.port())); + params.append(Param("serial number", upnpDeviceDescriptor.serialNumber())); + descriptor.setParams(params); + deviceDescriptors.append(descriptor); + } + } } emit devicesDiscovered(wemoSwitchDeviceClassId, deviceDescriptors); } +void DevicePluginWemo::upnpNotifyReceived(const QByteArray ¬ifyData) +{ + Q_UNUSED(notifyData); +} + +bool DevicePluginWemo::verifyExistingDevices(UpnpDeviceDescriptor deviceDescriptor) +{ + foreach (WemoSwitch *wemoSwitch, m_wemoSwitches.keys()) { + // check if we allready have added this Wemo device and verify the params + if (wemoSwitch->serialNumber() == deviceDescriptor.serialNumber()) { + qDebug() << "verify wemo paramters... of" << wemoSwitch->serialNumber(); + Device *device = m_wemoSwitches.value(wemoSwitch); + // now check if ip or port changed + bool somethingChanged = false; + if (wemoSwitch->hostAddress() != deviceDescriptor.hostAddress()) { + device->setParamValue("host address", deviceDescriptor.hostAddress().toString()); + wemoSwitch->setHostAddress(deviceDescriptor.hostAddress()); + somethingChanged = true; + } + if(wemoSwitch->port() != deviceDescriptor.port()){ + device->setParamValue("port", deviceDescriptor.port()); + wemoSwitch->setPort(deviceDescriptor.port()); + somethingChanged = true; + } + if (somethingChanged) { + wemoSwitch->refresh(); + } + return true; + } + } + return false; +} + void DevicePluginWemo::wemoSwitchStateChanged() { WemoSwitch *wemoSwitch = static_cast(sender()); - if(m_wemoSwitches.contains(wemoSwitch)){ + if (m_wemoSwitches.contains(wemoSwitch)) { Device * device = m_wemoSwitches.value(wemoSwitch); device->setStateValue(powerStateTypeId, wemoSwitch->powerState()); device->setStateValue(reachableStateTypeId, wemoSwitch->reachable()); @@ -179,10 +216,10 @@ void DevicePluginWemo::wemoSwitchStateChanged() void DevicePluginWemo::setPowerFinished(const bool &succeeded, const ActionId &actionId) { - if(succeeded){ - emit actionExecutionFinished(actionId,DeviceManager::DeviceErrorNoError); - }else{ - emit actionExecutionFinished(actionId,DeviceManager::DeviceErrorHardwareFailure); + if (succeeded) { + emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorNoError); + } else { + emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorHardwareNotAvailable); } } diff --git a/plugins/deviceplugins/wemo/devicepluginwemo.h b/plugins/deviceplugins/wemo/devicepluginwemo.h index 7e2fa376..9ff3431b 100644 --- a/plugins/deviceplugins/wemo/devicepluginwemo.h +++ b/plugins/deviceplugins/wemo/devicepluginwemo.h @@ -20,7 +20,7 @@ #define DEVICEPLUGINWEMO_H #include "plugin/deviceplugin.h" -#include "wemodiscovery.h" +#include "wemoswitch.h" class DevicePluginWemo : public DevicePlugin { @@ -40,12 +40,14 @@ public: void deviceRemoved(Device *device) override; void guhTimer() override; + void upnpDiscoveryFinished(const QList &upnpDeviceDescriptorList) override; + void upnpNotifyReceived(const QByteArray ¬ifyData); - WemoDiscovery *m_discovery; +private: QHash m_wemoSwitches; + bool verifyExistingDevices(UpnpDeviceDescriptor deviceDescriptor); private slots: - void discoveryDone(QList deviceList); void wemoSwitchStateChanged(); void setPowerFinished(const bool &succeeded, const ActionId &actionId); diff --git a/plugins/deviceplugins/wemo/devicepluginwemo.json b/plugins/deviceplugins/wemo/devicepluginwemo.json index 3713fa04..dec0b72d 100644 --- a/plugins/deviceplugins/wemo/devicepluginwemo.json +++ b/plugins/deviceplugins/wemo/devicepluginwemo.json @@ -16,14 +16,6 @@ "name": "name", "type": "QString" }, - { - "name": "uuid", - "type": "QString" - }, - { - "name": "model", - "type": "QString" - }, { "name": "host address", "type": "QString" @@ -32,25 +24,9 @@ "name": "port", "type": "int" }, - { - "name": "model description", - "type": "QString" - }, { "name": "serial number", "type": "QString" - }, - { - "name": "location", - "type": "QString" - }, - { - "name": "manufacturer", - "type": "QString" - }, - { - "name": "device type", - "type": "QString" } ], "stateTypes": [ @@ -74,8 +50,16 @@ "id": "269f25eb-d0b7-4144-b9ef-801f4ff3e90c", "idName": "power", "name": "set power", - "type": "bool", - "defaultValue": true + "paramTypes": [ + { + "name": "power", + "type": "bool" + } + ] + }, + { + "id": "269cf3b8-d4dd-42e9-8309-6cb3ca8842df", + "name": "rediscover" } ] } diff --git a/plugins/deviceplugins/wemo/wemo.pro b/plugins/deviceplugins/wemo/wemo.pro index 114e662d..4ca60b0c 100644 --- a/plugins/deviceplugins/wemo/wemo.pro +++ b/plugins/deviceplugins/wemo/wemo.pro @@ -6,13 +6,11 @@ QT+= network SOURCES += \ devicepluginwemo.cpp \ - wemodiscovery.cpp \ wemoswitch.cpp HEADERS += \ devicepluginwemo.h \ - wemodiscovery.h \ wemoswitch.h diff --git a/plugins/deviceplugins/wemo/wemodiscovery.cpp b/plugins/deviceplugins/wemo/wemodiscovery.cpp deleted file mode 100644 index 4f2926a3..00000000 --- a/plugins/deviceplugins/wemo/wemodiscovery.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * This file is part of guh. * - * * - * Guh is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, version 2 of the License. * - * * - * Guh 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 guh. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "wemodiscovery.h" - -WemoDiscovery::WemoDiscovery(QObject *parent) : - QUdpSocket(parent) -{ - m_timeout = new QTimer(this); - m_timeout->setSingleShot(true); - connect(m_timeout,SIGNAL(timeout()),this,SLOT(discoverTimeout())); - - m_manager = new QNetworkAccessManager(this); - connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*))); - - m_port = 1900; - m_host = QHostAddress("239.255.255.250"); - setSocketOption(QAbstractSocket::MulticastTtlOption,QVariant(1)); - setSocketOption(QAbstractSocket::MulticastLoopbackOption,QVariant(1)); - bind(QHostAddress::AnyIPv4,m_port,QUdpSocket::ShareAddress); - - if(!joinMulticastGroup(m_host)){ - qWarning() << "ERROR: could not join multicast group"; - } - - connect(this,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(error(QAbstractSocket::SocketError))); - connect(this,SIGNAL(readyRead()),this,SLOT(readData())); -} - -bool WemoDiscovery::checkXmlData(QByteArray data) -{ - QByteArray xmlOut; - QXmlStreamReader reader(data); - QXmlStreamWriter writer(&xmlOut); - writer.setAutoFormatting(true); - - while (!reader.atEnd()) { - reader.readNext(); - if (!reader.isWhitespace()) { - writer.writeCurrentToken(reader); - } - } - if(reader.hasError()){ - qDebug() << "ERROR reading XML device information: " << reader.errorString(); - qDebug() << "--------------------------------------------"; - return false; - } - m_deviceInformationData = xmlOut; - return true; -} - -QString WemoDiscovery::printXmlData(QByteArray data) -{ - QString xmlOut; - QXmlStreamReader reader(data); - QXmlStreamWriter writer(&xmlOut); - writer.setAutoFormatting(true); - - while (!reader.atEnd()) { - reader.readNext(); - if (!reader.isWhitespace()) { - writer.writeCurrentToken(reader); - } - } - if(reader.hasError()){ - qDebug() << "ERROR reading XML device information: " << reader.errorString(); - qDebug() << "--------------------------------------------"; - } - return xmlOut; -} - -void WemoDiscovery::error(QAbstractSocket::SocketError error) -{ - qWarning() << errorString() << error; -} - -void WemoDiscovery::sendDiscoverMessage() -{ - QByteArray ssdpSearchMessage("M-SEARCH * HTTP/1.1\r\n" - "HOST:239.255.255.250:1900\r\n" - "ST:upnp:rootdevice\r\n" - "MX:2\r\n" - "MAN:\"ssdp:discover\"\r\n\r\n"); - writeDatagram(ssdpSearchMessage,m_host,m_port); -} - -void WemoDiscovery::readData() -{ - QByteArray data; - QHostAddress sender; - quint16 udpPort; - - // read the answere from the multicast - while (hasPendingDatagrams()) { - data.resize(pendingDatagramSize()); - readDatagram(data.data(), data.size(), &sender, &udpPort); - } - - if(data.contains("HTTP/1.1 200 OK")){ - const QStringList lines = QString(data).split("\r\n"); - - QUrl location; - QString uuid; - - foreach( const QString& line, lines){ - int separatorIndex = line.indexOf(':'); - QString key = line.left(separatorIndex).toUpper(); - QString value = line.mid(separatorIndex+1).trimmed(); - - // get location - if(key.contains("LOCATION")){ - location = QUrl(value); - } - - // get uuid - if(key.contains("USN")){ - int startIndex = value.indexOf(":"); - int endIndex = value.indexOf("::"); - uuid = value.mid(startIndex +1 ,(endIndex - startIndex)-1); - // check if we found a socket...else return - if(!uuid.startsWith("Socket-1_0")){ - return; - } - } - - if(!location.isEmpty() && !uuid.isEmpty()){ - // check if we already discovered this device - foreach (WemoSwitch *device, m_deviceList) { - if(device->uuid() == uuid){ - return; - } - } - - // get port from location (it changes between 49152-5 so fare...) - QByteArray locationData = location.toString().toUtf8(); - locationData = locationData.left(locationData.length() - 10); - qDebug() << "locationData" << locationData; - int port = locationData.right(5).toInt(); - - - WemoSwitch *device = new WemoSwitch(this); - device->setHostAddress(sender); - device->setUuid(uuid); - device->setLocation(location); - device->setPort(port); - - qDebug() << "--> UPnP searcher discovered wemo..."; - qDebug() << "location: " << device->location().toString(); - qDebug() << "ip: " << device->hostAddress().toString(); - qDebug() << "uuid: " << device->uuid(); - qDebug() << "port: " << device->port(); - qDebug() << "--------------------------------------------"; - - m_deviceList.append(device); - requestDeviceInformation(location); - } - } - } -} - -void WemoDiscovery::discoverTimeout() -{ - emit discoveryDone(m_deviceList); -} - -void WemoDiscovery::requestDeviceInformation(QUrl location) -{ - m_manager->get(QNetworkRequest(location)); -} - -void WemoDiscovery::replyFinished(QNetworkReply *reply) -{ - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - switch (status) { - case(200): - parseDeviceInformation(reply->readAll()); - break; - default: - qWarning() << "HTTP request error " << status; - return; - } -} - -void WemoDiscovery::parseDeviceInformation(QByteArray data) -{ - - QXmlStreamReader xml(data); - - QString name; - QString uuid; - QString modelName; - QString modelDescription; - QString serialNumber; - QString deviceType; - QString manufacturer; - - while(!xml.atEnd() && !xml.hasError()){ - xml.readNext(); - if(xml.isStartDocument()){ - continue; - } - if(xml.isStartElement()){ - if(xml.name().toString() == "device"){ - while(!xml.atEnd()){ - if(xml.name() == "friendlyName" && xml.isStartElement()){ - name = xml.readElementText(); - } - if(xml.name() == "manufacturer" && xml.isStartElement()){ - manufacturer = xml.readElementText(); - } - if(xml.name() == "modelDescription" && xml.isStartElement()){ - modelDescription = xml.readElementText(); - } - if(xml.name() == "modelName" && xml.isStartElement()){ - modelName = xml.readElementText(); - } - if(xml.name() == "serialNumber" && xml.isStartElement()){ - serialNumber = xml.readElementText(); - } - if(xml.name() == "deviceType" && xml.isStartElement()){ - deviceType = xml.readElementText(); - } - if(xml.name() == "UDN" && xml.isStartElement()){ - uuid = xml.readElementText(); - if(uuid.startsWith("uuid:")){ - uuid = uuid.right(uuid.length()-5); - } - } - xml.readNext(); - } - xml.readNext(); - } - } - } - foreach (WemoSwitch *device, m_deviceList) { - // find our device with this uuid - if(device->uuid() == uuid){ - device->setName(name); - device->setModelName(modelName); - device->setDeviceType(deviceType); - device->setManufacturer(manufacturer); - device->setModelDescription(modelDescription); - device->setSerialNumber(serialNumber); - - qDebug() << "--> fetched Wemo information..."; - qDebug() << "name: " << device->name(); - qDebug() << "model name: " << device->modelName(); - qDebug() << "device type: " << device->deviceType(); - qDebug() << "manufacturer: " << device->manufacturer(); - qDebug() << "address: " << device->hostAddress().toString(); - qDebug() << "location: " << device->location().toString(); - qDebug() << "uuid: " << device->uuid(); - qDebug() << "model description " << device->modelDescription(); - qDebug() << "serial number " << device->serialNumber(); - qDebug() << "--------------------------------------------"; - } - } -} - -void WemoDiscovery::discover(int timeout) -{ - m_deviceList.clear(); - m_timeout->stop(); - sendDiscoverMessage(); - m_timeout->start(timeout); -} diff --git a/plugins/deviceplugins/wemo/wemodiscovery.h b/plugins/deviceplugins/wemo/wemodiscovery.h deleted file mode 100644 index 19252b30..00000000 --- a/plugins/deviceplugins/wemo/wemodiscovery.h +++ /dev/null @@ -1,74 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * This file is part of guh. * - * * - * Guh is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, version 2 of the License. * - * * - * Guh 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 guh. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef WEMODISCOVERY_H -#define WEMODISCOVERY_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wemoswitch.h" - -class WemoDiscovery : public QUdpSocket -{ - Q_OBJECT -public: - explicit WemoDiscovery(QObject *parent = 0); - -private: - QHostAddress m_host; - qint16 m_port; - - QTimer *m_timeout; - - QNetworkAccessManager *m_manager; - - QByteArray m_deviceInformationData; - bool checkXmlData(QByteArray data); - QString printXmlData(QByteArray data); - - QList m_deviceList; - -signals: - void discoveryDone(QList deviceList); - -private slots: - void error(QAbstractSocket::SocketError error); - void sendDiscoverMessage(); - void readData(); - void discoverTimeout(); - - void requestDeviceInformation(QUrl location); - void replyFinished(QNetworkReply *reply); - void parseDeviceInformation(QByteArray data); - -public slots: - void discover(int timeout); - - -}; - -#endif // WEMODISCOVERY_H diff --git a/plugins/deviceplugins/wemo/wemoswitch.cpp b/plugins/deviceplugins/wemo/wemoswitch.cpp index 76c7e28e..e4c2dbbb 100644 --- a/plugins/deviceplugins/wemo/wemoswitch.cpp +++ b/plugins/deviceplugins/wemo/wemoswitch.cpp @@ -18,112 +18,16 @@ #include "wemoswitch.h" -WemoSwitch::WemoSwitch(QObject *parent) : - QObject(parent) +WemoSwitch::WemoSwitch(QObject *parent, UpnpDeviceDescriptor upnpDeviceDescriptor): + UpnpDevice(parent, upnpDeviceDescriptor) { m_manager = new QNetworkAccessManager(this); connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*))); } -void WemoSwitch::setLocation(const QUrl &location) +WemoSwitch::~WemoSwitch() { - m_location = location; -} - -QUrl WemoSwitch::location() const -{ - return m_location; -} - -void WemoSwitch::setHostAddress(const QHostAddress &hostAddress) -{ - m_hostAddress = hostAddress; -} - -QHostAddress WemoSwitch::hostAddress() const -{ - return m_hostAddress; -} - -void WemoSwitch::setPort(const int &port) -{ - m_port = port; -} - -int WemoSwitch::port() const -{ - return m_port; -} - -void WemoSwitch::setManufacturer(const QString &manufacturer) -{ - m_manufacturer = manufacturer; -} - -QString WemoSwitch::manufacturer() const -{ - return m_manufacturer; -} - -void WemoSwitch::setName(const QString &name) -{ - m_name = name; -} - -QString WemoSwitch::name() const -{ - return m_name; -} - -void WemoSwitch::setDeviceType(const QString &deviceType) -{ - m_deviceType = deviceType; -} - -QString WemoSwitch::deviceType() const -{ - return m_deviceType; -} - -void WemoSwitch::setModelDescription(const QString &modelDescription) -{ - m_modelDescription = modelDescription; -} - -QString WemoSwitch::modelDescription() const -{ - return m_modelDescription; -} - -void WemoSwitch::setModelName(const QString &modelName) -{ - m_modelName = modelName; -} - -QString WemoSwitch::modelName() const -{ - return m_modelName; -} - -void WemoSwitch::setSerialNumber(const QString &serialNumber) -{ - m_serialNumber = serialNumber; -} - -QString WemoSwitch::serialNumber() const -{ - return m_serialNumber; -} - -void WemoSwitch::setUuid(const QString &uuid) -{ - m_uuid = uuid; -} - -QString WemoSwitch::uuid() const -{ - return m_uuid; } bool WemoSwitch::powerState() @@ -138,32 +42,39 @@ bool WemoSwitch::reachable() void WemoSwitch::replyFinished(QNetworkReply *reply) { - if(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200){ + if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) { + // clean up + if (reply == m_setPowerReplay) { + emit setPowerFinished(false,m_actionId); + m_setPowerReplay->deleteLater(); + } + if (reply == m_refrashReplay) { + m_refrashReplay->deleteLater(); + } m_reachable = false; emit stateChanged(); - m_setPowerReplay->deleteLater(); return; - }else{ + } else { m_reachable = true; } // if this is the answerer to a refresh request - if(reply == m_refrashReplay){ + if (reply == m_refrashReplay) { QByteArray data = reply->readAll(); - if(data.contains("0")){ + if (data.contains("0")) { m_powerState = false; } - if(data.contains("1")){ + if (data.contains("1")) { m_powerState = true; } m_refrashReplay->deleteLater(); } // if this is the answerer to a "set power" request - if(reply == m_setPowerReplay){ + if (reply == m_setPowerReplay) { QByteArray data = reply->readAll(); - if(data.contains("1") || data.contains("0")){ + if (data.contains("1") || data.contains("0")) { emit setPowerFinished(true,m_actionId); - }else{ + } else { emit setPowerFinished(false,m_actionId); } refresh(); @@ -178,7 +89,7 @@ void WemoSwitch::refresh() QByteArray getBinarayStateMessage("1"); QNetworkRequest request; - request.setUrl(QUrl("http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/upnp/control/basicevent1")); + request.setUrl(QUrl("http://" + hostAddress().toString() + ":" + QString::number(port()) + "/upnp/control/basicevent1")); request.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("text/xml; charset=\"utf-8\"")); request.setHeader(QNetworkRequest::UserAgentHeader,QVariant("guh")); request.setRawHeader("SOAPACTION", "\"urn:Belkin:service:basicevent:1#GetBinaryState\""); @@ -186,22 +97,23 @@ void WemoSwitch::refresh() m_refrashReplay = m_manager->post(request,getBinarayStateMessage); } -void WemoSwitch::setPower(const bool &power, const ActionId &actionId) +bool WemoSwitch::setPower(const bool &power, const ActionId &actionId) { m_actionId = actionId; - if(m_powerState == power){ - emit setPowerFinished(true,actionId); - return; + // check if the power state changed... + if (m_powerState == power) { + return false; } QByteArray setPowerMessage("" + QByteArray::number((int)power) + ""); QNetworkRequest request; - request.setUrl(QUrl("http://" + m_hostAddress.toString() + ":" + QString::number(m_port) + "/upnp/control/basicevent1")); + request.setUrl(QUrl("http://" + hostAddress().toString() + ":" + QString::number(port()) + "/upnp/control/basicevent1")); request.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("text/xml; charset=\"utf-8\"")); request.setHeader(QNetworkRequest::UserAgentHeader,QVariant("guh")); request.setRawHeader("SOAPACTION", "\"urn:Belkin:service:basicevent:1#SetBinaryState\""); m_setPowerReplay = m_manager->post(request,setPowerMessage); + return true; } diff --git a/plugins/deviceplugins/wemo/wemoswitch.h b/plugins/deviceplugins/wemo/wemoswitch.h index 11fe4aac..2c341dc8 100644 --- a/plugins/deviceplugins/wemo/wemoswitch.h +++ b/plugins/deviceplugins/wemo/wemoswitch.h @@ -30,58 +30,19 @@ #include #include "plugin/deviceplugin.h" +#include "hardware/upnpdiscovery/upnpdevice.h" -class WemoSwitch : public QObject +class WemoSwitch : public UpnpDevice { Q_OBJECT public: - explicit WemoSwitch(QObject *parent = 0); - - void setLocation(const QUrl &location); - QUrl location() const; - - void setHostAddress(const QHostAddress &hostAddress); - QHostAddress hostAddress() const; - - void setPort(const int &port); - int port() const; - - void setManufacturer(const QString &manufacturer); - QString manufacturer() const; - - void setName(const QString &name); - QString name() const; - - void setDeviceType(const QString &deviceType); - QString deviceType() const; - - void setModelDescription(const QString &modelDescription); - QString modelDescription() const; - - void setModelName(const QString &modelName); - QString modelName() const; - - void setSerialNumber(const QString &serialNumber); - QString serialNumber() const; - - void setUuid(const QString &uuid); - QString uuid() const; + explicit WemoSwitch(QObject *parent = 0, UpnpDeviceDescriptor upnpDeviceDescriptor = UpnpDeviceDescriptor()); + ~WemoSwitch(); bool powerState(); bool reachable(); private: - QUrl m_location; - QHostAddress m_hostAddress; - int m_port; - QString m_name; - QString m_deviceType; - QString m_modelName; - QString m_modelDescription; - QString m_manufacturer; - QString m_serialNumber; - QString m_uuid; - QNetworkAccessManager *m_manager; QNetworkReply *m_refrashReplay; QNetworkReply *m_setPowerReplay; @@ -99,7 +60,7 @@ private slots: public slots: void refresh(); - void setPower(const bool &power, const ActionId &actionId); + bool setPower(const bool &power, const ActionId &actionId); }; #endif // WEMOSWITCH_H