6 #ifndef __CONTACTSTATE_H__
7 #define __CONTACTSTATE_H__
10 #include "MultiChannelDevice.h"
11 #include "sensors/PinPosition.h"
13 #ifndef SABOTAGE_ACTIVE_STATE
14 #define SABOTAGE_ACTIVE_STATE LOW
19 template <
class Sensor,
class HALTYPE,
class List0Type,
class List1Type,
class List4Type,
int PEERCOUNT>
22 class EventSender :
public Alarm {
28 virtual ~EventSender () {}
29 virtual void trigger (__attribute__ ((unused))
AlarmClock& clock) {
31 msg.init(channel.device().nextcount(),channel.number(),count++,state,channel.device().battery().low());
32 #ifdef CONTACT_STATE_WITH_BATTERY
33 msg.append(channel.device().battery().current());
36 channel.device().sendPeerEvent(msg,channel);
54 BaseChannel::setup(dev,number,addr);
57 void init (uint8_t sab) {
67 uint8_t status ()
const {
71 uint8_t flags ()
const {
72 uint8_t flags = sabotage ? 0x07 << 1 : 0x00;
73 flags |= this->device().battery().low() ? 0x80 : 0x00;
77 void trigger (__attribute__ ((unused))
AlarmClock& clock) {
79 if( possens.interval() > 0) {
80 set(possens.interval());
83 uint8_t newstate = sender.state;
86 switch( possens.position() ) {
87 case Sensor::State::PosA:
88 msg = this->getList1().msgForPosA();
90 case Sensor::State::PosB:
91 msg = this->getList1().msgForPosB();
93 case Sensor::State::PosC:
94 msg = this->getList1().msgForPosC();
100 if( msg == 1) newstate = 0;
101 else if( msg == 2) newstate = 200;
102 else if( msg == 3) newstate = 100;
105 newstate = possens.remap(newstate);
107 if( sender.state == 255 ) {
109 sender.state = newstate;
111 else if( newstate != sender.state ) {
112 uint8_t delay = this->getList1().eventDelaytime();
113 sender.state = newstate;
114 sysclock.cancel(sender);
116 sender.trigger(sysclock);
119 sender.set(AskSinBase::byteTimeCvtSeconds(delay));
120 sysclock.add(sender);
122 uint16_t ledtime = (uint16_t)this->getList1().ledOntime() * 5;
124 this->device().led().ledOn(millis2ticks(ledtime),0);
128 bool sabstate = (possens.interval()==0 ? digitalRead(sabpin) :
AskSinBase::readPin(sabpin) == SABOTAGE_ACTIVE_STATE);
129 if( sabotage != sabstate && this->device().getList0().sabotageMsg() == true ) {
136 #ifdef CONTACT_STATE_WITH_BATTERY
137 void patchStatus (
Message& msg) {
139 msg.append(this->device().battery().current());
145 template <
class Sensor,
class HALTYPE,
class List0Type,
class List1Type,
class List4Type,
int PEERCOUNT>
148 template <
class HALTYPE,
class List0Type,
class List1Type,
class List4Type,
int PEERCOUNT>
156 void init (uint8_t pin1,uint8_t pin2, uint8_t sab,
const uint8_t* pmap) {
157 BaseChannel::possens.init(pin1,pin2,pmap);
158 BaseChannel::init(sab);
161 void init (uint8_t pin1,uint8_t pin2,
const uint8_t* pmap) {
162 BaseChannel::possens.init(pin1,pin2,pmap);
166 void init (uint8_t pin1,uint8_t pin2, uint8_t sab) {
167 BaseChannel::possens.init(pin1,pin2);
168 BaseChannel::init(sab);
171 void init (uint8_t pin1,uint8_t pin2) {
172 BaseChannel::possens.init(pin1,pin2);
177 template <
class HALTYPE,
class List0Type,
class List1Type,
class List4Type,
int PEERCOUNT, u
int16_t WAITMILLIS_AFTER_ENABLE=0>
185 void init (uint8_t pin, uint8_t en, uint8_t sab) {
186 BaseChannel::init(sab);
187 BaseChannel::possens.init(pin, en);
190 void init (uint8_t pin, uint8_t sab) {
191 BaseChannel::init(sab);
192 BaseChannel::possens.init(pin, 0);
195 void init (uint8_t pin) {
197 BaseChannel::possens.init(pin, 0);
201 #define DEFCYCLETIME seconds2ticks(60UL*60*20)
202 template<
class HalType,
class ChannelType,
int ChannelCount,
class List0Type,u
int32_t CycleTime=DEFCYCLETIME>
204 class CycleInfoAlarm :
public Alarm {
208 virtual ~CycleInfoAlarm () {}
213 for( uint8_t idx=1; idx<=dev.channels(); ++idx) {
214 dev.channel(idx).changed(
true);
223 virtual void configChanged () {
225 if( this->getList0().cycleInfoMsg() ==
true ) {
226 DPRINTLN(F(
"Activate Cycle Msg"));
227 sysclock.cancel(cycle);
228 cycle.set(CycleTime);
232 DPRINTLN(F(
"Deactivate Cycle Msg"));
233 sysclock.cancel(cycle);
239 template<
class HalType,
class ChannelType,
int ChannelCount,
class List0Type,u
int32_t CycleTime=DEFCYCLETIME>
243 #define contactISR(pin,func) if( digitalPinToInterrupt(pin) == NOT_AN_INTERRUPT ) \
244 enableInterrupt(pin,func,CHANGE); \
246 attachInterrupt(digitalPinToInterrupt(pin),func,CHANGE);