rewrite hue plugin
This commit is contained in:
parent
15e8b4fbc8
commit
1dae30eb80
@ -191,7 +191,7 @@ void Device::setStateValue(const StateTypeId &stateTypeId, const QVariant &value
|
||||
|
||||
|
||||
// TODO: check min/max value + possible values
|
||||
// to prevent an invalid state type
|
||||
// to prevent an invalid state type from the plugin side
|
||||
|
||||
State newState(stateTypeId, m_id);
|
||||
newState.setValue(value);
|
||||
@ -200,7 +200,7 @@ void Device::setStateValue(const StateTypeId &stateTypeId, const QVariant &value
|
||||
return;
|
||||
}
|
||||
}
|
||||
qCWarning(dcDeviceManager) << "failed setting state for" << m_name;
|
||||
qCWarning(dcDeviceManager) << "failed setting state for" << m_name << value;
|
||||
}
|
||||
|
||||
/*! Returns the \l{State} with the given \a stateTypeId of this Device. */
|
||||
|
||||
@ -74,11 +74,16 @@ StateTypeId hueReachableStateTypeId = StateTypeId("15794d26-fde8-4a61-8f83-d7830
|
||||
|
||||
DevicePluginPhilipsHue::DevicePluginPhilipsHue()
|
||||
{
|
||||
m_timer = new QTimer(this);
|
||||
m_timer->setSingleShot(false);
|
||||
m_timer->setInterval(1000);
|
||||
|
||||
connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResources DevicePluginPhilipsHue::requiredHardware() const
|
||||
{
|
||||
return DeviceManager::HardwareResourceTimer | DeviceManager::HardwareResourceUpnpDisovery | DeviceManager::HardwareResourceNetworkManager;
|
||||
return DeviceManager::HardwareResourceUpnpDisovery | DeviceManager::HardwareResourceNetworkManager;
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginPhilipsHue::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
||||
@ -98,81 +103,78 @@ DeviceManager::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *dev
|
||||
foreach (HueBridge *b, m_unconfiguredBridges) {
|
||||
if (b->hostAddress().toString() == device->paramValue("host address").toString()) {
|
||||
m_unconfiguredBridges.removeAll(b);
|
||||
|
||||
qCDebug(dcPhilipsHue) << "Setup unconfigured Hue Bridge" << b->name();
|
||||
// set data which was not known during discovery
|
||||
device->setParamValue("name", b->name());
|
||||
device->setParamValue("api key", b->apiKey());
|
||||
device->setParamValue("zigbee channel", b->zigbeeChannel());
|
||||
device->setParamValue("api version", b->apiVersion());
|
||||
device->setParamValue("software version", b->softwareVersion());
|
||||
device->setParamValue("id", b->id());
|
||||
device->setParamValue("mac address", b->macAddress());
|
||||
device->setStateValue(bridgeReachableStateTypeId, true);
|
||||
m_bridges.insert(b, device);
|
||||
|
||||
// now add the child lights from this bridge as auto device
|
||||
QList<DeviceDescriptor> descriptors;
|
||||
foreach (HueLight *light, b->lights()) {
|
||||
DeviceDescriptor descriptor(hueLightDeviceClassId, "Philips Hue Light", light->name());
|
||||
ParamList params;
|
||||
params.append(Param("name", light->name()));
|
||||
params.append(Param("api key", light->apiKey()));
|
||||
params.append(Param("bridge", device->id().toString()));
|
||||
params.append(Param("host address", light->hostAddress().toString()));
|
||||
params.append(Param("model id", light->modelId()));
|
||||
params.append(Param("light id", light->lightId()));
|
||||
descriptor.setParams(params);
|
||||
descriptors.append(descriptor);
|
||||
}
|
||||
emit autoDevicesAppeared(hueLightDeviceClassId, descriptors);
|
||||
|
||||
device->setStateValue(bridgeReachableStateTypeId, true);
|
||||
discoverBridgeDevices(b);
|
||||
m_timer->start();
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
// loaded bridge
|
||||
HueBridge *bridge = new HueBridge(device->paramValue("api key").toString(),
|
||||
QHostAddress(device->paramValue("host address").toString()));
|
||||
|
||||
qCDebug(dcPhilipsHue) << "Setup Hue Bridge" << device->paramValue("name").toString();
|
||||
HueBridge *bridge = new HueBridge(this);
|
||||
bridge->setId(device->paramValue("id").toString());
|
||||
bridge->setApiKey(device->paramValue("api key").toString());
|
||||
bridge->setHostAddress(QHostAddress(device->paramValue("host address").toString()));
|
||||
bridge->setName(device->paramValue("name").toString());
|
||||
bridge->setApiVersion(device->paramValue("api version").toString());
|
||||
bridge->setSoftwareVersion(device->paramValue("software version").toString());
|
||||
bridge->setMacAddress(device->paramValue("mac address").toString());
|
||||
bridge->setZigbeeChannel(device->paramValue("zigbee channel").toInt());
|
||||
|
||||
m_bridges.insert(bridge, device);
|
||||
m_timer->start();
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
|
||||
// hue lights
|
||||
// hue color light
|
||||
if (device->deviceClassId() == hueLightDeviceClassId) {
|
||||
qCDebug(dcPhilipsHue) << "Setup Hue color light" << device->paramValue("name").toString();
|
||||
HueLight *hueLight = new HueLight(this);
|
||||
hueLight->setId(device->paramValue("light id").toInt());
|
||||
hueLight->setHostAddress(QHostAddress(device->paramValue("host address").toString()));
|
||||
hueLight->setName(device->paramValue("name").toString());
|
||||
hueLight->setApiKey(device->paramValue("api key").toString());
|
||||
hueLight->setModelId(device->paramValue("model id").toString());
|
||||
hueLight->setUuid(device->paramValue("uuid").toString());
|
||||
hueLight->setBridgeId(DeviceId(device->paramValue("bridge").toString()));
|
||||
|
||||
HueLight *hueLight = 0;
|
||||
|
||||
// check if this is a unconfigured light
|
||||
for (int i = 0; i < m_unconfiguredLights.count(); i++) {
|
||||
if (m_unconfiguredLights.at(i)->apiKey() == device->paramValue("api key").toString()) {
|
||||
hueLight = m_unconfiguredLights.takeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check if this is a light from settings
|
||||
if (hueLight == 0) {
|
||||
hueLight = new HueLight(device->paramValue("light id").toInt(),
|
||||
QHostAddress(device->paramValue("host address").toString()),
|
||||
device->paramValue("name").toString(),
|
||||
device->paramValue("api key").toString(),
|
||||
device->paramValue("model id").toString(),
|
||||
DeviceId(device->paramValue("bridge").toString()),
|
||||
this);
|
||||
connect(hueLight, &HueLight::stateChanged, this, &DevicePluginPhilipsHue::lightStateChanged);
|
||||
}
|
||||
connect(hueLight, &HueLight::stateChanged, this, &DevicePluginPhilipsHue::lightStateChanged);
|
||||
device->setParentId(device->paramValue("bridge").toString());
|
||||
m_lights.insert(hueLight, device);
|
||||
|
||||
setLightName(device, device->paramValue("name").toString());
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
|
||||
return DeviceManager::DeviceSetupStatusAsync;
|
||||
// hue white light
|
||||
if (device->deviceClassId() == hueWhiteLightDeviceClassId) {
|
||||
qCDebug(dcPhilipsHue) << "Setup Hue white light" << device->paramValue("name").toString();
|
||||
|
||||
HueLight *hueLight = new HueLight(this);
|
||||
hueLight->setId(device->paramValue("light id").toInt());
|
||||
hueLight->setHostAddress(QHostAddress(device->paramValue("host address").toString()));
|
||||
hueLight->setName(device->paramValue("name").toString());
|
||||
hueLight->setApiKey(device->paramValue("api key").toString());
|
||||
hueLight->setModelId(device->paramValue("model id").toString());
|
||||
hueLight->setUuid(device->paramValue("uuid").toString());
|
||||
hueLight->setBridgeId(DeviceId(device->paramValue("bridge").toString()));
|
||||
|
||||
connect(hueLight, &HueLight::stateChanged, this, &DevicePluginPhilipsHue::lightStateChanged);
|
||||
device->setParentId(device->paramValue("bridge").toString());
|
||||
m_lights.insert(hueLight, device);
|
||||
|
||||
setLightName(device, device->paramValue("name").toString());
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::deviceRemoved(Device *device)
|
||||
@ -183,26 +185,36 @@ void DevicePluginPhilipsHue::deviceRemoved(Device *device)
|
||||
bridge->deleteLater();
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == hueLightDeviceClassId) {
|
||||
if (device->deviceClassId() == hueLightDeviceClassId || device->deviceClassId() == hueWhiteLightDeviceClassId) {
|
||||
HueLight *light = m_lights.key(device);
|
||||
m_lights.remove(light);
|
||||
light->deleteLater();
|
||||
}
|
||||
|
||||
if (myDevices().isEmpty())
|
||||
m_timer->stop();
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList)
|
||||
{
|
||||
if (upnpDeviceDescriptorList.isEmpty()) {
|
||||
qCDebug(dcPhilipsHue) << "No UPnP device found. Try N-UPNP discovery.";
|
||||
QNetworkRequest request(QUrl("https://www.meethue.com/api/nupnp"));
|
||||
QNetworkReply *reply = networkManagerGet(request);
|
||||
m_discoveryRequests.append(reply);
|
||||
return;
|
||||
}
|
||||
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
foreach (const UpnpDeviceDescriptor &upnpDevice, upnpDeviceDescriptorList) {
|
||||
if (upnpDevice.modelDescription().contains("Philips")) {
|
||||
DeviceDescriptor descriptor(hueBridgeDeviceClassId, "Philips Hue Bridge", upnpDevice.hostAddress().toString());
|
||||
ParamList params;
|
||||
params.append(Param("name", QString()));
|
||||
params.append(Param("name", upnpDevice.friendlyName()));
|
||||
params.append(Param("host address", upnpDevice.hostAddress().toString()));
|
||||
params.append(Param("api key", QString()));
|
||||
params.append(Param("mac address", QString()));
|
||||
params.append(Param("api version", QString()));
|
||||
params.append(Param("software version", QString()));
|
||||
params.append(Param("id", upnpDevice.serialNumber().toLower()));
|
||||
params.append(Param("zigbee channel", -1));
|
||||
descriptor.setParams(params);
|
||||
deviceDescriptors.append(descriptor);
|
||||
@ -267,8 +279,54 @@ void DevicePluginPhilipsHue::networkManagerReplyReady(QNetworkReply *reply)
|
||||
}
|
||||
processInformationResponse(pairingInfo, reply->readAll());
|
||||
|
||||
} else if (m_lightRefreshRequests.keys().contains(reply)) {
|
||||
} else if (m_discoveryRequests.contains(reply)) {
|
||||
m_discoveryRequests.removeAll(reply);
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
qCWarning(dcPhilipsHue) << "N-UPNP discovery error:" << status << reply->errorString();
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
processNUpnpResponse(reply->readAll());
|
||||
|
||||
} else if (m_bridgeLightsDiscoveryRequests.keys().contains(reply)) {
|
||||
Device *device = m_bridgeLightsDiscoveryRequests.take(reply);
|
||||
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
qCWarning(dcPhilipsHue) << "Bridge light discovery error:" << status << reply->errorString();
|
||||
onBridgeError(device);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
processBridgeLightDiscoveryResponse(device, reply->readAll());
|
||||
|
||||
} else if (m_bridgeSensorsDiscoveryRequests.keys().contains(reply)) {
|
||||
Device *device = m_bridgeSensorsDiscoveryRequests.take(reply);
|
||||
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
qCWarning(dcPhilipsHue) << "Bridge sensor discovery error:" << status << reply->errorString();
|
||||
onBridgeError(device);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
processBridgeSensorDiscoveryResponse(device, reply->readAll());
|
||||
|
||||
} else if (m_bridgeSearchDevicesRequests.keys().contains(reply)) {
|
||||
Device *device = m_bridgeSearchDevicesRequests.take(reply);
|
||||
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
qCWarning(dcPhilipsHue) << "Bridge search new devices error:" << status << reply->errorString();
|
||||
onBridgeError(device);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
discoverBridgeDevices(m_bridges.key(device));
|
||||
|
||||
} else if (m_lightRefreshRequests.keys().contains(reply)) {
|
||||
Device *device = m_lightRefreshRequests.take(reply);
|
||||
|
||||
// check HTTP status code
|
||||
@ -280,26 +338,54 @@ void DevicePluginPhilipsHue::networkManagerReplyReady(QNetworkReply *reply)
|
||||
}
|
||||
processLightRefreshResponse(device, reply->readAll());
|
||||
|
||||
} else if (m_bridgeRefreshRequests.keys().contains(reply)) {
|
||||
} else if (m_lightsRefreshRequests.keys().contains(reply)) {
|
||||
Device *device = m_lightsRefreshRequests.take(reply);
|
||||
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
if (device->stateValue(bridgeReachableStateTypeId).toBool()) {
|
||||
qCWarning(dcPhilipsHue) << "Refresh Hue Bridge request error:" << status << reply->errorString();
|
||||
onBridgeError(device);
|
||||
}
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
processLightsRefreshResponse(device, reply->readAll());
|
||||
|
||||
} else if (m_sensorsRefreshRequests.keys().contains(reply)) {
|
||||
Device *device = m_lightsRefreshRequests.take(reply);
|
||||
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
if (device->stateValue(bridgeReachableStateTypeId).toBool()) {
|
||||
qCWarning(dcPhilipsHue) << "Refresh Hue Bridge request error:" << status << reply->errorString();
|
||||
onBridgeError(device);
|
||||
}
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
processSensorsRefreshResponse(device, reply->readAll());
|
||||
|
||||
} else if (m_bridgeRefreshRequests.keys().contains(reply)) {
|
||||
Device *device = m_bridgeRefreshRequests.take(reply);
|
||||
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
qCWarning(dcPhilipsHue) << "Refresh Hue Bridge request error:" << status << reply->errorString();
|
||||
onBridgeError(device);
|
||||
if (device->stateValue(bridgeReachableStateTypeId).toBool()) {
|
||||
qCWarning(dcPhilipsHue) << "Refresh Hue Bridge request error:" << status << reply->errorString();
|
||||
onBridgeError(device);
|
||||
}
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
processBridgeRefreshResponse(device, reply->readAll());
|
||||
|
||||
} else if (m_asyncActions.keys().contains(reply)) {
|
||||
|
||||
QPair<Device *, ActionId> actionInfo = m_asyncActions.take(reply);
|
||||
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
qCWarning(dcPhilipsHue) << "Refresh Hue Light request error:" << status << reply->errorString();
|
||||
qCWarning(dcPhilipsHue) << "Execute Hue Light action request error:" << status << reply->errorString();
|
||||
onBridgeError(actionInfo.first);
|
||||
emit actionExecutionFinished(actionInfo.second, DeviceManager::DeviceErrorHardwareNotAvailable);
|
||||
reply->deleteLater();
|
||||
@ -309,12 +395,12 @@ void DevicePluginPhilipsHue::networkManagerReplyReady(QNetworkReply *reply)
|
||||
processActionResponse(actionInfo.first, actionInfo.second, data);
|
||||
|
||||
} else if (m_lightSetNameRequests.keys().contains(reply)) {
|
||||
|
||||
Device *device = m_lightSetNameRequests.take(reply);
|
||||
|
||||
// check HTTP status code
|
||||
if (status != 200) {
|
||||
qCWarning(dcPhilipsHue) << "Set name of Hue Light request error:" << status << reply->errorString();
|
||||
onBridgeError(device);
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
@ -324,15 +410,10 @@ void DevicePluginPhilipsHue::networkManagerReplyReady(QNetworkReply *reply)
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::guhTimer()
|
||||
{
|
||||
foreach (Device *device, m_bridges.values()) {
|
||||
refreshBridge(device);
|
||||
}
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const Action &action)
|
||||
{
|
||||
qCDebug(dcPhilipsHue) << "Execute action" << action.actionTypeId() << action.params();
|
||||
|
||||
if (device->deviceClassId() == hueLightDeviceClassId) {
|
||||
HueLight *light = m_lights.key(device);
|
||||
|
||||
@ -367,8 +448,41 @@ DeviceManager::DeviceError DevicePluginPhilipsHue::executeAction(Device *device,
|
||||
return DeviceManager::DeviceErrorActionTypeNotFound;
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == hueWhiteLightDeviceClassId) {
|
||||
HueLight *light = m_lights.key(device);
|
||||
|
||||
if (!light->reachable())
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
if (action.actionTypeId() == huePowerActionTypeId) {
|
||||
QPair<QNetworkRequest, QByteArray> request = light->createSetPowerRequest(action.param("power").value().toBool());
|
||||
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
} else if (action.actionTypeId() == hueBrightnessActionTypeId) {
|
||||
QPair<QNetworkRequest, QByteArray> request = light->createSetBrightnessRequest(percentageToBrightness(action.param("brightness").value().toInt()));
|
||||
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
} else if (action.actionTypeId() == hueAlertActionTypeId) {
|
||||
QPair<QNetworkRequest, QByteArray> request = light->createFlashRequest(action.param("alert").value().toString());
|
||||
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
}
|
||||
return DeviceManager::DeviceErrorActionTypeNotFound;
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == hueBridgeDeviceClassId) {
|
||||
// TODO: search if a light was added or removed from bridge
|
||||
if (!device->stateValue(bridgeReachableStateTypeId).toBool())
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
HueBridge *bridge = m_bridges.key(device);
|
||||
if (action.actionTypeId() == searchNewDevicesActionTypeId) {
|
||||
searchNewDevices(bridge);
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
} else if (action.actionTypeId() == checkForUpdatesActionTypeId) {
|
||||
QPair<QNetworkRequest, QByteArray> request = bridge->createCheckUpdatesRequest();
|
||||
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
}
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
}
|
||||
return DeviceManager::DeviceErrorDeviceClassNotFound;
|
||||
@ -382,19 +496,40 @@ void DevicePluginPhilipsHue::lightStateChanged()
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
device->setStateValue(hueReachableStateTypeId, light->reachable());
|
||||
device->setStateValue(hueColorStateTypeId, QVariant::fromValue(light->color()));
|
||||
device->setStateValue(huePowerStateTypeId, light->power());
|
||||
device->setStateValue(hueBrightnessStateTypeId, brightnessToPercentage(light->brightness()));
|
||||
device->setStateValue(hueTemperatureStateTypeId, light->ct());
|
||||
device->setStateValue(hueEffectStateTypeId, light->effect());
|
||||
if (device->deviceClassId() == hueLightDeviceClassId) {
|
||||
device->setStateValue(hueReachableStateTypeId, light->reachable());
|
||||
device->setStateValue(hueColorStateTypeId, QVariant::fromValue(light->color()));
|
||||
device->setStateValue(huePowerStateTypeId, light->power());
|
||||
device->setStateValue(hueBrightnessStateTypeId, brightnessToPercentage(light->brightness()));
|
||||
device->setStateValue(hueTemperatureStateTypeId, light->ct());
|
||||
device->setStateValue(hueEffectStateTypeId, light->effect());
|
||||
} else if (device->deviceClassId() == hueWhiteLightDeviceClassId) {
|
||||
device->setStateValue(hueReachableStateTypeId, light->reachable());
|
||||
device->setStateValue(huePowerStateTypeId, light->power());
|
||||
device->setStateValue(hueBrightnessStateTypeId, brightnessToPercentage(light->brightness()));
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::onTimeout()
|
||||
{
|
||||
foreach (Device *device, m_bridges.values()) {
|
||||
HueBridge *bridge = m_bridges.key(device);
|
||||
if (!device->stateValue(hueReachableStateTypeId).toBool()) {
|
||||
if (!m_bridgeRefreshRequests.values().contains(device))
|
||||
refreshBridge(device);
|
||||
} else {
|
||||
refreshBridge(device);
|
||||
refreshLights(bridge);
|
||||
refreshSensors(bridge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::refreshLight(Device *device)
|
||||
{
|
||||
HueLight *light = m_lights.key(device);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + light->hostAddress().toString() + "/api/" + light->apiKey() + "/lights/" + QString::number(light->lightId())));
|
||||
QNetworkRequest request(QUrl("http://" + light->hostAddress().toString() + "/api/" + light->apiKey() + "/lights/" + QString::number(light->id())));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
QNetworkReply *reply = networkManagerGet(request);
|
||||
|
||||
@ -405,14 +540,57 @@ void DevicePluginPhilipsHue::refreshBridge(Device *device)
|
||||
{
|
||||
HueBridge *bridge = m_bridges.key(device);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + bridge->hostAddress().toString() + "/api/" + bridge->apiKey() + "/lights/"));
|
||||
QNetworkRequest request(QUrl("http://" + bridge->hostAddress().toString() + "/api/" + bridge->apiKey() + "/config"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
QNetworkReply *reply = networkManagerGet(request);
|
||||
|
||||
m_bridgeRefreshRequests.insert(reply, device);
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::setLightName(Device *device, QString name)
|
||||
void DevicePluginPhilipsHue::refreshLights(HueBridge *bridge)
|
||||
{
|
||||
Device *device = m_bridges.value(bridge);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + bridge->hostAddress().toString() + "/api/" + bridge->apiKey() + "/lights"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
QNetworkReply *reply = networkManagerGet(request);
|
||||
|
||||
m_lightsRefreshRequests.insert(reply, device);
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::refreshSensors(HueBridge *bridge)
|
||||
{
|
||||
Device *device = m_bridges.value(bridge);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + bridge->hostAddress().toString() + "/api/" + bridge->apiKey() + "/sensors"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
QNetworkReply *reply = networkManagerGet(request);
|
||||
|
||||
m_sensorsRefreshRequests.insert(reply, device);
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::discoverBridgeDevices(HueBridge *bridge)
|
||||
{
|
||||
Device *device = m_bridges.value(bridge);
|
||||
qCDebug(dcPhilipsHue) << "Discover bridge devices" << bridge->hostAddress();
|
||||
|
||||
QPair<QNetworkRequest, QByteArray> lightsRequest = bridge->createDiscoverLightsRequest();
|
||||
m_bridgeLightsDiscoveryRequests.insert(networkManagerGet(lightsRequest.first), device);
|
||||
|
||||
QPair<QNetworkRequest, QByteArray> sensorsRequest = bridge->createSearchSensorsRequest();
|
||||
m_bridgeSensorsDiscoveryRequests.insert(networkManagerGet(sensorsRequest.first), device);
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::searchNewDevices(HueBridge *bridge)
|
||||
{
|
||||
Device *device = m_bridges.value(bridge);
|
||||
qCDebug(dcPhilipsHue) << "Discover bridge devices" << bridge->hostAddress();
|
||||
|
||||
QPair<QNetworkRequest, QByteArray> request = bridge->createSearchLightsRequest();
|
||||
m_bridgeSearchDevicesRequests.insert(networkManagerPost(request.first, request.second), device);
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::setLightName(Device *device, const QString &name)
|
||||
{
|
||||
HueLight *light = m_lights.key(device);
|
||||
|
||||
@ -421,13 +599,166 @@ void DevicePluginPhilipsHue::setLightName(Device *device, QString name)
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(requestMap);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + light->hostAddress().toString() + "/api/" + light->apiKey() +
|
||||
"/lights/" + QString::number(light->lightId())));
|
||||
"/lights/" + QString::number(light->id())));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
QNetworkReply *reply = networkManagerPut(request,jsonDoc.toJson());
|
||||
m_lightSetNameRequests.insert(reply, device);
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::processNUpnpResponse(const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
// check JSON error
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcPhilipsHue) << "N-UPNP discovery JSON error in response" << error.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantList bridgeList = jsonDoc.toVariant().toList();
|
||||
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
foreach (const QVariant &bridgeVariant, bridgeList) {
|
||||
QVariantMap bridgeMap = bridgeVariant.toMap();
|
||||
DeviceDescriptor descriptor(hueBridgeDeviceClassId, "Philips Hue Bridge", bridgeMap.value("internalipaddress").toString());
|
||||
ParamList params;
|
||||
params.append(Param("name", "Philips hue"));
|
||||
params.append(Param("host address", bridgeMap.value("internalipaddress").toString()));
|
||||
params.append(Param("api key", QString()));
|
||||
params.append(Param("mac address", QString()));
|
||||
params.append(Param("id", bridgeMap.value("id").toString().toLower()));
|
||||
params.append(Param("zigbee channel", -1));
|
||||
descriptor.setParams(params);
|
||||
deviceDescriptors.append(descriptor);
|
||||
}
|
||||
qCDebug(dcPhilipsHue) << "N-UPNP discover finished. Found" << deviceDescriptors.count() << "devices.";
|
||||
emit devicesDiscovered(hueBridgeDeviceClassId, deviceDescriptors);
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::processBridgeLightDiscoveryResponse(Device *device, const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
// check JSON error
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcPhilipsHue) << "Bridge light discovery json error in response" << error.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
// check response error
|
||||
if (data.contains("error")) {
|
||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to discover Hue Bridge lights:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
} else {
|
||||
qCWarning(dcPhilipsHue) << "Failed to discover Hue Bridge lights: Invalid error message format";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// create Lights if not already added
|
||||
QList<DeviceDescriptor> lightDescriptors;
|
||||
QList<DeviceDescriptor> whiteLightDescriptors;
|
||||
|
||||
QVariantMap lightsMap = jsonDoc.toVariant().toMap();
|
||||
foreach (QString lightId, lightsMap.keys()) {
|
||||
QVariantMap lightMap = lightsMap.value(lightId).toMap();
|
||||
|
||||
QString uuid = lightMap.value("uniqueid").toString();
|
||||
QString model = lightMap.value("modelid").toString();
|
||||
|
||||
if (lightAlreadyAdded(uuid))
|
||||
continue;
|
||||
|
||||
// check if this is a white light
|
||||
if (model == "LWB004" || model == "LWB006" || model == "LWB007") {
|
||||
DeviceDescriptor descriptor(hueWhiteLightDeviceClassId, "Philips Hue White Light", lightMap.value("name").toString());
|
||||
ParamList params;
|
||||
params.append(Param("name", lightMap.value("name").toString()));
|
||||
params.append(Param("api key", device->paramValue("api key").toString()));
|
||||
params.append(Param("bridge", device->id().toString()));
|
||||
params.append(Param("host address", device->paramValue("host address").toString()));
|
||||
params.append(Param("model id", model));
|
||||
params.append(Param("uuid", uuid));
|
||||
params.append(Param("light id", lightId));
|
||||
descriptor.setParams(params);
|
||||
whiteLightDescriptors.append(descriptor);
|
||||
|
||||
qCDebug(dcPhilipsHue) << "Found new white light" << lightMap.value("name").toString() << model;
|
||||
|
||||
} else {
|
||||
DeviceDescriptor descriptor(hueLightDeviceClassId, "Philips Hue Light", lightMap.value("name").toString());
|
||||
ParamList params;
|
||||
params.append(Param("name", lightMap.value("name").toString()));
|
||||
params.append(Param("api key", device->paramValue("api key").toString()));
|
||||
params.append(Param("bridge", device->id().toString()));
|
||||
params.append(Param("host address", device->paramValue("host address").toString()));
|
||||
params.append(Param("model id", model));
|
||||
params.append(Param("uuid", uuid));
|
||||
params.append(Param("light id", lightId));
|
||||
descriptor.setParams(params);
|
||||
lightDescriptors.append(descriptor);
|
||||
qCDebug(dcPhilipsHue) << "Found new color light" << lightMap.value("name").toString() << model;
|
||||
}
|
||||
}
|
||||
emit autoDevicesAppeared(hueLightDeviceClassId, lightDescriptors);
|
||||
emit autoDevicesAppeared(hueWhiteLightDeviceClassId, whiteLightDescriptors);
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::processBridgeSensorDiscoveryResponse(Device *device, const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
// check JSON error
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcPhilipsHue) << "Bridge sensor discovery json error in response" << error.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
// check response error
|
||||
if (data.contains("error")) {
|
||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to discover Hue Bridge sensors:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
} else {
|
||||
qCWarning(dcPhilipsHue) << "Failed to discover Hue Bridge sensors: Invalid error message format";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// create Lights if not already added
|
||||
QList<DeviceDescriptor> sensorDescriptors;
|
||||
|
||||
QVariantMap sensorsMap = jsonDoc.toVariant().toMap();
|
||||
foreach (QString sensorId, sensorsMap.keys()) {
|
||||
QVariantMap sensorMap = sensorsMap.value(sensorId).toMap();
|
||||
|
||||
QString uuid = sensorMap.value("uniqueid").toString();
|
||||
QString model = sensorMap.value("modelid").toString();
|
||||
|
||||
if (sensorAlreadyAdded(uuid))
|
||||
continue;
|
||||
|
||||
// check if this is a white light
|
||||
if (model == "RWL021") {
|
||||
DeviceDescriptor descriptor(hueRemoteDeviceClassId, "Philips Hue Remote", sensorMap.value("name").toString());
|
||||
ParamList params;
|
||||
params.append(Param("name", sensorMap.value("name").toString()));
|
||||
params.append(Param("api key", device->paramValue("api key").toString()));
|
||||
params.append(Param("bridge", device->id().toString()));
|
||||
params.append(Param("host address", device->paramValue("host address").toString()));
|
||||
params.append(Param("model id", model));
|
||||
params.append(Param("uuid", uuid));
|
||||
params.append(Param("sensor id", sensorId));
|
||||
descriptor.setParams(params);
|
||||
sensorDescriptors.append(descriptor);
|
||||
qCDebug(dcPhilipsHue) << "Found new remote" << sensorMap.value("name").toString() << model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::processLightRefreshResponse(Device *device, const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
@ -441,12 +772,16 @@ void DevicePluginPhilipsHue::processLightRefreshResponse(Device *device, const Q
|
||||
|
||||
// check response error
|
||||
if (data.contains("error")) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Light:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Light:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
} else {
|
||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Light: Invalid error message format";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
HueLight *hueLight = m_lights.key(device);
|
||||
hueLight->updateStates(jsonDoc.toVariant().toMap().value("state").toMap());
|
||||
HueRemote *remote = m_remotes.key(device);
|
||||
remote->updateStates(jsonDoc.toVariant().toMap().value("state").toMap());
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::processBridgeRefreshResponse(Device *device, const QByteArray &data)
|
||||
@ -460,27 +795,94 @@ void DevicePluginPhilipsHue::processBridgeRefreshResponse(Device *device, const
|
||||
return;
|
||||
}
|
||||
|
||||
// check response error
|
||||
if (data.contains("error")) {
|
||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Bridge:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
onBridgeError(device);
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap configMap = jsonDoc.toVariant().toMap();
|
||||
|
||||
// mark bridge as reachable
|
||||
device->setStateValue(bridgeReachableStateTypeId, true);
|
||||
device->setStateValue(apiVersionStateTypeId, configMap.value("apiversion").toString());
|
||||
device->setStateValue(softwareVersionStateTypeId, configMap.value("swversion").toString());
|
||||
|
||||
int updateStatus = configMap.value("swupdate").toMap().value("updatestate").toInt();
|
||||
switch (updateStatus) {
|
||||
case 0:
|
||||
device->setStateValue(updateStatusStateTypeId, "Up to date");
|
||||
break;
|
||||
case 1:
|
||||
device->setStateValue(updateStatusStateTypeId, "Downloading updates");
|
||||
break;
|
||||
case 2:
|
||||
device->setStateValue(updateStatusStateTypeId, "Updates ready to install");
|
||||
break;
|
||||
case 3:
|
||||
device->setStateValue(updateStatusStateTypeId, "Installing updates");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::processLightsRefreshResponse(Device *device, const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
// check JSON error
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
// check response error
|
||||
if (data.contains("error")) {
|
||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Lights:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
} else {
|
||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Lights: Invalid error message format";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Update light states
|
||||
QVariantMap lightsMap = jsonDoc.toVariant().toMap();
|
||||
foreach (const QString &lightId, lightsMap.keys()) {
|
||||
QVariantMap lightMap = lightsMap.value(lightId).toMap();
|
||||
// get the light of this bridge
|
||||
foreach (HueLight *light, m_lights.keys()) {
|
||||
if (light->lightId() == lightId.toInt() && light->bridgeId() == device->id()) {
|
||||
if (light->id() == lightId.toInt() && light->bridgeId() == device->id()) {
|
||||
light->updateStates(lightMap.value("state").toMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::processSensorsRefreshResponse(Device *device, const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
// check JSON error
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
// check response error
|
||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Sensors:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
return;
|
||||
}
|
||||
|
||||
//qCDebug(dcPhilipsHue) << jsonDoc.toJson();
|
||||
|
||||
Q_UNUSED(device)
|
||||
}
|
||||
|
||||
void DevicePluginPhilipsHue::processSetNameResponse(Device *device, const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
@ -495,14 +897,18 @@ void DevicePluginPhilipsHue::processSetNameResponse(Device *device, const QByteA
|
||||
|
||||
// check response error
|
||||
if (data.contains("error")) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to set name of Hue:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to set name of Hue:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
} else {
|
||||
qCWarning(dcPhilipsHue) << "Failed to set name of Hue: Invalid error message format";
|
||||
}
|
||||
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess);
|
||||
|
||||
if (device->deviceClassId() == hueLightDeviceClassId)
|
||||
if (device->deviceClassId() == hueLightDeviceClassId || device->deviceClassId() == hueWhiteLightDeviceClassId)
|
||||
refreshLight(device);
|
||||
|
||||
}
|
||||
@ -522,7 +928,11 @@ void DevicePluginPhilipsHue::processPairingResponse(PairingInfo *pairingInfo, co
|
||||
|
||||
// check response error
|
||||
if (data.contains("error")) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to pair Hue Bridge:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to pair Hue Bridge:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
} else {
|
||||
qCWarning(dcPhilipsHue) << "Failed to pair Hue Bridge: Invalid error message format";
|
||||
}
|
||||
emit pairingFinished(pairingInfo->pairingTransactionId(), DeviceManager::DeviceSetupStatusFailure);
|
||||
pairingInfo->deleteLater();
|
||||
return;
|
||||
@ -533,14 +943,14 @@ void DevicePluginPhilipsHue::processPairingResponse(PairingInfo *pairingInfo, co
|
||||
qCDebug(dcPhilipsHue) << "Got api key from bridge:" << pairingInfo->apiKey();
|
||||
|
||||
if (pairingInfo->apiKey().isEmpty()) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to pair Hue Bridge: did not get any username from the bridge";
|
||||
qCWarning(dcPhilipsHue) << "Failed to pair Hue Bridge: did not get any key from the bridge";
|
||||
emit pairingFinished(pairingInfo->pairingTransactionId(), DeviceManager::DeviceSetupStatusFailure);
|
||||
pairingInfo->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
// Paired successfully, check bridge/light information
|
||||
QNetworkRequest request(QUrl("http://" + pairingInfo->host().toString() + "/api/" + pairingInfo->apiKey() + "/"));
|
||||
// Paired successfully, check bridge information
|
||||
QNetworkRequest request(QUrl("http://" + pairingInfo->host().toString() + "/api/" + pairingInfo->apiKey() + "/config"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
QNetworkReply *reply = networkManagerGet(request);
|
||||
|
||||
@ -552,8 +962,6 @@ void DevicePluginPhilipsHue::processInformationResponse(PairingInfo *pairingInfo
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
//qCDebug(dcPhilipsHue) << "Process information response" << pairingInfo->host().toString() << pairingInfo->apiKey();
|
||||
|
||||
// check JSON error
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
||||
@ -573,35 +981,18 @@ void DevicePluginPhilipsHue::processInformationResponse(PairingInfo *pairingInfo
|
||||
}
|
||||
|
||||
// create Bridge
|
||||
HueBridge *bridge = new HueBridge(pairingInfo->apiKey(), pairingInfo->host(), this);
|
||||
|
||||
bridge->setApiVersion(response.value("config").toMap().value("apiversion").toString());
|
||||
bridge->setSoftwareVersion(response.value("config").toMap().value("swversion").toString());
|
||||
bridge->setMacAddress(response.value("config").toMap().value("mac").toString());
|
||||
bridge->setName(response.value("config").toMap().value("name").toString());
|
||||
bridge->setZigbeeChannel(response.value("config").toMap().value("zigbeechannel").toInt());
|
||||
HueBridge *bridge = new HueBridge(this);
|
||||
bridge->setId(response.value("bridgeid").toString());
|
||||
bridge->setApiKey(pairingInfo->apiKey());
|
||||
bridge->setHostAddress(pairingInfo->host());
|
||||
bridge->setApiVersion(response.value("apiversion").toString());
|
||||
bridge->setSoftwareVersion(response.value("swversion").toString());
|
||||
bridge->setMacAddress(response.value("mac").toString());
|
||||
bridge->setName(response.value("name").toString());
|
||||
bridge->setZigbeeChannel(response.value("zigbeechannel").toInt());
|
||||
|
||||
m_unconfiguredBridges.append(bridge);
|
||||
|
||||
// create Lights
|
||||
QVariantMap lightsMap = response.value("lights").toMap();
|
||||
foreach (QString lightId, lightsMap.keys()) {
|
||||
QVariantMap lightMap = lightsMap.value(lightId).toMap();
|
||||
HueLight *hueLight = new HueLight(lightId.toInt(),
|
||||
bridge->hostAddress(),
|
||||
lightMap.value("name").toString(),
|
||||
pairingInfo->apiKey(),
|
||||
lightMap.value("modelid").toString(),
|
||||
DeviceId(),
|
||||
this);
|
||||
|
||||
hueLight->updateStates(lightMap.value("state").toMap());
|
||||
|
||||
bridge->addLight(hueLight);
|
||||
m_unconfiguredLights.append(hueLight);
|
||||
|
||||
connect(hueLight, &HueLight::stateChanged, this, &DevicePluginPhilipsHue::lightStateChanged);
|
||||
}
|
||||
emit pairingFinished(pairingInfo->pairingTransactionId(), DeviceManager::DeviceSetupStatusSuccess);
|
||||
pairingInfo->deleteLater();
|
||||
}
|
||||
@ -620,12 +1011,18 @@ void DevicePluginPhilipsHue::processActionResponse(Device *device, const ActionI
|
||||
|
||||
// check response error
|
||||
if (data.contains("error")) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to execute Hue action:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||
qCWarning(dcPhilipsHue) << "Failed to execute Hue action:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||
} else {
|
||||
qCWarning(dcPhilipsHue) << "Failed to execute Hue action: Invalid error message format";
|
||||
}
|
||||
emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
|
||||
m_lights.key(device)->processActionResponse(jsonDoc.toVariant().toList());
|
||||
if (device->deviceClassId() != hueBridgeDeviceClassId)
|
||||
m_lights.key(device)->processActionResponse(jsonDoc.toVariant().toList());
|
||||
|
||||
emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorNoError);
|
||||
}
|
||||
|
||||
@ -636,33 +1033,55 @@ void DevicePluginPhilipsHue::onBridgeError(Device *device)
|
||||
device->setStateValue(bridgeReachableStateTypeId, false);
|
||||
foreach (HueLight *light, m_lights.keys()) {
|
||||
if (light->bridgeId() == device->id()) {
|
||||
light->setReachable(false);
|
||||
device->setStateValue(hueReachableStateTypeId, false);
|
||||
}
|
||||
}
|
||||
} else if (device->deviceClassId() == hueLightDeviceClassId) {
|
||||
DeviceId bridgeId = DeviceId(device->paramValue("bridge").toString());
|
||||
// mark lamps as unreachable
|
||||
foreach (HueLight *light, m_lights.keys()) {
|
||||
if (light->bridgeId() == bridgeId) {
|
||||
device->setStateValue(hueReachableStateTypeId, false);
|
||||
}
|
||||
}
|
||||
// mark bridge as unreachable
|
||||
foreach (Device *d, m_bridges.values()) {
|
||||
if (d->id() == bridgeId) {
|
||||
d->setStateValue(bridgeReachableStateTypeId, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DevicePluginPhilipsHue::bridgeAlreadyAdded(const QString &id)
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
if (device->deviceClassId() == hueBridgeDeviceClassId) {
|
||||
if (device->paramValue("id").toString() == id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DevicePluginPhilipsHue::lightAlreadyAdded(const QString &uuid)
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
if (device->deviceClassId() == hueLightDeviceClassId || device->deviceClassId() == hueWhiteLightDeviceClassId) {
|
||||
if (device->paramValue("uuid").toString() == uuid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DevicePluginPhilipsHue::sensorAlreadyAdded(const QString &uuid)
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
if (device->deviceClassId() == hueRemoteDeviceClassId) {
|
||||
if (device->paramValue("uuid").toString() == uuid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int DevicePluginPhilipsHue::brightnessToPercentage(int brightness)
|
||||
{
|
||||
return (int)(((100.0 * brightness) / 255.0) + 0.5);
|
||||
return qRound((100.0 * brightness) / 255.0);
|
||||
}
|
||||
|
||||
int DevicePluginPhilipsHue::percentageToBrightness(int percentage)
|
||||
{
|
||||
return (int)(((255.0 * percentage) / 100.0) + 0.5);
|
||||
return qRound((255.0 * percentage) / 100.0);
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "plugin/deviceplugin.h"
|
||||
#include "huebridge.h"
|
||||
#include "huelight.h"
|
||||
#include "hueremote.h"
|
||||
#include "pairinginfo.h"
|
||||
|
||||
class QNetworkReply;
|
||||
@ -40,45 +41,67 @@ public:
|
||||
explicit DevicePluginPhilipsHue();
|
||||
|
||||
DeviceManager::HardwareResources requiredHardware() const override;
|
||||
|
||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||
|
||||
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
void upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList) override;
|
||||
|
||||
void upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList) override;
|
||||
DeviceManager::DeviceSetupStatus confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList ¶ms, const QString &secret) override;
|
||||
|
||||
void networkManagerReplyReady(QNetworkReply *reply) override;
|
||||
|
||||
void guhTimer() override;
|
||||
|
||||
public slots:
|
||||
DeviceManager::DeviceError executeAction(Device *device, const Action &action);
|
||||
|
||||
private slots:
|
||||
void lightStateChanged();
|
||||
void onTimeout();
|
||||
|
||||
private:
|
||||
QTimer *m_timer;
|
||||
|
||||
QHash<QNetworkReply *, PairingInfo *> m_pairingRequests;
|
||||
QHash<QNetworkReply *, PairingInfo *> m_informationRequests;
|
||||
|
||||
QList<HueBridge *> m_unconfiguredBridges;
|
||||
QList<HueLight *> m_unconfiguredLights;
|
||||
QList<QNetworkReply *> m_discoveryRequests;
|
||||
|
||||
QHash<QNetworkReply *, Device *> m_lightRefreshRequests;
|
||||
QHash<QNetworkReply *, Device *> m_lightSetNameRequests;
|
||||
QHash<QNetworkReply *, Device *> m_bridgeRefreshRequests;
|
||||
QHash<QNetworkReply *, Device *> m_lightsRefreshRequests;
|
||||
QHash<QNetworkReply *, Device *> m_sensorsRefreshRequests;
|
||||
QHash<QNetworkReply *, Device *> m_bridgeLightsDiscoveryRequests;
|
||||
QHash<QNetworkReply *, Device *> m_bridgeSensorsDiscoveryRequests;
|
||||
QHash<QNetworkReply *, Device *> m_bridgeSearchDevicesRequests;
|
||||
|
||||
QHash<QNetworkReply *, QPair<Device *, ActionId> > m_asyncActions;
|
||||
|
||||
QHash<HueBridge*, Device*> m_bridges;
|
||||
QHash<HueLight*, Device*> m_lights;
|
||||
QHash<HueBridge *, Device *> m_bridges;
|
||||
QHash<HueLight *, Device *> m_lights;
|
||||
QHash<HueRemote *, Device *> m_remotes;
|
||||
|
||||
void refreshLight(Device *device);
|
||||
void refreshBridge(Device *device);
|
||||
|
||||
void setLightName(Device *device, QString name);
|
||||
void refreshLights(HueBridge *bridge);
|
||||
void refreshSensors(HueBridge *bridge);
|
||||
|
||||
void discoverBridgeDevices(HueBridge *bridge);
|
||||
void searchNewDevices(HueBridge *bridge);
|
||||
|
||||
void setLightName(Device *device, const QString &name);
|
||||
|
||||
void processNUpnpResponse(const QByteArray &data);
|
||||
void processBridgeLightDiscoveryResponse(Device *device, const QByteArray &data);
|
||||
void processBridgeSensorDiscoveryResponse(Device *device, const QByteArray &data);
|
||||
void processLightRefreshResponse(Device *device, const QByteArray &data);
|
||||
void processBridgeRefreshResponse(Device *device, const QByteArray &data);
|
||||
void processLightsRefreshResponse(Device *device, const QByteArray &data);
|
||||
void processSensorsRefreshResponse(Device *device, const QByteArray &data);
|
||||
void processSetNameResponse(Device *device, const QByteArray &data);
|
||||
void processPairingResponse(PairingInfo *pairingInfo, const QByteArray &data);
|
||||
void processInformationResponse(PairingInfo *pairingInfo, const QByteArray &data);
|
||||
@ -86,6 +109,10 @@ private:
|
||||
|
||||
void onBridgeError(Device *device);
|
||||
|
||||
bool bridgeAlreadyAdded(const QString &id);
|
||||
bool lightAlreadyAdded(const QString &uuid);
|
||||
bool sensorAlreadyAdded(const QString &uuid);
|
||||
|
||||
int brightnessToPercentage(int brightness);
|
||||
int percentageToBrightness(int percentage);
|
||||
};
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
{
|
||||
"deviceClassId": "642aa4c7-19aa-45ed-ba06-aa1ae6c9edf7",
|
||||
"idName": "hueBridge",
|
||||
"name": "Hue Bridge",
|
||||
"name": "Hue gateway",
|
||||
"createMethods": ["discovery"],
|
||||
"setupMethod": "pushButton",
|
||||
"pairingInfo": "Please press the button on the Hue Bridge within 30 seconds before you continue",
|
||||
@ -40,7 +40,7 @@
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "api version",
|
||||
"name": "id",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
@ -60,7 +60,47 @@
|
||||
"id": "15794d26-fde8-4a61-8f83-d7830534975f",
|
||||
"idName": "bridgeReachable",
|
||||
"name": "reachable",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "7a230e89-c4ce-4276-90e0-6a9ddb890603",
|
||||
"idName": "apiVersion",
|
||||
"name": "api version",
|
||||
"defaultValue": "-",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "4c707b18-6604-4e6d-b6bc-4e27769c2adc",
|
||||
"idName": "softwareVersion",
|
||||
"name": "software version",
|
||||
"defaultValue": "-",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "16a126f3-0cef-4931-bb2b-9e1b49bec7fc",
|
||||
"idName": "updateStatus",
|
||||
"name": "update status",
|
||||
"type": "QString",
|
||||
"defaultValue": "Up to date",
|
||||
"possibleValues": [
|
||||
"Up to date",
|
||||
"Downloading updates",
|
||||
"Updates ready to install",
|
||||
"Installing updates"
|
||||
]
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "cca3f171-6318-44e7-a2ac-d841857c1c24",
|
||||
"idName": "searchNewDevices",
|
||||
"name": "search devices"
|
||||
},
|
||||
{
|
||||
"id": "07a85e91-d064-4bce-b017-13fd0c320c0b",
|
||||
"idName": "checkForUpdates",
|
||||
"name": "check updates"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -85,6 +125,16 @@
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "uuid",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "api key",
|
||||
"type" : "QString",
|
||||
@ -108,6 +158,7 @@
|
||||
"id": "19bb8d10-1b28-4ba3-99b7-a634138dcfde",
|
||||
"idName": "hueReachable",
|
||||
"name": "reachable",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
@ -180,6 +231,193 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceClassId": "4fa568ef-7a3a-422b-b0c0-206d37cb4eed",
|
||||
"idName": "hueWhiteLight",
|
||||
"name": "Hue White Light",
|
||||
"createMethods": ["auto"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"name": "name",
|
||||
"type" : "QString",
|
||||
"inputType": "TextLine"
|
||||
},
|
||||
{
|
||||
"name": "bridge",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "model id",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "uuid",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "api key",
|
||||
"type" : "QString",
|
||||
"inputType": "TextLine",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "host address",
|
||||
"type" : "QString",
|
||||
"inputType": "IPv4Address",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "light id",
|
||||
"type" : "int",
|
||||
"readOnly": true
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "19bb8d10-1b28-4ba3-99b7-a634138dcfde",
|
||||
"idName": "hueReachable",
|
||||
"name": "reachable",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "90aaffe5-6a76-47d2-a14a-550f60390245",
|
||||
"idName": "huePower",
|
||||
"name": "power",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "90e91f64-a208-468c-a5a2-7f47e08859e2",
|
||||
"idName": "hueBrightness",
|
||||
"name": "brightness",
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0,
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"writable": true
|
||||
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "d25dcfbc-d28c-4905-80e3-300ffb1248f5",
|
||||
"idName": "hueAlert",
|
||||
"name": "flash",
|
||||
"paramTypes": [
|
||||
{
|
||||
"name": "alert",
|
||||
"type": "QString",
|
||||
"allowedValues": [
|
||||
"flash once",
|
||||
"flash 30 seconds"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceClassId": "bb482d39-67ef-46dc-88e9-7b181d642b28",
|
||||
"idName": "hueRemote",
|
||||
"name": "Hue Remote",
|
||||
"createMethods": ["auto"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"name": "name",
|
||||
"type" : "QString",
|
||||
"inputType": "TextLine"
|
||||
},
|
||||
{
|
||||
"name": "bridge",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "model id",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "uuid",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "api key",
|
||||
"type" : "QString",
|
||||
"inputType": "TextLine",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "host address",
|
||||
"type" : "QString",
|
||||
"inputType": "IPv4Address",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "sensor id",
|
||||
"type" : "int",
|
||||
"readOnly": true
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "19bb8d10-1b28-4ba3-99b7-a634138dcfde",
|
||||
"idName": "hueReachable",
|
||||
"name": "reachable",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "683e493a-9796-4d5e-b0e3-61cb178d5819",
|
||||
"idName": "battery",
|
||||
"name": "battery",
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0,
|
||||
"minValue": 0,
|
||||
"maxValue": 100
|
||||
}
|
||||
],
|
||||
"eventTypes": [
|
||||
{
|
||||
"id": "de769db0-4c31-46cf-9760-dbc6f9209c26",
|
||||
"idName": "onButton",
|
||||
"name": "on"
|
||||
},
|
||||
{
|
||||
"id": "8e3d6a62-6a19-4e9a-a25b-e1da2e56ede9",
|
||||
"idName": "brightnessUpButton",
|
||||
"name": "brightness up"
|
||||
},
|
||||
{
|
||||
"id": "efd8b972-9a37-43f2-b9bc-f9dfe144a96d",
|
||||
"idName": "brightnessDownButton",
|
||||
"name": "brightness down"
|
||||
},
|
||||
{
|
||||
"id": "7c2a58f1-137c-4bf3-8f9e-453dff020487",
|
||||
"idName": "offButton",
|
||||
"name": "off"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -20,14 +20,8 @@
|
||||
|
||||
#include "huebridge.h"
|
||||
|
||||
HueBridge::HueBridge(QString apiKey, QHostAddress hostAddress, QObject *parent) :
|
||||
HueBridge::HueBridge(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_apiKey(apiKey),
|
||||
m_hostAddress(hostAddress),
|
||||
m_name(QString()),
|
||||
m_macAddress(QString()),
|
||||
m_apiVersion(QString()),
|
||||
m_softwareVersion(QString()),
|
||||
m_zigbeeChannel(-1)
|
||||
{
|
||||
|
||||
@ -43,6 +37,16 @@ void HueBridge::setName(const QString &name)
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
QString HueBridge::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void HueBridge::setId(const QString &id)
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
QString HueBridge::apiKey() const
|
||||
{
|
||||
return m_apiKey;
|
||||
@ -112,3 +116,41 @@ void HueBridge::addLight(HueLight *light)
|
||||
{
|
||||
m_lights.append(light);
|
||||
}
|
||||
|
||||
QPair<QNetworkRequest, QByteArray> HueBridge::createDiscoverLightsRequest()
|
||||
{
|
||||
QNetworkRequest request(QUrl("http://" + hostAddress().toString() + "/api/" + apiKey() + "/lights/"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
return QPair<QNetworkRequest, QByteArray>(request, QByteArray());
|
||||
}
|
||||
|
||||
QPair<QNetworkRequest, QByteArray> HueBridge::createSearchLightsRequest()
|
||||
{
|
||||
QNetworkRequest request(QUrl("http://" + hostAddress().toString() + "/api/" + apiKey() + "/lights/"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
return QPair<QNetworkRequest, QByteArray>(request, QByteArray());
|
||||
}
|
||||
|
||||
QPair<QNetworkRequest, QByteArray> HueBridge::createSearchSensorsRequest()
|
||||
{
|
||||
QNetworkRequest request(QUrl("http://" + hostAddress().toString() + "/api/" + apiKey() + "/sensors/"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
return QPair<QNetworkRequest, QByteArray>(request, QByteArray());
|
||||
}
|
||||
|
||||
QPair<QNetworkRequest, QByteArray> HueBridge::createCheckUpdatesRequest()
|
||||
{
|
||||
QVariantMap updateMap;
|
||||
updateMap.insert("checkforupdate", true);
|
||||
|
||||
QVariantMap requestMap;
|
||||
requestMap.insert("swupdate", updateMap);
|
||||
requestMap.insert("portalservices", true);
|
||||
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(requestMap);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + hostAddress().toString() + "/api/" + apiKey() + "/config"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
return QPair<QNetworkRequest, QByteArray>(request, jsonDoc.toJson());
|
||||
}
|
||||
|
||||
@ -30,11 +30,14 @@ class HueBridge : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HueBridge(QString apiKey, QHostAddress hostAddress, QObject *parent = 0);
|
||||
explicit HueBridge(QObject *parent = 0);
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
|
||||
QString id() const;
|
||||
void setId(const QString &id);
|
||||
|
||||
QString apiKey() const;
|
||||
void setApiKey(const QString &apiKey);
|
||||
|
||||
@ -56,7 +59,13 @@ public:
|
||||
QList<HueLight *> lights() const;
|
||||
void addLight(HueLight *light);
|
||||
|
||||
QPair<QNetworkRequest, QByteArray> createDiscoverLightsRequest();
|
||||
QPair<QNetworkRequest, QByteArray> createSearchLightsRequest();
|
||||
QPair<QNetworkRequest, QByteArray> createSearchSensorsRequest();
|
||||
QPair<QNetworkRequest, QByteArray> createCheckUpdatesRequest();
|
||||
|
||||
private:
|
||||
QString m_id;
|
||||
QString m_apiKey;
|
||||
QHostAddress m_hostAddress;
|
||||
QString m_name;
|
||||
|
||||
108
plugins/deviceplugins/philipshue/huedevice.cpp
Normal file
108
plugins/deviceplugins/philipshue/huedevice.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
#include "huedevice.h"
|
||||
|
||||
HueDevice::HueDevice(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int HueDevice::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void HueDevice::setId(const int &id)
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
QString HueDevice::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void HueDevice::setName(const QString &name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
DeviceId HueDevice::bridgeId() const
|
||||
{
|
||||
return m_bridgeId;
|
||||
}
|
||||
|
||||
void HueDevice::setBridgeId(const DeviceId &bridgeId)
|
||||
{
|
||||
m_bridgeId = bridgeId;
|
||||
}
|
||||
|
||||
QHostAddress HueDevice::hostAddress() const
|
||||
{
|
||||
return m_hostAddress;
|
||||
}
|
||||
|
||||
void HueDevice::setHostAddress(const QHostAddress hostAddress)
|
||||
{
|
||||
m_hostAddress = hostAddress;
|
||||
}
|
||||
|
||||
QString HueDevice::uuid()
|
||||
{
|
||||
return m_uuid;
|
||||
}
|
||||
|
||||
void HueDevice::setUuid(const QString &uuid)
|
||||
{
|
||||
m_uuid = uuid;
|
||||
}
|
||||
|
||||
QString HueDevice::apiKey() const
|
||||
{
|
||||
return m_apiKey;
|
||||
}
|
||||
|
||||
void HueDevice::setApiKey(const QString &apiKey)
|
||||
{
|
||||
m_apiKey = apiKey;
|
||||
}
|
||||
|
||||
QString HueDevice::modelId() const
|
||||
{
|
||||
return m_modelId;
|
||||
}
|
||||
|
||||
void HueDevice::setModelId(const QString &modelId)
|
||||
{
|
||||
m_modelId = modelId;
|
||||
}
|
||||
|
||||
QString HueDevice::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void HueDevice::setType(const QString &type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
QString HueDevice::softwareVersion() const
|
||||
{
|
||||
return m_softwareVersion;
|
||||
}
|
||||
|
||||
void HueDevice::setSoftwareVersion(const QString &softwareVersion)
|
||||
{
|
||||
m_softwareVersion = softwareVersion;
|
||||
}
|
||||
|
||||
bool HueDevice::reachable() const
|
||||
{
|
||||
return m_reachable;
|
||||
}
|
||||
|
||||
void HueDevice::setReachable(const bool &reachable)
|
||||
{
|
||||
m_reachable = reachable;
|
||||
}
|
||||
|
||||
62
plugins/deviceplugins/philipshue/huedevice.h
Normal file
62
plugins/deviceplugins/philipshue/huedevice.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef HUEDEVICE_H
|
||||
#define HUEDEVICE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
#include <QHostAddress>
|
||||
#include <QNetworkRequest>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "typeutils.h"
|
||||
|
||||
class HueDevice : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HueDevice(QObject *parent = 0);
|
||||
|
||||
int id() const;
|
||||
void setId(const int &id);
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
|
||||
DeviceId bridgeId() const;
|
||||
void setBridgeId(const DeviceId &bridgeId);
|
||||
|
||||
QHostAddress hostAddress() const;
|
||||
void setHostAddress(const QHostAddress hostAddress);
|
||||
|
||||
QString uuid();
|
||||
void setUuid(const QString &uuid);
|
||||
|
||||
QString apiKey() const;
|
||||
void setApiKey(const QString &apiKey);
|
||||
|
||||
QString modelId() const;
|
||||
void setModelId(const QString &modelId);
|
||||
|
||||
QString type() const;
|
||||
void setType(const QString &type);
|
||||
|
||||
QString softwareVersion() const;
|
||||
void setSoftwareVersion(const QString &softwareVersion);
|
||||
|
||||
bool reachable() const;
|
||||
void setReachable(const bool &reachable);
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
QString m_name;
|
||||
QHostAddress m_hostAddress;
|
||||
QString m_apiKey;
|
||||
QString m_modelId;
|
||||
QString m_uuid;
|
||||
DeviceId m_bridgeId;
|
||||
QString m_type;
|
||||
QString m_softwareVersion;
|
||||
|
||||
bool m_reachable;
|
||||
};
|
||||
|
||||
#endif // HUEDEVICE_H
|
||||
@ -22,97 +22,11 @@
|
||||
#include "huelight.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
HueLight::HueLight(const int &lightId, const QHostAddress &hostAddress, const QString &name, const QString &apiKey, const QString &modelId, const DeviceId &bridgeId, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_lightId(lightId),
|
||||
m_hostAddress(hostAddress),
|
||||
m_name(name),
|
||||
m_apiKey(apiKey),
|
||||
m_modelId(modelId),
|
||||
m_bridgeId(bridgeId)
|
||||
HueLight::HueLight(QObject *parent) :
|
||||
HueDevice(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int HueLight::lightId() const
|
||||
{
|
||||
return m_lightId;
|
||||
}
|
||||
|
||||
void HueLight::setLightId(const int &lightId)
|
||||
{
|
||||
m_lightId = lightId;
|
||||
}
|
||||
|
||||
DeviceId HueLight::bridgeId() const
|
||||
{
|
||||
return m_bridgeId;
|
||||
}
|
||||
|
||||
void HueLight::setBridgeId(const DeviceId &bridgeDeviceId)
|
||||
{
|
||||
m_bridgeId = bridgeDeviceId;
|
||||
}
|
||||
|
||||
QHostAddress HueLight::hostAddress() const
|
||||
{
|
||||
return m_hostAddress;
|
||||
}
|
||||
|
||||
void HueLight::setHostAddress(const QHostAddress hostAddress)
|
||||
{
|
||||
m_hostAddress = hostAddress;
|
||||
}
|
||||
|
||||
QString HueLight::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void HueLight::setName(const QString &name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
QString HueLight::apiKey() const
|
||||
{
|
||||
return m_apiKey;
|
||||
}
|
||||
|
||||
void HueLight::setApiKey(const QString &apiKey)
|
||||
{
|
||||
m_apiKey = apiKey;
|
||||
}
|
||||
|
||||
QString HueLight::modelId() const
|
||||
{
|
||||
return m_modelId;
|
||||
}
|
||||
|
||||
void HueLight::setModelId(const QString &modelId)
|
||||
{
|
||||
m_modelId = modelId;
|
||||
}
|
||||
|
||||
QString HueLight::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void HueLight::setType(const QString &type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
QString HueLight::softwareVersion() const
|
||||
{
|
||||
return m_softwareVersion;
|
||||
}
|
||||
|
||||
void HueLight::setSoftwareVersion(const QString &softwareVersion)
|
||||
{
|
||||
m_softwareVersion = softwareVersion;
|
||||
}
|
||||
|
||||
bool HueLight::power() const
|
||||
{
|
||||
return m_power;
|
||||
@ -123,16 +37,6 @@ void HueLight::setPower(const bool &power)
|
||||
m_power = power;
|
||||
}
|
||||
|
||||
bool HueLight::reachable() const
|
||||
{
|
||||
return m_reachable;
|
||||
}
|
||||
|
||||
void HueLight::setReachable(const bool &reachable)
|
||||
{
|
||||
m_reachable = reachable;
|
||||
}
|
||||
|
||||
quint8 HueLight::brightness() const
|
||||
{
|
||||
return m_brightness;
|
||||
@ -244,7 +148,8 @@ void HueLight::updateStates(const QVariantMap &statesMap)
|
||||
setReachable(statesMap.value("reachable").toBool());
|
||||
setSat(statesMap.value("sat").toInt());
|
||||
setHue(statesMap.value("hue").toInt());
|
||||
setXy(QPointF(statesMap.value("xy").toList().first().toFloat(),statesMap.value("xy").toList().last().toFloat()));
|
||||
if (!statesMap.value("xy").toList().isEmpty())
|
||||
setXy(QPointF(statesMap.value("xy").toList().first().toFloat(), statesMap.value("xy").toList().last().toFloat()));
|
||||
|
||||
emit stateChanged();
|
||||
}
|
||||
@ -255,38 +160,38 @@ void HueLight::processActionResponse(const QVariantList &responseList)
|
||||
QVariantMap result = resultVariant.toMap();
|
||||
if (result.contains("success")) {
|
||||
QVariantMap successMap = result.value("success").toMap();
|
||||
if (successMap.contains("/lights/" + QString::number(m_lightId) + "/state/on")) {
|
||||
m_power = successMap.value("/lights/" + QString::number(m_lightId) + "/state/on").toBool();
|
||||
if (successMap.contains("/lights/" + QString::number(id()) + "/state/on")) {
|
||||
m_power = successMap.value("/lights/" + QString::number(id()) + "/state/on").toBool();
|
||||
}
|
||||
if (successMap.contains("/lights/" + QString::number(m_lightId) + "/state/hue")) {
|
||||
m_hue = successMap.value("/lights/" + QString::number(m_lightId) + "/state/hue").toInt();
|
||||
if (successMap.contains("/lights/" + QString::number(id()) + "/state/hue")) {
|
||||
m_hue = successMap.value("/lights/" + QString::number(id()) + "/state/hue").toInt();
|
||||
m_colorMode = ColorModeHS;
|
||||
}
|
||||
if (successMap.contains("/lights/" + QString::number(m_lightId) + "/state/bri")) {
|
||||
m_brightness = successMap.value("/lights/" + QString::number(m_lightId) + "/state/bri").toInt();
|
||||
if (successMap.contains("/lights/" + QString::number(id()) + "/state/bri")) {
|
||||
m_brightness = successMap.value("/lights/" + QString::number(id()) + "/state/bri").toInt();
|
||||
}
|
||||
if (successMap.contains("/lights/" + QString::number(m_lightId) + "/state/sat")) {
|
||||
m_sat = successMap.value("/lights/" + QString::number(m_lightId) + "/state/sat").toInt();
|
||||
if (successMap.contains("/lights/" + QString::number(id()) + "/state/sat")) {
|
||||
m_sat = successMap.value("/lights/" + QString::number(id()) + "/state/sat").toInt();
|
||||
m_colorMode = ColorModeHS;
|
||||
}
|
||||
if (successMap.contains("/lights/" + QString::number(m_lightId) + "/state/xy")) {
|
||||
m_xy = successMap.value("/lights/" + QString::number(m_lightId) + "/state/xy").toPoint();
|
||||
if (successMap.contains("/lights/" + QString::number(id()) + "/state/xy")) {
|
||||
m_xy = successMap.value("/lights/" + QString::number(id()) + "/state/xy").toPoint();
|
||||
m_colorMode = ColorModeXY;
|
||||
}
|
||||
if (successMap.contains("/lights/" + QString::number(m_lightId) + "/state/ct")) {
|
||||
m_ct = successMap.value("/lights/" + QString::number(m_lightId) + "/state/ct").toInt();
|
||||
if (successMap.contains("/lights/" + QString::number(id()) + "/state/ct")) {
|
||||
m_ct = successMap.value("/lights/" + QString::number(id()) + "/state/ct").toInt();
|
||||
m_colorMode = ColorModeCT;
|
||||
}
|
||||
if (successMap.contains("/lights/" + QString::number(m_lightId) + "/state/effect")) {
|
||||
QString effect = successMap.value("/lights/" + QString::number(m_lightId) + "/state/effect").toString();
|
||||
if (successMap.contains("/lights/" + QString::number(id()) + "/state/effect")) {
|
||||
QString effect = successMap.value("/lights/" + QString::number(id()) + "/state/effect").toString();
|
||||
if (effect == "none") {
|
||||
setEffect("none");
|
||||
} else if (effect == "colorloop") {
|
||||
setEffect("color loop");
|
||||
}
|
||||
}
|
||||
if (successMap.contains("/lights/" + QString::number(m_lightId) + "/state/alert")) {
|
||||
m_alert = successMap.value("/lights/" + QString::number(m_lightId) + "/state/alert").toString();
|
||||
if (successMap.contains("/lights/" + QString::number(id()) + "/state/alert")) {
|
||||
m_alert = successMap.value("/lights/" + QString::number(id()) + "/state/alert").toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -302,8 +207,8 @@ QPair<QNetworkRequest, QByteArray> HueLight::createSetPowerRequest(const bool &p
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(requestMap);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + hostAddress().toString() + "/api/" + apiKey() +
|
||||
"/lights/" + QString::number(lightId()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
"/lights/" + QString::number(id()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
return QPair<QNetworkRequest, QByteArray>(request, jsonDoc.toJson());
|
||||
}
|
||||
|
||||
@ -317,8 +222,8 @@ QPair<QNetworkRequest, QByteArray> HueLight::createSetColorRequest(const QColor
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(requestMap);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + hostAddress().toString() + "/api/" + apiKey() +
|
||||
"/lights/" + QString::number(lightId()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
"/lights/" + QString::number(id()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
return QPair<QNetworkRequest, QByteArray>(request, jsonDoc.toJson());
|
||||
}
|
||||
|
||||
@ -335,8 +240,8 @@ QPair<QNetworkRequest, QByteArray> HueLight::createSetBrightnessRequest(const in
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(requestMap);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + hostAddress().toString() + "/api/" + apiKey() +
|
||||
"/lights/" + QString::number(lightId()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
"/lights/" + QString::number(id()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
return QPair<QNetworkRequest, QByteArray>(request, jsonDoc.toJson());
|
||||
}
|
||||
|
||||
@ -352,8 +257,8 @@ QPair<QNetworkRequest, QByteArray> HueLight::createSetEffectRequest(const QStrin
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(requestMap);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + hostAddress().toString() + "/api/" + apiKey() +
|
||||
"/lights/" + QString::number(lightId()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
"/lights/" + QString::number(id()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
return QPair<QNetworkRequest, QByteArray>(request, jsonDoc.toJson());
|
||||
}
|
||||
|
||||
@ -366,8 +271,8 @@ QPair<QNetworkRequest, QByteArray> HueLight::createSetTemperatureRequest(const i
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(requestMap);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + hostAddress().toString() + "/api/" + apiKey() +
|
||||
"/lights/" + QString::number(lightId()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
"/lights/" + QString::number(id()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
return QPair<QNetworkRequest, QByteArray>(request, jsonDoc.toJson());
|
||||
}
|
||||
|
||||
@ -382,7 +287,7 @@ QPair<QNetworkRequest, QByteArray> HueLight::createFlashRequest(const QString &a
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(requestMap);
|
||||
|
||||
QNetworkRequest request(QUrl("http://" + hostAddress().toString() + "/api/" + apiKey() +
|
||||
"/lights/" + QString::number(lightId()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
"/lights/" + QString::number(id()) + "/state"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
return QPair<QNetworkRequest, QByteArray>(request, jsonDoc.toJson());
|
||||
}
|
||||
|
||||
@ -31,9 +31,9 @@
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "typeutils.h"
|
||||
#include "types/action.h"
|
||||
#include "huedevice.h"
|
||||
|
||||
class HueLight : public QObject
|
||||
class HueLight : public HueDevice
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -44,38 +44,11 @@ public:
|
||||
ColorModeCT
|
||||
};
|
||||
|
||||
explicit HueLight(const int &lightId, const QHostAddress &hostAddress, const QString &name, const QString &apiKey, const QString &modelId, const DeviceId &bridgeId, QObject *parent = 0);
|
||||
|
||||
int lightId() const;
|
||||
void setLightId(const int &lightId);
|
||||
|
||||
DeviceId bridgeId() const;
|
||||
void setBridgeId(const DeviceId &bridgeDeviceId);
|
||||
|
||||
QHostAddress hostAddress() const;
|
||||
void setHostAddress(const QHostAddress hostAddress);
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
|
||||
QString apiKey() const;
|
||||
void setApiKey(const QString &apiKey);
|
||||
|
||||
QString modelId() const;
|
||||
void setModelId(const QString &modelId);
|
||||
|
||||
QString type() const;
|
||||
void setType(const QString &type);
|
||||
|
||||
QString softwareVersion() const;
|
||||
void setSoftwareVersion(const QString &softwareVersion);
|
||||
explicit HueLight(QObject *parent = 0);
|
||||
|
||||
bool power() const;
|
||||
void setPower(const bool &power);
|
||||
|
||||
bool reachable() const;
|
||||
void setReachable(const bool &reachable);
|
||||
|
||||
quint8 brightness() const;
|
||||
void setBrigtness(const quint8 brightness);
|
||||
|
||||
@ -115,17 +88,7 @@ public:
|
||||
QPair<QNetworkRequest, QByteArray> createFlashRequest(const QString &alert);
|
||||
|
||||
private:
|
||||
int m_lightId;
|
||||
QHostAddress m_hostAddress;
|
||||
QString m_name;
|
||||
QString m_apiKey;
|
||||
QString m_modelId;
|
||||
DeviceId m_bridgeId;
|
||||
QString m_type;
|
||||
QString m_softwareVersion;
|
||||
|
||||
bool m_power;
|
||||
bool m_reachable;
|
||||
|
||||
quint8 m_brightness;
|
||||
quint16 m_hue;
|
||||
|
||||
43
plugins/deviceplugins/philipshue/hueremote.cpp
Normal file
43
plugins/deviceplugins/philipshue/hueremote.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "hueremote.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
HueRemote::HueRemote(QObject *parent) :
|
||||
HueDevice(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int HueRemote::battery() const
|
||||
{
|
||||
return m_battery;
|
||||
}
|
||||
|
||||
void HueRemote::setBattery(const int &battery)
|
||||
{
|
||||
m_battery = battery;
|
||||
}
|
||||
|
||||
void HueRemote::updateStates(const QVariantMap &statesMap)
|
||||
{
|
||||
qCDebug(dcPhilipsHue) << statesMap;
|
||||
}
|
||||
|
||||
56
plugins/deviceplugins/philipshue/hueremote.h
Normal file
56
plugins/deviceplugins/philipshue/hueremote.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef HUEREMOTE_H
|
||||
#define HUEREMOTE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
#include <QHostAddress>
|
||||
#include <QNetworkRequest>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "typeutils.h"
|
||||
#include "huedevice.h"
|
||||
|
||||
class HueRemote : public HueDevice
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HueRemote(QObject *parent = 0);
|
||||
|
||||
int battery() const;
|
||||
void setBattery(const int &battery);
|
||||
|
||||
void updateStates(const QVariantMap &statesMap);
|
||||
|
||||
private:
|
||||
int m_battery;
|
||||
|
||||
signals:
|
||||
void onPressed();
|
||||
void brightnessUpPressed();
|
||||
void brightnessDownPressed();
|
||||
void offPressed();
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // HUEREMOTE_H
|
||||
@ -10,7 +10,9 @@ SOURCES += \
|
||||
#light.cpp \
|
||||
huebridge.cpp \
|
||||
huelight.cpp \
|
||||
pairinginfo.cpp
|
||||
pairinginfo.cpp \
|
||||
hueremote.cpp \
|
||||
huedevice.cpp
|
||||
|
||||
HEADERS += \
|
||||
devicepluginphilipshue.h \
|
||||
@ -19,7 +21,9 @@ HEADERS += \
|
||||
#lightinterface.h \
|
||||
huebridge.h \
|
||||
huelight.h \
|
||||
pairinginfo.h
|
||||
pairinginfo.h \
|
||||
hueremote.h \
|
||||
huedevice.h
|
||||
|
||||
|
||||
|
||||
|
||||
@ -607,7 +607,10 @@ void DeviceHandler::devicesDiscovered(const DeviceClassId &deviceClassId, const
|
||||
return; // We didn't start this discovery... Ignore it.
|
||||
}
|
||||
|
||||
JsonReply *reply = m_discoverRequests.take(deviceClassId);
|
||||
JsonReply *reply = 0;
|
||||
reply = m_discoverRequests.take(deviceClassId);
|
||||
if (!reply)
|
||||
return;
|
||||
|
||||
QVariantMap returns;
|
||||
returns.insert("deviceDescriptors", JsonTypes::packDeviceDescriptors(deviceDescriptors));
|
||||
|
||||
Reference in New Issue
Block a user