9 #include "MultiChannelDevice.h"
15 DEFREGISTER(SwitchReg1,CREG_AES_ACTIVE,CREG_TRANSMITTRYMAX,CREG_POWERUPACTION,CREG_STATUSINFO)
17 class SwitchList1 :
public RegList1<SwitchReg1> {
19 SwitchList1(uint16_t addr) : RegList1<SwitchReg1>(addr) {}
30 #define SWITCH_LIST3_STANDARD_REGISTER PREG_CTDELAYONOFF,PREG_CTONOFF,PREG_CONDVALUELOW,PREG_CONDVALUEHIGH,\
31 PREG_ONDELAYTIME,PREG_ONTIME,PREG_OFFDELAYTIME,PREG_OFFTIME,PREG_ACTIONTYPE,PREG_JTONOFF,PREG_JTDELAYONOFF
33 DEFREGISTER(SwitchReg3,SWITCH_LIST3_STANDARD_REGISTER)
35 typedef RegList3<SwitchReg3> SwitchPeerList;
37 template <
class PeerRegisterListType>
42 PeerRegisterListType ssl = this->sh();
54 ssl.actionType(AS_CM_ACTIONTYPE_JUMP_TO_TARGET);
70 ssl.actionType(AS_CM_ACTIONTYPE_JUMP_TO_TARGET);
78 PeerRegisterListType ssl = this->sh();
79 ssl.jtOn(AS_CM_JT_OFFDELAY);
80 ssl.jtOff(AS_CM_JT_OFF);
81 ssl.jtDlyOn(AS_CM_JT_OFF);
82 ssl.jtDlyOff(AS_CM_JT_OFF);
84 ssl.jtOn(AS_CM_JT_OFFDELAY);
85 ssl.jtOff(AS_CM_JT_OFF);
86 ssl.jtDlyOn(AS_CM_JT_OFF);
87 ssl.jtDlyOff(AS_CM_JT_OFF);
92 PeerRegisterListType ssl = this->sh();
93 ssl.jtOn(AS_CM_JT_ON);
94 ssl.jtOff(AS_CM_JT_ONDELAY);
95 ssl.jtDlyOn(AS_CM_JT_ON);
96 ssl.jtDlyOff(AS_CM_JT_ON);
98 ssl.jtOn(AS_CM_JT_ON);
99 ssl.jtOff(AS_CM_JT_ONDELAY);
100 ssl.jtDlyOn(AS_CM_JT_ON);
101 ssl.jtDlyOff(AS_CM_JT_ON);
106 PeerRegisterListType ssl = this->sh();
107 ssl.jtOn(AS_CM_JT_OFFDELAY);
108 ssl.jtOff(AS_CM_JT_ONDELAY);
109 ssl.jtDlyOn(AS_CM_JT_ON);
110 ssl.jtDlyOff(AS_CM_JT_OFF);
112 ssl.jtOn(AS_CM_JT_OFFDELAY);
113 ssl.jtOff(AS_CM_JT_ONDELAY);
114 ssl.jtDlyOn(AS_CM_JT_ON);
115 ssl.jtDlyOff(AS_CM_JT_OFF);
116 ssl.multiExec(
false);
124 #define DELAY_NO 0x00
125 #define DELAY_INFINITE 0xffffffff
127 class StateAlarm :
public Alarm {
132 void list(SwitchPeerList l) {lst=l;}
133 virtual void trigger (__attribute__((unused))
AlarmClock& clock) {
134 uint8_t next = sm.getNextState();
135 uint32_t dly = sm.getDelayForState(next,lst);
136 sm.setState(next,dly,lst);
140 void setState (uint8_t next,uint32_t delay,
const SwitchPeerList& lst=SwitchPeerList(0),uint8_t deep=0) {
142 if( next != AS_CM_JT_NONE && deep < 4) {
144 sysclock.cancel(alarm);
147 switchState(state, next,delay);
150 if (delay == DELAY_NO) {
152 next = getNextState();
153 delay = getDelayForState(next,lst);
154 setState(next, delay, lst, ++deep);
156 else if (delay != DELAY_INFINITE) {
173 bool changed ()
const {
return change; }
174 void changed (
bool c) { change=c; }
176 void setup(__attribute__ ((unused))
BaseList l1) {}
178 virtual void switchState(__attribute__((unused)) uint8_t oldstate,__attribute__((unused)) uint8_t newstate,__attribute__((unused)) uint32_t delay) {}
180 void jumpToTarget(
const SwitchPeerList& lst) {
181 uint8_t next = getJumpTarget(state,lst);
182 if( next != AS_CM_JT_NONE ) {
184 uint32_t dly = getDelayForState(next,lst);
186 if( next == state && (next == AS_CM_JT_ON || next == AS_CM_JT_OFF) && dly < DELAY_INFINITE) {
187 bool minimal = next == AS_CM_JT_ON ? lst.onTimeMode() : lst.offTimeMode();
189 if( minimal ==
true ) {
191 uint32_t curdly = sysclock.get(alarm);
192 if( curdly == 0 || curdly > dly ) {
199 setState(next,dly,lst);
203 void toggleState () {
204 setState( state == AS_CM_JT_ON ? AS_CM_JT_OFF : AS_CM_JT_ON, DELAY_INFINITE);
207 uint8_t getNextState () {
209 case AS_CM_JT_ONDELAY:
return AS_CM_JT_ON;
210 case AS_CM_JT_ON:
return AS_CM_JT_OFFDELAY;
211 case AS_CM_JT_OFFDELAY:
return AS_CM_JT_OFF;
212 case AS_CM_JT_OFF:
return AS_CM_JT_ONDELAY;
214 return AS_CM_JT_NONE;
217 uint8_t getJumpTarget(uint8_t stat,
const SwitchPeerList& lst)
const {
219 case AS_CM_JT_ONDELAY:
return lst.jtDlyOn();
220 case AS_CM_JT_ON:
return lst.jtOn();
221 case AS_CM_JT_OFFDELAY:
return lst.jtDlyOff();
222 case AS_CM_JT_OFF:
return lst.jtOff();
224 return AS_CM_JT_NONE;
227 uint8_t getConditionForState(uint8_t stat,
const SwitchPeerList& lst)
const {
229 case AS_CM_JT_ONDELAY:
return lst.ctDlyOn();
230 case AS_CM_JT_ON:
return lst.ctOn();
231 case AS_CM_JT_OFFDELAY:
return lst.ctDlyOff();
232 case AS_CM_JT_OFF:
return lst.ctOff();
234 return AS_CM_CT_X_GE_COND_VALUE_LO;
237 uint32_t getDelayForState(uint8_t stat,
const SwitchPeerList& lst)
const {
238 if( lst.valid() ==
false ) {
239 return getDefaultDelay(stat);
243 case AS_CM_JT_ONDELAY: value = lst.onDly();
break;
244 case AS_CM_JT_ON: value = lst.onTime();
break;
245 case AS_CM_JT_OFFDELAY: value = lst.offDly();
break;
246 case AS_CM_JT_OFF: value = lst.offTime();
break;
248 return AskSinBase::byteTimeCvt(value);
251 uint32_t getDefaultDelay(uint8_t stat)
const {
255 return DELAY_INFINITE;
260 bool delayActive ()
const {
return sysclock.get(alarm) > 0; }
262 bool set (uint8_t value,__attribute__ ((unused)) uint16_t ramp,uint16_t delay) {
263 status(value, delay);
267 void remote (
const SwitchPeerList& lst,uint8_t counter) {
269 switch (lst.actionType()) {
270 case AS_CM_ACTIONTYPE_JUMP_TO_TARGET:
273 case AS_CM_ACTIONTYPE_TOGGLE_TO_COUNTER:
274 setState((counter & 0x01) == 0x01 ? AS_CM_JT_ON : AS_CM_JT_OFF, DELAY_INFINITE);
276 case AS_CM_ACTIONTYPE_TOGGLE_INVERSE_TO_COUNTER:
277 setState((counter & 0x01) == 0x00 ? AS_CM_JT_ON : AS_CM_JT_OFF, DELAY_INFINITE);
282 void sensor (
const SwitchPeerList& lst,uint8_t counter,uint8_t value) {
283 uint8_t cond = getConditionForState(state,lst);
286 case AS_CM_CT_X_GE_COND_VALUE_LO:
287 doit = (value >= lst.ctValLo());
289 case AS_CM_CT_X_GE_COND_VALUE_HI:
290 doit = (value >= lst.ctValHi());
292 case AS_CM_CT_X_LT_COND_VALUE_LO:
293 doit = (value < lst.ctValLo());
295 case AS_CM_CT_X_LT_COND_VALUE_HI:
296 doit = (value < lst.ctValHi());
298 case AS_CM_CT_COND_VALUE_LO_LE_X_LT_COND_VALUE_HI:
299 doit = ((lst.ctValLo() <= value) && (value < lst.ctValHi()));
301 case AS_CM_CT_X_LT_COND_VALUE_LO_OR_X_GE_COND_VALUE_HI:
302 doit =((value < lst.ctValLo()) || (value >= lst.ctValHi()));
312 void status (uint8_t stat, uint16_t delay) {
313 setState( stat == 0 ? AS_CM_JT_OFF : AS_CM_JT_ON, AskSinBase::intTimeCvt(delay) );
316 uint8_t status ()
const {
317 return state == AS_CM_JT_OFF ? 0 : 200;
320 uint8_t flags ()
const {
321 return delayActive() ? 0x40 : 0x00;
325 template <
class HalType,
int PeerCount,
class List0Type,
class IODriver=ArduinoPins>
337 void init (uint8_t p,
bool value=
false) {
339 IODriver::setOutput(pin);
341 typename BaseChannel::List1 l1 = BaseChannel::getList1();
342 this->set(l1.powerUpAction() ==
true ? 200 : 0, 0, 0xffff );
346 uint8_t flags ()
const {
347 uint8_t flags = BaseChannel::flags();
348 if( this->device().battery().low() ==
true ) {
355 virtual void switchState(__attribute__((unused)) uint8_t oldstate,uint8_t newstate,__attribute__((unused)) uint32_t delay) {
356 if( newstate == AS_CM_JT_ON ) {
357 if( lowact ==
true ) IODriver::setLow(pin);
358 else IODriver::setHigh(pin);
360 else if ( newstate == AS_CM_JT_OFF ) {
361 if( lowact ==
true ) IODriver::setHigh(pin);
362 else IODriver::setLow(pin);