566 lines
27 KiB
C++
566 lines
27 KiB
C++
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
*
|
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
|
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
|
*
|
|
* This file is part of nymea-energy-plugin-nymea.
|
|
*
|
|
* nymea-energy-plugin-nymea.s 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, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* nymea-energy-plugin-nymea.s 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 nymea-energy-plugin-nymea. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
#include "integrationpluginenergymocks.h"
|
|
|
|
#include "plugininfo.h"
|
|
#include "mockcontroller.h"
|
|
|
|
#include <QTimer>
|
|
|
|
#include <hardware/electricity.h>
|
|
|
|
IntegrationPluginEnergyMocks::IntegrationPluginEnergyMocks(QObject *parent) : IntegrationPlugin(parent)
|
|
{
|
|
|
|
}
|
|
|
|
void IntegrationPluginEnergyMocks::setupThing(ThingSetupInfo *info)
|
|
{
|
|
Thing *thing = info->thing();
|
|
qCDebug(dcEnergyMocks()) << "Setting up" << thing << thing->params();
|
|
|
|
if (thing->thingClassId() == chargerThingClassId) {
|
|
EnergyMockController *controller = new EnergyMockController(thing, this);
|
|
ParamType paramType = thing->thingClass().paramTypes().findByName("port");
|
|
quint16 port = thing->paramValue(paramType.id()).toUInt();
|
|
if (!controller->listen(QHostAddress::Any, port)) {
|
|
qCWarning(dcEnergyMocks()) << "Failed to start mock controller on port" << controller->errorString();
|
|
delete controller;
|
|
info->finish(Thing::ThingErrorThingInUse);
|
|
return;
|
|
}
|
|
|
|
connect(controller, &EnergyMockController::updateStateRequestReceived, thing, [=](const QUrlQuery &query){
|
|
if (query.hasQueryItem("connected"))
|
|
thing->setStateValue("connected", QVariant(query.queryItemValue("connected")).toBool());
|
|
|
|
if (query.hasQueryItem("power"))
|
|
thing->setStateValue("power", QVariant(query.queryItemValue("power")).toBool());
|
|
|
|
if (query.hasQueryItem("pluggedIn"))
|
|
thing->setStateValue("pluggedIn", QVariant(query.queryItemValue("pluggedIn")).toBool());
|
|
|
|
if (query.hasQueryItem("usedPhases")) {
|
|
thing->setStateValue("usedPhases", query.queryItemValue("usedPhases"));
|
|
thing->setStateValue("phaseCount", Electricity::getPhaseCount(Electricity::convertPhasesFromString(query.queryItemValue("usedPhases"))));
|
|
}
|
|
|
|
if (query.hasQueryItem("maxChargingCurrent"))
|
|
thing->setStateValue("maxChargingCurrent", QVariant(query.queryItemValue("maxChargingCurrent")).toInt());
|
|
|
|
if (query.hasQueryItem("maxChargingCurrentMaxValue"))
|
|
thing->setStateMaxValue("maxChargingCurrent", QVariant(query.queryItemValue("maxChargingCurrentMaxValue")).toInt());
|
|
|
|
|
|
updateChargerMeter(thing);
|
|
|
|
qCDebug(dcEnergyMocks()) << "--> States" << thing->name();
|
|
foreach (const State &state, thing->states())
|
|
qCDebug(dcEnergyMocks()) << " -" << thing->thingClass().stateTypes().findById(state.stateTypeId()).displayName() << ":" << state.value();
|
|
|
|
});
|
|
|
|
|
|
qCDebug(dcEnergyMocks()) << "Setting up charger" << thing->name() << "finished successfully";
|
|
m_controllers.insert(thing, controller);
|
|
info->finish(Thing::ThingErrorNoError);
|
|
|
|
thing->setStateValue("usedPhases", thing->paramValue("phases").toString());
|
|
thing->setStateValue("phaseCount", Electricity::getPhaseCount(Electricity::convertPhasesFromString(thing->stateValue("usedPhases").toString())));
|
|
thing->setStateMaxValue("maxChargingCurrent", QVariant(thing->paramValue("maxChargingCurrentUpperLimit")).toInt());
|
|
|
|
updateChargerMeter(thing);
|
|
|
|
return;
|
|
|
|
} else if (thing->thingClassId() == chargerPhaseSwitchingThingClassId) {
|
|
EnergyMockController *controller = new EnergyMockController(thing, this);
|
|
ParamType paramType = thing->thingClass().paramTypes().findByName("port");
|
|
quint16 port = thing->paramValue(paramType.id()).toUInt();
|
|
if (!controller->listen(QHostAddress::Any, port)) {
|
|
qCWarning(dcEnergyMocks()) << "Failed to start mock controller on port" << controller->errorString();
|
|
delete controller;
|
|
info->finish(Thing::ThingErrorThingInUse);
|
|
return;
|
|
}
|
|
|
|
connect(controller, &EnergyMockController::updateStateRequestReceived, thing, [=](const QUrlQuery &query){
|
|
|
|
if (query.hasQueryItem("connected"))
|
|
thing->setStateValue("connected", QVariant(query.queryItemValue("connected")).toBool());
|
|
|
|
if (query.hasQueryItem("power"))
|
|
thing->setStateValue("power", QVariant(query.queryItemValue("power")).toBool());
|
|
|
|
if (query.hasQueryItem("pluggedIn"))
|
|
thing->setStateValue("pluggedIn", QVariant(query.queryItemValue("pluggedIn")).toBool());
|
|
|
|
if (query.hasQueryItem("usedPhases")) {
|
|
thing->setStateValue("usedPhases", query.queryItemValue("usedPhases"));
|
|
thing->setStateValue("phaseCount", Electricity::getPhaseCount(Electricity::convertPhasesFromString(query.queryItemValue("usedPhases"))));
|
|
}
|
|
|
|
if (query.hasQueryItem("maxChargingCurrent"))
|
|
thing->setStateValue("maxChargingCurrent", QVariant(query.queryItemValue("maxChargingCurrent")).toInt());
|
|
|
|
if (query.hasQueryItem("maxChargingCurrentMaxValue"))
|
|
thing->setStateMaxValue("maxChargingCurrent", QVariant(query.queryItemValue("maxChargingCurrentMaxValue")).toInt());
|
|
|
|
if (query.hasQueryItem("desiredPhaseCount"))
|
|
thing->setStateValue("desiredPhaseCount", QVariant(query.queryItemValue("desiredPhaseCount")).toUInt());
|
|
|
|
updateChargerMeter(thing);
|
|
|
|
qCDebug(dcEnergyMocks()) << "--> States" << thing->name();
|
|
foreach (const State &state, thing->states())
|
|
qCDebug(dcEnergyMocks()) << " -" << thing->thingClass().stateTypes().findById(state.stateTypeId()).displayName() << ":" << state.value();
|
|
|
|
});
|
|
|
|
qCDebug(dcEnergyMocks()) << "Setting up charger" << thing->name() << "finished successfully";
|
|
m_controllers.insert(thing, controller);
|
|
info->finish(Thing::ThingErrorNoError);
|
|
|
|
thing->setStateValue("usedPhases", thing->paramValue("phases").toString());
|
|
thing->setStateValue("phaseCount", Electricity::getPhaseCount(Electricity::convertPhasesFromString(thing->stateValue("usedPhases").toString())));
|
|
thing->setStateMaxValue("maxChargingCurrent", QVariant(thing->paramValue("maxChargingCurrentUpperLimit")).toInt());
|
|
|
|
updateChargerMeter(thing);
|
|
|
|
return;
|
|
|
|
} else if (thing->thingClassId() == simpleChargerThingClassId) {
|
|
EnergyMockController *controller = new EnergyMockController(thing, this);
|
|
ParamType paramType = thing->thingClass().paramTypes().findByName("port");
|
|
quint16 port = thing->paramValue(paramType.id()).toUInt();
|
|
if (!controller->listen(QHostAddress::Any, port)) {
|
|
qCWarning(dcEnergyMocks()) << "Failed to start mock controller on port" << controller->errorString();
|
|
delete controller;
|
|
info->finish(Thing::ThingErrorThingInUse);
|
|
return;
|
|
}
|
|
|
|
connect(controller, &EnergyMockController::updateStateRequestReceived, thing, [=](const QUrlQuery &query){
|
|
if (query.hasQueryItem("connected"))
|
|
thing->setStateValue("connected", QVariant(query.queryItemValue("connected")).toBool());
|
|
|
|
if (query.hasQueryItem("power"))
|
|
thing->setStateValue("power", QVariant(query.queryItemValue("power")).toBool());
|
|
|
|
if (query.hasQueryItem("pluggedIn"))
|
|
thing->setStateValue("pluggedIn", QVariant(query.queryItemValue("pluggedIn")).toBool());
|
|
|
|
if (query.hasQueryItem("phaseCount"))
|
|
thing->setStateValue("phaseCount", QVariant(query.queryItemValue("phaseCount")).toInt());
|
|
|
|
if (query.hasQueryItem("maxChargingCurrent"))
|
|
thing->setStateValue("maxChargingCurrent", QVariant(query.queryItemValue("maxChargingCurrent")).toInt());
|
|
|
|
if (query.hasQueryItem("maxChargingCurrentMaxValue"))
|
|
thing->setStateMaxValue("maxChargingCurrent", QVariant(query.queryItemValue("maxChargingCurrentMaxValue")).toInt());
|
|
|
|
|
|
qCDebug(dcEnergyMocks()) << "--> States" << thing->name();
|
|
foreach (const State &state, thing->states())
|
|
qCDebug(dcEnergyMocks()) << " -" << thing->thingClass().stateTypes().findById(state.stateTypeId()).displayName() << ":" << state.value();
|
|
|
|
});
|
|
|
|
m_controllers.insert(thing, controller);
|
|
qCDebug(dcEnergyMocks()) << "Setting up simple charger" << thing->name() << "finished successfully";
|
|
info->finish(Thing::ThingErrorNoError);
|
|
return;
|
|
|
|
} else if (thing->thingClassId() == meterThingClassId) {
|
|
|
|
EnergyMockController *controller = new EnergyMockController(thing, this);
|
|
ParamType paramType = thing->thingClass().paramTypes().findByName("port");
|
|
quint16 port = thing->paramValue(paramType.id()).toUInt();
|
|
if (!controller->listen(QHostAddress::Any, port)) {
|
|
qCWarning(dcEnergyMocks()) << "Failed to start mock controller on port" << controller->errorString();
|
|
delete controller;
|
|
info->finish(Thing::ThingErrorThingInUse);
|
|
return;
|
|
}
|
|
|
|
|
|
connect(controller, &EnergyMockController::updateStateRequestReceived, thing, [=](const QUrlQuery &query){
|
|
|
|
if (query.hasQueryItem("connected"))
|
|
thing->setStateValue("connected", QVariant(query.queryItemValue("connected")).toBool());
|
|
|
|
if (query.hasQueryItem("originalPower")) {
|
|
// Split the original power on the 3 phases and add the current power (depending on the phases) from the charger
|
|
// double originalPhasePower = query.queryItemValue("originalPower").toInt() / 3.0;
|
|
|
|
// double phaseA = originalPhasePower;
|
|
// double phaseB = originalPhasePower;
|
|
// double phaseC = originalPhasePower;
|
|
|
|
// // Get charger phases, set each phase and then the sum
|
|
// foreach (Thing *chargerThing, myThings().filterByThingClassId(chargerThingClassId)) {
|
|
// Electricity::Phases phases = Electricity::convertPhasesFromString(thing->paramValue("phases").toString());
|
|
|
|
// //
|
|
// }
|
|
}
|
|
|
|
if (query.hasQueryItem("currentPowerPhaseA") && query.hasQueryItem("currentPowerPhaseB") && query.hasQueryItem("currentPowerPhaseC")) {
|
|
// We directly set the current power on the 3 phases, no need to perform calculations (for tests to emulate a certain situation)
|
|
int currentPowerPhaseA = query.queryItemValue("currentPowerPhaseA").toInt();
|
|
int currentPowerPhaseB = query.queryItemValue("currentPowerPhaseB").toInt();
|
|
int currentPowerPhaseC = query.queryItemValue("currentPowerPhaseC").toInt();
|
|
|
|
thing->setStateValue("currentPhaseA", currentPowerPhaseA / 230.0);
|
|
thing->setStateValue("currentPhaseB", currentPowerPhaseB / 230.0);
|
|
thing->setStateValue("currentPhaseC", currentPowerPhaseC / 230.0);
|
|
|
|
thing->setStateValue("currentPowerPhaseA", currentPowerPhaseA);
|
|
thing->setStateValue("currentPowerPhaseB", currentPowerPhaseB);
|
|
thing->setStateValue("currentPowerPhaseC", currentPowerPhaseC);
|
|
|
|
// Note: set the current power at the end since that triggers caclulations....
|
|
|
|
thing->setStateValue("currentPower", currentPowerPhaseA + currentPowerPhaseB + currentPowerPhaseC);
|
|
}
|
|
|
|
qCDebug(dcEnergyMocks()) << "--> States" << thing->name();
|
|
foreach (const State &state, thing->states())
|
|
qCDebug(dcEnergyMocks()) << " -" << thing->thingClass().stateTypes().findById(state.stateTypeId()).displayName() << ":" << state.value();
|
|
|
|
});
|
|
|
|
m_controllers.insert(thing, controller);
|
|
qCDebug(dcEnergyMocks()) << "Setting up meter" << thing->name() << "finished successfully";
|
|
info->finish(Thing::ThingErrorNoError);
|
|
return;
|
|
|
|
} else if (thing->thingClassId() == carThingClassId) {
|
|
|
|
EnergyMockController *controller = new EnergyMockController(thing, this);
|
|
ParamType paramType = thing->thingClass().paramTypes().findByName("port");
|
|
quint16 port = thing->paramValue(paramType.id()).toUInt();
|
|
if (!controller->listen(QHostAddress::Any, port)) {
|
|
qCWarning(dcEnergyMocks()) << "Failed to start mock controller on port" << controller->errorString();
|
|
delete controller;
|
|
info->finish(Thing::ThingErrorThingInUse);
|
|
return;
|
|
}
|
|
|
|
connect(controller, &EnergyMockController::updateStateRequestReceived, thing, [=](const QUrlQuery &query){
|
|
if (query.hasQueryItem("batteryLevel"))
|
|
thing->setStateValue("batteryLevel", QVariant(query.queryItemValue("batteryLevel")).toInt());
|
|
|
|
if (query.hasQueryItem("capacity"))
|
|
thing->setStateValue("capacity", QVariant(query.queryItemValue("capacity")).toInt());
|
|
|
|
if (query.hasQueryItem("minChargingCurrent"))
|
|
thing->setStateValue("minChargingCurrent", QVariant(query.queryItemValue("minChargingCurrent")).toInt());
|
|
|
|
if (query.hasQueryItem("phaseCount")) {
|
|
thing->setSettingValue(carSettingsPhaseCountParamTypeId, QVariant(query.queryItemValue("phaseCount")).toInt());
|
|
thing->setStateValue("phaseCount", QVariant(query.queryItemValue("phaseCount")).toInt());
|
|
}
|
|
|
|
});
|
|
|
|
// Set the min charging current state if the settings value changed
|
|
connect(thing, &Thing::settingChanged, controller, [thing](const ParamTypeId ¶mTypeId, const QVariant &value){
|
|
if (paramTypeId == carSettingsCapacityParamTypeId) {
|
|
qCDebug(dcEnergyMocks()) << "Car capacity settings changed" << value << "kWh";
|
|
thing->setStateValue(carCapacityStateTypeId, value);
|
|
} else if (paramTypeId == carSettingsMinChargingCurrentParamTypeId) {
|
|
qCDebug(dcEnergyMocks()) << "Car minimum charging current settings changed" << value.toUInt() << "A";
|
|
thing->setStateValue(carMinChargingCurrentStateTypeId, value);
|
|
} else if (paramTypeId == carSettingsPhaseCountParamTypeId) {
|
|
qCDebug(dcEnergyMocks()) << "Car phase count settings changed" << value.toUInt();
|
|
thing->setStateValue(carPhaseCountStateTypeId, value);
|
|
}
|
|
|
|
qCDebug(dcEnergyMocks()) << "--> States" << thing->name();
|
|
foreach (const State &state, thing->states())
|
|
qCDebug(dcEnergyMocks()) << " -" << thing->thingClass().stateTypes().findById(state.stateTypeId()).displayName() << ":" << state.value();
|
|
|
|
});
|
|
|
|
|
|
qCDebug(dcEnergyMocks()) << "Setting car" << thing->name() << "finished successfully";
|
|
m_controllers.insert(thing, controller);
|
|
info->finish(Thing::ThingErrorNoError);
|
|
thing->setStateValue(carMinChargingCurrentStateTypeId, thing->setting(carSettingsMinChargingCurrentParamTypeId));
|
|
return;
|
|
} else if (thing->thingClassId() == notificationThingClassId) {
|
|
EnergyMockController *controller = new EnergyMockController(thing, this);
|
|
ParamType paramType = thing->thingClass().paramTypes().findByName("port");
|
|
quint16 port = thing->paramValue(paramType.id()).toUInt();
|
|
if (!controller->listen(QHostAddress::Any, port)) {
|
|
qCWarning(dcEnergyMocks()) << "Failed to start mock controller on port" << controller->errorString();
|
|
delete controller;
|
|
info->finish(Thing::ThingErrorThingInUse);
|
|
return;
|
|
}
|
|
|
|
connect(controller, &EnergyMockController::updateStateRequestReceived, thing, [=](const QUrlQuery &query){
|
|
Q_UNUSED(query)
|
|
});
|
|
|
|
m_controllers.insert(thing, controller);
|
|
qCDebug(dcEnergyMocks()) << "Setting up notification" << thing->name() << "finished successfully";
|
|
info->finish(Thing::ThingErrorNoError);
|
|
return;
|
|
} else if (thing->thingClassId() == energyStorageThingClassId) {
|
|
EnergyMockController * controller = new EnergyMockController(thing, this);
|
|
ParamType paramType = thing->thingClass().paramTypes().findByName("port");
|
|
quint16 port = thing->paramValue(paramType.id()).toUInt();
|
|
if (!controller->listen(QHostAddress::Any, port)) {
|
|
qWarning(dcEnergyMocks()) << "Failed to start mock controller on port" << controller->errorString();
|
|
delete controller;
|
|
info->finish(Thing::ThingErrorThingInUse);
|
|
return;
|
|
}
|
|
|
|
connect(controller, &EnergyMockController::updateStateRequestReceived, thing, [=](const QUrlQuery &query){
|
|
if (query.hasQueryItem("batteryLevel")) {
|
|
thing->setStateValue("batteryLevel", QVariant(query.queryItemValue("batteryLevel")).toInt());
|
|
thing->setStateValue("batteryCritical", thing->stateValue("batteryLevel").toInt() < 10);
|
|
}
|
|
|
|
if (query.hasQueryItem("currentPower"))
|
|
thing->setStateValue("currentPower", QVariant(query.queryItemValue("currentPower")).toInt());
|
|
});
|
|
|
|
qCDebug(dcEnergyMocks()) << "Setting battery storage" << thing->name() << "finished successfully";
|
|
m_controllers.insert(thing, controller);
|
|
info->finish(Thing::ThingErrorNoError);
|
|
|
|
thing->setStateValue("capacity", thing->paramValue(energyStorageThingCapacityParamTypeId));
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
void IntegrationPluginEnergyMocks::thingRemoved(Thing *thing)
|
|
{
|
|
qCDebug(dcEnergyMocks()) << "Removing" << thing;
|
|
if (m_controllers.contains(thing)) {
|
|
delete m_controllers.take(thing);
|
|
}
|
|
}
|
|
|
|
void IntegrationPluginEnergyMocks::executeAction(ThingActionInfo *info)
|
|
{
|
|
Thing *thing = info->thing();
|
|
ThingClass thingClass = info->thing()->thingClass();
|
|
Action action = info->action();
|
|
ActionType actionType = thingClass.actionTypes().findById(action.actionTypeId());
|
|
|
|
qCDebug(dcEnergyMocks()) << "Executing action" << actionType.displayName() << "on" << thing->name() << action.params();
|
|
m_controllers.value(thing)->logActionExecuted(actionType, action);
|
|
|
|
// Update states
|
|
if (thing->thingClassId() == chargerThingClassId) {
|
|
|
|
// Note do this before every action execution since it might hase changed directly within the simulation
|
|
Electricity::Phases usedPhases = Electricity::convertPhasesFromString(thing->stateValue("usedPhases").toString());
|
|
uint phaseCount = Electricity::getPhaseCount(usedPhases);
|
|
thing->setStateValue("phaseCount", phaseCount);
|
|
|
|
if (actionType.name() == "maxChargingCurrent") {
|
|
uint maxChargingCurrent = action.paramValue(actionType.paramTypes().findByName("maxChargingCurrent").id()).toUInt();
|
|
thing->setStateValue("maxChargingCurrent", maxChargingCurrent);
|
|
updateChargerMeter(thing);
|
|
}
|
|
|
|
if (actionType.name() == "power") {
|
|
bool power = action.paramValue(actionType.paramTypes().findByName("power").id()).toBool();
|
|
qCDebug(dcEnergyMocks()) << "Setting charger power to" << power;
|
|
thing->setStateValue("power", power);
|
|
updateChargerMeter(thing);
|
|
}
|
|
|
|
if (actionType.name() == "update") {
|
|
updateChargerMeter(thing);
|
|
}
|
|
}
|
|
|
|
if (thing->thingClassId() == chargerPhaseSwitchingThingClassId) {
|
|
|
|
// Note do this before every action execution since it might has changed directly within the simulation
|
|
Electricity::Phases usedPhases = Electricity::convertPhasesFromString(thing->stateValue("usedPhases").toString());
|
|
uint phaseCount = Electricity::getPhaseCount(usedPhases);
|
|
thing->setStateValue("phaseCount", phaseCount);
|
|
|
|
if (actionType.name() == "maxChargingCurrent") {
|
|
uint maxChargingCurrent = action.paramValue(actionType.paramTypes().findByName("maxChargingCurrent").id()).toUInt();
|
|
thing->setStateValue("maxChargingCurrent", maxChargingCurrent);
|
|
updateChargerMeter(thing);
|
|
}
|
|
|
|
if (actionType.name() == "connected") {
|
|
bool connected = action.paramValue(actionType.paramTypes().findByName("connected").id()).toBool();
|
|
thing->setStateValue("connected", connected);
|
|
updateChargerMeter(thing);
|
|
}
|
|
|
|
if (actionType.name() == "pluggedIn") {
|
|
bool pluggedIn = action.paramValue(actionType.paramTypes().findByName("pluggedIn").id()).toBool();
|
|
thing->setStateValue("pluggedIn", pluggedIn);
|
|
updateChargerMeter(thing);
|
|
}
|
|
|
|
if (actionType.name() == "desiredPhaseCount") {
|
|
uint desiredPhaseCount = action.paramValue(actionType.paramTypes().findByName("desiredPhaseCount").id()).toUInt();
|
|
thing->setStateValue("desiredPhaseCount", desiredPhaseCount);
|
|
updateChargerMeter(thing);
|
|
}
|
|
|
|
if (actionType.name() == "power") {
|
|
bool power = action.paramValue(actionType.paramTypes().findByName("power").id()).toBool();
|
|
qCDebug(dcEnergyMocks()) << "Setting charger power to" << power;
|
|
thing->setStateValue("power", power);
|
|
updateChargerMeter(thing);
|
|
}
|
|
|
|
if (actionType.name() == "update") {
|
|
updateChargerMeter(thing);
|
|
}
|
|
}
|
|
|
|
|
|
if (thing->thingClassId() == simpleChargerThingClassId) {
|
|
if (actionType.name() == "maxChargingCurrent") {
|
|
uint maxChargingCurrent = action.paramValue(actionType.paramTypes().findByName("maxChargingCurrent").id()).toUInt();
|
|
thing->setStateValue("maxChargingCurrent", action.paramValue(actionType.paramTypes().findByName("maxChargingCurrent").id()).toUInt());
|
|
qCDebug(dcEnergyMocks()) << "Setting max charging current to" << maxChargingCurrent << "A";
|
|
}
|
|
|
|
if (actionType.name() == "power") {
|
|
bool power = action.paramValue(actionType.paramTypes().findByName("power").id()).toBool();
|
|
qCDebug(dcEnergyMocks()) << "Setting charger power to" << power;
|
|
thing->setStateValue("power", power);
|
|
}
|
|
}
|
|
|
|
if (thing->thingClassId() == carThingClassId) {
|
|
if (action.actionTypeId() == carBatteryLevelActionTypeId) {
|
|
thing->setStateValue(carBatteryLevelStateTypeId, action.paramValue(carBatteryLevelActionBatteryLevelParamTypeId));
|
|
thing->setStateValue(carBatteryCriticalStateTypeId, action.paramValue(carBatteryLevelActionBatteryLevelParamTypeId).toInt() < 10);
|
|
info->finish(Thing::ThingErrorNoError);
|
|
return;
|
|
} else {
|
|
Q_ASSERT_X(false, "executeAction", QString("Unhandled action: %1").arg(action.actionTypeId().toString()).toUtf8());
|
|
}
|
|
}
|
|
|
|
info->finish(Thing::ThingErrorNoError);
|
|
}
|
|
|
|
void IntegrationPluginEnergyMocks::updateChargerMeter(Thing *thing)
|
|
{
|
|
Electricity::Phases connectedPhases = Electricity::convertPhasesFromString(thing->paramValue("phases").toString());
|
|
bool canSwitchPhases = thing->hasState("desiredPhaseCount");
|
|
|
|
Electricity::Phases usedPhases = Electricity::PhaseNone;
|
|
if (canSwitchPhases) {
|
|
uint desiredPhaseCount = thing->stateValue("desiredPhaseCount").toUInt();
|
|
if (desiredPhaseCount == 1) {
|
|
usedPhases = Electricity::PhaseA;
|
|
} else {
|
|
usedPhases = Electricity::PhaseAll;
|
|
}
|
|
|
|
thing->setStateValue("usedPhases", Electricity::convertPhasesToString(usedPhases));
|
|
} else {
|
|
usedPhases = Electricity::convertPhasesFromString(thing->stateValue("usedPhases").toString());
|
|
}
|
|
|
|
uint phaseCount = Electricity::getPhaseCount(usedPhases);
|
|
thing->setStateValue("phaseCount", phaseCount);
|
|
|
|
if (connectedPhases.testFlag(Electricity::PhaseA)) {
|
|
thing->setStateValue("voltagePhaseA", 230);
|
|
} else {
|
|
thing->setStateValue("voltagePhaseA", 0);
|
|
}
|
|
|
|
if (connectedPhases.testFlag(Electricity::PhaseB)) {
|
|
thing->setStateValue("voltagePhaseB", 230);
|
|
} else {
|
|
thing->setStateValue("voltagePhaseB", 0);
|
|
}
|
|
|
|
if (connectedPhases.testFlag(Electricity::PhaseC)) {
|
|
thing->setStateValue("voltagePhaseC", 230);
|
|
} else {
|
|
thing->setStateValue("voltagePhaseC", 0);
|
|
}
|
|
|
|
double maxChargingCurrent = thing->stateValue("maxChargingCurrent").toDouble();
|
|
|
|
if (thing->stateValue("power").toBool() && thing->stateValue("connected").toBool() && thing->stateValue("pluggedIn").toBool()) {
|
|
double currentPower = maxChargingCurrent * 230 * phaseCount;
|
|
double phasePower = currentPower / phaseCount;
|
|
double phaseAmpere = maxChargingCurrent;
|
|
if (usedPhases.testFlag(Electricity::PhaseA)) {
|
|
thing->setStateValue("currentPhaseA", phaseAmpere);
|
|
thing->setStateValue("currentPowerPhaseA", phasePower);
|
|
} else {
|
|
thing->setStateValue("currentPhaseA", 0);
|
|
thing->setStateValue("currentPowerPhaseA", 0);
|
|
}
|
|
|
|
if (usedPhases.testFlag(Electricity::PhaseB)) {
|
|
thing->setStateValue("currentPhaseB", phaseAmpere);
|
|
thing->setStateValue("currentPowerPhaseB", phasePower);
|
|
} else {
|
|
thing->setStateValue("currentPhaseB", 0);
|
|
thing->setStateValue("currentPowerPhaseB", 0);
|
|
}
|
|
|
|
if (usedPhases.testFlag(Electricity::PhaseC)) {
|
|
thing->setStateValue("currentPhaseC", phaseAmpere);
|
|
thing->setStateValue("currentPowerPhaseC", phasePower);
|
|
} else {
|
|
thing->setStateValue("currentPhaseC", 0);
|
|
thing->setStateValue("currentPowerPhaseC", 0);
|
|
}
|
|
|
|
thing->setStateValue("currentPower", currentPower);
|
|
thing->setStateValue("charging", true);
|
|
} else {
|
|
thing->setStateValue("currentPhaseA", 0);
|
|
thing->setStateValue("currentPowerPhaseA", 0);
|
|
thing->setStateValue("currentPhaseB", 0);
|
|
thing->setStateValue("currentPowerPhaseB", 0);
|
|
thing->setStateValue("currentPhaseC", 0);
|
|
thing->setStateValue("currentPowerPhaseC", 0);
|
|
thing->setStateValue("currentPower", 0);
|
|
thing->setStateValue("charging", false);
|
|
}
|
|
|
|
|
|
}
|
|
|