Uniot Core
0.8.1
Loading...
Searching...
No Matches
AppKit.h
Go to the documentation of this file.
1/*
2 * This is a part of the Uniot project.
3 * Copyright (C) 2016-2023 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
26
34
35#pragma once
36
38#include <CrashStorage.h>
39#include <Date.h>
40#include <EventBus.h>
43#include <LispDevice.h>
44#include <LispPrimitives.h>
45#include <Logger.h>
46#include <MQTTKit.h>
47#include <NetworkController.h>
48#include <Singleton.h>
49#include <TopDevice.h>
50#include <unLisp.h>
51
59
64namespace uniot {
80class AppKit : public ICoreEventBusConnectionKit, public ISchedulerConnectionKit, public Singleton<AppKit> {
81 friend class Singleton<AppKit>;
82
83 public:
92 uint8_t pinBtn = UINT8_MAX;
93 uint8_t activeLevelBtn = LOW;
94 uint8_t pinLed = UINT8_MAX;
95 uint8_t activeLevelLed = HIGH;
96 uint8_t maxRebootCount = 3;
97 uint32_t rebootWindowMs = 10000;
98 bool registerLispBtn = true;
99 };
100
106 return unLisp::getInstance();
107 }
108
114 return mMQTT;
115 }
116
122 return mCredentials;
123 }
124
134 bool setWiFiCredentials(const String &ssid, const String &password) {
135 return mNetwork.setCredentials(ssid, password);
136 }
137
147 bool setUserId(const String &userId) {
148 if (!userId.isEmpty()) {
149 mCredentials.setOwnerId(userId);
150 mCredentials.store();
151 return true;
152 }
153 return false;
154 }
155
164 virtual void pushTo(TaskScheduler &scheduler) override {
165 scheduler.push(mNetwork);
166 scheduler.push(mMQTT);
167 scheduler.push("lisp_task", getLisp().getTask());
168 scheduler.push("lisp_cleanup", getLisp().getCleanupTask());
169
170 mTopDevice.setScheduler(scheduler);
171
172 if (mpNetworkDevice) {
173 scheduler.push(*mpNetworkDevice);
174 } else {
175 UNIOT_LOG_WARN("Configure Network Controller before pushing to the scheduler");
176 }
177 }
178
185 virtual void attach() override {
186 _initPrimitives();
187 mNetwork.attach();
188 mMQTT.attach();
189
190 if (mpNetworkDevice) {
191 mpNetworkDevice->attach();
192 }
193
194#if defined(ESP8266)
195 analogWriteRange(1023);
196#elif defined(ESP32)
197 analogWriteResolution(10);
198#endif
199
200 getLisp().getCleanupTask()->attach(15000);
201 mLispDevice.runStoredCode();
202 }
203
212 virtual void registerWithBus(CoreEventBus &eventBus) override {
220 eventBus.registerEntity(&mNetwork);
221 eventBus.registerEntity(&mMQTT);
222 eventBus.registerEntity(&getLisp());
223 eventBus.registerEntity(&mLispDevice);
224 eventBus.registerEntity(mpNetworkEventListener
226 ->listenToEvent(events::mqtt::Topic::CONNECTION));
227
228 if (mpNetworkDevice) {
229 eventBus.registerEntity(mpNetworkDevice.get());
230 } else {
231 UNIOT_LOG_WARN("Configure Network Controller before registering to the event bus");
232 }
233 }
234
243 virtual void unregisterFromBus(CoreEventBus &eventBus) override {
251 eventBus.unregisterEntity(&mNetwork);
252 eventBus.unregisterEntity(&mMQTT);
253 eventBus.unregisterEntity(&getLisp());
254 eventBus.unregisterEntity(&mLispDevice);
255 eventBus.unregisterEntity(mpNetworkEventListener
256 ->stopListeningToEvent(events::network::Topic::CONNECTION)
257 ->stopListeningToEvent(events::mqtt::Topic::CONNECTION));
258
259 if (mpNetworkDevice) {
260 eventBus.unregisterEntity(mpNetworkDevice.get());
261 }
262 }
263
274 config.activeLevelBtn,
275 config.pinLed,
276 config.activeLevelLed,
277 config.maxRebootCount,
278 config.rebootWindowMs,
279 config.registerLispBtn);
280 }
281
295 void configureNetworkController(uint8_t pinBtn = UINT8_MAX,
296 uint8_t activeLevelBtn = LOW,
297 uint8_t pinLed = UINT8_MAX,
298 uint8_t activeLevelLed = HIGH,
299 uint8_t maxRebootCount = 3,
300 uint32_t rebootWindowMs = 10000,
301 bool registerLispBtn = true) {
302 if (mpNetworkDevice) {
303 UNIOT_LOG_WARN("Network Controller already configured");
304 return;
305 }
306
307 mpNetworkDevice = MakeUnique<NetworkController>(mNetwork, pinBtn, activeLevelBtn, pinLed, activeLevelLed, maxRebootCount, rebootWindowMs);
308 auto ctrlBtn = mpNetworkDevice->getButton();
309 if (ctrlBtn && registerLispBtn) {
311 }
312 }
313
323 mLispDevice.setEventInterceptor(interceptor);
324 }
325
335 void publishLispEvent(const String &eventID, int32_t value) {
336 mLispDevice.publishLispEvent(eventID, value);
337 }
338
339 private:
346 AppKit()
347 : mNetwork(mCredentials),
348 mMQTT(mCredentials, [this](CBORObject &info) {
349 auto obj = info.putMap("primitives");
351
352 auto registers = info.putMap("misc").putMap("registers");
354
355 // TODO: add uniot core version
356 info.put("timestamp", static_cast<int64_t>(Date::now()));
357 info.put("creator", mCredentials.getCreatorId().c_str());
358 info.put("public_key", mCredentials.getPublicKey().c_str());
359 info.put("mqtt_size", MQTT_MAX_PACKET_SIZE);
360 info.put("debug", UNIOT_LOG_ENABLED);
361 info.put("lisp_heap", UNIOT_LISP_HEAP);
362 }),
363 mpNetworkDevice(nullptr) {
364 _initMqtt();
365 _initTasks();
366 _initListeners();
367 }
368
375 inline void _initMqtt() {
376 // TODO: should I move configs to the Credentials class?
377 mMQTT.setServer("mqtt.uniot.io", 1883);
378 mMQTT.addDevice(mTopDevice);
379 mMQTT.addDevice(mLispDevice);
380 mTopDevice.syncSubscriptions();
381 mLispDevice.syncSubscriptions();
382 }
383
389 inline void _initTasks() {
390 // TODO: init new tasks here
391 }
392
399 inline void _initPrimitives() {
402 }
405 }
408 }
411 }
414 }
415 }
416
423 inline void _initListeners() {
424 mpNetworkEventListener = MakeUnique<CoreCallbackEventListener>([&](int topic, int msg) {
426 switch (msg) {
428 UNIOT_LOG_DEBUG("AppKit Subscriber, SUCCESS, ip: %s", WiFi.localIP().toString().c_str());
429 break;
431 UNIOT_LOG_DEBUG("AppKit Subscriber, ACCESS_POINT");
432 mpNetworkEventListener->receiveDataFromChannel(events::network::Channel::OUT_SSID, [this](unsigned int id, bool empty, Bytes data) {
433 if (!empty) {
434 UNIOT_LOG_DEBUG("SSID: %s", data.terminate().c_str());
435 }
436 });
437 break;
438
440 UNIOT_LOG_DEBUG("AppKit Subscriber, CONNECTING");
441 mpNetworkEventListener->receiveDataFromChannel(events::network::Channel::OUT_SSID, [this](unsigned int id, bool empty, Bytes data) {
442 if (!empty) {
443 UNIOT_LOG_DEBUG("SSID: %s", data.terminate().c_str());
444 }
445 });
446 break;
447
449 UNIOT_LOG_DEBUG("AppKit Subscriber, DISCONNECTING");
450 break;
451
453 UNIOT_LOG_DEBUG("AppKit Subscriber, DISCONNECTED");
454 break;
455
457 UNIOT_LOG_DEBUG("AppKit Subscriber, AVAILABLE");
458 break;
459
461 default:
462 UNIOT_LOG_DEBUG("AppKit Subscriber, FAILED");
463 break;
464 }
465 return;
466 }
467 if (events::mqtt::Topic::CONNECTION == topic) {
468 switch (msg) {
470 UNIOT_LOG_DEBUG("AppKit Subscriber, MQTT SUCCESS");
471 if (mCredentials.isOwnerChanged()) {
472 UNIOT_LOG_INFO("Owner changed, renewing subscriptions");
473 mMQTT.renewSubscriptions();
474 mCredentials.resetOwnerChanged();
475 } else {
476 UNIOT_LOG_INFO("Owner not changed, do not renew subscriptions");
477 }
478 break;
480 default:
481 UNIOT_LOG_DEBUG("AppKit Subscriber, MQTT FAILED");
482 break;
483 }
484 return;
485 }
486 });
487 }
488
489 Credentials mCredentials;
490 NetworkScheduler mNetwork;
491 MQTTKit mMQTT;
492 TopDevice mTopDevice;
493 LispDevice mLispDevice;
494
495 UniquePointer<NetworkController> mpNetworkDevice;
496 UniquePointer<CoreCallbackEventListener> mpNetworkEventListener;
497};
498
499} // namespace uniot
Defines the interface for components that can connect to an EventBus.
High-level network management controller with user interface.
Bytes & terminate()
Ensures the byte array is null-terminated.
Definition Bytes.h:246
const char * c_str() const
Gets the byte array as a C string.
Definition Bytes.h:266
Definition AppKit.h:80
bool setUserId(const String &userId)
Set the user identifier for device association.
Definition AppKit.h:147
MQTTKit & getMQTT()
Get the MQTT communication kit instance.
Definition AppKit.h:113
bool setWiFiCredentials(const String &ssid, const String &password)
Set WiFi network credentials.
Definition AppKit.h:134
virtual void pushTo(TaskScheduler &scheduler) override
Add all managed tasks to the scheduler.
Definition AppKit.h:164
void setLispEventInterceptor(LispEventInterceptor interceptor)
Set event interceptor for Lisp interpreter.
Definition AppKit.h:322
void publishLispEvent(const String &eventID, int32_t value)
Publish an event to the Lisp interpreter.
Definition AppKit.h:335
virtual void registerWithBus(CoreEventBus &eventBus) override
Register all components with the event bus.
Definition AppKit.h:212
unLisp & getLisp()
Get the Lisp interpreter instance.
Definition AppKit.h:105
virtual void unregisterFromBus(CoreEventBus &eventBus) override
Unregister all components from the event bus.
Definition AppKit.h:243
void configureNetworkController(uint8_t pinBtn=UINT8_MAX, uint8_t activeLevelBtn=LOW, uint8_t pinLed=UINT8_MAX, uint8_t activeLevelLed=HIGH, uint8_t maxRebootCount=3, uint32_t rebootWindowMs=10000, bool registerLispBtn=true)
Configure the NetworkController with individual parameters.
Definition AppKit.h:295
const Credentials & getCredentials()
Get the device credentials.
Definition AppKit.h:121
virtual void attach() override
Initialize and attach all components.
Definition AppKit.h:185
void configureNetworkController(const NetworkControllerConfig &config)
Configure the NetworkController using a config structure.
Definition AppKit.h:272
Definition CBORObject.h:40
Manages device identity and cryptographic credentials for Uniot devices.
Definition Credentials.h:61
const String & getCreatorId() const
Gets the creator ID.
Definition Credentials.h:147
const String & getPublicKey() const
Gets the device's public key as a hexadecimal string.
Definition Credentials.h:165
static time_t now()
Returns the current Unix timestamp.
Definition Date.h:74
bool registerEntity(EventEntity< T_topic, T_msg, T_data > *entity)
Registers an entity (emitter or listener) with this EventBus.
Definition EventBus.cpp:44
void unregisterEntity(EventEntity< T_topic, T_msg, T_data > *entity)
Unregisters an entity from this EventBus.
Definition EventBus.cpp:53
bool closeDataChannel(T_topic topic)
Closes a previously opened data channel.
Definition EventBus.cpp:66
bool openDataChannel(T_topic topic, size_t limit)
Opens a data channel for a specific topic with a size limit.
Definition EventBus.cpp:61
Interface for connecting components to the TaskScheduler.
Definition ISchedulerConnectionKit.h:35
Definition MQTTKit.h:75
static RegisterManager & getRegisterManager()
Gets the static register manager instance.
Definition PrimitiveExpeditor.h:71
void serializeRegisters(CBORObject &obj)
Serializes all registers (GPIO and Object) to a CBOR object.
Definition RegisterManager.h:165
bool link(const String &name, RecordPtr link, uint32_t id=FOURCC(____))
Links an object to a named register.
Definition RegisterManager.h:111
Singleton(const Singleton &)=delete
static unLisp & getInstance()
Definition Singleton.h:73
Definition TaskScheduler.h:164
Definition unLisp.h:219
TaskScheduler::TaskPtr getCleanupTask()
Definition unLisp.h:231
void serializePrimitives(CBORObject &obj)
Serialize all registered primitive functions to CBOR format.
Definition unLisp.h:315
unLisp * pushPrimitive(Primitive *primitive)
Add a new primitive function to the Lisp environment.
Definition unLisp.h:295
Object aread(Root root, VarObject env, VarObject list)
Analog read primitive function for reading analog input.
Definition LispPrimitives.cpp:74
Object bclicked(Root root, VarObject env, VarObject list)
Button clicked primitive function for checking button click status.
Definition LispPrimitives.cpp:91
Object dwrite(Root root, VarObject env, VarObject list)
Definition LispPrimitives.cpp:23
Object awrite(Root root, VarObject env, VarObject list)
Analog write primitive function for setting PWM output.
Definition LispPrimitives.cpp:57
Object dread(Root root, VarObject env, VarObject list)
Digital read primitive function for reading pin input state.
Definition LispPrimitives.cpp:40
std::unique_ptr< T > UniquePointer
Type alias for std::unique_ptr with cleaner syntax.
Definition Common.h:152
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:179
#define FOURCC(name)
Creates a FourCC constant from a string literal.
Definition Common.h:107
IEventBusConnectionKit< unsigned int, int, Bytes > ICoreEventBusConnectionKit
A specific instance of IEventBusConnectionKit for core system events.
Definition IEventBusConnectionKit.h:87
EventBus< unsigned int, int, Bytes > CoreEventBus
Standard EventBus configuration used throughout the core system.
Definition EventBus.h:211
#define UNIOT_LOG_INFO(...)
Log an INFO level message Used for general information about system operation. Only compiled if UNIOT...
Definition Logger.h:268
#define UNIOT_LOG_WARN(...)
Log an WARN level message Used for warnings about potentially problematic situations....
Definition Logger.h:247
#define UNIOT_LOG_DEBUG(...)
Log an DEBUG level message Used for general information about system operation. Only compiled if UNIO...
Definition Logger.h:293
TaskScheduler & push(const char *name, TaskPtr task)
Add a named task to the scheduler.
Definition TaskScheduler.h:214
constexpr const char * dread
Primitive for digital read operations.
Definition DefaultPrimitives.h:59
constexpr const char * aread
Primitive for analog read operations.
Definition DefaultPrimitives.h:73
constexpr const char * awrite
Primitive for analog write operations.
Definition DefaultPrimitives.h:66
constexpr const char * dwrite
Primitive for digital write operations.
Definition DefaultPrimitives.h:52
constexpr const char * bclicked
Primitive for detecting button click events.
Definition DefaultPrimitives.h:80
@ OUT_LISP_LOG
Channel for Lisp log messages and debug information.
Definition LispEvents.h:74
@ IN_EVENT
Channel for incoming events from the application to Lisp.
Definition LispEvents.h:77
@ OUT_LISP
Channel for standard Lisp output (stdout equivalent)
Definition LispEvents.h:73
@ OUT_LISP_ERR
Channel for Lisp error messages and exceptions.
Definition LispEvents.h:75
@ OUT_EVENT
Channel for outgoing events from Lisp to the application.
Definition LispEvents.h:76
@ CONNECTION
MQTT connection state changes and operations.
Definition MQTTEvents.h:61
@ SUCCESS
MQTT connection established successfully.
Definition MQTTEvents.h:73
@ FAILED
MQTT connection failed or was lost.
Definition MQTTEvents.h:72
@ DISCONNECTING
Currently disconnecting from network.
Definition NetworkEvents.h:88
@ 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
@ CONNECTION
WiFi connection state changes and operations.
Definition NetworkEvents.h:74
@ OUT_SSID
Channel for broadcasting current SSID information.
Definition NetworkEvents.h:63
Contains all classes and functions related to the Uniot Core.
std::function< bool(const LispEvent &event)> LispEventInterceptor
Definition LispDevice.h:41
Configuration parameters for NetworkController.
Definition AppKit.h:91
uint8_t pinBtn
Button pin (UINT8_MAX means not used)
Definition AppKit.h:92
bool registerLispBtn
Whether to register the button with the Lisp interpreter.
Definition AppKit.h:98
uint8_t activeLevelLed
Active level for LED (LOW or HIGH)
Definition AppKit.h:95
uint8_t maxRebootCount
Maximum number of consecutive reboots.
Definition AppKit.h:96
uint8_t activeLevelBtn
Active level for button (LOW or HIGH)
Definition AppKit.h:93
uint32_t rebootWindowMs
Time window in ms for counting reboots.
Definition AppKit.h:97
uint8_t pinLed
LED pin (UINT8_MAX means not used)
Definition AppKit.h:94
#define UNIOT_LISP_HEAP
Definition unLisp.h:54