9 #include "MultiChannelDevice.h"
14 DEFREGISTER(IButtonReg1,CREG_AES_ACTIVE,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7)
15 class IButtonList1 :
public RegList1<IButtonReg1> {
17 IButtonList1 (uint16_t addr) : RegList1<IButtonReg1>(addr) {}
23 template<
class HALTYPE,
int PEERCOUNT,
class List0Type=List0>
26 enum { none=0, released, longpressed, longreleased };
28 uint8_t state, matches, repeatcnt;
36 virtual void trigger (__attribute__((unused))
AlarmClock& clock) {
41 uint8_t status ()
const {
45 uint8_t flags ()
const {
53 bool check (uint8_t* addr) {
54 if( free() ==
false && isID(addr) ==
true ) {
55 matches |= 0b00000001;
63 if( this->device().getList0().buttonMode() == 0 ) {
66 if( (matches & 0b00111111) == 0b00000111 || (matches & 0b00111111) == 0b00111111 ) {
68 DPRINTLN(F(
"longpressed"));
70 matches &= 0b11000111;
73 else if( (matches & 0b00001111) == 0b00001110 ) {
75 DPRINTLN(F(
"longreleased"));
78 else if( (matches & 0b00000011) == 0b00000010 ) {
80 DPRINTLN(F(
"released"));
84 msg.init(this->device().nextcount(),this->number(),repeatcnt,(s==longreleased || s==longpressed),this->device().battery().low());
85 if( s == released || s == longreleased) {
87 this->device().sendPeerEvent(msg,*
this);
90 else if (s == longpressed) {
92 this->device().broadcastPeerEvent(msg,*
this);
98 uint8_t newstate = state;
99 uint8_t mask = (matches & 0b00000111);
100 if( mask == 0b00000111) newstate = 100;
101 else if( mask == 0b00000000) newstate = 0;
102 if( state != newstate ) {
105 msg.init(this->device().nextcount(),this->number(),repeatcnt++,state,this->device().battery().low());
106 this->device().sendPeerEvent(msg,*
this);
111 bool match (uint8_t* addr) {
113 bool res = check(addr);
118 bool isID (uint8_t* buf) {
119 IButtonList1 l = this->getList1();
120 for( uint8_t n=0; n<8; ++n ) {
121 if( l.readRegister(0xe0+n) != buf[n] ) {
128 void storeID (uint8_t* buf) {
129 if( learn() ==
true ) {
130 for( uint8_t n=0; n<8; ++n ) {
131 this->getList1().writeRegister(0xe0+n,buf[n]);
135 sysclock.cancel(*
this);
140 return this->getList1().readRegister(0xe0) == 0;
143 bool learn ()
const {
151 set(seconds2ticks(60));
157 bool process (__attribute__((unused))
const RemoteEventMsg& msg) {
return false; }
158 bool process (__attribute__((unused))
const SensorEventMsg& msg) {
return false; }
159 bool process (__attribute__((unused))
const ActionCommandMsg& msg) {
return false; }
163 template <
class IButtonDev,
class IButtonChannel,
int READER_PIN,
int LED_GREEN,
int LED_RED>
170 IButtonScanner (IButtonDev& d) :
Alarm(millis2ticks(500)), ow(READER_PIN), dev(d), cnt(0) {
176 for( uint8_t i=0; i<dev.ibuttonCount(); ++i ) {
178 if( bc.learn() ==
true ) {
186 for( uint8_t i=0; i<dev.ibuttonCount(); ++i ) {
188 if( bc.match(addr) ==
true ) {
196 for( uint8_t i=0; i<dev.ibuttonCount(); ++i ) {
198 if( bc.isID(addr) ==
true ) {
205 bool scan (uint8_t* addr) {
207 if ( ow.search(addr) ==
false || OneWire::crc8(addr, 7) != addr[7] ) {
215 for( uint8_t i=0; i<dev.ibuttonCount(); ++i ) {
222 for( uint8_t i=0; i<dev.ibuttonCount(); ++i ) {
228 bool check (uint8_t* addr) {
230 for( uint8_t i=0; i<dev.ibuttonCount(); ++i ) {
232 res |= bc.check(addr);
243 while( ow.search(addr) == 1 ) {
244 if( OneWire::crc8(addr,7) == addr[7] ) {
245 if( addr[0] == 0x01 ) {
247 if( check(addr) ==
true ) {
255 if( found > 0 && dev.getList0().buttonMode() == 0 ) {
256 if( found == known ) {
257 led.ledOn(millis2ticks(500),0);
260 led.ledOn(0,millis2ticks(500));
268 while( ow.search(addr) == 1 ) {
269 if( OneWire::crc8(addr,7) == addr[7] ) {
270 if( addr[0] == 0x01 ) {
271 if( find(addr) == 0 ) {
283 set(millis2ticks(250));
289 uint8_t cycle = cnt & 0x01;
290 led.ledOn(cycle == 0 ? tick : 0, cycle == 0 ? 0 : tick);
292 if( learn(lc) ==
true ) {
294 set(seconds2ticks(5));