-
Notifications
You must be signed in to change notification settings - Fork 0
/
relay.cpp
133 lines (119 loc) · 3.02 KB
/
relay.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "Arduino.h"
#include "relay.h"
#include "relayboard.h"
#include "setup.h"
#include "nvram.h"
void Relay::saveState(uint8_t data)
{
data<<=1;
data |= (_relayState & 0x01);
Device::saveState(data);
}
uint8_t Relay::restoreState()
{
uint8_t data = Device::restoreState();
_relayState = data & 0x01;
data >>=1;
setOn(_relayState);
return data;
}
Relay::Relay(uint8_t id, uint8_t nvSlot, uint8_t board, uint8_t relay, enum DeviceType type) : Device(id, nvSlot, type)
{
_board = board;
_relay = relay;
_relayState = 0;
_invert = 0;
_lastRefresh = 0;
setOn(_relayState);
}
Relay::Relay(uint8_t id, uint8_t nvSlot, uint8_t board, uint8_t relay): Relay(id, nvSlot, board, relay, RELAY)
{
}
Relay::Relay(uint8_t id, unsigned char *initData): Device(id,initData)
{
_board = initData[_offset++];
_relay = initData[_offset++];
_invert = initData[_offset++];
_lastRefresh = 0;
// _relayState will be restored in restoreState(), so nothing to do here
}
Relay::~Relay()
{
}
uint8_t Relay::saveConfig(unsigned char *initData)
{
uint8_t offset = Device::saveConfig(initData);
initData[offset++]=_board;
initData[offset++]=_relay;
initData[offset++]=_invert;
return offset;
}
void Relay::printInfo()
{
Device::printInfo();
Serial.print(F("\tboard # "));
Serial.println(_board);
Serial.print(F("\trelay # "));
Serial.println(_relay);
Serial.print(F("\tinvert? "));
Serial.println(_invert);
Serial.print(F("\tcurrent relay state "));
Serial.println(_relayState);
}
void Relay::setOn(uint8_t state)
{
_relayState = state;
Device *rb = Device::getDeviceForId(_board);
if(rb != NULL && rb->getType()==RELAYBOARD)
{
if(_invert) state = !state;
((RelayBoard *)rb)->setOn(_relay, state);
}
notifyAll(_relayState);
}
uint8_t Relay::relayState()
{
return _relayState;
}
void Relay::printDefinition(uint8_t first)
{
if(_invert != 0)
{
char buffer[40];
sprintf(buffer,"setinvert %d %d",getId(), _invert);
Serial.println(buffer);
}
Device::printDefinition(0);
};
bool Relay::isType(enum DeviceType type)
{
if(type == RELAY)
return true;
else
return Device::isType(type);
}
void Relay::loop()
{
#ifdef USE_RELAY_FAILSAFE
if(_invert) // inverted relays are the important ones!
{
// Every 10 seconds, we request a delayed relay off (which means on for inverted devices).
// This will make the lights go on if we lose i2c or otherwise lock up.
if (millis() > _lastRefresh + 10000)
{
if(verbose)
{
Serial.print(F("delayed on for device "));
Serial.println(getId());
}
_lastRefresh = millis();
Device *rb = Device::getDeviceForId(_board);
if(rb != NULL && rb->getType()==RELAYBOARD)
{
((RelayBoard *)rb)->delayedSetOn(_relay, 0, 30);
}
}
}
#endif
Device::loop();
}