Skip to content

Commit 45885d2

Browse files
committed
Count down - basic implementation, missing template and remaining handling
1 parent 6f35145 commit 45885d2

File tree

3 files changed

+158
-82
lines changed

3 files changed

+158
-82
lines changed

src/FunctionBlocks.templ.xml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -228,32 +228,32 @@
228228
<Union SizeInBit="560">
229229
<Memory CodeSegment="%MID%" Offset="2" BitOffset="0" />
230230
<!-- Count Down Time Start Ko-->
231-
<Parameter Id="%AID%_UP-%TT%%CC%197" Name="CH%C%FCBCountDownTimeStartKo" ParameterType="%AID%_PT-FCBCountDownTimeStartKo" Offset="0" BitOffset="0" Text="Start mit Zeit" Value="1" />
231+
<Parameter Id="%AID%_UP-%TT%%CC%197" Name="CH%C%CountDownTimeStartKo" ParameterType="%AID%_PT-FCBCountDownTimeStartKo" Offset="0" BitOffset="0" Text="Start mit Zeit" Value="1" />
232232
<!-- 4 bits free -->
233233
<!-- Count Down Start Value-->
234-
<Parameter Id="%AID%_UP-%TT%%CC%198" Name="CH%C%FCBCountDownStartValue" ParameterType="%AID%_PT-FCBCountDownStartValue" Offset="1" BitOffset="0" Text="Ablauf Zeit" Value="60" />
234+
<Parameter Id="%AID%_UP-%TT%%CC%198" Name="CH%C%CountDownStartValue" ParameterType="%AID%_PT-FCBCountDownStartValue" Offset="1" BitOffset="0" Text="Ablauf Zeit" Value="60" />
235235
<!-- ^^^ 32 bit value ^^^ -->
236236
<!-- Count Down Zeitoffset -->
237-
<Parameter Id="%AID%_UP-%TT%%CC%199" Name="CH%C%FCBCountDownTimeOffset" ParameterType="%AID%_PT-FCBCountDownTimeOffset" Offset="5" BitOffset="0" Text="Zeitoffset" Value="1" />
237+
<Parameter Id="%AID%_UP-%TT%%CC%199" Name="CH%C%CountDownTimeOffset" ParameterType="%AID%_PT-FCBCountDownTimeOffset" Offset="5" BitOffset="0" Text="Zeitoffset" Value="1" />
238238
<!-- Count Down Trigger -->
239-
<Parameter Id="%AID%_UP-%TT%%CC%200" Name="CH%C%FCBCountDownTrigger" ParameterType="%AID%_PT-FCBCountDownTrigger" Offset="5" BitOffset="4" Text="Trigger" Value="1" />
239+
<Parameter Id="%AID%_UP-%TT%%CC%200" Name="CH%C%CountDownTrigger" ParameterType="%AID%_PT-FCBCountDownTrigger" Offset="5" BitOffset="4" Text="Trigger" Value="1" />
240240
<!-- Text Template -->
241-
<Parameter Id="%AID%_UP-%TT%%CC%201" Name="CH%C%FCBCountDownTemplate" ParameterType="%AID%_PT-FCBCountDownTextTemplate" Offset="6" BitOffset="0" Text="Standard" Value="H2:M2 %" />
241+
<Parameter Id="%AID%_UP-%TT%%CC%201" Name="CH%C%CountDownTemplate" ParameterType="%AID%_PT-FCBCountDownTextTemplate" Offset="6" BitOffset="0" Text="Standard" Value="H2:M2 %" />
242242
<!-- ^^^ 14 + 1 byte for 0 terminator = 15 bytes ^^^-->
243243
<!-- Text Template kleiner 1 Stunde -->
244-
<Parameter Id="%AID%_UP-%TT%%CC%202" Name="CH%C%FCBCountDownTemplate1h" ParameterType="%AID%_PT-FCBCountDownTextTemplate" Offset="21" BitOffset="0" Text="kleiner eine Stunde" Value="M2 Minuten %" />
244+
<Parameter Id="%AID%_UP-%TT%%CC%202" Name="CH%C%CountDownTemplate1h" ParameterType="%AID%_PT-FCBCountDownTextTemplate" Offset="21" BitOffset="0" Text="kleiner eine Stunde" Value="M2 Minuten %" />
245245
<!-- ^^^ 14 + 1 byte for 0 terminator = 15 bytes ^^^-->
246246
<!-- Text Template kleiner 1 Minute -->
247-
<Parameter Id="%AID%_UP-%TT%%CC%203" Name="CH%C%FCBCountDownTemplate1m" ParameterType="%AID%_PT-FCBCountDownTextTemplate" Offset="36" BitOffset="0" Text="kleiner eine Minute" Value="S2 Sekunden %" />
247+
<Parameter Id="%AID%_UP-%TT%%CC%203" Name="CH%C%CountDownTemplate1m" ParameterType="%AID%_PT-FCBCountDownTextTemplate" Offset="36" BitOffset="0" Text="kleiner eine Minute" Value="S2 Sekunden %" />
248248
<!-- ^^^ 14 + 1 byte for 0 terminator = 15 bytes ^^^-->
249249
<!-- Text Template Ende -->
250-
<Parameter Id="%AID%_UP-%TT%%CC%204" Name="CH%C%FCBCountDownTemplateEnd" ParameterType="%AID%_PT-FCBCountDownTextTemplate" Offset="51" BitOffset="0" Text="Ende" Value="Ende" />
250+
<Parameter Id="%AID%_UP-%TT%%CC%204" Name="CH%C%CountDownTemplateEnd" ParameterType="%AID%_PT-FCBCountDownTextTemplate" Offset="51" BitOffset="0" Text="Ende" Value="Ende" />
251251
<!-- ^^^ 14 + 1 byte for 0 terminator = 15 bytes ^^^-->
252252
<!-- Text Template Pause -->
253-
<Parameter Id="%AID%_UP-%TT%%CC%205" Name="CH%C%FCBCountDownTextPause" ParameterType="%AID%_PT-FCBCountDownTextTemplatePauseRun" Offset="66" BitOffset="0" Text="Pause" Value="=" />
253+
<Parameter Id="%AID%_UP-%TT%%CC%205" Name="CH%C%CountDownTextPause" ParameterType="%AID%_PT-FCBCountDownTextTemplatePauseRun" Offset="66" BitOffset="0" Text="Pause" Value="=" />
254254
<!-- ^^^ 1 + 1 byte for 0 terminator = 2 bytes ^^^-->
255255
<!-- Text Template Läuft -->
256-
<Parameter Id="%AID%_UP-%TT%%CC%206" Name="CH%C%FCBCountDownTextRun" ParameterType="%AID%_PT-FCBCountDownTextTemplatePauseRun" Offset="68" BitOffset="0" Text="Läuft" Value="v" />
256+
<Parameter Id="%AID%_UP-%TT%%CC%206" Name="CH%C%CountDownTextRun" ParameterType="%AID%_PT-FCBCountDownTextTemplatePauseRun" Offset="68" BitOffset="0" Text="Läuft" Value="v" />
257257
<!-- ^^^ 1 + 1 byte for 0 terminator = 2 bytes ^^^-->
258258
</Union>
259259

