Generic Things: Add generic garage doors

pull/1/head
Michael Zanetti 2020-08-03 13:39:11 +02:00
parent 345793bdb5
commit 86018b95bc
3 changed files with 269 additions and 16 deletions

View File

@ -45,15 +45,12 @@ void IntegrationPluginGenericThings::setupThing(ThingSetupInfo *info)
Thing *thing = info->thing();
if (thing->thingClassId() == extendedBlindThingClassId) {
uint closingTime = thing->setting(extendedBlindSettingsClosingTimeParamTypeId).toUInt();
if (closingTime == 0) {
return info->finish(Thing::ThingErrorSetupFailed, tr("Invalid closing time"));
}
uint closingDuration = thing->setting(extendedBlindSettingsClosingDurationParamTypeId).toUInt();
QTimer* timer = new QTimer(this);
timer->setInterval(closingTime/100.00); // closing timer / 100 to update on every percent
timer->setInterval(closingDuration/100.00); // closing timer / 100 to update on every percent
m_extendedBlindPercentageTimer.insert(thing, timer);
connect(thing, &Thing::settingChanged, thing, [timer] (const ParamTypeId &paramTypeId, const QVariant &value) {
if (paramTypeId == extendedBlindSettingsClosingTimeParamTypeId) {
if (paramTypeId == extendedBlindSettingsClosingDurationParamTypeId) {
timer->setInterval(value.toUInt()/100.00);
}
});
@ -91,7 +88,7 @@ void IntegrationPluginGenericThings::setupThing(ThingSetupInfo *info)
}
});
} else if (info->thing()->thingClassId() == venetianBlindThingClassId) {
uint closingTime = thing->setting(venetianBlindSettingsClosingTimeParamTypeId).toUInt();
uint closingTime = thing->setting(venetianBlindSettingsClosingDurationParamTypeId).toUInt();
uint angleTime = thing->setting(venetianBlindSettingsAngleTimeParamTypeId).toUInt();
if (closingTime < angleTime) {
return info->finish(Thing::ThingErrorSetupFailed, tr("Invalid closing or angle time"));
@ -142,7 +139,7 @@ void IntegrationPluginGenericThings::setupThing(ThingSetupInfo *info)
angleTimer->setInterval(angleTime/180.00); // -90 to 90 degree -> 180 degree total
m_venetianBlindAngleTimer.insert(thing, angleTimer);
connect(thing, &Thing::settingChanged, thing, [closingTimer, angleTimer] (const ParamTypeId &paramTypeId, const QVariant &value) {
if (paramTypeId == venetianBlindSettingsClosingTimeParamTypeId) {
if (paramTypeId == venetianBlindSettingsClosingDurationParamTypeId) {
closingTimer->setInterval(value.toUInt()/100.00);
} else if (paramTypeId == venetianBlindSettingsAngleTimeParamTypeId) {
angleTimer->setInterval(value.toUInt()/180.00);
@ -204,6 +201,48 @@ void IntegrationPluginGenericThings::setupThing(ThingSetupInfo *info)
thing->setStateValue(extendedSmartMeterConsumerCurrentPowerStateTypeId, power*1000);
m_pulsesPerTimeframe.insert(thing, 0);
});
} else if (thing->thingClassId() == extendedStatefulGaragedoorThingClassId) {
uint openingDuration = thing->setting(extendedStatefulGaragedoorSettingsOpeningDurationParamTypeId).toUInt();
QTimer* timer = new QTimer(this);
timer->setInterval(openingDuration/100.00); // closing timer / 100 to update on every percent
m_statefulGaragePercentageTimer.insert(thing, timer);
connect(thing, &Thing::settingChanged, thing, [timer] (const ParamTypeId &paramTypeId, const QVariant &value) {
if (paramTypeId == extendedStatefulGaragedoorSettingsOpeningDurationParamTypeId) {
timer->setInterval(value.toUInt()/100.00);
}
});
connect(timer, &QTimer::timeout, this, [thing, timer, this] {
uint currentPercentage = thing->stateValue(extendedStatefulGaragedoorPercentageStateTypeId).toUInt();
uint targetPercentage = m_statefulGarageTargetPercentage.value(thing);
if (currentPercentage < targetPercentage) {
currentPercentage++;
thing->setStateValue(extendedStatefulGaragedoorPercentageStateTypeId, currentPercentage);
thing->setStateValue(extendedStatefulGaragedoorStateStateTypeId, "closing");
thing->setStateValue(extendedStatefulGaragedoorMovingStateTypeId, true);
thing->setStateValue(extendedStatefulGaragedoorOpeningOutputStateTypeId, false);
thing->setStateValue(extendedStatefulGaragedoorClosingOutputStateTypeId, true);
} else if (currentPercentage > targetPercentage) {
currentPercentage--;
thing->setStateValue(extendedStatefulGaragedoorPercentageStateTypeId, currentPercentage);
thing->setStateValue(extendedStatefulGaragedoorStateStateTypeId, "opening");
thing->setStateValue(extendedStatefulGaragedoorMovingStateTypeId, true);
thing->setStateValue(extendedStatefulGaragedoorOpeningOutputStateTypeId, true);
thing->setStateValue(extendedStatefulGaragedoorClosingOutputStateTypeId, false);
}
if (currentPercentage == targetPercentage){
QString state = currentPercentage == 100 ? "open" : currentPercentage == 0 ? "closed" : "intermediate";
thing->setStateValue(extendedStatefulGaragedoorStateStateTypeId, state);
thing->setStateValue(extendedStatefulGaragedoorMovingStateTypeId, false);
thing->setStateValue(extendedStatefulGaragedoorOpeningOutputStateTypeId, false);
thing->setStateValue(extendedStatefulGaragedoorClosingOutputStateTypeId, false);
qCDebug(dcGenericThings()) << "Stopping garage timer";
timer->stop();
}
});
}
info->finish(Thing::ThingErrorNoError);
}
@ -536,6 +575,57 @@ void IntegrationPluginGenericThings::executeAction(ThingActionInfo *info)
} else {
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
}
} else if (thing->thingClassId() == impulseGaragedooorThingClassId) {
if (action.actionTypeId() == impulseGaragedooorTriggerImpulseActionTypeId) {
uint duration = thing->setting(impulseGaragedooorSettingsImpulseDurationParamTypeId).toUInt();
thing->setStateValue(impulseGaragedooorImpulseStateTypeId, true);
QTimer::singleShot(duration, thing, [thing](){
thing->setStateValue(impulseGaragedooorImpulseStateTypeId, false);
});
info->finish(Thing::ThingErrorNoError);
return;
}
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
} else if (thing->thingClassId() == simpleGaragedoorThingClassId) {
if (action.actionTypeId() == simpleGaragedoorOpenActionTypeId) {
thing->setStateValue(simpleGaragedoorClosingOutputStateTypeId, false);
thing->setStateValue(simpleGaragedoorOpeningOutputStateTypeId, true);
info->finish(Thing::ThingErrorNoError);
return;
}
if (action.actionTypeId() == simpleGaragedoorCloseActionTypeId) {
thing->setStateValue(simpleGaragedoorOpeningOutputStateTypeId, false);
thing->setStateValue(simpleGaragedoorClosingOutputStateTypeId, true);
info->finish(Thing::ThingErrorNoError);
return;
}
if (action.actionTypeId() == simpleGaragedoorStopActionTypeId) {
thing->setStateValue(simpleGaragedoorClosingOutputStateTypeId, false);
thing->setStateValue(simpleGaragedoorOpeningOutputStateTypeId, false);
info->finish(Thing::ThingErrorNoError);
return;
}
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
} else if (thing->thingClassId() == extendedStatefulGaragedoorThingClassId) {
if (action.actionTypeId() == extendedStatefulGaragedoorOpenActionTypeId) {
m_statefulGarageTargetPercentage[thing] = 0;
m_statefulGaragePercentageTimer[thing]->start();
info->finish(Thing::ThingErrorNoError);
return;
}
if (action.actionTypeId() == extendedStatefulGaragedoorCloseActionTypeId) {
m_statefulGarageTargetPercentage[thing] = 100;
m_statefulGaragePercentageTimer[thing]->start();
info->finish(Thing::ThingErrorNoError);
return;
}
if (action.actionTypeId() == extendedStatefulGaragedoorStopActionTypeId) {
m_statefulGarageTargetPercentage[thing] = thing->stateValue(extendedStatefulGaragedoorPercentageStateTypeId).toUInt();
info->finish(Thing::ThingErrorNoError);
return;
}
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
} else {
Q_ASSERT_X(false, "executeAction", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
}

View File

@ -59,6 +59,8 @@ private:
QHash<Thing *, QTimer *> m_smartMeterTimer;
QHash<Thing *, uint> m_extendedBlindTargetPercentage;
QHash<Thing *, int> m_venetianBlindTargetAngle;
QHash<Thing *, QTimer *> m_statefulGaragePercentageTimer;
QHash<Thing *, uint> m_statefulGarageTargetPercentage;
enum BlindState {
BlindStateOpening,

View File

@ -133,16 +133,16 @@
{
"id": "40aa9f3c-a23c-4f7f-8786-fcf3554f3e19",
"name": "extendedBlind",
"displayName": "Generic extended blind",
"displayName": "Generic blind with position control",
"createMethods": ["user"],
"interfaces": ["extendedblind"],
"settingsTypes": [
{
"id": "27a95b8d-7f97-441b-a3be-0646c517cb06",
"name": "closingTime",
"displayName": "Closing time [MilliSecond]",
"name": "closingDuration",
"displayName": "Closing duration [ms]",
"type": "uint",
"minValue": 1,
"minValue": 1000,
"defaultValue": 5000
}
],
@ -231,16 +231,16 @@
"settingsTypes": [
{
"id": "4c0bf07d-aaab-4f67-af65-00ceaefbaa84",
"name": "closingTime",
"displayName": "Closing time [MilliSecond]",
"minValue": 1,
"name": "closingDuration",
"displayName": "Closing duration [ms]",
"minValue": 1000,
"type": "uint",
"defaultValue": 5000
},
{
"id": "6c8340bf-7fd3-43e3-a75b-dfa2f6426e11",
"name": "angleTime",
"displayName": "Angle end to end time [MilliSecond]",
"displayName": "Angle end to end time [ms]",
"minValue": 1,
"type": "uint",
"defaultValue": 1000
@ -396,6 +396,167 @@
}
]
},
{
"id": "d6699a12-f4a6-4c50-951c-f4f1cd0501dc",
"name": "impulseGaragedooor",
"displayName": "Impulse based garage door",
"createMethods": ["user"],
"interfaces": ["impulsegaragedoor"],
"settingsTypes": [
{
"id": "962b356c-e975-4d33-b114-10f655eaf74c",
"name": "impulseDuration",
"displayName": "Impulse duration",
"type": "uint",
"defaultValue": "200"
}
],
"actionTypes": [
{
"id": "ff5461c6-70fc-435e-8424-96fa59ed321e",
"name": "triggerImpulse",
"displayName": "Operate"
}
],
"stateTypes": [
{
"id": "5ccaf0aa-01a4-441f-b6ca-18940da096a5",
"name": "impulse",
"displayName": "Impulse",
"displayNameEvent": "Impulse changed",
"type": "bool",
"defaultValue": false,
"ioType": "digitalInput"
}
]
},
{
"id": "572403b1-bc22-4620-8170-53147a546033",
"name": "simpleGaragedoor",
"displayName": "Simple garage door",
"createMethods": ["user"],
"interfaces": ["simplegaragedoor"],
"actionTypes": [
{
"id": "3edb25af-ad51-495b-9ac9-ab97669339b7",
"name": "open",
"displayName": "Open"
},
{
"id": "1111c0ed-69b6-480c-9fd5-15292600d4f4",
"name": "close",
"displayName": "Close"
},
{
"id": "f346766f-44ee-452b-bb9c-e89ec0f56016",
"name": "stop",
"displayName": "Stop"
}
],
"stateTypes": [
{
"id": "fcd421eb-54f2-4195-bdef-ffa69e9dcc57",
"name": "openingOutput",
"displayName": "Opening output",
"displayNameEvent": "Opening output changed",
"type": "bool",
"defaultValue": false,
"ioType": "digitalInput"
},
{
"id": "44ef060a-e6fc-4f33-84d2-b24ac7d31ff1",
"name": "closingOutput",
"displayName": "Closing output",
"displayNameEvent": "Closing output changed",
"type": "bool",
"defaultValue": false,
"ioType": "digitalInput"
}
]
},
{
"id": "7341e689-4495-4422-851a-3e7c790394b8",
"name": "extendedStatefulGaragedoor",
"displayName": "Garage door with position control",
"createMethods": ["user"],
"interfaces": ["extendedstatefulgaragedoor"],
"settingsTypes": [
{
"id": "04fb7724-a870-4df9-a79e-fab693931238",
"name": "openingDuration",
"displayName": "Opening duration [ms]",
"type": "uint",
"minValue": 1000,
"defaultValue": 5000
}
],
"stateTypes": [
{
"id": "0cc74edb-7116-47cf-953a-409933f26557",
"name": "state",
"displayName": "State",
"displayNameEvent": "State changed",
"type": "QString",
"possibleValues": ["open", "closed", "opening", "closing", "intermediate"],
"defaultValue": "closed"
},
{
"id": "963bed3d-2ccb-4dd0-b609-c7e9f25d32d6",
"name": "moving",
"displayName": "Moving",
"displayNameEvent": "Moving changed",
"type": "bool",
"defaultValue": false
},
{
"id": "f9244c14-0bc9-49ce-90a5-437e66245594",
"name": "percentage",
"displayName": "Open position",
"displayNameEvent": "Open position changed",
"displayNameAction": "Set open position",
"type": "int",
"minValue": 0,
"maxValue": 100,
"defaultValue": 100,
"writable": true
},
{
"id": "ecc799c7-4d74-4d1f-94e5-2d74e77493ae",
"name": "openingOutput",
"displayName": "Opening output",
"displayNameEvent": "Opening output changed",
"type": "bool",
"defaultValue": false,
"ioType": "digitalInput"
},
{
"id": "e1c14bcd-6131-494b-8dd1-46738e9c8f5e",
"name": "closingOutput",
"displayName": "Closing output",
"displayNameEvent": "Closing output changed",
"type": "bool",
"defaultValue": false,
"ioType": "digitalInput"
}
],
"actionTypes": [
{
"id": "4a3a3b88-47e9-436f-86be-b5955f3fc2f7",
"name": "open",
"displayName": "Open"
},
{
"id": "2420fcdb-03d3-4edb-aa89-e3b93c7d6d18",
"name": "close",
"displayName": "Close"
},
{
"id": "109c3eaf-26a0-4121-8be2-1363253178fd",
"name": "stop",
"displayName": "Stop"
}
]
},
{
"id": "4e7261af-a27b-4446-8346-914ea59f7547",
"name": "socket",