Rely on deviceTypeId instead of localizez label when determining the

device type.
Fixed the parsing of events data.
This commit is contained in:
Paul Bot 2021-10-28 12:08:49 +03:00
parent 6d3d8f243e
commit a8ae371c80
4 changed files with 92 additions and 27 deletions

View File

@ -66,6 +66,14 @@ IntegrationPluginMiele::IntegrationPluginMiele()
m_mieleDeviceTypeLabelToThingClassId.insert("refrigerator", fridgeThingClassId); m_mieleDeviceTypeLabelToThingClassId.insert("refrigerator", fridgeThingClassId);
m_mieleDeviceTypeLabelToThingClassId.insert("hood", hoodThingClassId); m_mieleDeviceTypeLabelToThingClassId.insert("hood", hoodThingClassId);
m_mieleDeviceTypeToThingClassId.insert(Miele::DeviceType::Oven, ovenThingClassId);
m_mieleDeviceTypeToThingClassId.insert(Miele::DeviceType::WashingMachine, washerThingClassId);
m_mieleDeviceTypeToThingClassId.insert(Miele::DeviceType::DishWasher, dishwasherThingClassId);
m_mieleDeviceTypeToThingClassId.insert(Miele::DeviceType::CoffeeSystem, coffeeMakerThingClassId);
m_mieleDeviceTypeToThingClassId.insert(Miele::DeviceType::TumbleDryer, dryerThingClassId);
m_mieleDeviceTypeToThingClassId.insert(Miele::DeviceType::Fridge, fridgeThingClassId);
m_mieleDeviceTypeToThingClassId.insert(Miele::DeviceType::Hood, hoodThingClassId);
} }
void IntegrationPluginMiele::startPairing(ThingPairingInfo *info) void IntegrationPluginMiele::startPairing(ThingPairingInfo *info)
@ -202,7 +210,7 @@ void IntegrationPluginMiele::postSetupThing(Thing *thing)
qWarning(dcMiele()) << "No Miele account found for" << thing->name(); qWarning(dcMiele()) << "No Miele account found for" << thing->name();
continue; continue;
} }
miele->getDevicesShort(); miele->getDevices();
Q_FOREACH (Thing *childThing, myThings().filterByParentId(thing->id())) { Q_FOREACH (Thing *childThing, myThings().filterByParentId(thing->id())) {
QString deviceId = childThing->paramValue(m_idParamTypeIds.value(childThing->thingClassId())).toString(); QString deviceId = childThing->paramValue(m_idParamTypeIds.value(childThing->thingClassId())).toString();
miele->getDeviceState(deviceId); miele->getDeviceState(deviceId);
@ -213,7 +221,7 @@ void IntegrationPluginMiele::postSetupThing(Thing *thing)
if (thing->thingClassId() == mieleAccountThingClassId) { if (thing->thingClassId() == mieleAccountThingClassId) {
Miele *miele = m_mieleConnections.value(thing); Miele *miele = m_mieleConnections.value(thing);
miele->getDevicesShort(); miele->getDevices();
miele->connectEventStream(); miele->connectEventStream();
thing->setStateValue(mieleAccountConnectedStateTypeId, true); thing->setStateValue(mieleAccountConnectedStateTypeId, true);
thing->setStateValue(mieleAccountLoggedInStateTypeId, true); thing->setStateValue(mieleAccountLoggedInStateTypeId, true);
@ -413,12 +421,12 @@ void IntegrationPluginMiele::onDevicesFound(QList<Miele::DeviceShort> devices)
ThingDescriptors descriptors; ThingDescriptors descriptors;
foreach(Miele::DeviceShort ds, devices) { foreach(Miele::DeviceShort ds, devices) {
qCDebug(dcMiele()) << "Setting up device: " << ds.type << " " << ds.name << " " << ds.state; qCDebug(dcMiele()) << "Setting up device: " << ds.type << " " << ds.name;
if (!m_mieleDeviceTypeLabelToThingClassId.contains(ds.type.toLower())) { if (!m_mieleDeviceTypeToThingClassId.contains(ds.type)) {
qCDebug(dcMiele()) << "Device type [" << ds.type << "] is not supported!"; qCDebug(dcMiele()) << "Device type [" << ds.type << "] is not supported!";
continue; continue;
} }
ThingClassId deviceClassId = m_mieleDeviceTypeLabelToThingClassId.value(ds.type.toLower()); ThingClassId deviceClassId = m_mieleDeviceTypeToThingClassId.value(ds.type);
ThingDescriptor descriptor(deviceClassId, ds.name, "Appliance type: " + ds.type, parentDevice->id()); ThingDescriptor descriptor(deviceClassId, ds.name, "Appliance type: " + ds.type, parentDevice->id());
ParamList params; ParamList params;
params.append(Param(m_idParamTypeIds.value(deviceClassId), ds.fabNumber)); params.append(Param(m_idParamTypeIds.value(deviceClassId), ds.fabNumber));

View File

@ -67,18 +67,19 @@ private:
QHash<ThingClassId, ParamTypeId> m_idParamTypeIds; QHash<ThingClassId, ParamTypeId> m_idParamTypeIds;
QHash<ThingClassId, StateTypeId> m_connectedStateTypeIds; QHash<ThingClassId, StateTypeId> m_connectedStateTypeIds;
QHash<QString, ThingClassId> m_mieleDeviceTypeLabelToThingClassId; QHash<QString, ThingClassId> m_mieleDeviceTypeLabelToThingClassId;
QHash<Miele::DeviceType, ThingClassId> m_mieleDeviceTypeToThingClassId;
Miele *createMieleConnection(); Miele *createMieleConnection();
void setThingState(Thing *thing, const QVariantMap &state); void setThingState(Thing *thing, const QVariantMap &state);
private slots: private slots:
void onConnectionChanged(bool connected); void onConnectionChanged(bool connected);
void onAuthenticationStatusChanged(bool authenticated); void onAuthenticationStatusChanged(bool authenticated);
void onRequestExecuted(QUuid requestId, bool success); void onRequestExecuted(QUuid requestId, bool success);
void onDevicesFound(QList<Miele::DeviceShort> devices); void onDevicesFound(QList<Miele::DeviceShort> devices);
void onDeviceStateReceived(const QString &deviceId, const QVariantMap &deviceState); void onDeviceStateReceived(const QString &deviceId, const QVariantMap &deviceState);
void onDeviceNotFound(const QString &deviceId); void onDeviceNotFound(const QString &deviceId);
}; };

View File

@ -92,7 +92,7 @@ void Miele::getAccessTokenFromRefreshToken(const QByteArray &refreshToken)
qCWarning(dcMiele()) << "No refresh token given!"; qCWarning(dcMiele()) << "No refresh token given!";
setAuthenticated(false); setAuthenticated(false);
return; return;
} }
QUrl url(m_tokenUrl); QUrl url(m_tokenUrl);
QUrlQuery query; QUrlQuery query;
@ -173,7 +173,7 @@ void Miele::getAccessTokenFromAuthorizationCode(const QByteArray &authorizationC
} }
m_accessToken = jsonDoc.toVariant().toMap().value("access_token").toByteArray(); m_accessToken = jsonDoc.toVariant().toMap().value("access_token").toByteArray();
receivedAccessToken(m_accessToken); receivedAccessToken(m_accessToken);
m_refreshToken = jsonDoc.toVariant().toMap().value("refresh_token").toByteArray(); m_refreshToken = jsonDoc.toVariant().toMap().value("refresh_token").toByteArray();
receivedRefreshToken(m_refreshToken); receivedRefreshToken(m_refreshToken);
if (jsonDoc.toVariant().toMap().contains("expires_in")) { if (jsonDoc.toVariant().toMap().contains("expires_in")) {
@ -184,7 +184,7 @@ void Miele::getAccessTokenFromAuthorizationCode(const QByteArray &authorizationC
qCWarning(dcMiele()) << "Expire time too short"; qCWarning(dcMiele()) << "Expire time too short";
return; return;
} }
m_accessTokenExpireTime = QDateTime::currentMSecsSinceEpoch() + (expireTime-(m_refreshInterval*1000)); m_accessTokenExpireTime = QDateTime::currentMSecsSinceEpoch() + (expireTime-(m_refreshInterval*1000));
} }
}); });
} }
@ -211,13 +211,23 @@ void Miele::getDevices()
if (!checkStatusCode(reply, rawData)) { if (!checkStatusCode(reply, rawData)) {
return; return;
} }
QVariantMap map = QJsonDocument::fromJson(rawData).toVariant().toMap(); QVariantMap map = QJsonDocument::fromJson(rawData).toVariant().toMap();
if (map.contains("data")) {
QVariantMap dataMap = map.value("data").toMap(); QList<DeviceShort> foundDevices;
qCDebug(dcMiele()) << "key" << dataMap.value("key").toString() << "value" << dataMap.value("value").toString() << dataMap.value("unit").toString(); foreach (QVariant deviceData, map.values()) {
} else if (map.contains("error")) { QVariantMap deviceDetails = deviceData.toMap();
qCWarning(dcMiele()) << "Send command" << map.value("error").toMap().value("description").toString(); if (!deviceDetails.contains("ident")) {
qCWarning(dcMiele()) << "Got device but no ident available";
continue;
}
DeviceShort ds;
QVariantMap deviceIdentMap = deviceDetails.value("ident").toMap();
ds.fabNumber = deviceIdentMap.value("deviceIdentLabel").toMap().value("fabNumber").toString();
ds.name = deviceIdentMap.value("deviceName").toString();
ds.type = static_cast<DeviceType>(deviceIdentMap.value("type").toMap().value("value_raw").toInt());
foundDevices.append(ds);
} }
emit devicesFound(foundDevices);
}); });
} }
@ -251,7 +261,7 @@ void Miele::getDevicesShort()
ds.fabNumber = deviceObj["fabNumber"].toString(); ds.fabNumber = deviceObj["fabNumber"].toString();
ds.name = deviceObj["deviceName"].toString(); ds.name = deviceObj["deviceName"].toString();
ds.state = deviceObj["state"].toString(); ds.state = deviceObj["state"].toString();
ds.type = deviceObj["type"].toString(); //ds.type = deviceObj["type"].toString();
foundDevices.append(ds); foundDevices.append(ds);
} }
emit devicesFound(foundDevices); emit devicesFound(foundDevices);
@ -373,7 +383,7 @@ QUuid Miele::setTargetTemperature(const QString &deviceId, int zone, int targetT
QJsonArray tempZones; QJsonArray tempZones;
tempZones.push_front(temperatureObj); tempZones.push_front(temperatureObj);
object.insert("targetTemperature", tempZones); object.insert("targetTemperature", tempZones);
doc.setObject(object); doc.setObject(object);
return putAction(deviceId, doc); return putAction(deviceId, doc);
} }
@ -440,16 +450,34 @@ void Miele::connectEventStream()
connect(reply, &QNetworkReply::readyRead, this, [this, reply]{ connect(reply, &QNetworkReply::readyRead, this, [this, reply]{
while (reply->canReadLine()) { while (reply->canReadLine()) {
QByteArray rawData = reply->readAll(); QByteArray eventTypeLine = reply->readLine();
qCDebug(dcMiele()) << "Raw events data: " << rawData; if (eventTypeLine == "\n") {
QJsonDocument data = QJsonDocument::fromJson(rawData); continue;
qCDebug(dcMiele()) << "Got events data: " << data.toJson(); }
if (!eventTypeLine.startsWith("event")) {
qCWarning(dcMiele()) << "Invalid event type line: " << eventTypeLine;
return;
}
QString eventType = eventTypeLine.split(':').last().trimmed();
if (eventType != "devices") {
qCWarning(dcMiele()) << "Ignoring '" << eventType << "' events";
return;
}
QByteArray eventDataLine = reply->readLine();
if (!eventDataLine.startsWith("data")) {
qCWarning(dcMiele()) << "Invalid data received: " << eventDataLine;
return;
}
qCDebug(dcMiele()) << "Raw events data: " << eventDataLine;
QJsonDocument data = QJsonDocument::fromJson(eventDataLine.replace("data: ", ""));
qCDebug(dcMiele()) << "Got events data: " << data.toJson(QJsonDocument::Compact);
QVariantMap eventsData = data.toVariant().toMap(); QVariantMap eventsData = data.toVariant().toMap();
foreach (QVariant eventEntry, eventsData.values()) { foreach (QVariant eventEntry, eventsData.values()) {
QVariantMap eventEntryMap = eventEntry.toMap(); QVariantMap eventEntryMap = eventEntry.toMap();
if (!eventEntryMap.contains("ident")) { if (!eventEntryMap.contains("ident")) {
qCWarning(dcMiele()) << "Got event but no device ident available"; qCWarning(dcMiele()) << "Got event but no device ident available";
return; continue;
} }
QVariantMap deviceIdent = eventEntryMap.value("ident").toMap().value("deviceIdentLabel").toMap(); QVariantMap deviceIdent = eventEntryMap.value("ident").toMap().value("deviceIdentLabel").toMap();
QString deviceId = deviceIdent.value("fabNumber").toString(); QString deviceId = deviceIdent.value("fabNumber").toString();

View File

@ -90,12 +90,40 @@ public:
StatusNotConnected = 255 StatusNotConnected = 255
}; };
enum DeviceType {
WashingMachine = 1,
TumbleDryer = 2,
DishWasher = 7,
Oven = 12,
OvenMicrowave = 13,
HobHighlight = 14,
SteamOven = 15,
MicroWave = 16,
CoffeeSystem = 17,
Hood = 18,
Fridge = 19,
Freezer = 20,
FridgeFreezer = 21,
VacuumCleaner = 23,
WasherDryer = 24,
DishWarmer = 25,
HobInduction = 27,
SteamOvenCombination = 31,
WineCabinet = 32,
WineConditioningUnit = 33,
WineStorageConditioningUnit = 34,
SteamOvenMicrowaveCombination = 45,
VacuumDrawer = 48,
DialogOven= 67,
WineCabinetFreezerCombination = 68
};
struct DeviceShort { struct DeviceShort {
QString details; QString details;
QString name; QString name;
QString fabNumber; QString fabNumber;
QString state; QString state;
QString type; DeviceType type;
}; };
Miele(NetworkAccessManager *networkmanager, const QByteArray &clientId, const QByteArray &clientSecret, const QString &language = "en", QObject *parent = nullptr); Miele(NetworkAccessManager *networkmanager, const QByteArray &clientId, const QByteArray &clientSecret, const QString &language = "en", QObject *parent = nullptr);
@ -125,7 +153,7 @@ public:
QUuid setColorsStr(const QString &deviceId, const QString &color); QUuid setColorsStr(const QString &deviceId, const QString &color);
QUuid setModes(const QString &deviceId, Mode mode); QUuid setModes(const QString &deviceId, Mode mode);
QUuid setVentilationStep(const QString &deviceId, int step); QUuid setVentilationStep(const QString &deviceId, int step);
QUuid setStartTime(const QString &deviceId, int seconds); QUuid setStartTime(const QString &deviceId, int seconds);
// EVENTS // EVENTS
void connectEventStream(); void connectEventStream();