mirror of
https://github.com/nymea/nymea-plugins.git
synced 2026-07-18 00:43:48 +02:00
throttle brightness requests
This commit is contained in:
parent
cda658f0a2
commit
9014a17618
@ -36,6 +36,18 @@ DevicePluginYeelight::DevicePluginYeelight()
|
||||
|
||||
}
|
||||
|
||||
void DevicePluginYeelight::init()
|
||||
{
|
||||
m_connectedStateTypeIds.insert(colorBulbDeviceClassId, colorBulbConnectedStateTypeId);
|
||||
m_connectedStateTypeIds.insert(dimmableBulbDeviceClassId, dimmableBulbConnectedStateTypeId);
|
||||
|
||||
m_powerStateTypeIds.insert(colorBulbDeviceClassId, colorBulbPowerStateTypeId);
|
||||
m_powerStateTypeIds.insert(dimmableBulbDeviceClassId, dimmableBulbPowerStateTypeId);
|
||||
|
||||
m_brightnessStateTypeIds.insert(colorBulbDeviceClassId, colorBulbBrightnessStateTypeId);
|
||||
m_brightnessStateTypeIds.insert(dimmableBulbDeviceClassId, dimmableBulbBrightnessStateTypeId);
|
||||
}
|
||||
|
||||
void DevicePluginYeelight::discoverDevices(DeviceDiscoveryInfo *info)
|
||||
{
|
||||
if (info->deviceClassId() == colorBulbDeviceClassId) {
|
||||
@ -78,7 +90,7 @@ void DevicePluginYeelight::setupDevice(DeviceSetupInfo *info)
|
||||
m_yeelightConnections.insert(device->id(), yeelight);
|
||||
connect(yeelight, &Yeelight::connectionChanged, this, &DevicePluginYeelight::onConnectionChanged);
|
||||
connect(yeelight, &Yeelight::requestExecuted, this, &DevicePluginYeelight::onRequestExecuted);
|
||||
connect(yeelight, &Yeelight::propertyListReceived, this, &DevicePluginYeelight::onPropertyListReceived);
|
||||
connect(yeelight, &Yeelight::colorModeNotificationReceived, this, &DevicePluginYeelight::onColorModeNotificationReceived);
|
||||
connect(yeelight, &Yeelight::powerNotificationReceived, this, &DevicePluginYeelight::onPowerNotificationReceived);
|
||||
connect(yeelight, &Yeelight::brightnessNotificationReceived, this, &DevicePluginYeelight::onBrightnessNotificationReceived);
|
||||
connect(yeelight, &Yeelight::colorTemperatureNotificationReceived, this, &DevicePluginYeelight::onColorTemperatureNotificationReceived);
|
||||
@ -99,31 +111,32 @@ void DevicePluginYeelight::postSetupDevice(Device *device)
|
||||
Device *device = myDevices().findById(id);
|
||||
Yeelight *yeelight = m_yeelightConnections.value(id);
|
||||
if (yeelight->isConnected()) {
|
||||
QList<Yeelight::Property> properties;
|
||||
QList<Yeelight::YeelightProperty> properties;
|
||||
if (device->deviceClassId() == colorBulbDeviceClassId) {
|
||||
properties << Yeelight::Property::Name;
|
||||
properties << Yeelight::Property::Ct;
|
||||
properties << Yeelight::Property::Rgb;
|
||||
properties << Yeelight::Property::Power;
|
||||
properties << Yeelight::Property::Bright;
|
||||
properties << Yeelight::Property::ColorMode;
|
||||
properties << Yeelight::YeelightProperty::Name;
|
||||
properties << Yeelight::YeelightProperty::Ct;
|
||||
properties << Yeelight::YeelightProperty::Rgb;
|
||||
properties << Yeelight::YeelightProperty::Power;
|
||||
properties << Yeelight::YeelightProperty::Bright;
|
||||
properties << Yeelight::YeelightProperty::ColorMode;
|
||||
} //TODO add white color bulb with other property requests
|
||||
yeelight->getParam(properties);
|
||||
} else {
|
||||
yeelight->connectDevice();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
m_pluginTimer->timeout();
|
||||
}
|
||||
|
||||
void DevicePluginYeelight::executeAction(DeviceActionInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
Action action = info->action();
|
||||
Yeelight *yeelight = m_yeelightConnections.value(device->id());
|
||||
if (!yeelight)
|
||||
return info->finish(Device::DeviceErrorHardwareFailure);
|
||||
|
||||
if (device->deviceClassId() == colorBulbDeviceClassId) {
|
||||
Yeelight *yeelight = m_yeelightConnections.value(device->id());
|
||||
|
||||
if (action.actionTypeId() == colorBulbPowerActionTypeId) {
|
||||
bool power = action.param(colorBulbPowerActionPowerParamTypeId).value().toBool();
|
||||
@ -131,12 +144,23 @@ void DevicePluginYeelight::executeAction(DeviceActionInfo *info)
|
||||
connect(info, &DeviceActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||
m_asyncActions.insert(requestId, info);
|
||||
} else if (action.actionTypeId() == colorBulbBrightnessActionTypeId) {
|
||||
int brightness = action.param(colorBulbBrightnessActionBrightnessParamTypeId).value().toInt();
|
||||
|
||||
if (!device->stateValue(colorBulbPowerStateTypeId).toBool())
|
||||
yeelight->setPower(true);
|
||||
int requestId = yeelight->setBrightness(brightness);
|
||||
connect(info, &DeviceActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||
m_asyncActions.insert(requestId, info);
|
||||
|
||||
if (m_pendingBrightnessAction.contains(device->id())) {
|
||||
//Scrap old info and insert new one
|
||||
m_pendingBrightnessAction.insert(device->id(), info);
|
||||
} else {
|
||||
m_pendingBrightnessAction.insert(device->id(), info);
|
||||
QTimer::singleShot(500, this, [yeelight, info, this]{
|
||||
int brightness = info->action().param(colorBulbBrightnessActionBrightnessParamTypeId).value().toInt();
|
||||
m_pendingBrightnessAction.remove(info->device()->id());
|
||||
int requestId = yeelight->setBrightness(brightness);
|
||||
connect(info, &DeviceActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||
m_asyncActions.insert(requestId, info);
|
||||
});
|
||||
}
|
||||
} else if (action.actionTypeId() == colorBulbColorActionColorParamTypeId) {
|
||||
QRgb color = action.param(colorBulbColorActionColorParamTypeId).value().toUInt();
|
||||
if (!device->stateValue(colorBulbPowerStateTypeId).toBool())
|
||||
@ -180,6 +204,34 @@ void DevicePluginYeelight::executeAction(DeviceActionInfo *info)
|
||||
} else {
|
||||
qCWarning(dcYeelight()) << "Unhandled action";
|
||||
}
|
||||
} else if (device->deviceClassId() == dimmableBulbDeviceClassId) {
|
||||
if (action.actionTypeId() == dimmableBulbPowerActionTypeId) {
|
||||
bool power = action.param(dimmableBulbPowerActionPowerParamTypeId).value().toBool();
|
||||
int requestId = yeelight->setPower(power);
|
||||
connect(info, &DeviceActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||
} else if (action.actionTypeId() == dimmableBulbBrightnessActionTypeId) {
|
||||
int brightness = action.param(dimmableBulbBrightnessActionBrightnessParamTypeId).value().toInt();
|
||||
if (!device->stateValue(dimmableBulbPowerStateTypeId).toBool())
|
||||
yeelight->setPower(true);
|
||||
int requestId = yeelight->setBrightness(brightness);
|
||||
connect(info, &DeviceActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||
m_asyncActions.insert(requestId, info);
|
||||
} else if (action.actionTypeId() == dimmableBulbAlertActionTypeId) {
|
||||
QString alertType = action.param(dimmableBulbAlertActionAlertParamTypeId).value().toString();
|
||||
if (!device->stateValue(dimmableBulbPowerStateTypeId).toBool())
|
||||
yeelight->setPower(true);
|
||||
if (alertType.contains("15")) { //Flash 15 sec
|
||||
int requestId = yeelight->flash15s();
|
||||
connect(info, &DeviceActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||
m_asyncActions.insert(requestId, info);
|
||||
} else {
|
||||
int requestId = yeelight->flash();
|
||||
connect(info, &DeviceActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);});
|
||||
m_asyncActions.insert(requestId, info);
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcYeelight()) << "Unhandled action";
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcYeelight()) << "Unhandled device class";
|
||||
}
|
||||
@ -187,7 +239,7 @@ void DevicePluginYeelight::executeAction(DeviceActionInfo *info)
|
||||
|
||||
void DevicePluginYeelight::deviceRemoved(Device *device)
|
||||
{
|
||||
if (device->deviceClassId() == colorBulbDeviceClassId){
|
||||
if ((device->deviceClassId() == colorBulbDeviceClassId) || (device->deviceClassId() == dimmableBulbDeviceClassId)){
|
||||
Yeelight *yeelight = m_yeelightConnections.take(device->id());
|
||||
yeelight->deleteLater();
|
||||
}
|
||||
@ -207,7 +259,7 @@ void DevicePluginYeelight::onConnectionChanged(bool connected)
|
||||
if(!device)
|
||||
return;
|
||||
|
||||
device->setStateValue(colorBulbConnectedStateTypeId, connected);
|
||||
device->setStateValue(m_connectedStateTypeIds.value(device->deviceClassId()), connected);
|
||||
}
|
||||
|
||||
void DevicePluginYeelight::onRequestExecuted(int requestId, bool success)
|
||||
@ -222,33 +274,6 @@ void DevicePluginYeelight::onRequestExecuted(int requestId, bool success)
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginYeelight::onPropertyListReceived(QVariantList value)
|
||||
{
|
||||
Yeelight *yeelight = static_cast<Yeelight *>(sender());
|
||||
Device * device = myDevices().findById(m_yeelightConnections.key(yeelight));
|
||||
if(!device)
|
||||
return;
|
||||
|
||||
/*
|
||||
* properties << Yeelight::Property::Name;
|
||||
* properties << Yeelight::Property::Ct;
|
||||
* properties << Yeelight::Property::Rgb;
|
||||
* properties << Yeelight::Property::Power;
|
||||
* properties << Yeelight::Property::Bright;
|
||||
* properties << Yeelight::Property::ColorMode;
|
||||
*/
|
||||
|
||||
if(value.length() < 6)
|
||||
return;
|
||||
|
||||
device->setName(value[0].toString());
|
||||
device->setStateValue(colorBulbColorTemperatureStateTypeId, value[1].toInt());
|
||||
device->setStateValue(colorBulbColorStateTypeId, value[2].toString());
|
||||
device->setStateValue(colorBulbPowerStateTypeId, (value[3].toString() == "on"));
|
||||
device->setStateValue(colorBulbBrightnessStateTypeId, value[4].toInt());
|
||||
device->setStateValue(colorBulbColorModeStateTypeId, value[5].toString());
|
||||
}
|
||||
|
||||
void DevicePluginYeelight::onPowerNotificationReceived(bool status)
|
||||
{
|
||||
Yeelight *yeelight = static_cast<Yeelight *>(sender());
|
||||
@ -256,7 +281,7 @@ void DevicePluginYeelight::onPowerNotificationReceived(bool status)
|
||||
if(!device)
|
||||
return;
|
||||
|
||||
device->setStateValue(colorBulbPowerStateTypeId, status);
|
||||
device->setStateValue(m_powerStateTypeIds.value(device->deviceClassId()), status);
|
||||
}
|
||||
|
||||
void DevicePluginYeelight::onBrightnessNotificationReceived(int percentage)
|
||||
@ -266,7 +291,7 @@ void DevicePluginYeelight::onBrightnessNotificationReceived(int percentage)
|
||||
if(!device)
|
||||
return;
|
||||
|
||||
device->setStateValue(colorBulbBrightnessStateTypeId, percentage);
|
||||
device->setStateValue(m_brightnessStateTypeIds.value(device->deviceClassId()), percentage);
|
||||
}
|
||||
|
||||
void DevicePluginYeelight::onColorTemperatureNotificationReceived(int kelvin)
|
||||
@ -279,7 +304,7 @@ void DevicePluginYeelight::onColorTemperatureNotificationReceived(int kelvin)
|
||||
device->setStateValue(colorBulbColorTemperatureStateTypeId, kelvin/11.12); //TODO needs proper conversion
|
||||
}
|
||||
|
||||
void DevicePluginYeelight::onRgbNotificationReceived(int rgbColor)
|
||||
void DevicePluginYeelight::onRgbNotificationReceived(QRgb rgbColor)
|
||||
{
|
||||
Yeelight *yeelight = static_cast<Yeelight *>(sender());
|
||||
Device * device = myDevices().findById(m_yeelightConnections.key(yeelight));
|
||||
@ -297,3 +322,23 @@ void DevicePluginYeelight::onNameNotificationReceived(const QString &name)
|
||||
return;
|
||||
device->setName(name);
|
||||
}
|
||||
|
||||
void DevicePluginYeelight::onColorModeNotificationReceived(Yeelight::YeelightColorMode colorMode)
|
||||
{
|
||||
Yeelight *yeelight = static_cast<Yeelight *>(sender());
|
||||
Device * device = myDevices().findById(m_yeelightConnections.key(yeelight));
|
||||
if(!device)
|
||||
return;
|
||||
|
||||
switch (colorMode) {
|
||||
case Yeelight::RGB:
|
||||
device->setStateValue(colorBulbColorModeStateTypeId, "RGB");
|
||||
break;
|
||||
case Yeelight::HSV:
|
||||
device->setStateValue(colorBulbColorModeStateTypeId, "HSV");
|
||||
break;
|
||||
case Yeelight::ColorTemperature:
|
||||
device->setStateValue(colorBulbColorModeStateTypeId, "Color temperature");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ class DevicePluginYeelight : public DevicePlugin
|
||||
public:
|
||||
explicit DevicePluginYeelight();
|
||||
|
||||
void init() override;
|
||||
void discoverDevices(DeviceDiscoveryInfo *info) override;
|
||||
void setupDevice(DeviceSetupInfo *info) override;
|
||||
void postSetupDevice(Device *device) override;
|
||||
@ -61,17 +62,23 @@ private:
|
||||
QHash<int, DeviceActionInfo *> m_asyncActions;
|
||||
QHash<DeviceId, Yeelight *> m_yeelightConnections;
|
||||
|
||||
QHash<DeviceClassId, StateTypeId> m_connectedStateTypeIds;
|
||||
QHash<DeviceClassId, StateTypeId> m_powerStateTypeIds;
|
||||
QHash<DeviceClassId, StateTypeId> m_brightnessStateTypeIds;
|
||||
|
||||
QHash<DeviceId, DeviceActionInfo *> m_pendingBrightnessAction;
|
||||
|
||||
private slots:
|
||||
void onDeviceNameChanged();
|
||||
void onConnectionChanged(bool connected);
|
||||
void onRequestExecuted(int requestId, bool success);
|
||||
void onPropertyListReceived(QVariantList value);
|
||||
|
||||
void onPowerNotificationReceived(bool status);
|
||||
void onBrightnessNotificationReceived(int percentage);
|
||||
void onColorTemperatureNotificationReceived(int kelvin);
|
||||
void onRgbNotificationReceived(int rgbColor);
|
||||
void onRgbNotificationReceived(QRgb rgbColor);
|
||||
void onNameNotificationReceived(const QString &name);
|
||||
void onColorModeNotificationReceived(Yeelight::YeelightColorMode colorMode);
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINYEELIGHT_H
|
||||
|
||||
@ -143,6 +143,95 @@
|
||||
"writable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "5112eb03-7b5a-44a1-994a-01a70c850555",
|
||||
"name": "dimmableBulb",
|
||||
"displayName": "Dimmable bulb",
|
||||
"createMethods": ["user", "discovery"],
|
||||
"interfaces": ["dimmablelight", "alert", "connectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "32f4f50c-a3f2-4379-8838-295024d200b4",
|
||||
"name": "host",
|
||||
"displayName": "Host address",
|
||||
"type" : "QString",
|
||||
"inputType": "IPv4Address",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"id": "df51023e-7f18-4e11-8c7a-30d153b50952",
|
||||
"name": "port",
|
||||
"displayName": "Port",
|
||||
"type" : "int",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"id": "5a526561-588a-49bd-ae2b-ce3c3b4fd04e",
|
||||
"name": "id",
|
||||
"displayName": "Id",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "a50780d1-259d-4240-8f71-a0bb5c57362b",
|
||||
"name": "default",
|
||||
"displayName": "Set default"
|
||||
},
|
||||
{
|
||||
"id": "ba513820-1ace-4ad2-aa84-b7bd01318bc3",
|
||||
"name": "alert",
|
||||
"displayName": "flash",
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "1c0f4e9e-95fd-4715-8386-9ac28ffa3c6e",
|
||||
"name": "alert",
|
||||
"displayName": "alert",
|
||||
"type": "QString",
|
||||
"defaultValue": "flash",
|
||||
"allowedValues": [
|
||||
"flash",
|
||||
"flash 15 [s]"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "fcfe37cb-4c9d-4af2-9789-56190c9d8d7f",
|
||||
"name": "connected",
|
||||
"displayName": "Reachable",
|
||||
"displayNameEvent": "Reachable changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "0786e242-1257-437c-9327-f202b427ab1b",
|
||||
"name": "power",
|
||||
"displayName": "Power",
|
||||
"displayNameEvent": "Power changed",
|
||||
"displayNameAction": "Set power",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "b0db1fd8-cec8-4cd4-acd0-5fc415095e10",
|
||||
"name": "brightness",
|
||||
"displayName": "Brightness",
|
||||
"displayNameEvent": "Brightness changed",
|
||||
"displayNameAction": "Set brigtness",
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0,
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"writable": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -41,6 +41,10 @@ Yeelight::Yeelight(NetworkAccessManager *networkManager, const QHostAddress &add
|
||||
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()
|
||||
@ -54,7 +58,7 @@ void Yeelight::connectDevice()
|
||||
}
|
||||
|
||||
|
||||
int Yeelight::getParam(QList<Yeelight::Property> properties)
|
||||
int Yeelight::getParam(QList<Yeelight::YeelightProperty> properties)
|
||||
{
|
||||
int requestId = static_cast<int>(QRandomGenerator::global()->generate());
|
||||
QJsonDocument doc;
|
||||
@ -62,81 +66,83 @@ int Yeelight::getParam(QList<Yeelight::Property> properties)
|
||||
obj["id"] = requestId;
|
||||
obj["method"] = "get_prop";
|
||||
QJsonArray params;
|
||||
m_propertyRequests.insert(requestId, properties);
|
||||
|
||||
foreach (Property property, properties) {
|
||||
foreach (YeelightProperty property, properties) {
|
||||
switch (property) {
|
||||
case Property::Ct:
|
||||
case YeelightProperty::Ct:
|
||||
params.append("ct");
|
||||
break;
|
||||
case Property::Power:
|
||||
case YeelightProperty::Power:
|
||||
params.append("power");
|
||||
break;
|
||||
case Property::Bright:
|
||||
case YeelightProperty::Bright:
|
||||
params.append("bright");
|
||||
break;
|
||||
case Property::Hue:
|
||||
case YeelightProperty::Hue:
|
||||
params.append("hue");
|
||||
break;
|
||||
case Property::Rgb:
|
||||
case YeelightProperty::Rgb:
|
||||
params.append("rgb");
|
||||
break;
|
||||
case Property::Sat:
|
||||
case YeelightProperty::Sat:
|
||||
params.append("sat");
|
||||
break;
|
||||
case Property::Name:
|
||||
case YeelightProperty::Name:
|
||||
params.append("name");
|
||||
break;
|
||||
case Property::BgCt:
|
||||
case YeelightProperty::BgCt:
|
||||
params.append("bg_ct");
|
||||
break;
|
||||
case Property::NlBr:
|
||||
case YeelightProperty::NlBr:
|
||||
params.append("nl_br");
|
||||
break;
|
||||
case Property::BgHue:
|
||||
case YeelightProperty::BgHue:
|
||||
params.append("bg_hue");
|
||||
break;
|
||||
case Property::BgRgb:
|
||||
case YeelightProperty::BgRgb:
|
||||
params.append("bg_rgb");
|
||||
break;
|
||||
case Property::BgSat:
|
||||
case YeelightProperty::BgSat:
|
||||
params.append("bg_sat");
|
||||
break;
|
||||
case Property::BgLmode:
|
||||
case YeelightProperty::BgLmode:
|
||||
params.append("bg_lmode");
|
||||
break;
|
||||
case Property::BgPower:
|
||||
case YeelightProperty::BgPower:
|
||||
params.append("bg_power");
|
||||
break;
|
||||
case Property::Flowing:
|
||||
case YeelightProperty::Flowing:
|
||||
params.append("flowing");
|
||||
break;
|
||||
case Property::MusicOn:
|
||||
case YeelightProperty::MusicOn:
|
||||
params.append("music_on");
|
||||
break;
|
||||
case Property::BgBright:
|
||||
case YeelightProperty::BgBright:
|
||||
params.append("bg_bright");
|
||||
break;
|
||||
case Property::DelayOff:
|
||||
case YeelightProperty::DelayOff:
|
||||
params.append("delay_off");
|
||||
break;
|
||||
case Property::BgFlowing:
|
||||
case YeelightProperty::BgFlowing:
|
||||
params.append("bg_flowing");
|
||||
break;
|
||||
case Property::ColorMode:
|
||||
case YeelightProperty::ColorMode:
|
||||
params.append("color_mode");
|
||||
break;
|
||||
case Property::ActiveMode:
|
||||
case YeelightProperty::ActiveMode:
|
||||
params.append("active_mode");
|
||||
break;
|
||||
case Property::FlowParams:
|
||||
case YeelightProperty::FlowParams:
|
||||
params.append("flow_params");
|
||||
break;
|
||||
case Property::BgFlowParams:
|
||||
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();
|
||||
@ -326,6 +332,10 @@ void Yeelight::onStateChanged(QAbstractSocket::SocketState 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;
|
||||
@ -344,7 +354,17 @@ void Yeelight::onReadyRead()
|
||||
return;
|
||||
}
|
||||
QVariantMap map = doc.toVariant().toMap();
|
||||
if (map.contains("method")) {
|
||||
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")) {
|
||||
@ -357,7 +377,7 @@ void Yeelight::onReadyRead()
|
||||
emit colorTemperatureNotificationReceived(params["ct"].toInt());
|
||||
}
|
||||
if (params.contains("rgb")) {
|
||||
emit rgbNotificationReceived(params["rgb"].toInt());
|
||||
emit rgbNotificationReceived(QRgb(params["rgb"].toInt()));
|
||||
}
|
||||
if (params.contains("hue")) {
|
||||
emit hueNotificationReceived(params["hue"].toInt());
|
||||
@ -366,7 +386,7 @@ void Yeelight::onReadyRead()
|
||||
emit nameNotificationReceived(params["name"].toString());
|
||||
}
|
||||
if (params.contains("color_mode")) {
|
||||
//emit colorModeNotificationReceived(static_cast<ColorMode>((params["color_mode"].toInt())));
|
||||
emit colorModeNotificationReceived(YeelightColorMode(params["color_mode"].toInt()));
|
||||
}
|
||||
if (params.contains("sat")) {
|
||||
emit saturationNotificationReceived(params["sat"].toInt());
|
||||
@ -378,14 +398,55 @@ void Yeelight::onReadyRead()
|
||||
if ((result.length() == 1)) {
|
||||
if (result.first().toString() == "ok") {
|
||||
emit requestExecuted(id, true);
|
||||
} else {
|
||||
//TODO parse error, status code and error string
|
||||
//emit errorReceived()
|
||||
}
|
||||
} else {
|
||||
emit propertyListReceived(result);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -37,13 +37,13 @@ class Yeelight : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ColorMode {
|
||||
enum YeelightColorMode {
|
||||
RGB = 1,
|
||||
Temperature,
|
||||
ColorTemperature,
|
||||
HSV
|
||||
};
|
||||
|
||||
enum Property {
|
||||
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)
|
||||
@ -73,7 +73,7 @@ public:
|
||||
bool isConnected();
|
||||
void connectDevice();
|
||||
|
||||
int getParam(QList<Property> properties);
|
||||
int getParam(QList<YeelightProperty> properties);
|
||||
int setName(const QString &name);
|
||||
int setColorTemperature(int mirad, int msFadeTime=500);
|
||||
int setRgb(QRgb color, int msFadeTime = 500);
|
||||
@ -86,19 +86,22 @@ public:
|
||||
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 propertyListReceived(QVariantList value);
|
||||
void errorReceived(int code, const QString &message);
|
||||
|
||||
/*
|
||||
* Whenever there is state change of smart LED, it will send a notification message
|
||||
@ -106,14 +109,14 @@ signals:
|
||||
* will get the latest state of the smart LED in time without having to poll the status
|
||||
* from time to time.
|
||||
*/
|
||||
void notificationReceived(Property property, QVariant value);
|
||||
void notificationReceived(YeelightProperty property, QVariant value);
|
||||
void powerNotificationReceived(bool status);
|
||||
void brightnessNotificationReceived(int percentage);
|
||||
void colorTemperatureNotificationReceived(int kelvin);
|
||||
void rgbNotificationReceived(int rgbColor);
|
||||
void rgbNotificationReceived(QRgb rgbColor);
|
||||
void hueNotificationReceived(int hueColor);
|
||||
void nameNotificationReceived(const QString &name);
|
||||
void saturationNotificationReceived(int percentage);
|
||||
//void colorModeNotificationReceived(ColorMode colorMode);
|
||||
void colorModeNotificationReceived(YeelightColorMode colorMode);
|
||||
};
|
||||
#endif // YEELIGHT_H
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user