continued refacturing

This commit is contained in:
nymea 2019-08-15 10:09:46 +02:00
parent 15e2dff018
commit e5e1adb64e
6 changed files with 245 additions and 256 deletions

View File

@ -138,6 +138,13 @@ void BridgeConnection::discoverBridgeDevices()
//m_bridgeSensorsDiscoveryRequests.insert(reply, device);
}
void BridgeConnection::checkForUpdates()
{
QPair<QNetworkRequest, QByteArray> request = m_bridge->createCheckUpdatesRequest();
QNetworkReply *reply = m_hardwareManager->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
}
void BridgeConnection::searchNewDevices(const QString &serialNumber)
{
qCDebug(dcPhilipsHue) << "Discover bridge devices" << m_bridge->hostAddress();
@ -148,7 +155,7 @@ void BridgeConnection::searchNewDevices(const QString &serialNumber)
//m_bridgeSearchDevicesRequests.insert(reply, device);
}
void BridgeConnection::setPower(const QString &uuid, bool power)
QUuid BridgeConnection::setPower(const QString &uuid, bool power)
{
HueLight *light = m_lights.value(uuid);
QPair<QNetworkRequest, QByteArray> request = light->createSetPowerRequest(power);
@ -156,7 +163,7 @@ void BridgeConnection::setPower(const QString &uuid, bool power)
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
}
void BridgeConnection::setBrightness(const QString &uuid, quint8 percent)
QUuid BridgeConnection::setBrightness(const QString &uuid, quint8 percent)
{
HueLight *light = m_lights.value(uuid);
QPair<QNetworkRequest, QByteArray> request = light->createSetBrightnessRequest(percent);
@ -164,7 +171,7 @@ void BridgeConnection::setBrightness(const QString &uuid, quint8 percent)
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
}
void BridgeConnection::setColor(const QString &uuid, QColor color)
QUuid BridgeConnection::setColor(const QString &uuid, QColor color)
{
HueLight *light = m_lights.value(uuid);
QPair<QNetworkRequest, QByteArray> request = light->createSetColorRequest(color);
@ -172,7 +179,7 @@ void BridgeConnection::setColor(const QString &uuid, QColor color)
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
}
void BridgeConnection::setEffect(const QString &uuid, const QString &effect)
QUuid BridgeConnection::setEffect(const QString &uuid, const QString &effect)
{
HueLight *light = m_lights.value(uuid);
QPair<QNetworkRequest, QByteArray> request = light->createSetEffectRequest(effect);
@ -198,9 +205,9 @@ void BridgeConnection::setFlash(const QString &uuid, const QString &mode)
void BridgeConnection::setLightName(const QString &uuid, const QString &name)
QUuid BridgeConnection::setLightName(const QString &deviceUuid, const QString &name)
{
HueLight *light = m_lights.value(uuid);
HueLight *light = m_lights.value(deviceUuid);
QVariantMap requestMap;
requestMap.insert("name", name);
@ -212,15 +219,16 @@ void BridgeConnection::setLightName(const QString &uuid, const QString &name)
QNetworkReply *reply = m_hardwareManager->networkManager()->put(request,jsonDoc.toJson());
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
//m_setNameRequests.insert(reply, device);
QUuid actionUuid = scheduleActionRequest(request); // needs request, device uuid, request type
return actionUuid;
}
void BridgeConnection::setRemoteName(const QString &uuid, const QString &name)
{
HueRemote *remote = m_remotes.balue(uuid);
HueRemote *remote = m_remotes.value(uuid);
QVariantMap requestMap;
requestMap.insert("name", device->name());
requestMap.insert("name", name);
QJsonDocument jsonDoc = QJsonDocument::fromVariant(requestMap);
QNetworkRequest request(QUrl("http://" + remote->hostAddress().toString() + "/api/" + remote->apiKey() +
@ -229,10 +237,16 @@ void BridgeConnection::setRemoteName(const QString &uuid, const QString &name)
QNetworkReply *reply = m_hardwareManager->networkManager()->put(request,jsonDoc.toJson());
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
//m_setNameRequests.insert(reply, device);
if (!m_setNameRequests) {
m_setNameRequests = reply;
} else {
m_setNameRequests->abort();
m_setNameRequests->deleteLater();
m_setNameRequests = reply;
}
}
void BridgeConnection::processLightRefreshResponse(QString uuid, const QByteArray &data)
void BridgeConnection::processLightRefreshResponse(const QByteArray &data)
{
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
@ -429,46 +443,11 @@ void BridgeConnection::processBridgeLightDiscoveryResponse(const QByteArray &dat
QString uuid = lightMap.value("uniqueid").toString();
QString model = lightMap.value("modelid").toString();
if (lightAlreadyAdded(uuid))
continue;
HueLight *light = new HueLight();
light->modelId(model)
if (lightMap.value("type").toString() == "Dimmable light") {
DeviceDescriptor descriptor(dimmableLightDeviceClassId, lightMap.value("name").toString(), "Philips Hue White Light", device->id());
ParamList params;
params.append(Param(dimmableLightDeviceModelIdParamTypeId, model));
params.append(Param(dimmableLightDeviceTypeParamTypeId, lightMap.value("type").toString()));
params.append(Param(dimmableLightDeviceUuidParamTypeId, uuid));
params.append(Param(dimmableLightDeviceLightIdParamTypeId, lightId));
descriptor.setParams(params);
dimmableLightDescriptors.append(descriptor);
qCDebug(dcPhilipsHue) << "Found new dimmable light" << lightMap.value("name").toString() << model;
} else if (lightMap.value("type").toString() == "Color temperature light") {
DeviceDescriptor descriptor(colorTemperatureLightDeviceClassId, lightMap.value("name").toString(), "Philips Hue Color Temperature Light", device->id());
ParamList params;
params.append(Param(colorTemperatureLightDeviceModelIdParamTypeId, model));
params.append(Param(colorTemperatureLightDeviceTypeParamTypeId, lightMap.value("type").toString()));
params.append(Param(colorTemperatureLightDeviceUuidParamTypeId, uuid));
params.append(Param(colorTemperatureLightDeviceLightIdParamTypeId, lightId));
descriptor.setParams(params);
colorTemperatureLightDescriptors.append(descriptor);
qCDebug(dcPhilipsHue) << "Found new color temperature light" << lightMap.value("name").toString() << model;
} else {
DeviceDescriptor descriptor(colorLightDeviceClassId, lightMap.value("name").toString(), "Philips Hue Color Light", device->id());
ParamList params;
params.append(Param(colorLightDeviceModelIdParamTypeId, model));
params.append(Param(colorLightDeviceTypeParamTypeId, lightMap.value("type").toString()));
params.append(Param(colorLightDeviceUuidParamTypeId, uuid));
params.append(Param(colorLightDeviceLightIdParamTypeId, lightId));
descriptor.setParams(params);
colorLightDescriptors.append(descriptor);
qCDebug(dcPhilipsHue) << "Found new color light" << lightMap.value("name").toString() << model;
}
light->setModelId(model);
light->setType(lightMap.value("type").toString());
light->setUuid(uuid);
//light->setId(lightId);
}
if (!lights.isEmpty())
@ -597,11 +576,11 @@ void BridgeConnection::processBridgeSensorDiscoveryResponse(const QByteArray &da
}
if (!remotes.isEmpty()) {
emit remotesDiscovered(remotes);
emit remoteDiscovered(remotes);
}
if (!motionSensors.isEmpty()) {
emit motionSensorsDiscovered(motionSensors);
emit motionSensorDiscovered(motionSensors);
}
}
@ -655,12 +634,12 @@ void BridgeConnection::processInformationResponse(PairingInfo *pairingInfo, cons
{
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
pairingInfo->deleteLater();
// check JSON error
if (error.error != QJsonParseError::NoError) {
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
emit pairingFinished(pairingInfo->pairingTransactionId(), Device::DeviceSetupStatusFailure);
pairingInfo->deleteLater();
emit pairingFinished(false);
return;
}
@ -669,29 +648,13 @@ void BridgeConnection::processInformationResponse(PairingInfo *pairingInfo, cons
// check response error
if (response.contains("error")) {
qCWarning(dcPhilipsHue) << "Failed to get information from Hue Bridge:" << response.value("error").toMap().value("description").toString();
emit pairingFinished(pairingInfo->pairingTransactionId(), Device::DeviceSetupStatusFailure);
pairingInfo->deleteLater();
emit pairingFinished(false);
return;
}
// create Bridge
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);
emit pairingFinished(pairingInfo->pairingTransactionId(), Device::DeviceSetupStatusSuccess);
pairingInfo->deleteLater();
emit pairingFinished(true);
}
void BridgeConnection::processActionResponse(Device *device, const ActionId actionId, const QByteArray &data)
void BridgeConnection::processActionResponse(const QUuid actionUuid, const QByteArray &data)
{
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
@ -699,7 +662,7 @@ void BridgeConnection::processActionResponse(Device *device, const ActionId acti
// check JSON error
if (error.error != QJsonParseError::NoError) {
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
emit actionExecutionFinished(actionId, Device::DeviceErrorHardwareFailure);
emit actionFailed(actionUuid, error.errorString());
return;
}
@ -707,17 +670,14 @@ void BridgeConnection::processActionResponse(Device *device, const ActionId acti
if (data.contains("error")) {
if (!jsonDoc.toVariant().toList().isEmpty()) {
qCWarning(dcPhilipsHue) << "Failed to execute Hue action:" << jsonDoc.toJson(); //jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
emit actionFailed(actionUuid, "Failed to execute Hue action:");
} else {
qCWarning(dcPhilipsHue) << "Failed to execute Hue action: Invalid error message format";
emit actionFailed(actionUuid, "Invalid error message format");
}
emit actionExecutionFinished(actionId, Device::DeviceErrorHardwareFailure);
return;
}
if (device->deviceClassId() != bridgeDeviceClassId)
m_lights.key(device)->processActionResponse(jsonDoc.toVariant().toList());
emit actionExecutionFinished(actionId, Device::DeviceErrorNoError);
emit actionExecuted(actionUuid);
}
void BridgeConnection::networkManagerReplyReady()
@ -822,17 +782,17 @@ void BridgeConnection::networkManagerReplyReady()
}
processSensorsRefreshResponse(reply->readAll());
} else if (m_asyncActions.contains(reply)) {
QPair<Device *, ActionId> actionInfo = m_asyncActions.take(reply);
} else if (m_actionRequests.contains(reply)) {
QUuid actionUuid = m_actionRequests.take(reply);
// check HTTP status code
if (status != 200 || reply->error() != QNetworkReply::NoError) {
qCWarning(dcPhilipsHue) << "Execute Hue Light action request error:" << status << reply->errorString();
bridgeReachableChanged(false);
//emit actionExecutionFinished(actionInfo.second, Device::DeviceErrorHardwareNotAvailable);
emit actionFailed(actionUuid, reply->errorString());
return;
}
processActionResponse(actionInfo.second, reply->readAll());
processActionResponse(actionUuid, reply->readAll());
} else if (reply == m_setNameRequests) {
@ -859,6 +819,14 @@ int BridgeConnection::percentageToBrightness(int percentage)
return qRound((255.0 * percentage) / 100.0);
}
QUuid BridgeConnection::scheduleActionRequest(QNetworkRequest *request)
{
QUuid actionUuid;
request->url();
m_actionRequests.insert(request);
return actionUuid;
}
void BridgeConnection::abortRequests(QHash<QNetworkReply *, Device *> requestList, Device *device)
{
foreach (QNetworkReply* reply, requestList.keys()) {

View File

@ -52,34 +52,34 @@ public:
void discoverBridgeDevices();
void searchNewDevices(const QString &serialNumber);
//light actions
void setPower(const QString &uuid, bool power);
void setBrightness(const QString &uuid, quint8 percent);
void setColor(const QString &uuid, QColor percent);
void setEffect(const QString &uuid, const QString &effect);
void setFlash(const QString &uuid, const QString &flashMode);
void setTemperature(const QString &uuid, quint16 temperature);
//light action - the uuid is to track if the actions has been executed
QUuid setPower(const QString &uuid, bool power);
QUuid setBrightness(const QString &uuid, quint8 percent);
QUuid setColor(const QString &uuid, QColor percent);
QUuid setEffect(const QString &uuid, const QString &effect);
QUuid setFlash(const QString &uuid, const QString &flashMode);
QUuid setTemperature(const QString &uuid, quint16 temperature);
void setLightName(const QString &uuid, const QString &name);
void setRemoteName(const QString &uuid, const QString &name);
QUuid setLightName(const QString &uuid, const QString &name);
QUuid setRemoteName(const QString &uuid, const QString &name);
private slots:
void lightStateChanged();
void remoteStateChanged();
void onRemoteButtonEvent(int buttonCode);
// Motion sensor
void refreshLight(const QString &uuid); //
void refreshBridge();
void refreshLights();
void refreshSensors();
signals:
//Devices discovered
void pairingFinished(bool successful);
//Devices discovered
void lightDiscovered(QHash<QString, HueLight *>);
void remoteDiscovered(QHash<QString, HueRemote *>);
void motionSensorDiscovered(QHash<QString, HueMotionSensor *>);
// Light Device Events
void lightStateChanged();
void remoteStateChanged();
void onRemoteButtonEvent(int buttonCode);
void motionSensorReachableChanged(bool reachable);
void motionSensorBatteryLevelChanged(int batteryLevel);
@ -90,6 +90,9 @@ signals:
void networkManagerReplyReady();
void onDeviceNameChanged();
void actionExecuted(QUuid actionUuid);
void actionFailed(const QUuid &uuid, const QString &error);
private:
HardwareManager *m_hardwareManager = nullptr;
@ -100,6 +103,8 @@ private:
QHash<QNetworkReply *, PairingInfo *> m_pairingRequests;
QHash<QNetworkReply *, PairingInfo *> m_informationRequests;
QHash<QNetworkReply *, QUuid> m_actionRequests;
QNetworkReply *m_lightRefreshRequests;
QNetworkReply *m_setNameRequests;
QNetworkReply *m_bridgeRefreshRequests;
@ -109,18 +114,11 @@ private:
QNetworkReply *m_bridgeSensorsDiscoveryRequests;
QNetworkReply *m_bridgeSearchDevicesRequests;
QHash<QNetworkReply *, QPair<Device *, ActionId> > m_asyncActions;
HueBridge *m_bridge;
QHash<QString, HueLight *> m_lights;
QHash<QString, HueRemote *> m_remotes;
QHash<QString, HueMotionSensor *> m_motionSensors;
void refreshLight(const QString &uuid); //
void refreshBridge();
void refreshLights();
void refreshSensors();
void processBridgeLightDiscoveryResponse(const QByteArray &data);
void processBridgeSensorDiscoveryResponse(const QByteArray &data);
void processLightRefreshResponse(const QByteArray &data);
@ -130,17 +128,17 @@ private:
void processSetNameResponse(const QByteArray &data);
void processPairingResponse(PairingInfo *pairingInfo, const QByteArray &data);
void processInformationResponse(PairingInfo *pairingInfo, const QByteArray &data);
void processActionResponse(const ActionId actionId, const QByteArray &data);
void processActionResponse(const QUuid actionUuid, const QByteArray &data);
void bridgeReachableChanged(const bool &reachable);
bool lightAlreadyAdded(const QString &uuid);
bool sensorAlreadyAdded(const QString &uuid);
//bool lightAlreadyAdded(const QString &uuid);
//bool sensorAlreadyAdded(const QString &uuid);
int brightnessToPercentage(int brightness);
int percentageToBrightness(int percentage);
void abortRequests(QHash<QNetworkReply *, Device *> requestList);
QUuid scheduleActionRequest(QNetworkRequest *request);
};
#endif // BRIDGECONNECTION_H

View File

@ -39,7 +39,6 @@
DevicePluginPhilipsHue::DevicePluginPhilipsHue()
{
}
Device::DeviceError DevicePluginPhilipsHue::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
@ -137,7 +136,7 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
// hue bridge
if (device->deviceClassId() == bridgeDeviceClassId) {
// unconfigured bridges (from pairing)
foreach (HueBridge *b, m_unconfiguredBridges) {
/*foreach (HueBridge *b, m_unconfiguredBridges) {
if (b->hostAddress().toString() == device->paramValue(bridgeDeviceHostParamTypeId).toString()) {
m_unconfiguredBridges.removeAll(b);
qCDebug(dcPhilipsHue) << "Setup unconfigured Hue Bridge" << b->name();
@ -147,15 +146,14 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
device->setParamValue(bridgeDeviceMacParamTypeId, b->macAddress());
m_bridgeConnections.insert(device->id(), );
device->setStateValue(bridgeConnectedStateTypeId, true);
discoverBridgeDevices(b);
//discoverBridgeDevices();
return Device::DeviceSetupStatusSuccess;
}
}
}*/
// Loaded bridge
qCDebug(dcPhilipsHue) << "Setup Hue Bridge" << device->params();
HueBridge *bridge = new HueBridge(this);
bridge->setId(device->paramValue(bridgeDeviceIdParamTypeId).toString());
bridge->setApiKey(device->paramValue(bridgeDeviceApiKeyParamTypeId).toString());
@ -173,21 +171,11 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
// Hue color light
if (device->deviceClassId() == colorLightDeviceClassId) {
qCDebug(dcPhilipsHue) << "Setup Hue color light" << device->params();
BridgeConnection *bridge = m_bridgeConnections.value(device->parentId());
if (!bridge)
return Device::DeviceSetupStatusFailure;
BridgeConnection *bridge = m_bridgeConnections;
HueLight *hueLight = new HueLight(this);
hueLight->setHostAddress(bridge->hostAddress());
hueLight->setApiKey(bridge->apiKey());
hueLight->setId(device->paramValue(colorLightDeviceLightIdParamTypeId).toInt());
hueLight->setModelId(device->paramValue(colorLightDeviceModelIdParamTypeId).toString());
hueLight->setUuid(device->paramValue(colorLightDeviceUuidParamTypeId).toString());
hueLight->setType(device->paramValue(colorLightDeviceTypeParamTypeId).toString());
connect(hueLight, &HueLight::stateChanged, this, &DevicePluginPhilipsHue::lightStateChanged);
m_lights.insert(hueLight, device);
refreshLight(device);
bridge->refreshLight(device->paramValue(colorLightDeviceUuidParamTypeId).toString());
return Device::DeviceSetupStatusSuccess;
}
@ -195,20 +183,11 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
if (device->deviceClassId() == colorTemperatureLightDeviceClassId) {
qCDebug(dcPhilipsHue) << "Setup Hue color temperature light" << device->params();
HueBridge *bridge = m_bridges.key(myDevices().findById(device->parentId()));
HueLight *hueLight = new HueLight(this);
hueLight->setHostAddress(bridge->hostAddress());
hueLight->setApiKey(bridge->apiKey());
hueLight->setId(device->paramValue(colorTemperatureLightDeviceLightIdParamTypeId).toInt());
hueLight->setModelId(device->paramValue(colorTemperatureLightDeviceModelIdParamTypeId).toString());
hueLight->setUuid(device->paramValue(colorTemperatureLightDeviceUuidParamTypeId).toString());
hueLight->setType(device->paramValue(colorTemperatureLightDeviceTypeParamTypeId).toString());
connect(hueLight, &HueLight::stateChanged, this, &DevicePluginPhilipsHue::lightStateChanged);
m_lights.insert(hueLight, device);
refreshLight(device);
BridgeConnection *bridge = m_bridgeConnections.value(device->parentId());
if (!bridge)
return Device::DeviceSetupStatusFailure;
bridge->refreshLight(device->paramValue(colorTemperatureLightDeviceUuidParamTypeId).toString());
return Device::DeviceSetupStatusSuccess;
}
@ -216,11 +195,6 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
if (device->deviceClassId() == dimmableLightDeviceClassId) {
qCDebug(dcPhilipsHue) << "Setup Hue white light" << device->params();
HueBridge *bridge = m_bridges.key(myDevices().findById(device->parentId()));
HueLight *hueLight = new HueLight(this);
hueLight->setHostAddress(bridge->hostAddress());
hueLight->setApiKey(bridge->apiKey());
// Migrate device parameters after changing param type UUIDs in 0.14.
QMap<QString, ParamTypeId> migrationMap;
migrationMap.insert("095a463b-f59e-46b1-989a-a71f9cbe3e30", dimmableLightDeviceModelIdParamTypeId);
@ -245,16 +219,11 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
device->setParams(migratedParams);
// Migration done
hueLight->setModelId(device->paramValue(dimmableLightDeviceModelIdParamTypeId).toString());
hueLight->setType(device->paramValue(dimmableLightDeviceTypeParamTypeId).toString());
hueLight->setUuid(device->paramValue(dimmableLightDeviceUuidParamTypeId).toString());
hueLight->setId(device->paramValue(dimmableLightDeviceLightIdParamTypeId).toInt());
connect(hueLight, &HueLight::stateChanged, this, &DevicePluginPhilipsHue::lightStateChanged);
m_lights.insert(hueLight, device);
refreshLight(device);
BridgeConnection *bridge = m_bridgeConnections.value(device->parentId());
if (!bridge)
return Device::DeviceSetupStatusFailure;
bridge->refreshLight(device->paramValue(dimmableLightDeviceUuidParamTypeId).toString());
return Device::DeviceSetupStatusSuccess;
}
@ -262,11 +231,6 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
if (device->deviceClassId() == remoteDeviceClassId) {
qCDebug(dcPhilipsHue) << "Setup Hue remote" << device->params() << device->deviceClassId();
BridgeConnection *bridge = m_bridgeConnections.value(device->parentId());
HueRemote *hueRemote = new HueRemote(this);
hueRemote->setHostAddress(bridge->hostAddress());
hueRemote->setApiKey(bridge->apiKey());
// Migrate device parameters after changing param type UUIDs in 0.14.
QMap<QString, ParamTypeId> migrationMap;
migrationMap.insert("095a463b-f59e-46b1-989a-a71f9cbe3e30", remoteDeviceModelIdParamTypeId);
@ -388,40 +352,10 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
void DevicePluginPhilipsHue::deviceRemoved(Device *device)
{
abortRequests(m_lightRefreshRequests, device);
abortRequests(m_setNameRequests, device);
abortRequests(m_bridgeRefreshRequests, device);
abortRequests(m_lightsRefreshRequests, device);
abortRequests(m_sensorsRefreshRequests, device);
abortRequests(m_bridgeLightsDiscoveryRequests, device);
abortRequests(m_bridgeSensorsDiscoveryRequests, device);
abortRequests(m_bridgeSearchDevicesRequests, device);
if (device->deviceClassId() == bridgeDeviceClassId) {
HueBridge *bridge = m_bridges.key(device);
m_bridges.remove(bridge);
BridgeConnection *bridge = m_bridgeConnections.take(device->id());
bridge->deleteLater();
}
if (device->deviceClassId() == colorLightDeviceClassId
|| device->deviceClassId() == colorTemperatureLightDeviceClassId
|| device->deviceClassId() == dimmableLightDeviceClassId) {
HueLight *light = m_lights.key(device);
m_lights.remove(light);
light->deleteLater();
}
if (device->deviceClassId() == remoteDeviceClassId || device->deviceClassId() == tapDeviceClassId) {
HueRemote *remote = m_remotes.key(device);
m_remotes.remove(remote);
remote->deleteLater();
}
if (device->deviceClassId() == outdoorSensorDeviceClassId) {
HueMotionSensor *outdoorSensor = m_motionSensors.key(device);
m_motionSensors.remove(outdoorSensor);
outdoorSensor->deleteLater();
}
}
Device::DeviceSetupStatus DevicePluginPhilipsHue::confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList &params, const QString &secret)
@ -454,15 +388,49 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::confirmPairing(const PairingTr
void DevicePluginPhilipsHue::onDeviceNameChanged()
{
Device *device = static_cast<Device*>(sender());
if (m_lights.values().contains(device)) {
setLightName(device);
}
BridgeConnection *bridge = m_bridgeConnections.value(device->parentId());
if (!bridge)
return;
if (m_remotes.values().contains(device)) {
setRemoteName(device);
if (device->deviceClassId() == colorLightDeviceClassId) {
bridge->setLightName(device->paramValue(colorLightDeviceUuidParamTypeId).toString(), device->name());
}
if (device->deviceClassId() == colorTemperatureLightDeviceClassId) {
bridge->setLightName(device->paramValue(colorTemperatureLightDeviceUuidParamTypeId).toString(), device->name());
}
if (device->deviceClassId() == dimmableLightDeviceClassId) {
bridge->setLightName(device->paramValue(dimmableLightDeviceUuidParamTypeId).toString(), device->name());
}
if (device->deviceClassId() == remoteDeviceClassId) {
bridge->setLightName(device->paramValue(remoteDeviceUuidParamTypeId).toString(), device->name());
}
if (device->deviceClassId() == tapDeviceClassId) {
bridge->setLightName(device->paramValue(tapDeviceUuidParamTypeId).toString(), device->name());
}
if (device->deviceClassId() == outdoorSensorDeviceClassId) {
bridge->setLightName(device->paramValue(outdoorSensorDeviceUuidParamTypeId).toString(), device->name());
}
}
void DevicePluginPhilipsHue::onActionExecuted(const QUuid &uuid)
{
if (m_asyncActions.contains(uuid)) {
ActionId asyncAction = m_asyncActions.take(uuid);
emit actionExecutionFinished(asyncAction, Device::DeviceErrorNoError);
}
}
void DevicePluginPhilipsHue::onActionFailed(const QUuid &uuid, const QString &error)
{
if (m_asyncActions.contains(uuid)) {
qWarning(dcPhilipsHue()) << "Action failed: " << error;
ActionId asyncAction = m_asyncActions.take(uuid);
emit actionExecutionFinished(asyncAction, Device::DeviceErrorHardwareNotAvailable);
}
}
void DevicePluginPhilipsHue::finishDiscovery(DevicePluginPhilipsHue::DiscoveryJob *job)
{
if (job->upnpReply || job->nUpnpReply) {
@ -489,6 +457,37 @@ void DevicePluginPhilipsHue::finishDiscovery(DevicePluginPhilipsHue::DiscoveryJo
delete job;
}
Device *DevicePluginPhilipsHue::getDeviceByHueDeviceUuid(const QString &uuid)
{
foreach(Device* device, myDevices()) {
if (device->deviceClassId() == colorLightDeviceClassId) {
if(device->paramValue(colorLightDeviceUuidParamTypeId).toString() == uuid)
return device;
}
if (device->deviceClassId() == colorTemperatureLightDeviceClassId) {
if(device->paramValue(colorTemperatureLightDeviceUuidParamTypeId).toString() == uuid)
return device;
}
if (device->deviceClassId() == dimmableLightDeviceClassId) {
if(device->paramValue(dimmableLightDeviceUuidParamTypeId).toString() == uuid)
return device;
}
if (device->deviceClassId() == remoteDeviceClassId) {
if(device->paramValue(remoteDeviceUuidParamTypeId).toString() == uuid)
return device;
}
if (device->deviceClassId() == tapDeviceClassId) {
if(device->paramValue(tapDeviceUuidParamTypeId).toString() == uuid)
return device;
}
if (device->deviceClassId() == outdoorSensorDeviceClassId) {
if(device->paramValue(outdoorSensorDeviceUuidParamTypeId).toString() == uuid)
return device;
}
}
return nullptr;
}
Device::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const Action &action)
{
qCDebug(dcPhilipsHue) << "Execute action" << action.actionTypeId() << action.params();
@ -506,28 +505,28 @@ Device::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const
if (action.actionTypeId() == colorLightPowerActionTypeId) {
//get bridge
bridge->setPower(uuid, action.param(colorLightPowerActionPowerParamTypeId).value().toBool())
//m_asyncActions.insert(device, action.id());
return Device::DeviceErrorAsync;
QUuid actionUuid = bridge->setPower(uuid, action.param(colorLightPowerActionPowerParamTypeId).value().toBool());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
} else if (action.actionTypeId() == colorLightColorActionTypeId) {
bridge->setColor(uuid, action.param(colorLightColorActionColorParamTypeId).value().value<QColor>());
//m_asyncActions.insert(reply,QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setColor(uuid, action.param(colorLightColorActionColorParamTypeId).value().value<QColor>());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
} else if (action.actionTypeId() == colorLightBrightnessActionTypeId) {
bridge->setBrightness(uuid, action.param(colorLightBrightnessActionBrightnessParamTypeId).value().toInt());
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setBrightness(uuid, action.param(colorLightBrightnessActionBrightnessParamTypeId).value().toInt());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
} else if (action.actionTypeId() == colorLightEffectActionTypeId) {
bridge->setEffect(uuid, action.param(colorLightEffectActionEffectParamTypeId).value().toString());
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setEffect(uuid, action.param(colorLightEffectActionEffectParamTypeId).value().toString());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
} else if (action.actionTypeId() == colorLightAlertActionTypeId) {
bridge->setFlash(uuid, action.param(colorLightAlertActionAlertParamTypeId).value().toString());
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setFlash(uuid, action.param(colorLightAlertActionAlertParamTypeId).value().toString());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
} else if (action.actionTypeId() == colorLightColorTemperatureActionTypeId) {
bridge->setTemperature(uuid, action.param(colorLightColorTemperatureActionColorTemperatureParamTypeId).value().toInt());
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setTemperature(uuid, action.param(colorLightColorTemperatureActionColorTemperatureParamTypeId).value().toInt());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
}
return Device::DeviceErrorActionTypeNotFound;
@ -544,20 +543,20 @@ Device::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const
}*/ //TODO
if (action.actionTypeId() == colorTemperatureLightPowerActionTypeId) {
bridge->setTemperature(uuid, action.param(colorTemperatureLightPowerActionPowerParamTypeId).value().toBool());
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setTemperature(uuid, action.param(colorTemperatureLightPowerActionPowerParamTypeId).value().toBool());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
} else if (action.actionTypeId() == colorTemperatureLightBrightnessActionTypeId) {
bridge->setBrightness(uuid, action.param(colorTemperatureLightBrightnessActionBrightnessParamTypeId).value().toInt());
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setBrightness(uuid, action.param(colorTemperatureLightBrightnessActionBrightnessParamTypeId).value().toInt());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
} else if (action.actionTypeId() == colorTemperatureLightAlertActionTypeId) {
bridge->setFlash(uuid, action.param(colorTemperatureLightAlertActionAlertParamTypeId).value().toString());
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setFlash(uuid, action.param(colorTemperatureLightAlertActionAlertParamTypeId).value().toString());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
} else if (action.actionTypeId() == colorTemperatureLightColorTemperatureActionTypeId) {
bridge->setTemperature(uuid, action.param(colorTemperatureLightColorTemperatureActionColorTemperatureParamTypeId).value().toInt());
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setTemperature(uuid, action.param(colorTemperatureLightColorTemperatureActionColorTemperatureParamTypeId).value().toInt());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
}
return Device::DeviceErrorActionTypeNotFound;
@ -575,18 +574,16 @@ Device::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const
}*/ //TODO
if (action.actionTypeId() == dimmableLightPowerActionTypeId) {
bridge->setPower(uuid, action.param(dimmableLightPowerActionPowerParamTypeId).value().toBool());
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setPower(uuid, action.param(dimmableLightPowerActionPowerParamTypeId).value().toBool());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
} else if (action.actionTypeId() == dimmableLightBrightnessActionTypeId) {
bridge->setBrightness(uuid, action.param(dimmableLightBrightnessActionBrightnessParamTypeId).value().toInt());
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setBrightness(uuid, action.param(dimmableLightBrightnessActionBrightnessParamTypeId).value().toInt());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
} else if (action.actionTypeId() == dimmableLightAlertActionTypeId) {
bridge->setFlash(uuid, action.param(dimmableLightAlertActionAlertParamTypeId).value().toString());
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
QUuid actionUuid = bridge->setFlash(uuid, action.param(dimmableLightAlertActionAlertParamTypeId).value().toString());
m_asyncActions.insert(actionUuid, action.id());
return Device::DeviceErrorAsync;
}
return Device::DeviceErrorActionTypeNotFound;
@ -602,7 +599,7 @@ Device::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const
}
if (action.actionTypeId() == bridgeSearchNewDevicesActionTypeId) {
bridge->searchNewDevices(action.param(bridgeSearchNewDevicesActionSerialParamTypeId).value().toString());
QUuid actionUuid = bridge->searchNewDevices(action.param(bridgeSearchNewDevicesActionSerialParamTypeId).value().toString());
return Device::DeviceErrorNoError;
} else if (action.actionTypeId() == bridgeCheckForUpdatesActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = bridge->createCheckUpdatesRequest();
@ -622,6 +619,26 @@ Device::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const
return Device::DeviceErrorDeviceClassNotFound;
}
void DevicePluginPhilipsHue::onPairingFinished(bool successful)
{
if(successful) {
//BridgeConnection *bridge = static_cast<BridgeConnection *>(sender());
// create Bridge
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);
}
}
void DevicePluginPhilipsHue::onLightsDiscovered(QHash<QString, HueLight *> lights)
{
BridgeConnection *bridge = static_cast<BridgeConnection *>(sender());
@ -632,22 +649,22 @@ void DevicePluginPhilipsHue::onLightsDiscovered(QHash<QString, HueLight *> light
QList<DeviceDescriptor> colorTemperatureLightDescriptors;
QList<DeviceDescriptor> dimmableLightDescriptors;
foreach (HueLight *light, lights.values()) {
foreach (HueLight *light, lights.keys()) {
QString uuid = lights.key(light);
if (lightAlreadyAdded(uuid))
continue;
if (light->type() == "Dimmable light") {
DeviceDescriptor descriptor(dimmableLightDeviceClassId, light->name(), "Philips Hue White Light", parentDeviceId);
ParamList params;
params.append(Param(dimmableLightDeviceModelIdParamTypeId, model));
params.append(Param(dimmableLightDeviceModelIdParamTypeId, light->modelId()));
params.append(Param(dimmableLightDeviceTypeParamTypeId, light->type()));
params.append(Param(dimmableLightDeviceUuidParamTypeId, uuid));
params.append(Param(dimmableLightDeviceLightIdParamTypeId, lightId));
params.append(Param(dimmableLightDeviceLightIdParamTypeId, light->id()));
descriptor.setParams(params);
dimmableLightDescriptors.append(descriptor);
qCDebug(dcPhilipsHue) << "Found new dimmable light" << light->name() << light->modelId();
qCDebug(dcPhilipsHue) << "Found new dimmable light" << light->name();
} else if (light->type() == "Color temperature light") {
DeviceDescriptor descriptor(colorTemperatureLightDeviceClassId, light->name(), "Philips Hue Color Temperature Light", parentDeviceId);
@ -659,7 +676,7 @@ void DevicePluginPhilipsHue::onLightsDiscovered(QHash<QString, HueLight *> light
descriptor.setParams(params);
colorTemperatureLightDescriptors.append(descriptor);
qCDebug(dcPhilipsHue) << "Found new color temperature light" << light->name() << model;
qCDebug(dcPhilipsHue) << "Found new color temperature light" << light->name();
} else {
DeviceDescriptor descriptor(colorLightDeviceClassId, light->name(), "Philips Hue Color Light", parentDeviceId);
ParamList params;
@ -669,7 +686,7 @@ void DevicePluginPhilipsHue::onLightsDiscovered(QHash<QString, HueLight *> light
params.append(Param(colorLightDeviceLightIdParamTypeId, light->id()));
descriptor.setParams(params);
colorLightDescriptors.append(descriptor);
qCDebug(dcPhilipsHue) << "Found new color light" << light->name() << model;
qCDebug(dcPhilipsHue) << "Found new color light" << light->name();
}
}
@ -687,7 +704,7 @@ void DevicePluginPhilipsHue::onRemotesDiscovered(QHash<QString, HueRemote *> rem
DeviceId parentDeviceId = m_bridgeConnections.key(bridge);
foreach (HueRemote *remote, remotes.values()) {
QString baseUuid = motionSensors.key(motionSensor);
QString uuid = remotes.key(remote);
if (sensorAlreadyAdded(uuid))
continue;
@ -703,7 +720,7 @@ void DevicePluginPhilipsHue::onRemotesDiscovered(QHash<QString, HueRemote *> rem
}
if (remote->type() == "ZGPSwitch") {
DeviceDescriptor descriptor(tapDeviceClassId, remote->name(), "Philips Hue Tap", device->id());
DeviceDescriptor descriptor(tapDeviceClassId, remote->name(), "Philips Hue Tap", parentDeviceId);
ParamList params;
params.append(Param(tapDeviceUuidParamTypeId, remote->uuid()));
params.append(Param(tapDeviceModelIdParamTypeId, remote->modelId()));
@ -716,16 +733,18 @@ void DevicePluginPhilipsHue::onRemotesDiscovered(QHash<QString, HueRemote *> rem
void DevicePluginPhilipsHue::onMotionSensorDiscovered(QHash<QString, HueMotionSensor *> motionSensors)
{
BridgeConnection *bridge = static_cast<BridgeConnection *>(sender());
DeviceId parentDeviceId = m_bridgeConnections.key(bridge);
// Create outdoor sensors if there are any new sensors found
foreach (HueMotionSensor *motionSensor, motionSensors.values()) {
QString baseUuid = motionSensors.key(motionSensor);
QString uuid = motionSensors.key(motionSensor);
if (sensorAlreadyAdded(uuid))
continue;
if (motionSensor->isValid()) {
if (motionSensor->modelId() == "SML001") {
DeviceDescriptor descriptor(motionSensorDeviceClassId, tr("Philips Hue Motion sensor"), baseUuid, device->id());
DeviceDescriptor descriptor(motionSensorDeviceClassId, tr("Philips Hue Motion sensor"), uuid, parentDeviceId);
ParamList params;
params.append(Param(motionSensorDeviceUuidParamTypeId, motionSensor->uuid()));
params.append(Param(motionSensorDeviceModelIdParamTypeId, motionSensor->modelId()));
@ -736,10 +755,10 @@ void DevicePluginPhilipsHue::onMotionSensorDiscovered(QHash<QString, HueMotionSe
params.append(Param(motionSensorDeviceSensorUuidLightParamTypeId, motionSensor->lightSensorUuid()));
params.append(Param(motionSensorDeviceSensorIdLightParamTypeId, motionSensor->lightSensorId()));
descriptor.setParams(params);
qCDebug(dcPhilipsHue()) << "Found new motion sensor" << baseUuid << outdoorSensorDeviceClassId;
qCDebug(dcPhilipsHue()) << "Found new motion sensor" << uuid << outdoorSensorDeviceClassId;
emit autoDevicesAppeared(motionSensorDeviceClassId, {descriptor});
} else if (motionSensor->modelId() == "SML002") {
DeviceDescriptor descriptor(outdoorSensorDeviceClassId, tr("Philips Hue Outdoor sensor"), baseUuid, device->id());
DeviceDescriptor descriptor(outdoorSensorDeviceClassId, tr("Philips Hue Outdoor sensor"), uuid, parentDeviceId);
ParamList params;
params.append(Param(outdoorSensorDeviceUuidParamTypeId, motionSensor->uuid()));
params.append(Param(outdoorSensorDeviceModelIdParamTypeId, motionSensor->modelId()));
@ -750,20 +769,18 @@ void DevicePluginPhilipsHue::onMotionSensorDiscovered(QHash<QString, HueMotionSe
params.append(Param(outdoorSensorDeviceSensorUuidLightParamTypeId, motionSensor->lightSensorUuid()));
params.append(Param(outdoorSensorDeviceSensorIdLightParamTypeId, motionSensor->lightSensorId()));
descriptor.setParams(params);
qCDebug(dcPhilipsHue()) << "Found new outdoor sensor" << baseUuid << outdoorSensorDeviceClassId;
qCDebug(dcPhilipsHue()) << "Found new outdoor sensor" << uuid << outdoorSensorDeviceClassId;
emit autoDevicesAppeared(outdoorSensorDeviceClassId, {descriptor});
}
}
}
}
void DevicePluginPhilipsHue::lightStateChanged()
void DevicePluginPhilipsHue::onLightStateChanged(const QString &uuid)
{
HueLight *light = static_cast<HueLight *>(sender());
Device *device = m_lights.value(light);
Device *device = getDeviceByHueDeviceUuid(uuid);
if (!device) {
qCWarning(dcPhilipsHue) << "Could not find device for light" << light->name();
qCWarning(dcPhilipsHue) << "Could not find device for light" << uuid;
return;
}
@ -786,7 +803,7 @@ void DevicePluginPhilipsHue::lightStateChanged()
}
}
void DevicePluginPhilipsHue::remoteStateChanged()
void DevicePluginPhilipsHue::onRemoteStateChanged()
{
HueRemote *remote = static_cast<HueRemote *>(sender());
@ -891,6 +908,7 @@ void DevicePluginPhilipsHue::onMotionSensorTemperatureChanged(double temperature
void DevicePluginPhilipsHue::onMotionSensorPresenceChanged(bool presence)
{
HueMotionSensor *sensor = static_cast<HueMotionSensor *>(sender());
myDevices().filterByParam()
Device *sensorDevice = m_motionSensors.value(sensor);
sensorDevice->setStateValue(sensor->isPresentStateTypeId(), presence);
if (presence) sensorDevice->setStateValue(sensor->lastSeenTimeStateTypeId(), QDateTime::currentDateTime().toTime_t());

View File

@ -56,6 +56,7 @@ public:
Device::DeviceError executeAction(Device *device, const Action &action) override;
private slots:
void onPairingFinished(bool successful);
//Devices discovered
void onLightsDiscovered(QHash<QString, HueLight *> remotes);
@ -78,6 +79,9 @@ private slots:
void onDeviceNameChanged();
void onActionExecuted(const QUuid &uuid);
void onActionFailed(const QUuid &uuid, const QString &error);
private:
class DiscoveryJob {
public:
@ -87,7 +91,6 @@ private:
};
void finishDiscovery(DiscoveryJob* job);
QHash<QNetworkReply *, PairingInfo *> m_pairingRequests;
QHash<QNetworkReply *, PairingInfo *> m_informationRequests;
QHash<DeviceId, BridgeConnection *> m_bridgeConnections;
@ -95,7 +98,9 @@ private:
QList<HueBridge *> m_unconfiguredBridges;
QList<HueLight *> m_unconfiguredLights;
QHash<QNetworkReply *, QPair<Device *, ActionId> > m_asyncActions;
QHash<QUuid, ActionId> m_asyncActions;
Device *getDeviceByHueDeviceUuid(const QString &uuid);
bool lightAlreadyAdded(const QString &uuid);
bool sensorAlreadyAdded(const QString &uuid);

View File

@ -50,8 +50,8 @@ public:
QString presenceSensorUuid() const;
void setPresenceSensorUuid(const QString &presenceSensorUuid);
int sensorId() const;
void setSensorId(int sensorId);
int lightSensorId() const;
void setLightSensorId(int sensorId);
QString lightSensorUuid() const;
void setLightSensorUuid(const QString &lightSensorUuid);

View File

@ -56,8 +56,8 @@ public:
int battery() const;
void setBattery(const int &battery);
int remoteSensorId() const;
void setRemoteSensorId(int sensorId);
int remoteId() const;
void setRemoteId(int sensorId);
void updateStates(const QVariantMap &statesMap, const QVariantMap &configMap);