6 #ifndef LIBRARIES_ASKSINPP_MOTION_H_
7 #define LIBRARIES_ASKSINPP_MOTION_H_
9 #include "MultiChannelDevice.h"
16 DEFREGISTER(MotionReg1,CREG_EVENTFILTER,CREG_INTERVAL,CREG_AES_ACTIVE,CREG_LEDONTIME)
17 static const uint8_t MotionReg1Defaults[] = {0x11,0x74,0x00,0x64};
22 init(MotionReg1Defaults,
sizeof(MotionReg1Defaults));
36 void init(uint8_t msgcnt,uint8_t ch,uint8_t counter,uint8_t brightness,uint8_t next) {
37 Message::init(0xd,msgcnt,AS_MESSAGE_SENSOR_EVENT,Message::BIDI|Message::WKMEUP,ch & 0x3f,counter);
38 pload[0] = brightness;
39 pload[1] = (next+4) << 4;
43 template <
class HalType,
int PeerCount,
class List0Type=List0,
class BrightnessSensor=Brightness>
46 class QuietMode :
public Alarm {
52 virtual ~QuietMode () {}
53 virtual void trigger (__attribute__ ((unused))
AlarmClock& clock) {
54 DPRINTLN(F(
"minInterval End"));
56 if( motion ==
true ) {
58 channel.motionDetected();
64 #define LIGHTCYCLE seconds2ticks(5*60)
65 class Cycle :
public Alarm {
78 uint32_t getMinInterval () {
79 switch( this->getList1().minInterval() ) {
80 case 0:
return seconds2ticks(15);
81 case 1:
return seconds2ticks(30);
82 case 2:
return seconds2ticks(60);
83 case 3:
return seconds2ticks(120);
85 return seconds2ticks(240);
92 volatile bool isrenabled : 1;
93 BrightnessSensor brightsens;
100 brightsens(), maxbright(1) {}
103 BrightnessSensor& brightnessSensor () {
108 ChannelType::setup(dev,number,addr);
115 brightsens.measure();
116 uint32_t bright = brightsens.brightness();
117 if( bright > maxbright ) {
121 return (uint8_t)(bright * 255UL / maxbright);
124 uint8_t flags ()
const {
125 return this->device().battery().low() ? 0x80 : 0x00;
131 d.sendInfoActuatorStatus(d.getMasterID(),d.nextcount(),*
this);
135 void pirInterruptOn () {
139 void pirInterruptOff () {
144 virtual void trigger (__attribute__ ((unused))
AlarmClock& clock) {
145 if( quiet.enabled ==
false ) {
147 sysclock.cancel(cycle);
148 cycle.set(LIGHTCYCLE);
151 DPRINTLN(F(
"Motion"));
153 quiet.tick = getMinInterval();
154 quiet.enabled =
true;
157 if( this->device().led().active() ==
false ) {
158 this->device().led().ledOn( centis2ticks(this->getList1().ledOntime()) / 2);
161 msg.init(this->device().nextcount(),this->number(),++counter,status(),this->getList1().minInterval());
164 this->device().sendPeerEvent(msg,*
this);
167 else if ( this->getList1().captureWithinInterval() ==
true ) {
174 void motionDetected () {
175 if( isrenabled==
true ) {
177 sysclock.cancel(*
this);
184 bool isMotion ()
const {
185 return quiet.enabled ==
true;
190 #define motionISR(device,chan,pin) class device##chan##ISRHandler { \
192 static void isr () { device.channel(chan).motionDetected(); } \
194 pinMode(pin,INPUT); \
195 if( digitalPinToInterrupt(pin) == NOT_AN_INTERRUPT ) \
196 enableInterrupt(pin,device##chan##ISRHandler::isr,RISING); \
198 attachInterrupt(digitalPinToInterrupt(pin),device##chan##ISRHandler::isr,RISING);
200 #define motionChannelISR(chan,pin) class __##pin##ISRHandler { \
202 static void isr () { chan.motionDetected(); } \
204 pinMode(pin,INPUT); \
205 if( digitalPinToInterrupt(pin) == NOT_AN_INTERRUPT ) \
206 enableInterrupt(pin,__##pin##ISRHandler::isr,RISING); \
208 attachInterrupt(digitalPinToInterrupt(pin),__##pin##ISRHandler::isr,RISING);