From 2c8e57ecff70745f07500e7b30925f56540acd9b Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Mon, 11 Mar 2024 21:32:22 +0100 Subject: [PATCH] Replaced u_hold with more generic u_stabilize. --- apps/aqhome-react/aqhome_react.c | 12 +- apps/aqhome-react/units/0BUILD | 4 +- .../units/{u_hold.c => u_stabilize.c} | 142 +++++++++++------- .../units/{u_hold.h => u_stabilize.h} | 9 +- 4 files changed, 101 insertions(+), 66 deletions(-) rename apps/aqhome-react/units/{u_hold.c => u_stabilize.c} (52%) rename apps/aqhome-react/units/{u_hold.h => u_stabilize.h} (64%) diff --git a/apps/aqhome-react/aqhome_react.c b/apps/aqhome-react/aqhome_react.c index f5ebf0b..16133a5 100644 --- a/apps/aqhome-react/aqhome_react.c +++ b/apps/aqhome-react/aqhome_react.c @@ -13,7 +13,9 @@ #include "./aqhome_react_p.h" #include "aqhome-react/units/u_or.h" #include "aqhome-react/units/u_valuefilter.h" -#include "aqhome-react/units/u_hold.h" +#include "aqhome-react/units/u_stabilize.h" +#include "aqhome-react/units/u_lowpass.h" +#include "aqhome-react/units/u_highpass.h" #include @@ -168,8 +170,12 @@ AQHREACT_UNIT *AqHomeReact_CreateUnitByName(AQHOME_REACT *aqh, const char *unitT return AqHomeReact_UnitOr_new(); else if (strcasecmp(unitType, "valueFilter")==0) return AqHomeReact_UnitValueFilter_new(); - else if (strcasecmp(unitType, "hold")==0) - return AqHomeReact_UnitHold_new(); + else if (strcasecmp(unitType, "stabilize")==0) + return AqHomeReact_UnitStabilize_new(); + else if (strcasecmp(unitType, "lowPass")==0) + return AqHomeReact_UnitLowPass_new(); + else if (strcasecmp(unitType, "highPass")==0) + return AqHomeReact_UnitHighPass_new(); else { DBG_ERROR(NULL, "Unknown unit type \"%s\"", unitType); return NULL; diff --git a/apps/aqhome-react/units/0BUILD b/apps/aqhome-react/units/0BUILD index 15029af..a5e3813 100644 --- a/apps/aqhome-react/units/0BUILD +++ b/apps/aqhome-react/units/0BUILD @@ -42,9 +42,9 @@ u_varchanges.h u_valuefilter.h u_timer.h - u_hold.h u_lowpass.h u_highpass.h + u_stabilize.h @@ -54,9 +54,9 @@ u_varchanges.c u_valuefilter.c u_timer.c - u_hold.c u_lowpass.c u_highpass.c + u_stabilize.c diff --git a/apps/aqhome-react/units/u_hold.c b/apps/aqhome-react/units/u_stabilize.c similarity index 52% rename from apps/aqhome-react/units/u_hold.c rename to apps/aqhome-react/units/u_stabilize.c index b1ac7ae..9a5a1ef 100644 --- a/apps/aqhome-react/units/u_hold.c +++ b/apps/aqhome-react/units/u_stabilize.c @@ -10,7 +10,7 @@ # include #endif -#include "./u_hold.h" +#include "./u_stabilize.h" #include @@ -21,10 +21,10 @@ * ------------------------------------------------------------------------------------------------ */ -#define AQHOMEREACT_UNIT_HOLD_INSLOT_INPUT 0 -#define AQHOMEREACT_UNIT_HOLD_INSLOT_TIMER 1 +#define AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT 0 +#define AQHOMEREACT_UNIT_STABILIZE_INSLOT_TIMER 1 -#define AQHOMEREACT_UNIT_HOLD_OUTSLOT_OUTPUT 0 +#define AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT 0 @@ -33,13 +33,13 @@ * ------------------------------------------------------------------------------------------------ */ -typedef struct AQHREACT_UNIT_HOLD AQHREACT_UNIT_HOLD; -struct AQHREACT_UNIT_HOLD { +typedef struct AQHREACT_UNIT_STABILIZE AQHREACT_UNIT_STABILIZE; +struct AQHREACT_UNIT_STABILIZE { uint64_t tsHoldUntil; int lastProcessedState; int currentOutState; }; -GWEN_INHERIT(AQHREACT_UNIT, AQHREACT_UNIT_HOLD) +GWEN_INHERIT(AQHREACT_UNIT, AQHREACT_UNIT_STABILIZE) @@ -51,6 +51,9 @@ GWEN_INHERIT(AQHREACT_UNIT, AQHREACT_UNIT_HOLD) static void GWENHYWFAR_CB _freeData(void *bp, void *p); static int _cbProcessFn(AQHREACT_UNIT *unit); static int _checkState(AQHREACT_UNIT *unit); +static int _handleStateNoChange(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newState); +static void _startTimer(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newState); +static void _setOutput(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newState); @@ -59,36 +62,36 @@ static int _checkState(AQHREACT_UNIT *unit); * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT *AqHomeReact_UnitHold_new(void) +AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(void) { - AQHREACT_UNIT_HOLD *xunit; + AQHREACT_UNIT_STABILIZE *xunit; AQHREACT_UNIT *unit; AQHREACT_OUTPUT_SLOT *outputSlot; AQHREACT_INPUT_SLOT *inputSlot; unit=AQHREACT_Unit_new(); - GWEN_NEW_OBJECT(AQHREACT_UNIT_HOLD, xunit); - GWEN_INHERIT_SETDATA(AQHREACT_UNIT, AQHREACT_UNIT_HOLD, unit, xunit, _freeData); + GWEN_NEW_OBJECT(AQHREACT_UNIT_STABILIZE, xunit); + GWEN_INHERIT_SETDATA(AQHREACT_UNIT, AQHREACT_UNIT_STABILIZE, unit, xunit, _freeData); - AQHREACT_Unit_SetName(unit, "hold"); - AQHREACT_Unit_SetDescription(unit, "Hold incoming signal for a given time"); + AQHREACT_Unit_SetName(unit, "stabilize"); + AQHREACT_Unit_SetDescription(unit, "Stabilize signal changes (only propagate changes stable for some time)"); AQHREACT_Unit_SetProcessFn(unit, _cbProcessFn); outputSlot=AQHREACT_OutputSlot_new(); AQHREACT_OutputSlot_SetName(outputSlot, "output"); - AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_HOLD_OUTSLOT_OUTPUT); + AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT); AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Unit_AddOutputSlot(unit, outputSlot); inputSlot=AQHREACT_InputSlot_new(); AQHREACT_InputSlot_SetName(inputSlot, "input"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_HOLD_INSLOT_INPUT); + AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT); AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Unit_AddInputSlot(unit, inputSlot); inputSlot=AQHREACT_InputSlot_new(); AQHREACT_InputSlot_SetName(inputSlot, "timer"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_HOLD_INSLOT_TIMER); + AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_STABILIZE_INSLOT_TIMER); AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Unit_AddInputSlot(unit, inputSlot); @@ -99,9 +102,9 @@ AQHREACT_UNIT *AqHomeReact_UnitHold_new(void) void _freeData(void *bp, void *p) { - AQHREACT_UNIT_HOLD *xunit; + AQHREACT_UNIT_STABILIZE *xunit; - xunit=(AQHREACT_UNIT_HOLD*) p; + xunit=(AQHREACT_UNIT_STABILIZE*) p; GWEN_FREE_OBJECT(xunit); } @@ -124,57 +127,31 @@ int _cbProcessFn(AQHREACT_UNIT *unit) int _checkState(AQHREACT_UNIT *unit) { - AQHREACT_UNIT_HOLD *xunit; + AQHREACT_UNIT_STABILIZE *xunit; int result=0; - xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_HOLD, unit); + xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_STABILIZE, unit); if (xunit) { AQHREACT_INPUT_SLOT *dataSlot; - dataSlot=AQHREACT_Unit_GetInputSlotByIdForUnit(unit, AQHOMEREACT_UNIT_HOLD_INSLOT_INPUT); + dataSlot=AQHREACT_Unit_GetInputSlotByIdForUnit(unit, AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT); if (dataSlot) { AQHREACT_DATAOBJECT *dataObject; dataObject=AQHREACT_InputSlot_GetCurrentDataObject(dataSlot); if (dataObject) { - double data; + int newState; - data=AQHREACT_DataObject_GetDoubleData(dataObject); - if (data>0.0) { - if (xunit->lastProcessedState==0) { /* was off, is on, turn output ON */ - DBG_INFO(NULL, "Turning output ON"); - AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_HOLD_OUTSLOT_OUTPUT, 1.0); - xunit->currentOutState=1; - result=1; - } - xunit->lastProcessedState=1; - } /* if new value is ON */ - else { - uint64_t now; - - now=(uint64_t) time(NULL); - if (xunit->lastProcessedState) { /* was 1, is now 0, start hold timer */ - int holdTime; - - DBG_INFO(NULL, "Starting timeout counter"); - holdTime=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_HOLD_PARAM_HOLDTIME, 30.0); - xunit->tsHoldUntil=now+holdTime; - result=1; - } - else { /* was 0, is 0, check timeout */ - if (xunit->currentOutState>0) { /* output is still ON, check hold time */ - if (now>xunit->tsHoldUntil) { - /* timeout, turn output OFF */ - DBG_INFO(NULL, "Turning output OFF"); - AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_HOLD_OUTSLOT_OUTPUT, 0.0); - xunit->currentOutState=0; - xunit->tsHoldUntil=0; - result=1; - } - } - } - xunit->lastProcessedState=0; + newState=(AQHREACT_DataObject_GetDoubleData(dataObject)>0.0)?1:0; + if (newState!=xunit->lastProcessedState) { + _startTimer(unit, xunit, newState); + result=1; } + else { + if (_handleStateNoChange(unit, xunit, newState)>0) + result=1; + } + xunit->lastProcessedState=newState; } } } @@ -183,3 +160,54 @@ int _checkState(AQHREACT_UNIT *unit) +int _handleStateNoChange(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newState) +{ + int result=0; + uint64_t now; + + now=(uint64_t) time(NULL); + if (now>xunit->tsHoldUntil) { + /* timeout, switch output */ + _setOutput(unit, xunit, newState); + result=1; + } + return result; +} + + + +void _startTimer(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newState) +{ + int holdTime; + uint64_t now; + + now=(uint64_t) time(NULL); + + DBG_INFO(NULL, "Starting timeout counter (%d)", newState); + if (newState) + holdTime=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_STABILIZE_PARAM_HOLDTIME_HIGH, 0.0); + else + holdTime=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_STABILIZE_PARAM_HOLDTIME_LOW, 30.0); + if (holdTime<=0.0) + _setOutput(unit, xunit, newState); + else + xunit->tsHoldUntil=now+holdTime; +} + + + +void _setOutput(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newState) +{ + /* timeout, switch output */ + DBG_INFO(NULL, "Switch output to %s", newState?"ON":"OFF"); + AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT, newState?1.0:0.0); + xunit->currentOutState=newState; + xunit->tsHoldUntil=0; +} + + + + + + + diff --git a/apps/aqhome-react/units/u_hold.h b/apps/aqhome-react/units/u_stabilize.h similarity index 64% rename from apps/aqhome-react/units/u_hold.h rename to apps/aqhome-react/units/u_stabilize.h index 7519544..cba8283 100644 --- a/apps/aqhome-react/units/u_hold.h +++ b/apps/aqhome-react/units/u_stabilize.h @@ -6,17 +6,18 @@ * should have received along with this file. ****************************************************************************/ -#ifndef AQHOMEREACT_U_HOLD_H -#define AQHOMEREACT_U_HOLD_H +#ifndef AQHOMEREACT_U_STABILIZE_H +#define AQHOMEREACT_U_STABILIZE_H #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" -#define AQHOMEREACT_UNIT_HOLD_PARAM_HOLDTIME "holdTime" +#define AQHOMEREACT_UNIT_STABILIZE_PARAM_HOLDTIME_HIGH "holdTimeHigh" +#define AQHOMEREACT_UNIT_STABILIZE_PARAM_HOLDTIME_LOW "holdTimeLow" -AQHREACT_UNIT *AqHomeReact_UnitHold_new(void); +AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(void);