src/FunctionBlocks/CountDownBlock.cpp

Lines changed: 145 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,135 @@
11
#include "CountDownBlock.h"
2-
#define FCB_CHStoppStart FCB_KoCHKO0
3-
#define FCB_CHPauseContinue FCB_KoCHKO1
4-
#define FCB_CHStartWithTime FCB_KoCHKO2
2+
#define FCB_KoCHStoppStart FCB_KoCHKO0
3+
#define FCB_KoCHPauseContinue FCB_KoCHKO1
4+
#define FCB_KoCHStartWithTime FCB_KoCHKO2
5+
#define FCB_KoCHTimeOffset FCB_KoCHKO3
56

6-
#define KoFCB_CHText KoFCB_CHKO6
7-
#define KoFCB_CHPauseActive KoFCB_CHKO7
8-
#define KoFCB_CHRemaining KoFCB_CHKO8
9-
#define KoFCB_CHRunning KoFCB_CHKO9
7+
#define KoFCB_CHText KoFCB_CHKO5
8+
#define KoFCB_CHPauseActive KoFCB_CHKO6
9+
#define KoFCB_CHRemaining KoFCB_CHKO7
10+
#define KoFCB_CHRunning KoFCB_CHKO8
11+
#define KoFCB_CHTrigger KoFCB_CHKO9
1012

