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("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)
@ -202,7 +210,7 @@ void IntegrationPluginMiele::postSetupThing(Thing *thing)
qWarning(dcMiele()) << "No Miele account found for" << thing->name();
continue;
}
miele->getDevicesShort();
miele->getDevices();
Q_FOREACH (Thing *childThing, myThings().filterByParentId(thing->id())) {
QString deviceId = childThing->paramValue(m_idParamTypeIds.value(childThing->thingClassId())).toString();
miele->getDeviceState(deviceId);
@ -213,7 +221,7 @@ void IntegrationPluginMiele::postSetupThing(Thing *thing)
if (thing->thingClassId() == mieleAccountThingClassId) {
Miele *miele = m_mieleConnections.value(thing);
miele->getDevicesShort();
miele->getDevices();
miele->connectEventStream();
thing->setStateValue(mieleAccountConnectedStateTypeId, true);
thing->setStateValue(mieleAccountLoggedInStateTypeId, true);
@ -413,12 +421,12 @@ void IntegrationPluginMiele::onDevicesFound(QList<Miele::DeviceShort> devices)
ThingDescriptors descriptors;
foreach(Miele::DeviceShort ds, devices) {
qCDebug(dcMiele()) << "Setting up device: " << ds.type << " " << ds.name << " " << ds.state;
if (!m_mieleDeviceTypeLabelToThingClassId.contains(ds.type.toLower())) {
qCDebug(dcMiele()) << "Setting up device: " << ds.type << " " << ds.name;
if (!m_mieleDeviceTypeToThingClassId.contains(ds.type)) {
qCDebug(dcMiele()) << "Device type [" << ds.type << "] is not supported!";
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());
ParamList params;
params.append(Param(m_idParamTypeIds.value(deviceClassId), ds.fabNumber));

View File

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

View File

@ -92,7 +92,7 @@ void Miele::getAccessTokenFromRefreshToken(const QByteArray &refreshToken)
qCWarning(dcMiele()) << "No refresh token given!";
setAuthenticated(false);
return;
}
}
QUrl url(m_tokenUrl);
QUrlQuery query;
@ -173,7 +173,7 @@ void Miele::getAccessTokenFromAuthorizationCode(const QByteArray &authorizationC
}
m_accessToken = jsonDoc.toVariant().toMap().value("access_token").toByteArray();
receivedAccessToken(m_accessToken);
m_refreshToken = jsonDoc.toVariant().toMap().value("refresh_token").toByteArray();
m_refreshToken = jsonDoc.toVariant().toMap().value("refresh_token").toByteArray();
receivedRefreshToken(m_refreshToken);
if (jsonDoc.toVariant().toMap().contains("expires_in")) {
@ -184,7 +184,7 @@ void Miele::getAccessTokenFromAuthorizationCode(const QByteArray &authorizationC
qCWarning(dcMiele()) << "Expire time too short";
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)) {
return;
}
QVariantMap map = QJsonDocument::fromJson(rawData).toVariant().toMap();
if (map.contains("data")) {
QVariantMap dataMap = map.value("data").toMap();
qCDebug(dcMiele()) << "key" << dataMap.value("key").toString() << "value" << dataMap.value("value").toString() << dataMap.value("unit").toString();
} else if (map.contains("error")) {
qCWarning(dcMiele()) << "Send command" << map.value("error").toMap().value("description").toString();
QVariantMap map = QJsonDocument::fromJson(rawData).toVariant().toMap();
QList<DeviceShort> foundDevices;
foreach (QVariant deviceData, map.values()) {
QVariantMap deviceDetails = deviceData.toMap();
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.name = deviceObj["deviceName"].toString();
ds.state = deviceObj["state"].toString();
ds.type = deviceObj["type"].toString();
//ds.type = deviceObj["type"].toString();
foundDevices.append(ds);
}
emit devicesFound(foundDevices);
@ -373,7 +383,7 @@ QUuid Miele::setTargetTemperature(const QString &deviceId, int zone, int targetT
QJsonArray tempZones;
tempZones.push_front(temperatureObj);
object.insert("targetTemperature", tempZones);
doc.setObject(object);
doc.setObject(object);
return putAction(deviceId, doc);
}
@ -440,16 +450,34 @@ void Miele::connectEventStream()
connect(reply, &QNetworkReply::readyRead, this, [this, reply]{
while (reply->canReadLine()) {
QByteArray rawData = reply->readAll();
qCDebug(dcMiele()) << "Raw events data: " << rawData;
QJsonDocument data = QJsonDocument::fromJson(rawData);
qCDebug(dcMiele()) << "Got events data: " << data.toJson();
QByteArray eventTypeLine = reply->readLine();
if (eventTypeLine == "\n") {
continue;
}
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();
foreach (QVariant eventEntry, eventsData.values()) {
QVariantMap eventEntryMap = eventEntry.toMap();
if (!eventEntryMap.contains("ident")) {
qCWarning(dcMiele()) << "Got event but no device ident available";
return;
continue;
}
QVariantMap deviceIdent = eventEntryMap.value("ident").toMap().value("deviceIdentLabel").toMap();
QString deviceId = deviceIdent.value("fabNumber").toString();

View File

@ -90,12 +90,40 @@ public:
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 {
QString details;
QString name;
QString fabNumber;
QString state;
QString type;
DeviceType type;
};
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 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 connectEventStream();