mirror of
https://github.com/nymea/nymea-plugins.git
synced 2026-07-18 00:43:48 +02:00
Added hood implementation.
Handled device disconnected.
This commit is contained in:
parent
7d2de6f268
commit
adbd78796a
@ -64,6 +64,7 @@ IntegrationPluginMiele::IntegrationPluginMiele()
|
||||
m_mieleDeviceTypeLabelToThingClassId.insert("coffee system", coffeeMakerThingClassId);
|
||||
m_mieleDeviceTypeLabelToThingClassId.insert("tumber dryer", dryerThingClassId);
|
||||
m_mieleDeviceTypeLabelToThingClassId.insert("refrigerator", fridgeThingClassId);
|
||||
m_mieleDeviceTypeLabelToThingClassId.insert("hood", hoodThingClassId);
|
||||
|
||||
}
|
||||
|
||||
@ -88,7 +89,9 @@ void IntegrationPluginMiele::startPairing(ThingPairingInfo *info)
|
||||
|
||||
void IntegrationPluginMiele::confirmPairing(ThingPairingInfo *info, const QString &username, const QString &secret)
|
||||
{
|
||||
Q_UNUSED(username);
|
||||
//Q_UNUSED(username);
|
||||
|
||||
qCDebug(dcMiele()) << "\n\n Confirm pairing for username: [" << username << "]";
|
||||
|
||||
if (info->thingClassId() == mieleAccountThingClassId) {
|
||||
qCDebug(dcMiele()) << "Confirm pairing Miele account";
|
||||
@ -166,6 +169,7 @@ void IntegrationPluginMiele::setupThing(ThingSetupInfo *info)
|
||||
connect(info, &ThingSetupInfo::aborted, miele, &Miele::deleteLater);
|
||||
connect(miele, &Miele::devicesFound, this, &IntegrationPluginMiele::onDevicesFound);
|
||||
connect(miele, &Miele::deviceStateReceived, this, &IntegrationPluginMiele::onDeviceStateReceived);
|
||||
connect(miele, &Miele::deviceNotFound, this, &IntegrationPluginMiele::onDeviceNotFound);
|
||||
}
|
||||
} else if (m_idParamTypeIds.contains(thing->thingClassId())) {
|
||||
Thing *parentThing = myThings().findById(thing->parentId());
|
||||
@ -212,8 +216,7 @@ void IntegrationPluginMiele::postSetupThing(Thing *thing)
|
||||
miele->getDevicesShort();
|
||||
//miele->connectEventStream();
|
||||
thing->setStateValue(mieleAccountConnectedStateTypeId, true);
|
||||
thing->setStateValue(mieleAccountLoggedInStateTypeId, true);
|
||||
//TBD Set user name
|
||||
thing->setStateValue(mieleAccountLoggedInStateTypeId, true);
|
||||
} else if (m_idParamTypeIds.contains(thing->thingClassId())) {
|
||||
Thing *parentThing = myThings().findById(thing->parentId());
|
||||
if (!parentThing)
|
||||
@ -245,10 +248,58 @@ void IntegrationPluginMiele::executeAction(ThingActionInfo *info)
|
||||
double targetTemp = action.param(fridgeTargetTemperatureActionTargetTemperatureParamTypeId).value().toDouble();
|
||||
int iTargetTemp = floor(targetTemp);
|
||||
qCDebug(dcMiele()) << "Setting fridge temp: " << iTargetTemp;
|
||||
miele->setTargetTemperature(deviceId, 1, iTargetTemp);
|
||||
QUuid requestId = miele->setTargetTemperature(deviceId, 1, iTargetTemp);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
thing->setStateValue(fridgeTargetTemperatureStateTypeId, iTargetTemp);
|
||||
m_pendingActions.insert(requestId, info);
|
||||
connect(info, &ThingActionInfo::aborted, [requestId, this] {
|
||||
m_pendingActions.remove(requestId);
|
||||
});
|
||||
} else if (action.actionTypeId() == fridgeStartSuperCoolingActionTypeId) {
|
||||
QUuid requestId = miele->processAction(deviceId, Miele::ProcessActionsStartSupercooling);
|
||||
m_pendingActions.insert(requestId, info);
|
||||
connect(info, &ThingActionInfo::aborted, [requestId, this] {
|
||||
m_pendingActions.remove(requestId);
|
||||
});
|
||||
// don't set state, it should come as event once it successfully started on the actual device
|
||||
//thing->setStateValue(fridgePowerStateTypeId, !currentSuperCoolingState);
|
||||
} else if (action.actionTypeId() == fridgeStopSuperCoolingActionTypeId) {
|
||||
QUuid requestId = miele->processAction(deviceId, Miele::ProcessActionsStopSupercooling);
|
||||
m_pendingActions.insert(requestId, info);
|
||||
connect(info, &ThingActionInfo::aborted, [requestId, this] {
|
||||
m_pendingActions.remove(requestId);
|
||||
});
|
||||
}
|
||||
} else if (thing->thingClassId() == hoodThingClassId) {
|
||||
if (action.actionTypeId() == hoodStopHoodActionTypeId) {
|
||||
// TODO: should check if current state of the hood allows the Stop action
|
||||
QUuid requestId = miele->processAction(deviceId, Miele::ProcessActionsStop);
|
||||
m_pendingActions.insert(requestId, info);
|
||||
connect(info, &ThingActionInfo::aborted, [requestId, this] {
|
||||
m_pendingActions.remove(requestId);
|
||||
});
|
||||
} else if (action.actionTypeId() == hoodVentilationStepActionTypeId) {
|
||||
int ventStep = action.param(hoodVentilationStepActionVentilationStepParamTypeId).value().toInt();
|
||||
QUuid requestId = miele->setVentilationStep(deviceId, ventStep);
|
||||
m_pendingActions.insert(requestId, info);
|
||||
connect(info, &ThingActionInfo::aborted, [requestId, this] {
|
||||
m_pendingActions.remove(requestId);
|
||||
});
|
||||
} else if (action.actionTypeId() == hoodLightColorActionTypeId) {
|
||||
QString color = action.param(hoodLightColorActionLightColorParamTypeId).value().toString();
|
||||
QUuid requestId = miele->setColorsStr(deviceId, color);
|
||||
m_pendingActions.insert(requestId, info);
|
||||
connect(info, &ThingActionInfo::aborted, [requestId, this] {
|
||||
m_pendingActions.remove(requestId);
|
||||
});
|
||||
} else if (action.actionTypeId() == hoodLightActionTypeId) {
|
||||
bool power = action.param(hoodLightActionLightParamTypeId).value().toBool();
|
||||
QUuid requestId = miele->setLight(deviceId, power);
|
||||
connect(info, &ThingActionInfo::aborted, [requestId, this] {
|
||||
m_pendingActions.remove(requestId);
|
||||
});
|
||||
}
|
||||
|
||||
} else if (thing->thingClassId() == ovenThingClassId) {
|
||||
|
||||
} else {
|
||||
@ -358,7 +409,7 @@ void IntegrationPluginMiele::onDevicesFound(QList<Miele::DeviceShort> devices)
|
||||
|
||||
if(m_mieleConnections.values().contains(miele)) {
|
||||
Thing *parentDevice = myThings().findById(m_mieleConnections.key(miele)->id());
|
||||
qCDebug(dcMiele()) << devices.size() << " devices received for prent: " << parentDevice->id();
|
||||
qCDebug(dcMiele()) << devices.size() << " devices received for parent: " << parentDevice->id();
|
||||
|
||||
ThingDescriptors descriptors;
|
||||
foreach(Miele::DeviceShort ds, devices) {
|
||||
@ -420,6 +471,7 @@ void IntegrationPluginMiele::setThingState(Thing *thing, const QVariantMap &stat
|
||||
? false
|
||||
: true;
|
||||
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), connected);
|
||||
thing->setStateValue(fridgeOperationStateStateTypeId, state.value("status").toMap().value("value_localized").toString());
|
||||
|
||||
// Fridges should have only one temperature zone
|
||||
QVariant fridgeTempZone = state.value("temperature").toList().first();
|
||||
@ -430,7 +482,60 @@ void IntegrationPluginMiele::setThingState(Thing *thing, const QVariantMap &stat
|
||||
double fridgeTargetTemp = fridgeTargetTempZone.toMap().value("value_raw").toDouble();
|
||||
thing->setStateValue(fridgeTargetTemperatureStateTypeId, fridgeTargetTemp / 100);
|
||||
|
||||
thing->setStateValue(fridgeSignalDoorStateTypeId, state.value("signalDoor").toBool());
|
||||
thing->setStateValue(fridgeSignalInfoStateTypeId, state.value("signalInfo").toBool());
|
||||
thing->setStateValue(fridgeSignalFailureStateTypeId, state.value("signalFailure").toBool());
|
||||
|
||||
QVariantMap remoteEnabledModes = state.value("remoteEnable").toMap();
|
||||
thing->setStateValue(fridgeFullRemoteControlStateTypeId, remoteEnabledModes.value("fullRemoteControl").toBool());
|
||||
thing->setStateValue(fridgeSmartGridStateTypeId, remoteEnabledModes.value("smartGrid").toBool());
|
||||
thing->setStateValue(fridgeMobileStartStateTypeId, remoteEnabledModes.value("mobileStart").toBool());
|
||||
|
||||
} else if (thing->thingClassId() == hoodThingClassId) {
|
||||
qCDebug(dcMiele()) << "Setting state for hood!";
|
||||
|
||||
int status = state.value("status").toMap().value("value_raw").toInt();
|
||||
bool connected = (status == Miele::StatusNotConnected) ? false : true;
|
||||
bool poweredOn = (status == Miele::StatusOff) ? false : true;
|
||||
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), connected);
|
||||
thing->setStateValue(hoodPowerStateTypeId, poweredOn);
|
||||
thing->setStateValue(hoodOperationStateStateTypeId, state.value("status").toMap().value("value_localized").toString());
|
||||
|
||||
thing->setStateValue(hoodSignalInfoStateTypeId, state.value("signalInfo").toBool());
|
||||
thing->setStateValue(hoodSignalFailureStateTypeId, state.value("signalFailure").toBool());
|
||||
thing->setStateValue(hoodLightStateTypeId, state.value("light").toInt() != 0 ? true : false);
|
||||
|
||||
QVariantMap remoteEnabledModes = state.value("remoteEnable").toMap();
|
||||
thing->setStateValue(hoodFullRemoteControlStateTypeId, remoteEnabledModes.value("fullRemoteControl").toBool());
|
||||
thing->setStateValue(hoodSmartGridStateTypeId, remoteEnabledModes.value("smartGrid").toBool());
|
||||
thing->setStateValue(hoodMobileStartStateTypeId, remoteEnabledModes.value("mobileStart").toBool());
|
||||
|
||||
int ventilationStep = state.value("ventilationStep").toMap().value("value_raw").toInt();
|
||||
thing->setStateValue(hoodVentilationStepStateTypeId, ventilationStep);
|
||||
} else {
|
||||
qCWarning(dcMiele()) << "Device " << thing->name() << " is not yet supported!";
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginMiele::onDeviceNotFound(const QString &deviceId)
|
||||
{
|
||||
Miele *miele = static_cast<Miele*>(sender());
|
||||
if (!m_mieleConnections.values().contains(miele)) {
|
||||
qCWarning(dcMiele()) << "Can't find Miele connection!";
|
||||
return;
|
||||
}
|
||||
|
||||
Thing *parentDevice = myThings().findById(m_mieleConnections.key(miele)->id());
|
||||
if (!parentDevice) {
|
||||
qCWarning(dcMiele()) << "Can't find parent thing!";
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(Thing *thing, myThings().filterByParentId(parentDevice->id())) {
|
||||
if (thing->paramValue(m_idParamTypeIds.value(thing->thingClassId())).toString() == deviceId) {
|
||||
qCDebug(dcMiele()) << "Device not found anymore: " << thing->name();
|
||||
emit autoThingDisappeared(thing->id());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,6 +79,7 @@ private slots:
|
||||
|
||||
void onDevicesFound(QList<Miele::DeviceShort> devices);
|
||||
void onDeviceStateReceived(const QString &deviceId, const QVariantMap &deviceState);
|
||||
void onDeviceNotFound(const QString &deviceId);
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINMIELE_H
|
||||
|
||||
@ -51,14 +51,6 @@
|
||||
"displayNameEvent": "Logged in changed",
|
||||
"defaultValue": true,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "a5b85688-d319-4f61-8907-7da8a2b16d64",
|
||||
"name": "userDisplayName",
|
||||
"displayName": "User name",
|
||||
"displayNameEvent": "User name changed",
|
||||
"defaultValue": "",
|
||||
"type": "QString"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -198,6 +190,38 @@
|
||||
"defaultValue": true,
|
||||
"cached": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "2f2039bb-b0af-4272-a8ba-558589f49299",
|
||||
"name": "operationState",
|
||||
"displayName": "Operation state",
|
||||
"displayNameEvent": "Operation state changed",
|
||||
"defaultValue": "Not Connected",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "bafefd33-cfdb-4715-a1c1-fb3d4215f84c",
|
||||
"name": "fullRemoteControl",
|
||||
"displayName": "Full remote control",
|
||||
"displayNameEvent": "Full remote control changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "89081d4a-5e46-4569-b0f9-52347491a013",
|
||||
"name": "smartGrid",
|
||||
"displayName": "Smart grid enabled",
|
||||
"displayNameEvent": "Smart grid enabled changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "a878082e-a530-439a-9d71-dfe430fb4988",
|
||||
"name": "mobileStart",
|
||||
"displayName": "Mobile start enabled",
|
||||
"displayNameEvent": "Mobile start enabled changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "ef656321-e2c8-4339-be18-aa3cdb53dea6",
|
||||
@ -225,15 +249,40 @@
|
||||
"ioType": "analogInput"
|
||||
},
|
||||
{
|
||||
"id": "60a46368-febc-4cff-bbfb-99064dbb93a9",
|
||||
"name": "power",
|
||||
"displayName": "On/off",
|
||||
"displayNameEvent": "Turned on/off",
|
||||
"displayNameAction": "Turn on/off",
|
||||
"type": "bool",
|
||||
"id": "6954a425-e02e-4930-b073-1cc70805305a",
|
||||
"name": "signalDoor",
|
||||
"displayName": "Door open",
|
||||
"displayNameEvent": "Door open changed",
|
||||
"defaultValue": false,
|
||||
"writable": true,
|
||||
"ioType": "digitalInput"
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "0469a4b9-ec7d-444c-9aa3-410518ec41ef",
|
||||
"name": "signalInfo",
|
||||
"displayName": "Unread notification",
|
||||
"displayNameEvent": "Unread notification changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "cbc573bd-ad3f-4d58-a796-b81bea14622d",
|
||||
"name": "signalFailure",
|
||||
"displayName": "Failure notification",
|
||||
"displayNameEvent": "Failure notification changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "0b206df2-47aa-4f8a-9c14-ff483c539826",
|
||||
"name": "startSuperCooling",
|
||||
"displayName": "Start SuperCooling"
|
||||
},
|
||||
{
|
||||
"id": "293568c2-5f8c-42f9-b150-769e181a8cbd",
|
||||
"name": "stopSuperCooling",
|
||||
"displayName": "Stop SuperCooling"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -296,7 +345,7 @@
|
||||
"id": "707e46a5-9ca0-4375-8249-2de19ec669ec",
|
||||
"name": "hood",
|
||||
"displayName": "Hood",
|
||||
"interfaces": ["connectable"],
|
||||
"interfaces": ["power", "connectable"],
|
||||
"createMethods": ["auto"],
|
||||
"paramTypes": [
|
||||
{
|
||||
@ -316,6 +365,115 @@
|
||||
"defaultValue": true,
|
||||
"cached": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "2d5c88b4-34fd-4f15-b731-332dc905ef27",
|
||||
"name": "power",
|
||||
"displayName": "Power",
|
||||
"displayNameEvent": "Powered on/off",
|
||||
"displayNameAction": "Power on/off",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "db566fc5-383f-4726-a730-9dadac76e2d0",
|
||||
"name": "operationState",
|
||||
"displayName": "Operation state",
|
||||
"displayNameEvent": "Operation state changed",
|
||||
"defaultValue": "Not Connected",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "d64b646c-8405-4384-8aa3-02e288dc0603",
|
||||
"name": "signalInfo",
|
||||
"displayName": "Unread notification",
|
||||
"displayNameEvent": "Unread notification changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "8da242c3-117c-4cb7-91f9-2bd34835e427",
|
||||
"name": "signalFailure",
|
||||
"displayName": "Failure notification",
|
||||
"displayNameEvent": "Failure notification changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "dd97c6dd-94fd-4dd3-b2ce-812c40e6247b",
|
||||
"name": "fullRemoteControl",
|
||||
"displayName": "Full remote control",
|
||||
"displayNameEvent": "Full remote control changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "0b1a6594-fda6-4c48-a898-7b54b30538f7",
|
||||
"name": "smartGrid",
|
||||
"displayName": "Smart grid enabled",
|
||||
"displayNameEvent": "Smart grid enabled changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "363d5770-6f11-41c8-981c-9f1d49278b3c",
|
||||
"name": "mobileStart",
|
||||
"displayName": "Mobile start enabled",
|
||||
"displayNameEvent": "Mobile start enabled changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "ae7044b9-3a46-4c98-bd02-2abded425c35",
|
||||
"name": "ventilationStep",
|
||||
"displayName": "Ventilation step",
|
||||
"displayNameEvent": "Ventilation step changed",
|
||||
"displayNameAction": "Set ventilation step",
|
||||
"defaultValue": 0,
|
||||
"type": "int",
|
||||
"possibleValues": [
|
||||
0, 1, 2, 3, 4
|
||||
],
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "29d4fb9f-0ad3-4911-89c1-68789d58e00c",
|
||||
"name": "light",
|
||||
"displayName": "Light",
|
||||
"displayNameEvent": "Light on/off changed",
|
||||
"displayNameAction": "Set light on/off",
|
||||
"defaultValue": false,
|
||||
"type": "bool",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "d5953bee-eb5a-4c3d-a7a4-3f24562f585d",
|
||||
"name": "lightColor",
|
||||
"displayName": "Light color",
|
||||
"displayNameEvent": "Light color changed",
|
||||
"displayNameAction": "Set light color",
|
||||
"defaultValue": "white",
|
||||
"type": "QString",
|
||||
"writable": true,
|
||||
"possibleValues": [
|
||||
"white",
|
||||
"blue",
|
||||
"red",
|
||||
"yellow",
|
||||
"orange",
|
||||
"green",
|
||||
"pink",
|
||||
"purple",
|
||||
"turquoise"
|
||||
]
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "0aae84bb-5502-437c-b821-46ef26209e09",
|
||||
"name": "stopHood",
|
||||
"displayName": "Stop"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -92,11 +92,7 @@ void Miele::getAccessTokenFromRefreshToken(const QByteArray &refreshToken)
|
||||
qCWarning(dcMiele()) << "No refresh token given!";
|
||||
setAuthenticated(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//delete me
|
||||
qCDebug(dcMiele()) << "Refresh token is not empty: " << refreshToken;
|
||||
qCDebug(dcMiele()) << "Client: " << m_clientId << " secret: " << m_clientSecret;
|
||||
}
|
||||
|
||||
QUrl url(m_tokenUrl);
|
||||
QUrlQuery query;
|
||||
@ -302,6 +298,10 @@ void Miele::getDeviceState(const QString &deviceId) {
|
||||
|
||||
QByteArray rawData = reply->readAll();
|
||||
if (!checkStatusCode(reply, rawData)) {
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
if (status == 404) {
|
||||
emit deviceNotFound(deviceId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
QVariantMap map = QJsonDocument::fromJson(rawData).toVariant().toMap();
|
||||
@ -387,6 +387,15 @@ QUuid Miele::setColors(const QString &deviceId, Miele::Color color)
|
||||
return putAction(deviceId, doc);
|
||||
}
|
||||
|
||||
QUuid Miele::setColorsStr(const QString &deviceId, const QString &color)
|
||||
{
|
||||
QJsonDocument doc;
|
||||
QJsonObject object;
|
||||
object.insert("colors", color.toLower());
|
||||
doc.setObject(object);
|
||||
return putAction(deviceId, doc);
|
||||
}
|
||||
|
||||
QUuid Miele::setModes(const QString &deviceId, Miele::Mode mode)
|
||||
{
|
||||
QJsonDocument doc;
|
||||
|
||||
@ -122,9 +122,10 @@ public:
|
||||
QUuid setLight(const QString &deviceId, bool power);
|
||||
QUuid setTargetTemperature(const QString &deviceId, int zone, int targetTemperature);
|
||||
QUuid setColors(const QString &deviceId, Color color);
|
||||
QUuid setColorsStr(const QString &deviceId, const QString &color);
|
||||
QUuid setModes(const QString &deviceId, Mode mode);
|
||||
QUuid setVentilationStep(const QString &deviceId, int step);
|
||||
QUuid setStartTime(const QString &deviceId, int seconds);
|
||||
QUuid setStartTime(const QString &deviceId, int seconds);
|
||||
|
||||
// EVENTS
|
||||
void getAllEvents();
|
||||
@ -162,6 +163,7 @@ signals:
|
||||
void commandExecuted(const QUuid &commandId, bool success);
|
||||
void devicesFound(QList<DeviceShort> devices);
|
||||
void deviceStateReceived(const QString &deviceId, const QVariantMap &deviceState);
|
||||
void deviceNotFound(const QString &deviceId);
|
||||
|
||||
private slots:
|
||||
void onRefreshTimeout();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user