Uniot Core
0.9.0
Loading...
Searching...
No Matches
NetworkController.h
Go to the documentation of this file.
1/*
2 * This is a part of the Uniot project.
3 * Copyright (C) 2016-2025 Uniot <contact@uniot.io>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include <Button.h>
22#include <CBORStorage.h>
23#include <Common.h>
24#include <EventListener.h>
26#include <NetworkEvents.h>
27#include <NetworkScheduler.h>
28
71
72namespace uniot {
94 public:
120 uint8_t pinBtn = UINT8_MAX,
121 uint8_t activeLevelBtn = LOW,
122 uint8_t pinLed = UINT8_MAX,
123 uint8_t activeLevelLed = HIGH,
124 uint8_t maxRebootCount = UNIOT_WIFI_REBOOT_RESET_COUNT,
125 uint32_t rebootWindowMs = UNIOT_WIFI_REBOOT_WINDOW_MS)
126 : CBORStorage("ctrl.cbor"),
127 mpNetwork(&network),
128 mNetworkLastState(events::network::Msg::SUCCESS),
129 mClickCounter(0),
130 mPinLed(pinLed),
131 mActiveLevelLed(activeLevelLed),
132 mMaxRebootCount(maxRebootCount),
133 mRebootWindowMs(rebootWindowMs),
134 mRebootCount(0) {
135 if (pinLed != UINT8_MAX) {
136 pinMode(mPinLed, OUTPUT);
137 }
138 if (pinBtn != UINT8_MAX) {
139 mpConfigBtn = MakeUnique<Button>(pinBtn, activeLevelBtn, 30, [&](Button *btn, Button::Event event) {
140 switch (event) {
142 if (mClickCounter > 3)
143 mpNetwork->forget();
144 else
145 mpNetwork->reconnect();
146 break;
147 case Button::CLICK:
148 if (!mClickCounter) {
149 mpTaskResetClickCounter->attach(5000, 1);
150 }
151 mClickCounter++;
152 default:
153 break;
154 }
155 });
156 }
157 _initTasks();
158 _checkAndHandleReboot();
160 }
161
172
180 virtual bool store() override {
181 object().put("reset", mRebootCount);
182 return CBORStorage::store();
183 }
184
192 virtual bool restore() override {
193 if (CBORStorage::restore()) {
194 mRebootCount = object().getInt("reset");
195 return true;
196 }
197 return false;
198 }
199
210 virtual void onEventReceived(unsigned int topic, int msg) override {
212 int lastState = _resetNetworkLastState(msg);
213 switch (msg) {
215 if (lastState != events::network::Msg::FAILED) {
217 }
218 break;
220 statusIdle();
221 break;
223 statusBusy();
224 break;
226 if (lastState != events::network::Msg::CONNECTING) {
227 // If previous state was CONNECTING, most likely there was a manual reconnect request
228 mpNetwork->reconnect();
229 }
230 break;
232 mpNetwork->reconnect();
233 break;
235 statusAlarm();
236 mpNetwork->config();
237 break;
238 default:
239 break;
240 }
241 }
242 }
243
252 virtual void pushTo(TaskScheduler &scheduler) override {
253 scheduler.push("signal_led", mpTaskSignalLed);
254 scheduler.push("rst_reboot_count", mpTaskResetRebootCounter);
255 if (_hasButton()) {
256 scheduler.push("btn_config", mpTaskConfigBtn);
257 scheduler.push("rst_click_count", mpTaskResetClickCounter);
258 }
259 }
260
267 virtual void attach() override {
268 if (_hasRebootReset()) {
269 mpTaskResetRebootCounter->once(mRebootWindowMs);
270 }
271 if (_hasButton()) {
272 mpTaskConfigBtn->attach(100);
273 }
274 statusBusy();
275 }
276
285 mpTaskSignalLed->attach(1000);
286 }
287
294 void statusBusy() {
295 mpTaskSignalLed->attach(500);
296 }
297
304 void statusAlarm() {
305 mpTaskSignalLed->attach(200);
306 }
307
314 void statusIdle() {
315 mpTaskSignalLed->attach(200, 1);
316 }
317
326 return _hasButton() ? mpConfigBtn.get() : nullptr;
327 }
328
329 private:
337 void _initTasks() {
338 mpTaskSignalLed = TaskScheduler::make([&](SchedulerTask &self, short t) {
339 static bool signalLevel = true;
340 signalLevel = (!signalLevel && t);
342
343 if (_hasLed()) {
344 digitalWrite(mPinLed, signalLevel ? mActiveLevelLed : !mActiveLevelLed);
345 }
346 });
347
348 if (_hasButton()) {
349 mpTaskConfigBtn = TaskScheduler::make(*mpConfigBtn);
350 mpTaskResetClickCounter = TaskScheduler::make([&](SchedulerTask &self, short t) {
351 UNIOT_LOG_DEBUG("click counter: %d", mClickCounter);
352 mClickCounter = 0;
353 });
354 }
355
356 mpTaskResetRebootCounter = TaskScheduler::make([&](SchedulerTask &self, short t) {
357 mRebootCount = 0;
359 });
360 }
361
370 void _checkAndHandleReboot() {
371 if (!_hasRebootReset()) {
372 return; // reboot-reset disabled: skip restore, increment, and store entirely
373 }
375 mRebootCount++;
376 if (mRebootCount >= mMaxRebootCount) {
377 mpTaskResetRebootCounter->detach();
378 mpNetwork->forget();
379 mRebootCount = 0;
380 }
382 }
383
393 int _resetNetworkLastState(int newState) {
394 auto oldState = mNetworkLastState;
395 mNetworkLastState = newState;
396 return oldState;
397 }
398
403 inline bool _hasButton() {
404 return mpConfigBtn.get() != nullptr;
405 }
406
411 inline bool _hasLed() {
412 return mPinLed != UINT8_MAX;
413 }
414
422 inline bool _hasRebootReset() {
423 return mMaxRebootCount != UINT8_MAX;
424 }
425
426 NetworkScheduler *mpNetwork;
427 int mNetworkLastState;
428
429 uint8_t mClickCounter;
430 uint8_t mPinLed;
431 uint8_t mActiveLevelLed;
432 uint8_t mMaxRebootCount;
433 uint32_t mRebootWindowMs;
434 uint8_t mRebootCount;
435
436 UniquePointer<Button> mpConfigBtn;
437
438 // Task pointers for scheduled operations
439 TaskScheduler::TaskPtr mpTaskSignalLed;
440 TaskScheduler::TaskPtr mpTaskConfigBtn;
441 TaskScheduler::TaskPtr mpTaskResetClickCounter;
442 TaskScheduler::TaskPtr mpTaskResetRebootCounter;
443};
444} // namespace uniot
445
Network event definitions for the Uniot event system.
Complete WiFi network management and configuration system.
Definition Button.h:58
Event
Defines types of button events that can be triggered.
Definition Button.h:64
@ LONG_PRESS
Button held down for longer than the defined threshold.
Definition Button.h:66
@ CLICK
Regular short button press and release.
Definition Button.h:65
long getInt(int key) const
Get an integer value at a specific integer key.
Definition CBORObject.h:409
CBORObject & put(int key, int value)
Put an integer value at a specific integer key.
Definition CBORObject.h:180
virtual bool restore() override
Restore the CBOR object from the filesystem.
Definition CBORStorage.h:102
virtual bool store() override
Store the CBOR object to the filesystem.
Definition CBORStorage.h:74
CBORStorage(const String &path)
Constructs a new CBORStorage object.
Definition CBORStorage.h:46
CBORObject & object()
Get access to the underlying CBORObject.
Definition CBORStorage.h:60
void emitEvent(unsigned int topic, int msg)
EventListener * stopListeningToEvent(unsigned int topic)
EventListener * listenToEvent(unsigned int topic)
Interface for connecting components to the TaskScheduler.
Definition ISchedulerConnectionKit.h:35
void statusIdle()
Set LED to idle status pattern.
Definition NetworkController.h:314
virtual ~NetworkController()
Destroy the NetworkController.
Definition NetworkController.h:168
virtual void onEventReceived(unsigned int topic, int msg) override
Handle network events and update controller state.
Definition NetworkController.h:210
void statusAlarm()
Set LED to alarm status pattern.
Definition NetworkController.h:304
void statusWaiting()
Set LED to waiting status pattern.
Definition NetworkController.h:284
NetworkController(NetworkScheduler &network, uint8_t pinBtn=UINT8_MAX, uint8_t activeLevelBtn=LOW, uint8_t pinLed=UINT8_MAX, uint8_t activeLevelLed=HIGH, uint8_t maxRebootCount=UNIOT_WIFI_REBOOT_RESET_COUNT, uint32_t rebootWindowMs=UNIOT_WIFI_REBOOT_WINDOW_MS)
Construct a new NetworkController.
Definition NetworkController.h:119
void statusBusy()
Set LED to busy status pattern.
Definition NetworkController.h:294
virtual bool restore() override
Restore controller state from persistent storage.
Definition NetworkController.h:192
Button * getButton()
Get access to the configuration button.
Definition NetworkController.h:325
virtual void attach() override
Attach the controller and start initial operations.
Definition NetworkController.h:267
virtual void pushTo(TaskScheduler &scheduler) override
Push all controller tasks to the scheduler.
Definition NetworkController.h:252
virtual bool store() override
Store controller state to persistent storage.
Definition NetworkController.h:180
Complete WiFi network management and configuration scheduler.
Definition NetworkScheduler.h:100
Definition TaskScheduler.h:67
Definition TaskScheduler.h:183
std::unique_ptr< T > UniquePointer
Type alias for std::unique_ptr with cleaner syntax.
Definition Common.h:305
#define UNIOT_WIFI_REBOOT_WINDOW_MS
How long after boot a reboot still counts towards the reset, in ms.
Definition Common.h:115
auto MakeUnique(Args &&...args) -> decltype(std::make_unique< T >(std::forward< Args >(args)...))
Creates a unique pointer instance, alias for std::make_unique.
Definition Common.h:332
#define UNIOT_WIFI_REBOOT_RESET_COUNT
Consecutive reboots that reset the stored network configuration.
Definition Common.h:104
EventListener< unsigned int, int, Bytes > CoreEventListener
Type alias for the common EventListener configuration used in the core system.
Definition EventListener.h:100
#define UNIOT_LOG_DEBUG(...)
Log an DEBUG level message Used for general information about system operation. Only compiled if UNIO...
Definition Logger.h:340
SharedPointer< SchedulerTask > TaskPtr
Shared pointer type for scheduler tasks.
Definition TaskScheduler.h:190
static TaskPtr make(SchedulerTask::SchedulerTaskCallback callback)
Static factory method to create a task with a callback.
Definition TaskScheduler.h:212
TaskScheduler & push(const char *name, TaskPtr task)
Add a named task to the scheduler.
Definition TaskScheduler.h:233
@ SUCCESS
Network operation completed successfully.
Definition NetworkEvents.h:86
@ ACCESS_POINT
Device is operating in access point mode.
Definition NetworkEvents.h:90
@ AVAILABLE
Configured network is available for connection.
Definition NetworkEvents.h:91
@ DISCONNECTED
Network connection has been lost or terminated.
Definition NetworkEvents.h:89
@ FAILED
Network operation failed (connection, scan, etc.)
Definition NetworkEvents.h:85
@ CONNECTING
Currently attempting to connect to network.
Definition NetworkEvents.h:87
@ WIFI_STATUS_LED
LED status indicators for network state.
Definition NetworkEvents.h:75
@ CONNECTION
WiFi connection state changes and operations.
Definition NetworkEvents.h:74
Definition DateEvents.h:51
Contains all classes and functions related to the Uniot Core.