1113
CountDownBlock::CountDownBlock(uint8_t channelIndex)
1214
: FunctionBlock(channelIndex, "CountDown")
1315
{
14-
// <Enumeration Id="%ENID%" Value="0" Text="Sekunden" />
15-
// <Enumeration Id="%ENID%" Value="1" Text="Minuten" />
16-
// <Enumeration Id="%ENID%" Value="2" Text="Stunden" />
17-
switch (ParamFCB_CHCountDownUnit)
18-
{
19-
case 0:
20-
_countValue = 1000;
21-
break;
22-
case 1:
23-
_countValue = 60 * 1000;
24-
break;
25-
case 2:
26-
_countValue = 60 * 60 * 1000;
27-
break;
28-
}
2916
KoFCB_CHRemaining.value(0ul, DPT_Value_1_Ucount);
3017
KoFCB_CHPauseActive.value(false, DPT_Switch);
3118
KoFCB_CHRunning.value(false, DPT_Switch);
32-
updateText(0);
19+
KoFCB_CHText.value("", DPT_String_8859_1);
20+
auto trigger = ParamFCB_CHCountDownTrigger;
21+
if (trigger > 1) // Trigger with time out
22+
KoFCB_CHTrigger.value(false, DPT_Switch);
23+
updateTextKo(0);
3324
}
3425

