diff --git a/plugins/deviceplugins/deviceplugins.pro b/plugins/deviceplugins/deviceplugins.pro index 58efbd9a..c95348e0 100644 --- a/plugins/deviceplugins/deviceplugins.pro +++ b/plugins/deviceplugins/deviceplugins.pro @@ -10,7 +10,8 @@ SUBDIRS += elro \ wakeonlan \ mailnotification \ philipshue \ - eq-3 \ + wemo \ + boblight { SUBDIRS += boblight diff --git a/plugins/deviceplugins/wemo/devicepluginwemo.cpp b/plugins/deviceplugins/wemo/devicepluginwemo.cpp new file mode 100644 index 00000000..615a3446 --- /dev/null +++ b/plugins/deviceplugins/wemo/devicepluginwemo.cpp @@ -0,0 +1,218 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * 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 "devicepluginwemo.h" + +#include "plugin/device.h" +#include "devicemanager.h" + +#include + +VendorId belkinVendorId = VendorId("b241f7f5-8153-4a72-b260-f62beadc2d19"); +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"); + + +DevicePluginWemo::DevicePluginWemo() +{ + m_discovery = new WemoDiscovery(this); + + connect(m_discovery,SIGNAL(discoveryDone(QList)),this,SLOT(discoveryDone(QList))); +} + +QList DevicePluginWemo::supportedVendors() const +{ + QList ret; + ret.append(Vendor(belkinVendorId, "Belkin")); + return ret; +} + +QList DevicePluginWemo::supportedDevices() const +{ + QList ret; + + // ============================== + // WeMo Switch + DeviceClass deviceClassWemoSwitch(pluginId(), belkinVendorId, wemoSwitchDeviceClassId); + deviceClassWemoSwitch.setName("WeMo Switch"); + deviceClassWemoSwitch.setCreateMethod(DeviceClass::CreateMethodDiscovery); + + // params + QList paramTypes; + + paramTypes.append(ParamType("name", QVariant::String)); + paramTypes.append(ParamType("uuid", QVariant::String)); + paramTypes.append(ParamType("model", QVariant::String)); + paramTypes.append(ParamType("host address", QVariant::String)); + paramTypes.append(ParamType("port", QVariant::Int)); + paramTypes.append(ParamType("model description", QVariant::String)); + paramTypes.append(ParamType("serial number", QVariant::String)); + paramTypes.append(ParamType("location", QVariant::String)); + paramTypes.append(ParamType("manufacturer", QVariant::String)); + paramTypes.append(ParamType("device type", QVariant::String)); + + deviceClassWemoSwitch.setParamTypes(paramTypes); + + // States + QList wemoSwitchStates; + + StateType powerState(powerStateTypeId); + powerState.setName("power"); + powerState.setType(QVariant::Bool); + powerState.setDefaultValue(false); + wemoSwitchStates.append(powerState); + + StateType reachableState(reachableStateTypeId); + reachableState.setName("reachable"); + reachableState.setType(QVariant::Bool); + reachableState.setDefaultValue(false); + wemoSwitchStates.append(reachableState); + + deviceClassWemoSwitch.setStateTypes(wemoSwitchStates); + + // Actions + QList wemoSwitchActons; + + ActionType powerAction(powerActionTypeId); + powerAction.setName("Set power"); + QList actionParamsPower; + actionParamsPower.append(ParamType("power", QVariant::Bool)); + powerAction.setParameters(actionParamsPower); + wemoSwitchActons.append(powerAction); + + deviceClassWemoSwitch.setActions(wemoSwitchActons); + + ret.append(deviceClassWemoSwitch); + return ret; +} + +QPair DevicePluginWemo::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) +{ + if(deviceClassId != wemoSwitchDeviceClassId){ + return report(DeviceManager::DeviceErrorDeviceClassNotFound); + } + + m_discovery->discover(2000); + + return report(DeviceManager::DeviceErrorAsync); +} + +QPair DevicePluginWemo::setupDevice(Device *device) +{ + if(device->deviceClassId() == wemoSwitchDeviceClassId){ + foreach (WemoSwitch *wemoSwitch, m_wemoSwitches.keys()) { + if(wemoSwitch->serialNumber() == device->paramValue("serial number").toString()){ + qWarning() << wemoSwitch->serialNumber() << " allready exists..."; + return reportDeviceSetup(DeviceManager::DeviceSetupStatusFailure,QString("Device allready added")); + } + } + + 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()); + + connect(wemoSwitch,SIGNAL(stateChanged()),this,SLOT(wemoSwitchStateChanged())); + + + m_wemoSwitches.insert(wemoSwitch,device); + return reportDeviceSetup(); + } + return reportDeviceSetup(DeviceManager::DeviceSetupStatusSuccess); +} + +DeviceManager::HardwareResources DevicePluginWemo::requiredHardware() const +{ + return DeviceManager::HardwareResourceTimer; +} + +QPair DevicePluginWemo::executeAction(Device *device, const Action &action) +{ + return report(); +} + +void DevicePluginWemo::deviceRemoved(Device *device) +{ + if (!m_wemoSwitches.values().contains(device)) { + return; + } + + WemoSwitch *wemoSwitch= m_wemoSwitches.key(device); + qDebug() << "remove wemo swich " << wemoSwitch->serialNumber(); + m_wemoSwitches.remove(wemoSwitch); +} + +QString DevicePluginWemo::pluginName() const +{ + return "WeMo"; +} + +PluginId DevicePluginWemo::pluginId() const +{ + return PluginId("2e3b5ce0-ecf1-43de-98f0-07df4068a583"); +} + +void DevicePluginWemo::guhTimer() +{ + foreach (WemoSwitch* device, m_wemoSwitches.keys()) { + device->refresh(); + } +} + +void DevicePluginWemo::discoveryDone(QList deviceList) +{ + 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); + } + emit devicesDiscovered(wemoSwitchDeviceClassId, deviceDescriptors); +} + +void DevicePluginWemo::wemoSwitchStateChanged() +{ + + + + +} + diff --git a/plugins/deviceplugins/wemo/devicepluginwemo.h b/plugins/deviceplugins/wemo/devicepluginwemo.h new file mode 100644 index 00000000..741d2610 --- /dev/null +++ b/plugins/deviceplugins/wemo/devicepluginwemo.h @@ -0,0 +1,61 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * 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 DEVICEPLUGINWEMO_H +#define DEVICEPLUGINWEMO_H + +#include "plugin/deviceplugin.h" +#include "wemodiscovery.h" + +class DevicePluginWemo : public DevicePlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "devicepluginwemo.json") + Q_INTERFACES(DevicePlugin) + +public: + explicit DevicePluginWemo(); + + QList supportedVendors() const override; + QList supportedDevices() const override; + + QPair discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override; + QPair setupDevice(Device *device) override; + DeviceManager::HardwareResources requiredHardware() const override; + QPair executeAction(Device *device, const Action &action) override; + + void deviceRemoved(Device *device) override; + + QString pluginName() const override; + PluginId pluginId() const override; + + void guhTimer() override; + + WemoDiscovery *m_discovery; + QHash m_wemoSwitches; + +private slots: + void discoveryDone(QList deviceList); + void wemoSwitchStateChanged(); +public slots: + + +}; + +#endif // DEVICEPLUGINWEMO_H diff --git a/plugins/deviceplugins/wemo/devicepluginwemo.json b/plugins/deviceplugins/wemo/devicepluginwemo.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/plugins/deviceplugins/wemo/devicepluginwemo.json @@ -0,0 +1 @@ +{} diff --git a/plugins/deviceplugins/wemo/wemo.pro b/plugins/deviceplugins/wemo/wemo.pro new file mode 100644 index 00000000..114e662d --- /dev/null +++ b/plugins/deviceplugins/wemo/wemo.pro @@ -0,0 +1,19 @@ +include(../../plugins.pri) + +TARGET = $$qtLibraryTarget(guh_devicepluginwemo) + +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 new file mode 100644 index 00000000..d00b09a3 --- /dev/null +++ b/plugins/deviceplugins/wemo/wemodiscovery.cpp @@ -0,0 +1,281 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * 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 allready 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 new file mode 100644 index 00000000..19252b30 --- /dev/null +++ b/plugins/deviceplugins/wemo/wemodiscovery.h @@ -0,0 +1,74 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * 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 new file mode 100644 index 00000000..c11665ac --- /dev/null +++ b/plugins/deviceplugins/wemo/wemoswitch.cpp @@ -0,0 +1,184 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * 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 "wemoswitch.h" + +WemoSwitch::WemoSwitch(QObject *parent) : + QObject(parent) +{ + m_manager = new QNetworkAccessManager(this); + + connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*))); +} + +void WemoSwitch::setLocation(const QUrl &location) +{ + 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() +{ + return m_powerState; +} + +void WemoSwitch::replyFinished(QNetworkReply *reply) +{ + if(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200){ + m_reachabel = false; + emit stateChanged(); + return; + }else{ + m_reachabel = true; + } + + if(reply == m_refrashReplay){ + QByteArray data = reply->readAll(); + if(data.contains("0")){ + qDebug() << "switch is off"; + m_powerState = false; + } + if(data.contains("1")){ + qDebug() << "switch is on"; + m_powerState = true; + } + } + emit stateChanged(); +} + +void WemoSwitch::refresh() +{ + QByteArray getBinarayStateMessage("1"); + + QNetworkRequest request; + request.setUrl(QUrl("http://" + m_hostAddress.toString() + ":" + QString::number(m_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\""); + + m_refrashReplay = m_manager->post(request,getBinarayStateMessage); +} + +void WemoSwitch::setPower(const bool &power, const ActionId &actionId) +{ + m_actionId = actionId; + + QByteArray setPowerMessage("" + QByteArray::number((int)power) + ""); + + QNetworkRequest request; + request.setUrl(QUrl("http://" + m_hostAddress.toString() + ":" + QString::number(m_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\""); + + m_refrashReplay = m_manager->post(request,setPowerMessage); +} diff --git a/plugins/deviceplugins/wemo/wemoswitch.h b/plugins/deviceplugins/wemo/wemoswitch.h new file mode 100644 index 00000000..16eeed72 --- /dev/null +++ b/plugins/deviceplugins/wemo/wemoswitch.h @@ -0,0 +1,105 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * 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 WEMOSWITCH_H +#define WEMOSWITCH_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "plugin/deviceplugin.h" + +class WemoSwitch : public QObject +{ + 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; + + bool powerState(); + bool reachabel(); + +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; + + bool m_powerState; + bool m_reachabel; + + ActionId m_actionId; +signals: + void stateChanged(); + void setPowerFinished(const bool &succeeded, const ActionId &actionId); + +private slots: + void replyFinished(QNetworkReply *reply); + +public slots: + void refresh(); + void setPower(const bool &power, const ActionId &actionId); +}; + +#endif // WEMOSWITCH_H diff --git a/server/main.cpp b/server/main.cpp index 590c021b..426c88d4 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -32,7 +32,7 @@ Q_IMPORT_PLUGIN(DevicePluginLircd) Q_IMPORT_PLUGIN(DevicePluginWakeOnLan) Q_IMPORT_PLUGIN(DevicePluginMailNotification) Q_IMPORT_PLUGIN(DevicePluginPhilipsHue) -Q_IMPORT_PLUGIN(DevicePluginEQ3) +Q_IMPORT_PLUGIN(DevicePluginWemo) #if USE_BOBLIGHT Q_IMPORT_PLUGIN(DevicePluginBoblight) diff --git a/server/server.pro b/server/server.pro index 1b7d4e4e..a1a863de 100644 --- a/server/server.pro +++ b/server/server.pro @@ -30,7 +30,7 @@ LIBS += -L../plugins/deviceplugins/lircd -lguh_devicepluginlircd LIBS += -L../plugins/deviceplugins/mailnotification -lguh_devicepluginmailnotification LIBS += -L../plugins/deviceplugins/wakeonlan -lguh_devicepluginwakeonlan LIBS += -L../plugins/deviceplugins/philipshue -lguh_devicepluginphilipshue -LIBS += -L../plugins/deviceplugins/eq-3 -lguh_deviceplugineq3 +LIBS += -L../plugins/deviceplugins/wemo -lguh_devicepluginwemo boblight { xcompile {