9 #include "MultiChannelDevice.h"
11 #include "StateMachine.h"
15 DEFREGISTER(BlindReg1,CREG_AES_ACTIVE,
16 CREG_REFERENCE_RUNNING_TIME_TOP_BOTTOM,CREG_REFERENCE_RUNNING_TIME_BOTTOM_TOP,
17 CREG_CHANGE_OVER_DELAY,CREG_REFERENCE_RUN_COUNTER,CREG_TRANSMITTRYMAX,
20 class BlindList1 :
public RegList1<BlindReg1> {
22 BlindList1 (uint16_t addr) : RegList1<BlindReg1>(addr) {}
31 refRunningTimeTopBottom(500);
32 refRunningTimeBottomTop(500);
38 DEFREGISTER(BlindReg3,PREG_CTRAMPONOFF,PREG_CTDELAYONOFF,PREG_CTONOFF,
39 PREG_CTREPONOFF,PREG_CONDVALUELOW,PREG_CONDVALUEHIGH,PREG_ONDELAYTIME,
40 PREG_ONTIME,PREG_OFFDELAYTIME,PREG_OFFTIME,PREG_ACTIONTYPE,PREG_JTONOFF,
41 PREG_JTDELAYONOFF,PREG_JTRAMPONOFF,PREG_JTREFONOFF,PREG_OFFLEVEL,
42 PREG_ONLEVEL,PREG_MAXTIMEFIRSTDIR,PREG_DRIVINGMODE)
44 typedef RegList3<BlindReg3> BlindPeerList;
50 BlindPeerList ssl = sh();
66 ssl.actionType(AS_CM_ACTIONTYPE_JUMP_TO_TARGET);
69 ssl.maxTimeFirstDir(255);
88 ssl.actionType(AS_CM_ACTIONTYPE_JUMP_TO_TARGET);
92 ssl.maxTimeFirstDir(5);
98 BlindPeerList ssl = sh();
99 ssl.jtOff(AS_CM_JT_OFFDELAY);
100 ssl.jtDlyOff(AS_CM_JT_REFOFF);
101 ssl.jtOn(AS_CM_JT_OFFDELAY);
102 ssl.jtDlyOn(AS_CM_JT_OFFDELAY);
103 ssl.jtRampOff(AS_CM_JT_RAMPOFF);
104 ssl.jtRampOn(AS_CM_JT_ON);
105 ssl.jtRefOff(AS_CM_JT_RAMPOFF);
106 ssl.jtRefOn(AS_CM_JT_ON);
108 ssl.jtOff(AS_CM_JT_OFFDELAY);
109 ssl.jtDlyOff(AS_CM_JT_REFOFF);
110 ssl.jtOn(AS_CM_JT_OFFDELAY);
111 ssl.jtDlyOn(AS_CM_JT_OFFDELAY);
112 ssl.jtRampOff(AS_CM_JT_RAMPOFF);
113 ssl.jtRampOn(AS_CM_JT_ON);
114 ssl.jtRefOff(AS_CM_JT_RAMPOFF);
115 ssl.jtRefOn(AS_CM_JT_ON);
120 BlindPeerList ssl = sh();
121 ssl.jtOff(AS_CM_JT_ONDELAY);
122 ssl.jtDlyOff(AS_CM_JT_ONDELAY);
123 ssl.jtOn(AS_CM_JT_ONDELAY);
124 ssl.jtDlyOn(AS_CM_JT_REFON);
125 ssl.jtRampOff(AS_CM_JT_OFF);
126 ssl.jtRampOn(AS_CM_JT_RAMPON);
127 ssl.jtRefOff(AS_CM_JT_OFF);
128 ssl.jtRefOn(AS_CM_JT_RAMPON);
130 ssl.jtOff(AS_CM_JT_ONDELAY);
131 ssl.jtDlyOff(AS_CM_JT_ONDELAY);
132 ssl.jtOn(AS_CM_JT_ONDELAY);
133 ssl.jtDlyOn(AS_CM_JT_REFON);
134 ssl.jtRampOff(AS_CM_JT_OFF);
135 ssl.jtRampOn(AS_CM_JT_RAMPON);
136 ssl.jtRefOff(AS_CM_JT_OFF);
137 ssl.jtRefOn(AS_CM_JT_RAMPON);
142 BlindPeerList ssl = sh();
143 ssl.jtOff(AS_CM_JT_ONDELAY);
144 ssl.jtDlyOff(AS_CM_JT_REFOFF);
145 ssl.jtOn(AS_CM_JT_OFFDELAY);
146 ssl.jtDlyOn(AS_CM_JT_REFON);
147 ssl.jtRampOn(AS_CM_JT_ON);
148 ssl.jtRefOn(AS_CM_JT_ON);
149 ssl.jtRampOff(AS_CM_JT_OFF);
150 ssl.jtRefOff(AS_CM_JT_ON);
152 ssl.jtOff(AS_CM_JT_ONDELAY);
153 ssl.jtDlyOff(AS_CM_JT_REFOFF);
154 ssl.jtOn(AS_CM_JT_OFFDELAY);
155 ssl.jtDlyOn(AS_CM_JT_REFON);
156 ssl.jtRampOn(AS_CM_JT_ON);
157 ssl.jtRefOn(AS_CM_JT_ON);
158 ssl.jtRampOff(AS_CM_JT_OFF);
159 ssl.jtRefOff(AS_CM_JT_OFF);
167 class LevelUpdate :
public Alarm {
178 startlevel = sm.status();
181 set(millis2ticks(100));
187 if( done > fulltime ) done = fulltime;
188 uint8_t dx = (done * 200UL) / fulltime;
189 if( sm.state == AS_CM_JT_RAMPON ) {
190 if( dx > (200-startlevel) ) dx = 200-startlevel;
191 sm.updateLevel(startlevel + dx);
193 else if( sm.state == AS_CM_JT_RAMPOFF ) {
194 if( dx > startlevel ) dx = startlevel;
195 sm.updateLevel(startlevel - dx);
202 set(millis2ticks(100));
208 void updateLevel (uint8_t l) {
211 DPRINT(F(
"New Level: "));DDECLN(level);
217 uint8_t level, destlevel;
222 uint8_t trigstate = state;
223 uint8_t trigdest = destlevel;
225 if( trigstate == AS_CM_JT_RAMPON || trigstate == AS_CM_JT_RAMPOFF ) {
226 if( trigdest != 0xff ) {
228 updateLevel(trigdest);
233 void triggerChanged () {
241 virtual void switchState(uint8_t oldstate,uint8_t newstate,__attribute__ ((unused)) uint32_t statedelay) {
242 DPRINT(F(
"Switch from "));DHEX(oldstate);DPRINT(F(
" to "));DHEX(newstate);DPRINT(F(
" delay: "));DHEXLN(statedelay);
244 case AS_CM_JT_RAMPON:
245 update.start(sysclock, list1.refRunningTimeBottomTop());
247 case AS_CM_JT_RAMPOFF:
248 update.start(sysclock, list1.refRunningTimeTopBottom());
253 case AS_CM_JT_RAMPON:
254 case AS_CM_JT_RAMPOFF:
255 update.stop(sysclock);
260 void setup(BlindList1 l1) {
265 setState(AS_CM_JT_OFF, BlindStateMachine::DELAY_INFINITE);
269 void jumpToTarget(
const BlindPeerList& lst) {
270 uint8_t next = getJumpTarget(state,lst);
271 DPRINT(F(
"jumpToTarget: "));DDEC(state);DPRINT(F(
" "));DDECLN(next);
272 if( next != AS_CM_JT_NONE ) {
274 case AS_CM_JT_ONDELAY:
276 case AS_CM_JT_RAMPON:
277 setDestLevel(lst.onLevel());
279 case AS_CM_JT_OFFDELAY:
280 case AS_CM_JT_REFOFF:
281 case AS_CM_JT_RAMPOFF:
282 setDestLevel(lst.offLevel());
287 uint32_t dly = getDelayForState(next,lst);
289 if( next == state && (next == AS_CM_JT_ON || next == AS_CM_JT_OFF) && dly < DELAY_INFINITE) {
290 bool minimal = next == AS_CM_JT_ON ? lst.onTimeMode() : lst.offTimeMode();
292 if( minimal ==
true ) {
294 uint32_t curdly = sysclock.get(*
this);
295 if( curdly == 0 || curdly > dly ) {
302 setState(next,dly,lst);
306 virtual uint8_t getNextState (uint8_t stat) {
309 case AS_CM_JT_ONDELAY:
return AS_CM_JT_REFON;
310 case AS_CM_JT_REFON:
return AS_CM_JT_RAMPON;
311 case AS_CM_JT_RAMPON:
312 if(actlst.valid() && destlevel == actlst.offLevel())
315 case AS_CM_JT_ON:
return AS_CM_JT_OFFDELAY;
316 case AS_CM_JT_OFFDELAY:
return AS_CM_JT_REFOFF;
317 case AS_CM_JT_REFOFF:
return AS_CM_JT_RAMPOFF;
318 case AS_CM_JT_RAMPOFF:
319 if(actlst.valid() && destlevel == actlst.onLevel())
322 case AS_CM_JT_OFF:
return AS_CM_JT_ONDELAY;
324 return AS_CM_JT_NONE;
327 virtual uint32_t getDelayForState(uint8_t stat,
const BlindPeerList& lst) {
328 if( lst.valid () ==
true ) {
329 if( stat == AS_CM_JT_RAMPON || stat == AS_CM_JT_RAMPOFF ) {
330 uint8_t first = lst.maxTimeFirstDir();
331 if( first != 0xff && first != 0x00 ) {
333 return decis2ticks(first);
341 virtual uint32_t getDefaultDelay(uint8_t stat)
const {
345 return DELAY_INFINITE;
348 case AS_CM_JT_REFOFF:
349 return decis2ticks(list1.changeOverDelay());
351 case AS_CM_JT_RAMPON:
352 return calcDriveTime(destlevel-level,list1.refRunningTimeBottomTop(),destlevel==200);
354 case AS_CM_JT_RAMPOFF:
355 return calcDriveTime(level-destlevel,list1.refRunningTimeTopBottom(),destlevel==0);
361 uint32_t calcDriveTime(uint8_t dx,uint32_t fulltime,
bool extratime)
const {
362 uint32_t dt = (fulltime * dx) / 200;
363 if( extratime ==
true ) dt += 20;
364 DPRINT(F(
"calcDriveTime: "));DDEC(fulltime);DPRINT(F(
" - "));DDEC(dx);DPRINT(F(
" - "));DDECLN(dt);
365 return decis2ticks(dt);
368 bool set (uint8_t value,__attribute__ ((unused)) uint16_t ramp,__attribute__ ((unused)) uint16_t delay) {
370 if( destlevel > level || destlevel == 200 ) {
371 setState(AS_CM_JT_ONDELAY, 0);
373 else if ( destlevel < level || destlevel == 0 ) {
374 setState(AS_CM_JT_OFFDELAY, 0);
379 void remote (
const BlindPeerList& lst,uint8_t counter) {
381 switch (lst.actionType()) {
382 case AS_CM_ACTIONTYPE_JUMP_TO_TARGET:
385 case AS_CM_ACTIONTYPE_TOGGLE_TO_COUNTER:
386 setDestLevel((counter & 0x01) == 0x01 ? lst.onLevel() : lst.offLevel());
388 case AS_CM_ACTIONTYPE_TOGGLE_INVERSE_TO_COUNTER:
389 setDestLevel((counter & 0x01) == 0x00 ? lst.onLevel() : lst.offLevel());
394 void sensor (
const BlindPeerList& lst,uint8_t counter,uint8_t value) {
395 if( checkCondition(state,lst,value) ==
true ) {
409 bool setDestLevel (uint8_t value) {
410 DPRINT(F(
"setDestLevel: "));DDECLN(value);
424 if( state == AS_CM_JT_RAMPON || state == AS_CM_JT_RAMPOFF ) {
425 setState(getNextState(state),DELAY_INFINITE);
429 uint8_t status ()
const {
433 uint8_t flags ()
const {
434 uint8_t f = (state == AS_CM_JT_ON || state == AS_CM_JT_OFF) ? 0x00 : AS_CM_EXTSTATE_RUNNING;
435 if( state == AS_CM_JT_RAMPON ) {
436 f |= AS_CM_EXTSTATE_UP;
438 else if( state == AS_CM_JT_RAMPOFF ) {
439 f |= AS_CM_EXTSTATE_DOWN;