3526
void CountDownBlock::handleKo(GroupObject &ko)
3627
{
3728
switch (ko.asap())
3829
{
39-
case FCB_CHStoppStart:
30+
case FCB_KoCHStoppStart: {
4031
if (ko.value(DPT_Switch))
41-
start(ParamFCB_CHFCBCountDownStartValue);
32+
start(*(uint32_t *)knx.paramData(FCB_ParamCalcIndex(FCB_CHCountDownStartValue)));
4233
else
4334
stop();
4435
break;
45-
case FCB_CHPauseContinue:
46-
pause(ko.value(DPT_Switch));
36+
}
37+
case FCB_KoCHStartWithTime: {
38+
uint8_t value = ko.value(DPT_Value_1_Ucount);
39+
// <Enumeration Id="%ENID%" Value="0" Text="Deaktiviert" />
40+
// <Enumeration Id="%ENID%" Value="1" Text="Sekunden" />
41+
// <Enumeration Id="%ENID%" Value="2" Text="Minuten" />
42+
// <Enumeration Id="%ENID%" Value="3" Text="Stunden" />
43+
switch (ParamFCB_CHCountDownTimeStartKo)
44+
{
45+
default:
46+
return;
47+
case 1:
48+
value *= 1;
49+
break;
50+
case 2:
51+
value *= 60;
52+
break;
53+
case 3:
54+
value *= 3600;
55+
break;
56+
}
57+
start(value);
4758
break;
48-
case FCB_CHStartWithTime:
49-
start(ko.value(DPT_Value_1_Ucount));
59+
}
60+
case FCB_KoCHTimeOffset: {
61+
bool up = ko.value(DPT_UpDown);
62+
// <Enumeration Id="%ENID%" Value="0" Text="Deaktiviert" />
63+
// <Enumeration Id="%ENID%" Value="1" Text="1 Sekunde" />
64+
// <Enumeration Id="%ENID%" Value="2" Text="5 Sekunden" />
65+
// <Enumeration Id="%ENID%" Value="3" Text="10 Sekunden" />
66+
// <Enumeration Id="%ENID%" Value="4" Text="15 Sekunden" />
67+
// <Enumeration Id="%ENID%" Value="5" Text="30 Sekunden" />
68+
// <Enumeration Id="%ENID%" Value="6" Text="1 Minute" />
69+
// <Enumeration Id="%ENID%" Value="7" Text="5 Minuten" />
70+
// <Enumeration Id="%ENID%" Value="8" Text="10 Minuten" />
71+
// <Enumeration Id="%ENID%" Value="9" Text="15 Minuten" />
72+
// <Enumeration Id="%ENID%" Value="10" Text="30 Minuten" />
73+
// <Enumeration Id="%ENID%" Value="11" Text="1 Stunde" />
74+
uint16_t value = 1;
75+
switch (ParamFCB_CHCountDownTimeOffset)
76+
{
77+
default:
78+
return;
79+
case 1:
80+
value = 1;
81+
break;
82+
case 2:
83+
value = 5;
84+
break;
85+
case 3:
86+
value = 10;
87+
break;
88+
case 4:
89+
value = 15;
90+
break;
91+
case 5:
92+
value = 30;
93+
break;
94+
case 6:
95+
value = 60;
96+
break;
97+
case 7:
98+
value = 300;
99+
break;
100+
case 8:
101+
value = 600;
102+
break;
103+
case 9:
104+
value = 900;
105+
break;
106+
case 10:
107+
value = 1800;
108+
break;
109+
case 11:
110+
value = 3600;
111+
break;
112+
}
113+
if (up)
114+
{
115+
if (_lastValueUpdate == 0)
116+
start(value);
117+
else
118+
_remainingSeconds += value;
119+
}
120+
else
121+
{
122+
if (_remainingSeconds <= value)
123+
stop();
124+
else
125+
_remainingSeconds -= value;
126+
}
50127
break;
128+
}
129+
case FCB_KoCHPauseContinue: {
130+
pause(ko.value(DPT_Switch));
131+
break;
132+
}
51133
}
52134
}
53135

@@ -67,10 +149,15 @@ void CountDownBlock::start(uint64_t startValue)
67149
}
68150
else
69151
{
70-
_lastValueUpdate = max(1ul, millis());
71-
KoFCB_CHRemaining.value(startValue, DPT_Value_1_Ucount);
152+
if (!_pause)
153+
_lastValueUpdate = max(1ul, millis());
154+
updateRemainingKo();
72155
KoFCB_CHRunning.value(true, DPT_Switch);
73-
updateText(startValue);
156+
auto trigger = ParamFCB_CHCountDownTrigger;
157+
if (trigger > 1) // Trigger with time out
158+
KoFCB_CHTrigger.valueCompare(false, DPT_Switch);
159+
160+
updateTextKo(true);
74161
}
75162
}
76163

@@ -88,10 +175,9 @@ void CountDownBlock::pause(bool pause)
88175
}
89176
else
90177
{
91-
_lastValueUpdate = max(1ul, millis() + _lastValueUpdate); // Start from now - already elapsed time
178+
_lastValueUpdate = max(1ul, millis() + _lastValueUpdate); // Start from now - already elapsed time
92179
}
93-
uint64_t value = KoFCB_CHRemaining.value(DPT_Value_1_Ucount);
94-
updateText(value);
180+
updateTextKo(true);
95181
}
96182
}
97183
}
@@ -100,66 +186,55 @@ void CountDownBlock::stop()
100186
{
101187
_lastValueUpdate = 0;
102188
KoFCB_CHRunning.value(false, DPT_Switch);
103-
KoFCB_CHText.value("Gestoppt", DPT_String_8859_1);
189+
updateTextKo(true);
104190
}
105191

