-
-
Notifications
You must be signed in to change notification settings - Fork 3
Application
An Application is the central orchestrator in ksIotFrameworkLib that integrates and manages components to achieve specific IoT functionality.
The Application class (ksApplication) serves as the entry point and coordinator for your IoT device. It manages the lifecycle of all components, handles their initialization, and coordinates their interactions.
- Component Management — Add, find, and remove components
- Lifecycle Orchestration — Coordinate init, postInit, and loop phases
- Dependency Resolution — Enable components to find each other
- State Management — Track initialization and execution state
┌─────────────────────────────────────────────────────────┐
│ 1. Application Created │
│ App rotator instantiates your application │
└─────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 2. init() Called │
│ Override to add components │
│ Return false to abort and switch apps │
└─────────────────────┬───────────────────────────────────┘
│ true
▼
┌─────────────────────────────────────────────────────────┐
│ 3. Component Initialization │
│ Framework calls init() on each component │
└─────────────────────┬───────────────────────────────────┘
│ all succeed
▼
┌─────────────────────────────────────────────────────────┐
│ 4. postInit() Called │
│ Override to find component references │
│ Components enter Active state │
└─────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 5. Loop Execution │
│ loop() called repeatedly │
│ Each component's loop() executed │
└─────────────────────┬───────────────────────────────────┘
│
▼ false
┌─────────────────────────────────────────────────────────┐
│ 6. Application Terminated │
│ Components destroyed │
│ Rotator switches to next app │
└─────────────────────────────────────────────────────────┘
#pragma once
#include <ksf/ksApplication.h>
class MyApp : public ksf::ksApplication
{
protected:
bool init() override {
// Phase 1: Add components
addComponent<SomeComponent>();
return true; // Return false to abort
}
bool postInit() override {
// Phase 2: Find component references
auto comp = findComponent<SomeComponent>();
return comp != nullptr; // Return false to abort
}
bool loop() override {
// Phase 3: Main application loop
// Return false to stop application
return true;
}
};Creates and adds a component to the application.
Parameters:
-
TComponentType— Component class type (template parameter) -
ctorArgs...— Constructor arguments for the component
Returns: std::shared_ptr<TComponentType> — Smart pointer to created component
Example:
// Add LED component with pin number
auto led = addComponent<ksf::comps::ksLed>(LED_BUILTIN);
// Add WiFi connector with device name
addComponent<ksf::comps::ksWifiConnector>("MyDevice");
// Add MQTT connector with no args
addComponent<ksf::comps::ksMqttConnector>();When to call:
- Always in
init()method - Can be called later, but it's exceptional
Finds the first component of a specific type.
Parameters:
-
TComponentType— Component class type to search for
Returns: std::shared_ptr<TComponentType> or nullptr
Example:
bool postInit() override {
auto mqtt = findComponent<ksf::comps::ksMqttConnector>();
if (mqtt) {
// Use mqtt component
mqtt->subscribe("topic");
}
return mqtt != nullptr;
}When to call:
- In
postInit()method - After all components have been added
Finds all components of a specific type.
Parameters:
-
TComponentType— Component class type to search for -
outVector— Vector to store found components
Example:
std::vector<std::shared_ptr<ksLed>> leds;
findComponents<ksf::comps::ksLed>(leds);
for (auto& led : leds) {
led->on();
}Called once when application is created. Use this to:
- Add all required components
- Set up initial hardware state
- Validate prerequisites
Return Value:
-
true— Continue to component initialization -
false— Abort and trigger app rotation
Example:
bool init() override {
// Check if configured
if (!hasConfiguration()) {
return false; // Will switch to config app
}
// Add components
addComponent<ksf::comps::ksWifiConnector>("Device1");
addComponent<ksf::comps::ksMqttConnector>();
addComponent<ksf::comps::ksLed>(LED_BUILTIN);
return true;
}Called after all components have been initialized. Use this to:
- Get references to other components
- Set up component interactions
- Register event handlers
Return Value:
-
true— Continue to application loop -
false— Abort and trigger app rotation
Example:
bool postInit() override {
// Get component references
mqtt = findComponent<ksf::comps::ksMqttConnector>();
wifi = findComponent<ksf::comps::ksWifiConnector>();
led = findComponent<ksf::comps::ksLed>();
// Validate all found
if (!mqtt || !wifi || !led) {
return false;
}
// Set up component interaction
mqtt->onMessage([this](auto topic, auto payload) {
led->toggle();
});
return true;
}Called repeatedly by the framework. Use this to:
- Implement application-level logic
- Coordinate component interactions
- Check application-level conditions
Return Value:
-
true— Continue running -
false— Stop application and trigger rotation
Example:
bool loop() override {
// Check error condition
if (fatalErrorDetected()) {
return false; // Stop this app
}
// Application logic
static unsigned long lastCheck = 0;
if (millis() - lastCheck > 60000) {
sendHeartbeat();
lastCheck = millis();
}
return true;
}bool init() override {
// ✅ Good - All components in init()
addComponent<ksWifiConnector>();
addComponent<ksMqttConnector>();
addComponent<ksLed>();
return true;
}bool postInit() override {
// ✅ Good - Get references when ready
mqtt = findComponent<ksMqttConnector>();
led = findComponent<ksLed>();
return mqtt && led;
}bool postInit() override {
// Find WiFi first (needed for MQTT)
auto wifi = findComponent<ksWifiConnector>();
if (!wifi) return false;
// Now find MQTT (depends on WiFi)
mqtt = findComponent<ksMqttConnector>();
if (!mqtt) return false;
return true;
}class MyApp : public ksApplication
{
private:
std::shared_ptr<ksf::comps::ksMqttConnector> mqtt;
std::shared_ptr<ksf::comps::ksLed> led;
bool postInit() override {
mqtt = findComponent<ksf::comps::ksMqttConnector>();
led = findComponent<ksf::comps::ksLed>();
return mqtt && led;
}
};bool init() override {
// Check configuration exists
if (!configFileExists()) {
// Let config app handle setup
return false;
}
// Try to load config
if (!loadConfiguration()) {
// Config invalid, trigger config app
return false;
}
// All good, add components
addComponent<ksWifiConnector>();
return true;
}class MainApp : public ksApplication
{
protected:
bool init() override {
// Add all runtime components
addComponent<ksWifiConnector>("MyDevice");
addComponent<ksMqttConnector>();
addComponent<DeviceLogic>();
addComponent<ksLed>(LED_BUILTIN);
return true;
}
bool postInit() override {
auto wifi = findComponent<ksWifiConnector>();
auto mqtt = findComponent<ksMqttConnector>();
return wifi && mqtt;
}
};class ConfigApp : public ksApplication
{
protected:
bool init() override {
// Minimal components for setup
addComponent<ksWifiConfigurator>();
addComponent<ksDevicePortal>();
addComponent<ksLed>(LED_BUILTIN);
return true;
}
bool loop() override {
// Auto-restart when configured
if (configurationComplete()) {
return false; // Switch back to main app
}
return true;
}
};class StatefulApp : public ksApplication
{
private:
enum State { CONNECTING, OPERATIONAL, ERROR };
State state = CONNECTING;
protected:
bool postInit() override {
mqtt = findComponent<ksMqttConnector>();
led = findComponent<ksLed>();
return mqtt && led;
}
bool loop() override {
switch (state) {
case CONNECTING:
if (mqtt->isConnected()) {
state = OPERATIONAL;
led->pattern(0b10101010); // Fast blink = connected
}
break;
case OPERATIONAL:
if (!mqtt->isConnected()) {
state = ERROR;
led->pattern(0b100100100); // Slow blink = error
}
break;
}
return true;
}
};bool loop() override {
// ❌ Bad - Adds component every loop!
if (needComponent) {
addComponent<SomeComponent>();
}
return true;
}private:
ksMqttConnector* mqtt; // ❌ Bad - Dangling pointer risk
bool postInit() override {
mqtt = findComponent<ksMqttConnector>().get(); // Don't
return true;
}bool init() override {
auto led = addComponent<ksLed>();
led->init(); // ❌ Bad - Framework handles this
return true;
}- Component — Building blocks of applications
- App-Rotator — Managing multiple applications
- Architecture — Framework design principles
- Examples — Complete application examples
🤖 This wiki is automatically generated and may contain errors.
Please report any issues here:
👉 https://github.com/cziter15/ksIotFrameworkLib/issues