mirror of
https://github.com/nymea/nymea-plugins.git
synced 2026-10-23 14:43:44 +02:00
removed deprecated files
This commit is contained in:
parent
e69fa63b67
commit
832cb2b03a
@ -1,183 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
*
|
|
||||||
* Copyright 2013 - 2020, nymea GmbH
|
|
||||||
* Contact: contact@nymea.io
|
|
||||||
*
|
|
||||||
* This file is part of nymea.
|
|
||||||
* This project including source code and documentation is protected by
|
|
||||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
|
||||||
* reproduction, publication, editing and translation, are reserved. The use of
|
|
||||||
* this project is subject to the terms of a license agreement to be concluded
|
|
||||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
|
||||||
* under https://nymea.io/license
|
|
||||||
*
|
|
||||||
* GNU Lesser General Public License Usage
|
|
||||||
* Alternatively, this project may be redistributed and/or modified under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free
|
|
||||||
* Software Foundation; version 3. This project is distributed in the hope that
|
|
||||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* For any further details and any questions please contact us under
|
|
||||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
|
||||||
* https://nymea.io/license/faq
|
|
||||||
*
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#include "ssdp.h"
|
|
||||||
#include "extern-plugininfo.h"
|
|
||||||
|
|
||||||
#include <QMetaObject>
|
|
||||||
#include <QNetworkInterface>
|
|
||||||
#include <QXmlStreamReader>
|
|
||||||
#include <QXmlStreamWriter>
|
|
||||||
#include <QNetworkConfiguration>
|
|
||||||
#include <QNetworkConfigurationManager>
|
|
||||||
|
|
||||||
Ssdp::Ssdp(QObject *parent) : QObject(parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Ssdp::~Ssdp()
|
|
||||||
{
|
|
||||||
if (m_socket) {
|
|
||||||
m_socket->waitForBytesWritten(1000);
|
|
||||||
m_socket->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Ssdp::enable()
|
|
||||||
{
|
|
||||||
// Clean up
|
|
||||||
if (m_socket) {
|
|
||||||
delete m_socket;
|
|
||||||
m_socket = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind udp socket and join multicast group
|
|
||||||
m_socket = new QUdpSocket(this);
|
|
||||||
m_socket2 = new QUdpSocket(this);
|
|
||||||
m_port = 1982;
|
|
||||||
m_host = QHostAddress("239.255.255.250");
|
|
||||||
|
|
||||||
m_socket->setSocketOption(QAbstractSocket::MulticastTtlOption,QVariant(1));
|
|
||||||
m_socket->setSocketOption(QAbstractSocket::MulticastLoopbackOption,QVariant(1));
|
|
||||||
|
|
||||||
if(!m_socket->bind(QHostAddress::AnyIPv4, m_port, QUdpSocket::ShareAddress)){
|
|
||||||
qCWarning(dcYeelight()) << "could not bind to port" << m_port;
|
|
||||||
m_available = false;
|
|
||||||
delete m_socket;
|
|
||||||
m_socket = nullptr;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!m_socket2->bind(QHostAddress::AnyIPv4, 34343, QUdpSocket::ShareAddress)){
|
|
||||||
qCWarning(dcYeelight()) << "could not bind to port" << 34343;
|
|
||||||
delete m_socket2;
|
|
||||||
m_socket2 = nullptr;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!m_socket->joinMulticastGroup(m_host)){
|
|
||||||
qCWarning(dcYeelight()) << "could not join multicast group" << m_host;
|
|
||||||
m_available = false;
|
|
||||||
delete m_socket;
|
|
||||||
m_socket = nullptr;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError)));
|
|
||||||
connect(m_socket, &QUdpSocket::readyRead, this, &Ssdp::readData);
|
|
||||||
connect(m_socket2, &QUdpSocket::readyRead, this, &Ssdp::readData2);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ssdp::discover()
|
|
||||||
{
|
|
||||||
QByteArray searchMessage = QByteArray("M-SEARCH * HTTP/1.1\r\n"
|
|
||||||
"HOST: 239.255.255.250:1982\r\n"
|
|
||||||
"MAN: \"ssdp:discover\"\r\n"
|
|
||||||
"ST: wifi_bulb\r\n");
|
|
||||||
m_socket2->writeDatagram(searchMessage, m_host, m_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Ssdp::error(QAbstractSocket::SocketError error)
|
|
||||||
{
|
|
||||||
qCWarning(dcYeelight()) << "socket error:" << error << m_socket->errorString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ssdp::readData()
|
|
||||||
{
|
|
||||||
QByteArray data;
|
|
||||||
quint16 port;
|
|
||||||
QHostAddress hostAddress;
|
|
||||||
QUrl location;
|
|
||||||
int id;
|
|
||||||
QString model;
|
|
||||||
|
|
||||||
// read the answere from the multicast
|
|
||||||
while (m_socket->hasPendingDatagrams()) {
|
|
||||||
data.resize(m_socket->pendingDatagramSize());
|
|
||||||
m_socket->readDatagram(data.data(), data.size(), &hostAddress, &port);
|
|
||||||
}
|
|
||||||
qCDebug(dcYeelight())<< "SSDP message received " << data;
|
|
||||||
|
|
||||||
if (data.contains("NOTIFY") && !QNetworkInterface::allAddresses().contains(hostAddress)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the data contains the HTTP OK header...
|
|
||||||
if (data.contains("HTTP/1.1 200 OK")) {
|
|
||||||
const QStringList lines = QString(data).split("\r\n");
|
|
||||||
foreach (const QString& line, lines) {
|
|
||||||
int separatorIndex = line.indexOf(':');
|
|
||||||
QString key = line.left(separatorIndex).toUpper();
|
|
||||||
QString value = line.mid(separatorIndex+1).trimmed();
|
|
||||||
|
|
||||||
if (key.contains("Location")) {
|
|
||||||
location = QUrl(value);
|
|
||||||
} else if (key.contains("id")) {
|
|
||||||
id = value.toUInt();
|
|
||||||
} else if (key.contains("model")) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit discovered(location.host(), location.port(), id, model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ssdp::readData2()
|
|
||||||
{
|
|
||||||
QByteArray data;
|
|
||||||
quint16 port;
|
|
||||||
QHostAddress hostAddress;
|
|
||||||
|
|
||||||
// read the answere from the multicast
|
|
||||||
while (m_socket->hasPendingDatagrams()) {
|
|
||||||
data.resize(m_socket->pendingDatagramSize());
|
|
||||||
m_socket->readDatagram(data.data(), data.size(), &hostAddress, &port);
|
|
||||||
}
|
|
||||||
qCDebug(dcYeelight())<< "SSDP message received " << data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Ssdp::disable()
|
|
||||||
{
|
|
||||||
if (!m_socket) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_socket->waitForBytesWritten();
|
|
||||||
m_socket->close();
|
|
||||||
delete m_socket;
|
|
||||||
m_socket = nullptr;
|
|
||||||
|
|
||||||
m_notificationTimer->stop();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
*
|
|
||||||
* Copyright 2013 - 2020, nymea GmbH
|
|
||||||
* Contact: contact@nymea.io
|
|
||||||
*
|
|
||||||
* This file is part of nymea.
|
|
||||||
* This project including source code and documentation is protected by
|
|
||||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
|
||||||
* reproduction, publication, editing and translation, are reserved. The use of
|
|
||||||
* this project is subject to the terms of a license agreement to be concluded
|
|
||||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
|
||||||
* under https://nymea.io/license
|
|
||||||
*
|
|
||||||
* GNU Lesser General Public License Usage
|
|
||||||
* Alternatively, this project may be redistributed and/or modified under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free
|
|
||||||
* Software Foundation; version 3. This project is distributed in the hope that
|
|
||||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* For any further details and any questions please contact us under
|
|
||||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
|
||||||
* https://nymea.io/license/faq
|
|
||||||
*
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#ifndef SSDP_H
|
|
||||||
#define SSDP_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#include <QUdpSocket>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QUdpSocket>
|
|
||||||
#include <QHostAddress>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
|
|
||||||
class Ssdp : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Ssdp(QObject *parent = nullptr);
|
|
||||||
~Ssdp();
|
|
||||||
bool enable();
|
|
||||||
void discover();
|
|
||||||
bool disable();
|
|
||||||
private:
|
|
||||||
QUdpSocket *m_socket = nullptr;
|
|
||||||
QUdpSocket *m_socket2 = nullptr;
|
|
||||||
QHostAddress m_host;
|
|
||||||
quint16 m_port;
|
|
||||||
|
|
||||||
QTimer *m_notificationTimer = nullptr;
|
|
||||||
|
|
||||||
QNetworkAccessManager *m_networkAccessManager = nullptr;
|
|
||||||
|
|
||||||
//QList<UpnpDiscoveryRequest *> m_discoverRequests;
|
|
||||||
// QHash<QNetworkReply*, UpnpDeviceDescriptor> m_informationRequestList;
|
|
||||||
|
|
||||||
bool m_available = false;
|
|
||||||
bool m_enabled = false;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void discovered(const QString &address, int port, int id, const QString &model);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void error(QAbstractSocket::SocketError error);
|
|
||||||
void readData();
|
|
||||||
void readData2();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SSDP_H
|
|
||||||
@ -1,460 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
*
|
|
||||||
* Copyright 2013 - 2020, nymea GmbH
|
|
||||||
* Contact: contact@nymea.io
|
|
||||||
*
|
|
||||||
* This file is part of nymea.
|
|
||||||
* This project including source code and documentation is protected by
|
|
||||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
|
||||||
* reproduction, publication, editing and translation, are reserved. The use of
|
|
||||||
* this project is subject to the terms of a license agreement to be concluded
|
|
||||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
|
||||||
* under https://nymea.io/license
|
|
||||||
*
|
|
||||||
* GNU Lesser General Public License Usage
|
|
||||||
* Alternatively, this project may be redistributed and/or modified under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free
|
|
||||||
* Software Foundation; version 3. This project is distributed in the hope that
|
|
||||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* For any further details and any questions please contact us under
|
|
||||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
|
||||||
* https://nymea.io/license/faq
|
|
||||||
*
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#include "yeelight.h"
|
|
||||||
#include "extern-plugininfo.h"
|
|
||||||
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QJsonArray>
|
|
||||||
|
|
||||||
#include <QColor>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
|
|
||||||
Yeelight::Yeelight(NetworkAccessManager *networkManager, const QHostAddress &address, quint16 port, QObject *parent) :
|
|
||||||
QObject(parent),
|
|
||||||
m_address(address),
|
|
||||||
m_port(port),
|
|
||||||
m_networkManager(networkManager)
|
|
||||||
{
|
|
||||||
m_socket = new QTcpSocket(this);
|
|
||||||
connect(m_socket, &QTcpSocket::stateChanged, this, &Yeelight::onStateChanged);
|
|
||||||
connect(m_socket, &QTcpSocket::readyRead, this, &Yeelight::onReadyRead);
|
|
||||||
m_socket->connectToHost(address, port);
|
|
||||||
|
|
||||||
m_reconnectTimer = new QTimer(this);
|
|
||||||
m_reconnectTimer->setSingleShot(true);
|
|
||||||
connect(m_reconnectTimer, &QTimer::timeout, this, &Yeelight::onReconnectTimer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Yeelight::isConnected()
|
|
||||||
{
|
|
||||||
return m_socket->isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Yeelight::connectDevice()
|
|
||||||
{
|
|
||||||
m_socket->connectToHost(m_address, m_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Yeelight::getParam(QList<Yeelight::YeelightProperty> properties)
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "get_prop";
|
|
||||||
QJsonArray params;
|
|
||||||
m_propertyRequests.insert(requestId, properties);
|
|
||||||
|
|
||||||
foreach (YeelightProperty property, properties) {
|
|
||||||
switch (property) {
|
|
||||||
case YeelightProperty::Ct:
|
|
||||||
params.append("ct");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Power:
|
|
||||||
params.append("power");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Bright:
|
|
||||||
params.append("bright");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Hue:
|
|
||||||
params.append("hue");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Rgb:
|
|
||||||
params.append("rgb");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Sat:
|
|
||||||
params.append("sat");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Name:
|
|
||||||
params.append("name");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::BgCt:
|
|
||||||
params.append("bg_ct");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::NlBr:
|
|
||||||
params.append("nl_br");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::BgHue:
|
|
||||||
params.append("bg_hue");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::BgRgb:
|
|
||||||
params.append("bg_rgb");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::BgSat:
|
|
||||||
params.append("bg_sat");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::BgLmode:
|
|
||||||
params.append("bg_lmode");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::BgPower:
|
|
||||||
params.append("bg_power");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Flowing:
|
|
||||||
params.append("flowing");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::MusicOn:
|
|
||||||
params.append("music_on");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::BgBright:
|
|
||||||
params.append("bg_bright");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::DelayOff:
|
|
||||||
params.append("delay_off");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::BgFlowing:
|
|
||||||
params.append("bg_flowing");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::ColorMode:
|
|
||||||
params.append("color_mode");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::ActiveMode:
|
|
||||||
params.append("active_mode");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::FlowParams:
|
|
||||||
params.append("flow_params");
|
|
||||||
break;
|
|
||||||
case YeelightProperty::BgFlowParams:
|
|
||||||
params.append("bg_flow_params");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QTimer::singleShot(10000, this, [requestId, this]{m_propertyRequests.remove(requestId);});
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
//qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Yeelight::setName(const QString &name)
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "set_name";
|
|
||||||
QJsonArray params;
|
|
||||||
params.append(name);
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
//qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Yeelight::setColorTemperature(int mirad, int msFadeTime)
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "set_ct_abx";
|
|
||||||
QJsonArray params;
|
|
||||||
params.append(mirad);
|
|
||||||
params.append("smooth");
|
|
||||||
params.append(msFadeTime);
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
//qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Yeelight::setRgb(QRgb color, int msFadeTime)
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "set_rgb";
|
|
||||||
QJsonArray params;
|
|
||||||
params.append(static_cast<int>(color & 0x00ffffff));
|
|
||||||
params.append("smooth");
|
|
||||||
params.append(msFadeTime);
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
//qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Yeelight::setBrightness(int percentage, int msFadeTime)
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "set_bright";
|
|
||||||
QJsonArray params;
|
|
||||||
params.append(percentage);
|
|
||||||
params.append("smooth");
|
|
||||||
params.append(msFadeTime);
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
//qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Yeelight::setPower(bool power, int msFadeTime)
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "set_power";
|
|
||||||
QJsonArray params;
|
|
||||||
if(power) {
|
|
||||||
params.append("on");
|
|
||||||
} else {
|
|
||||||
params.append("off");
|
|
||||||
}
|
|
||||||
params.append("smooth");
|
|
||||||
params.append(msFadeTime);
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
//qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Yeelight::setDefault()
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "set_default";
|
|
||||||
QJsonArray params;
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
//qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Yeelight::startColorFlow()
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "start_cf";
|
|
||||||
QJsonArray params;
|
|
||||||
params.append(0); //0 means infinite loop on the state changing
|
|
||||||
params.append(0); //LED recover to the state before the color flow started
|
|
||||||
params.append("2000, 1, 255, 50, 2000, 1, 5000, 50, 2000, 1, 6000, 50"); //Colors
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Yeelight::stopColorFlow()
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "stop_cf";
|
|
||||||
QJsonArray params;
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Yeelight::flash()
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "start_cf";
|
|
||||||
QJsonArray params;
|
|
||||||
params.append(4 * 3);
|
|
||||||
params.append(0); //LED recover to the state before the color flow started
|
|
||||||
params.append("50, 2, 6500, 100, 500, 7, 6500, 1, 50, 2, 6500, 1, 500, 7, 6500, 1");
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Yeelight::flash15s()
|
|
||||||
{
|
|
||||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
|
||||||
QJsonDocument doc;
|
|
||||||
QJsonObject obj;
|
|
||||||
obj["id"] = requestId;
|
|
||||||
obj["method"] = "start_cf";
|
|
||||||
QJsonArray params;
|
|
||||||
params.append(4 * 15);
|
|
||||||
params.append(0); //LED recover to the state before the color flow started
|
|
||||||
params.append("50, 2, 6500, 100, 500, 7, 6500, 1, 50, 2, 6500, 1, 500, 7, 6500, 1");
|
|
||||||
obj["params"] = params;
|
|
||||||
doc.setObject(obj);
|
|
||||||
qCDebug(dcYeelight()) << "Sending request" << doc.toJson();
|
|
||||||
m_socket->write(doc.toJson() + "\r\n");
|
|
||||||
return requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Yeelight::onStateChanged(QAbstractSocket::SocketState state)
|
|
||||||
{
|
|
||||||
switch (state) {
|
|
||||||
case QAbstractSocket::SocketState::ConnectedState:
|
|
||||||
emit connectionChanged(true);
|
|
||||||
break;
|
|
||||||
case QAbstractSocket::SocketState::UnconnectedState:
|
|
||||||
m_reconnectTimer->start(10 * 1000);
|
|
||||||
emit connectionChanged(false);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
emit connectionChanged(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Yeelight::onReadyRead()
|
|
||||||
{
|
|
||||||
QByteArray data = m_socket->readAll();
|
|
||||||
//qCDebug(dcYeelight()) << "Message received" << data;
|
|
||||||
|
|
||||||
QJsonParseError error;
|
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(data, &error);
|
|
||||||
if (error.error != QJsonParseError::NoError) {
|
|
||||||
qDebug(dcYeelight()) << "Recieved invalide JSON object";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QVariantMap map = doc.toVariant().toMap();
|
|
||||||
if (map.contains("error")) {
|
|
||||||
if(map.contains("id")) {
|
|
||||||
emit requestExecuted(map["id"].toInt(), false);
|
|
||||||
}
|
|
||||||
QVariantMap error = map["error"].toMap();
|
|
||||||
int code = error["code"].toInt();
|
|
||||||
QString message = error["message"].toString();
|
|
||||||
qCWarning(dcYeelight()) << "Error received: Code" << code << message;
|
|
||||||
emit errorReceived(code, message);
|
|
||||||
|
|
||||||
}else if (map.contains("method")) {
|
|
||||||
if (map["method"] == "props") {
|
|
||||||
QVariantMap params = map["params"].toMap();
|
|
||||||
if (params.contains("power")) {
|
|
||||||
emit powerNotificationReceived((params["power"].toString() == "on"));
|
|
||||||
}
|
|
||||||
if (params.contains("bright")) {
|
|
||||||
emit brightnessNotificationReceived(params["bright"].toInt());
|
|
||||||
}
|
|
||||||
if (params.contains("ct")) {
|
|
||||||
emit colorTemperatureNotificationReceived(params["ct"].toInt());
|
|
||||||
}
|
|
||||||
if (params.contains("rgb")) {
|
|
||||||
emit rgbNotificationReceived(QRgb(params["rgb"].toInt()));
|
|
||||||
}
|
|
||||||
if (params.contains("hue")) {
|
|
||||||
emit hueNotificationReceived(params["hue"].toInt());
|
|
||||||
}
|
|
||||||
if (params.contains("name")) {
|
|
||||||
emit nameNotificationReceived(params["name"].toString());
|
|
||||||
}
|
|
||||||
if (params.contains("color_mode")) {
|
|
||||||
emit colorModeNotificationReceived(YeelightColorMode(params["color_mode"].toInt()));
|
|
||||||
}
|
|
||||||
if (params.contains("sat")) {
|
|
||||||
emit saturationNotificationReceived(params["sat"].toInt());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int id = map["id"].toInt();
|
|
||||||
QVariantList result = map["result"].toList();
|
|
||||||
if ((result.length() == 1)) {
|
|
||||||
if (result.first().toString() == "ok") {
|
|
||||||
emit requestExecuted(id, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (m_propertyRequests.contains(id)) {
|
|
||||||
QList<YeelightProperty> properties = m_propertyRequests.take(id);
|
|
||||||
foreach (YeelightProperty property, properties) {
|
|
||||||
if (result.isEmpty()){
|
|
||||||
qCWarning(dcYeelight()) << "Value count does not match properties" << properties.count();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
QVariant value = result.takeFirst();
|
|
||||||
switch (property) {
|
|
||||||
case YeelightProperty::Name:
|
|
||||||
emit nameNotificationReceived(value.toString());
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Ct:
|
|
||||||
emit colorTemperatureNotificationReceived(value.toInt());
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Rgb:
|
|
||||||
emit rgbNotificationReceived(QRgb(value.toInt()));
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Hue:
|
|
||||||
emit hueNotificationReceived(value.toInt());
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Bright:
|
|
||||||
emit brightnessNotificationReceived(value.toInt());
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Power:
|
|
||||||
emit powerNotificationReceived((value.toString() == "on"));
|
|
||||||
break;
|
|
||||||
case YeelightProperty::ColorMode:
|
|
||||||
emit colorModeNotificationReceived(YeelightColorMode(value.toInt()));
|
|
||||||
break;
|
|
||||||
case YeelightProperty::Sat:
|
|
||||||
emit saturationNotificationReceived(value.toInt());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
qCWarning(dcYeelight()) << "Unhandled Yeelight property";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Yeelight::onReconnectTimer()
|
|
||||||
{
|
|
||||||
if(!m_socket->isOpen()) {
|
|
||||||
m_socket->connectToHost(m_address, m_port);
|
|
||||||
m_reconnectTimer->start(10 * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,128 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
*
|
|
||||||
* Copyright 2013 - 2020, nymea GmbH
|
|
||||||
* Contact: contact@nymea.io
|
|
||||||
*
|
|
||||||
* This file is part of nymea.
|
|
||||||
* This project including source code and documentation is protected by
|
|
||||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
|
||||||
* reproduction, publication, editing and translation, are reserved. The use of
|
|
||||||
* this project is subject to the terms of a license agreement to be concluded
|
|
||||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
|
||||||
* under https://nymea.io/license
|
|
||||||
*
|
|
||||||
* GNU Lesser General Public License Usage
|
|
||||||
* Alternatively, this project may be redistributed and/or modified under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free
|
|
||||||
* Software Foundation; version 3. This project is distributed in the hope that
|
|
||||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* For any further details and any questions please contact us under
|
|
||||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
|
||||||
* https://nymea.io/license/faq
|
|
||||||
*
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#ifndef YEELIGHT_H
|
|
||||||
#define YEELIGHT_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QHostAddress>
|
|
||||||
#include <QTcpSocket>
|
|
||||||
|
|
||||||
#include "network/networkaccessmanager.h"
|
|
||||||
#include <QRgb>
|
|
||||||
|
|
||||||
class Yeelight : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum YeelightColorMode {
|
|
||||||
RGB = 1,
|
|
||||||
ColorTemperature,
|
|
||||||
HSV
|
|
||||||
};
|
|
||||||
|
|
||||||
enum YeelightProperty {
|
|
||||||
Power, //on: smart LED is turned on / off: smart LED is turned off
|
|
||||||
Bright, //Brightness percentage. Range 1 ~ 100
|
|
||||||
Ct, //Color temperature. Range 1700 ~ 6500(k)
|
|
||||||
Rgb, //Color. Range 1 ~ 16777215
|
|
||||||
Hue, //Hue. Range 0 ~ 359
|
|
||||||
Sat, //Saturation. Range 0 ~ 100
|
|
||||||
ColorMode, //1: rgb mode / 2: color temperature mode / 3: hsv mode
|
|
||||||
Flowing, //0: no flow is running / 1:color flow is running
|
|
||||||
DelayOff, //The remaining time of a sleep timer. Range 1 ~ 60 (minutes)
|
|
||||||
FlowParams, //Current flow parameters (only meaningful when 'flowing' is 1)
|
|
||||||
MusicOn, //1: Music mode is on / 0: Music mode is off
|
|
||||||
Name, //The name of the device set by “set_name” command
|
|
||||||
BgPower, //Background light power status
|
|
||||||
BgFlowing, //Background light is flowing
|
|
||||||
BgFlowParams, //Current flow parameters of background light
|
|
||||||
BgCt, //Color temperature of background light
|
|
||||||
BgLmode, //1: rgb mode / 2: color temperature mode / 3: hsv mode
|
|
||||||
BgBright, //Brightness percentage of background light
|
|
||||||
BgRgb, //Color of background light
|
|
||||||
BgHue, //Hue of background light
|
|
||||||
BgSat, //Saturation of background light
|
|
||||||
NlBr, //Brightness of night mode light
|
|
||||||
ActiveMode //0: daylight mode / 1: moonlight mode (ceiling light only)
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit Yeelight(NetworkAccessManager *networkManager, const QHostAddress &address, quint16 port = 55443, QObject *parent = nullptr);
|
|
||||||
bool isConnected();
|
|
||||||
void connectDevice();
|
|
||||||
|
|
||||||
int getParam(QList<YeelightProperty> properties);
|
|
||||||
int setName(const QString &name);
|
|
||||||
int setColorTemperature(int mirad, int msFadeTime=500);
|
|
||||||
int setRgb(QRgb color, int msFadeTime = 500);
|
|
||||||
int setBrightness(int percentage, int msFadeTime = 500);
|
|
||||||
int setPower(bool power, int msFadeTime = 500);
|
|
||||||
int setDefault();
|
|
||||||
int startColorFlow();
|
|
||||||
int stopColorFlow();
|
|
||||||
int flash();
|
|
||||||
int flash15s();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QTimer *m_reconnectTimer = nullptr;
|
|
||||||
QTcpSocket *m_socket = nullptr;
|
|
||||||
QHostAddress m_address;
|
|
||||||
quint16 m_port;
|
|
||||||
NetworkAccessManager *m_networkManager = nullptr;
|
|
||||||
QHash<int, QList<YeelightProperty>> m_propertyRequests;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onStateChanged(QAbstractSocket::SocketState state);
|
|
||||||
void onReadyRead();
|
|
||||||
void onReconnectTimer();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void connectionChanged(bool connected);
|
|
||||||
void requestExecuted(int requestId, bool success);
|
|
||||||
void errorReceived(int code, const QString &message);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Whenever there is state change of smart LED, it will send a notification message
|
|
||||||
* to all connected 3rd party devices. This is to make sure all 3rd party devices
|
|
||||||
* will get the latest state of the smart LED in time without having to poll the status
|
|
||||||
* from time to time.
|
|
||||||
*/
|
|
||||||
void notificationReceived(YeelightProperty property, QVariant value);
|
|
||||||
void powerNotificationReceived(bool status);
|
|
||||||
void brightnessNotificationReceived(int percentage);
|
|
||||||
void colorTemperatureNotificationReceived(int kelvin);
|
|
||||||
void rgbNotificationReceived(QRgb rgbColor);
|
|
||||||
void hueNotificationReceived(int hueColor);
|
|
||||||
void nameNotificationReceived(const QString &name);
|
|
||||||
void saturationNotificationReceived(int percentage);
|
|
||||||
void colorModeNotificationReceived(YeelightColorMode colorMode);
|
|
||||||
};
|
|
||||||
#endif // YEELIGHT_H
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
@ -1,4 +0,0 @@
|
|||||||
TEMPLATE = aux
|
|
||||||
|
|
||||||
OTHER_FILES = integrationpluginyeelight.py \
|
|
||||||
integrationpluginyeelight.json
|
|
||||||
Loading…
x
Reference in New Issue
Block a user