106192
void CountDownBlock::loop()
107193
{
108194
if (_lastValueUpdate > 0 && !_pause)
109195
{
110196
unsigned long now = millis();
111-
if (now - _lastValueUpdate >= _countValue)
197+
if (now - _lastValueUpdate >= 1000)
112198
{
113-
auto toLateOffest = now - _lastValueUpdate;
114-
uint64_t value = KoFCB_CHRemaining.value(DPT_Value_1_Ucount);
115-
if (value > 0)
116-
value--;
199+
auto toLateOffest = now - _lastValueUpdate - 1000;
200+
if (_remainingSeconds > 0)
201+
_remainingSeconds--;
117202
else
118-
value = 0;
203+
_remainingSeconds = 0;
119204

120-
if (value == 0)
205+
if (_remainingSeconds == 0)
121206
_lastValueUpdate = 0;
122207
else
123208
_lastValueUpdate = max(1ul, now - toLateOffest);
124209

125-
KoFCB_CHRemaining.value(value, DPT_Value_1_Ucount);
210+
updateRemainingKo();
126211
if (_lastValueUpdate == 0)
127212
{
128213
KoFCB_CHRunning.value(false, DPT_Switch);
129-
KoFCB_CHText.value("Ende", DPT_String_8859_1);
214+
KoFCB_CHTrigger.value(true, DPT_Switch);
215+
updateTextKo(true, true);
130216
}
131217
else
132218
{
133-
updateText(value);
219+
updateTextKo(false);
134220
}
135221
}
136222
}
137223
}
138224

139-
void CountDownBlock::updateText(uint64_t value)
225+
void CountDownBlock::updateRemainingKo()
140226
{
141-
if (_lastValueUpdate == 0)
142-
{
143-
KoFCB_CHText.value("Gestoppt", DPT_String_8859_1);
144-
return;
145-
}
227+
// ToDo: Handling of remaining unit
228+
KoFCB_CHRemaining.value(_remainingSeconds, DPT_Value_1_Ucount);
229+
}
230+
231+
void CountDownBlock::updateTextKo(bool forceSend, bool end)
232+
{
233+
// ToDo: Add template handling
146234
char buffer[15] = {0};
147-
const char *unit = "";
148-
switch (ParamFCB_CHCountDownUnit)
149-
{
150-
case 0:
151-
unit = "s";
152-
break;
153-
case 1:
154-
unit = "m";
155-
break;
156-
case 2:
157-
unit = "h";
158-
break;
159-
}
160-
const char* pauseText = "";
161-
if (_pause)
162-
pauseText = " Pause";
163-
snprintf(buffer, sizeof(buffer), "%lu %s%s", value, unit, pauseText);
164-
KoFCB_CHText.value(buffer, DPT_String_8859_1);
235+
// snprintf(buffer, sizeof(buffer), "%lu %s%s", value, unit, pauseText);
236+
if (forceSend)
237+
KoFCB_CHText.value(buffer, DPT_String_8859_1);
238+
else
239+
KoFCB_CHText.valueCompare(buffer, DPT_String_8859_1);
165240
}

src/FunctionBlocks/CountDownBlock.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
class CountDownBlock : public FunctionBlock
55
{
66
private:
7-
unsigned long _countValue = 1000;
7+
uint64_t _remainingSeconds = 0ul;
88
unsigned long _lastValueUpdate = 0;
99
bool _pause = false;
1010
public:
@@ -16,6 +16,7 @@ class CountDownBlock : public FunctionBlock
1616
void pause(bool pause);
1717
void stop();
1818
void loop() override;
19-
void updateText(uint64_t value);
19+
void updateRemainingKo();
20+
void updateTextKo(bool forceSend, bool end = false);
2021

2122
};

0 commit comments

Comments
 (0)