supla-device
Loading...
Searching...
No Matches
relay.h
1// SPDX-FileCopyrightText: AC SOFTWARE SP. Z O.O.
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4/* Relay class
5 * This class is used to control any type of relay that can be controlled
6 * by setting LOW or HIGH output on selected GPIO.
7 */
8
9#ifndef SRC_SUPLA_CONTROL_RELAY_H_
10#define SRC_SUPLA_CONTROL_RELAY_H_
11
12#include <stdint.h>
13
14#include "../action_handler.h"
15#include "../channel_element.h"
16#include "../io.h"
17#include "weekly_schedule_component.h"
18
19#define STATE_ON_INIT_RESTORED_OFF -3
20#define STATE_ON_INIT_RESTORED_ON -2
21#define STATE_ON_INIT_RESTORE -1
22#define STATE_ON_INIT_OFF 0
23#define STATE_ON_INIT_ON 1
24
25#define RELAY_FLAGS_ON (1 << 0)
26#define RELAY_FLAGS_STAIRCASE (1 << 1)
27#define RELAY_FLAGS_IMPULSE_FUNCTION (1 << 2) // i.e. gate, door, gateway
28#define RELAY_FLAGS_OVERCURRENT (1 << 3)
29#define RELAY_FLAGS_AUTOMATIC_MODE (1 << 5)
30
31#define RELAY_STORED_MODE_NOT_SET 0
32#define RELAY_STORED_MODE_AUTOMATIC 1
33#define RELAY_STORED_MODE_FORCED_OFF 2
34#define RELAY_STORED_MODE_FORCED_ON 3
35
36namespace Supla {
37namespace Io {
38struct IoPin;
39}
40
41namespace Control {
42class Button;
43class RelayWeeklySchedule;
44
45class Relay : public ChannelElement, public ActionHandler {
46 public:
47 friend class RelayWeeklySchedule;
48
49 union RelayFlags {
50 struct {
51 uint8_t relayOn : 1;
52 uint8_t staircaseFunction : 1;
53 uint8_t impulseFunction : 1;
54 uint8_t overcurrent : 1;
55 uint8_t weeklySchedule : 1;
56 // AUTOMATIC remains encoded as bit 5 for OTA compatibility.
57 uint8_t operatingMode : 2;
58 uint8_t reserved : 1;
59 } flags;
60 uint8_t rawValue = 0;
61 };
62
63 static_assert(sizeof(RelayFlags) == sizeof(uint8_t),
64 "Flags size must be 1 byte");
65
66 explicit Relay(Supla::Io::IoPin outputPin,
67 _supla_int_t functions =
68 (0xFF ^ SUPLA_BIT_FUNC_CONTROLLINGTHEROLLERSHUTTER));
69 explicit Relay(Supla::Io::Base *io,
70 int pin,
71 bool highIsOn = true,
72 _supla_int_t functions =
73 (0xFF ^ SUPLA_BIT_FUNC_CONTROLLINGTHEROLLERSHUTTER));
74 explicit Relay(int pin,
75 bool highIsOn = true,
76 _supla_int_t functions =
77 (0xFF ^ SUPLA_BIT_FUNC_CONTROLLINGTHEROLLERSHUTTER));
78
79 virtual ~Relay();
80
81 virtual Relay &setDefaultStateOn();
82 virtual Relay &setDefaultStateOff();
83 virtual Relay &setDefaultStateRestore();
84 virtual Relay &setPreloadStateOnSoftReset(bool enabled = true);
85 virtual Relay &keepTurnOnDuration(bool keep = true); // DEPREACATED
86
87 [[deprecated("Use IoPin::writeActive/writeInactive instead")]] virtual uint8_t
88 pinOnValue();
89 [[deprecated("Use IoPin::writeActive/writeInactive instead")]] virtual uint8_t
90 pinOffValue();
91 virtual void turnOn(_supla_int_t duration = 0);
92 virtual void turnOff(_supla_int_t duration = 0);
93 virtual bool isOn();
94 virtual void toggle(_supla_int_t duration = 0);
95
96 void attach(Supla::Control::Button *);
97
98 void handleAction(int event, int action) override;
99
100 void onLoadConfig(SuplaDeviceClass *sdc) override;
101 void purgeConfig() override;
102 void onInit() override;
103 void onLoadState() override;
104 void onSaveState() override;
105 void iterateAlways() override;
106 bool iterateConnected() override;
107 int32_t handleNewValueFromServer(TSD_SuplaChannelNewValue *newValue) override;
108 void onRegistered(Supla::Protocol::SuplaSrpc *suplaSrpc) override;
109 Supla::ApplyConfigResult applyChannelConfig(TSD_ChannelConfig *result,
110 bool local = false) override;
111 void fillChannelConfig(void *channelConfig,
112 int *size,
113 uint8_t configType) override;
121 bool getRemainingCountdownTimerSec(uint32_t *remainingSec) const override;
122
123 // Method is used by external integrations to prepare TSD_SuplaChannelNewValue
124 // value for specific channel type (i.e. to prefill durationMS field when
125 // required)
127
128 unsigned _supla_int_t getStoredTurnOnDurationMs();
129 void setStoredTurnOnDurationMs(uint32_t durationMs);
130
131 bool isStaircaseFunction(uint32_t functionToCheck = 0) const;
132 bool isImpulseFunction(uint32_t functionToCheck = 0) const;
133 void disableCountdownTimerFunction();
134 void enableCountdownTimerFunction();
135 bool isCountdownTimerFunctionEnabled() const;
136 void setMinimumAllowedDurationMs(uint32_t durationMs);
137
138 static void setRelayStorageSaveDelay(uint32_t delayMs);
139
140 bool isDefaultRelatedMeterChannelSet() const;
141 uint32_t getCurrentValueFromMeter() const;
142 void setDefaultRelatedMeterChannelNo(int channelNo);
143 void setTurnOffWhenEmptyAggregator(bool turnOff);
144
150 void setOvercurrentThreshold(uint32_t value);
151
157 uint32_t getOvercurrentThreshold() const {
158 return overcurrentThreshold;
159 }
160
166 void setOvercurrentMaxAllowed(uint32_t value);
167
173 uint32_t getOvercurrentMaxAllowed() const {
174 return overcurrentMaxAllowed;
175 }
176
182 void setDefaultStaircaseDurationMs(uint16_t durationMs) {
183 defaultStaircaseDurationMs = durationMs;
184 }
185
191 void setDefaultImpulseDurationMs(uint16_t durationMs) {
192 defaultImpulseDurationMs = durationMs;
193 }
194
195 bool setRuntimeFunction(uint32_t channelFunction) override;
196 bool setAndSaveFunction(uint32_t channelFunction) override;
197
203 void setRestartTimerOnToggle(bool restart);
204
210 bool isRestartTimerOnToggle() const;
211
212 bool isFullyInitialized() const;
213
239 void enableCyclicMode(uint32_t turnOnTimeMs, uint32_t turnOffTimeMs);
240 void disableCyclicMode();
241 bool isCyclicMode() const;
242
243 bool isWeeklyScheduleSupported() const;
244 Relay &setWeeklyScheduleAvailable(bool available = true);
245 bool isWeeklyScheduleAvailable() const;
246 Relay &setAutomaticModeSupported(bool supported = true);
247 bool isAutomaticModeSupported() const;
248 bool isAutomaticMode() const;
249 bool setAutomaticMode(bool enabled);
250 bool setWeeklyScheduleController(
251 WeeklyScheduleController *controller,
252 WeeklyScheduleConfigHandler *configHandler = nullptr,
253 WeeklyScheduleProgramSource *programSource = nullptr);
254
255 protected:
256 Relay(Supla::Io::IoPin outputPin,
257 _supla_int_t functions,
258 Supla::Channel &externalChannel,
259 ElementMode mode);
260
262 Supla::Control::Button *button = nullptr;
263 ButtonListElement *next = nullptr;
264 };
265
266 void applyDuration(int32_t durationMs, bool turnOn);
267 void setOvercurrentThreshold(uint32_t value, bool local);
268
269 virtual void setNewChannelValue(bool value);
270 virtual void fillDefaultWeeklySchedule(
272 virtual bool canUseWeeklySchedule() const;
273 // Registration capability. Overrides must not depend on the function
274 // currently selected on the server.
275 virtual bool isWeeklyScheduleProgramModeSupported(uint8_t mode) const;
276 bool isWeeklyScheduleProgramModeAvailable(uint8_t mode) const;
277 // Runtime applicability after the server-selected function is known.
278 bool isWeeklyScheduleProgramModeApplicable(uint8_t mode) const;
279 bool hasAnyWeeklyScheduleProgramModeAvailable() const;
280 virtual void iterateAutomaticMode();
281
282 void saveConfig() const;
283 void loadRelayConfigOnly();
284 bool ensureNativeWeeklyScheduleController();
285 void updateWeeklyScheduleCapabilities();
286 void updateAutomaticModeCapability();
287 void purgeRelayConfigOnly();
288 void updateTimerValue();
289 void emitCountdownTimerActionIfNeeded();
290 void updateRelayHvacAggregator();
291 bool isManualActionAllowed(bool turnOn) const;
292 bool isManualForcedModeSupported() const;
293 bool setManualForcedMode(uint8_t mode);
294 void disableWeeklySchedule();
295 void applyWeeklyScheduleProgram(uint8_t programMode, bool programChanged);
296 virtual bool applyWeeklyScheduleState(bool on);
297 void notifyWeeklyScheduleManualAction();
298 uint32_t durationMs = 0;
299 uint32_t storedTurnOnDurationMs = 0;
300 uint32_t durationTimestamp = 0;
301 uint32_t turnOffDurationForCycle = 0;
302 uint16_t defaultStaircaseDurationMs = 10000;
303 uint16_t defaultImpulseDurationMs = 500;
304
305 uint32_t overcurrentThreshold = 0; // 0.01 A
306 uint32_t overcurrentMaxAllowed = 0; // 0.01 A
307 uint32_t overcurrentActiveTimestamp = 0;
308 uint32_t overcurrentCheckTimestamp = 0;
309
310 uint32_t timerUpdateTimestamp = 0;
311 uint32_t lastCountdownTimerRemainingSec = UINT32_MAX;
312 uint32_t postponeCommTimestamp = 0;
313
314 ButtonListElement *buttonList = nullptr;
315
316 uint16_t minimumAllowedDurationMs = 0;
317 int16_t defaultRelatedMeterChannelNo = -1;
318
319 // Runtime-only flags; state storage uses a separate representation.
322 : keepTurnOnDurationMs(false),
323 turnOffWhenEmptyAggregator(true),
324 initDone(false),
325 restartTimerOnToggle(false),
326 skipInitialStateSetting(false),
327 preloadStateOnSoftReset(false),
328 automaticModeSupported(false),
329 weeklyScheduleAvailable(false) {}
330
331 uint8_t keepTurnOnDurationMs : 1;
332 uint8_t turnOffWhenEmptyAggregator : 1;
333 uint8_t initDone : 1;
334 uint8_t restartTimerOnToggle : 1;
335 uint8_t skipInitialStateSetting : 1;
336 uint8_t preloadStateOnSoftReset : 1;
337 uint8_t automaticModeSupported : 1;
338 // Native weekly schedule remains opt-in.
339 uint8_t weeklyScheduleAvailable : 1;
340 };
341
342 static_assert(sizeof(RuntimeFlags) == sizeof(uint8_t),
343 "Relay runtime flags must fit in uint8_t");
344
345 RuntimeFlags runtimeFlags;
346
347 int8_t stateOnInit = STATE_ON_INIT_OFF;
348 Supla::Io::IoPin outputPin;
349 WeeklyScheduleComponents weeklyScheduleComponents;
350
351 static uint16_t relayStorageSaveDelay;
352};
353
354}; // namespace Control
355}; // namespace Supla
356
357#endif // SRC_SUPLA_CONTROL_RELAY_H_
Definition SuplaDevice.h:167
Definition action_handler.h:8
Definition channel_element.h:15
Definition channel.h:26
Definition button.h:21
Definition relay_weekly_schedule.h:19
Definition relay.h:45
bool setRuntimeFunction(uint32_t channelFunction) override
Sets channel's function at runtime.
Definition relay.cpp:1200
bool getRemainingCountdownTimerSec(uint32_t *remainingSec) const override
Returns remaining countdown timer time in seconds for an active relay countdown timer.
Definition relay.cpp:600
void setRestartTimerOnToggle(bool restart)
Set restart timer on toggle for staircase and impulse functions.
Definition relay.cpp:1781
uint32_t getOvercurrentMaxAllowed() const
Get overcurrent max level allowed.
Definition relay.h:173
void setOvercurrentThreshold(uint32_t value)
Set overcurrent threshold.
Definition relay.cpp:1722
void onRegistered(Supla::Protocol::SuplaSrpc *suplaSrpc) override
Method called each time when device successfully registers to Supla server.
Definition relay.cpp:305
uint32_t getOvercurrentThreshold() const
Get overcurrent threshold.
Definition relay.h:157
void enableCyclicMode(uint32_t turnOnTimeMs, uint32_t turnOffTimeMs)
Enable automatic cyclic relay operation.
Definition relay.cpp:1797
void onLoadConfig(SuplaDeviceClass *sdc) override
First method called on element in SuplaDevice.begin().
Definition relay.cpp:170
void setDefaultImpulseDurationMs(uint16_t durationMs)
Set default duration for impulse functions (controlling gate, door etc.)
Definition relay.h:191
void iterateAlways() override
Method called on each SuplaDevice iteration.
Definition relay.cpp:526
bool iterateConnected() override
Method called on each SuplaDevice iteration when device is connected and registered to Supla server o...
Definition relay.cpp:633
void onInit() override
Third method called on element in SuplaDevice.begin()
Definition relay.cpp:439
void setOvercurrentMaxAllowed(uint32_t value)
Set overcurrent max level allowed.
Definition relay.cpp:1718
bool isRestartTimerOnToggle() const
Get restart timer on toggle for staircase and impulse functions.
Definition relay.cpp:1785
void setDefaultStaircaseDurationMs(uint16_t durationMs)
Set default duration for staircase timer function.
Definition relay.h:182
void purgeConfig() override
Removes all configration data related to the element from Storage::Config.
Definition relay.cpp:1763
void onLoadState() override
Second method called on element in SuplaDevice.begin().
Definition relay.cpp:1003
void onSaveState() override
Method called periodically during SuplaDevice iteration.
Definition relay.cpp:950
int32_t handleNewValueFromServer(TSD_SuplaChannelNewValue *newValue) override
Handles "new value" request from server.
Definition relay.cpp:649
void fillSuplaChannelNewValue(TSD_SuplaChannelNewValue *value) override
Fills TSD_SuplaChannelNewValue based on current state.
Definition relay.cpp:782
Definition weekly_schedule_component.h:127
Definition weekly_schedule_component.h:114
Definition weekly_schedule_component.h:55
Definition weekly_schedule_component.h:34
Definition io.h:23
Definition supla_srpc.h:47
Definition io_pin.h:14
Definition proto.h:3276
Definition proto.h:3176
Definition proto.h:1243