Logo Pico-Framework A web-first embedded framework for C++
Loading...
Searching...
No Matches
app.cpp
Go to the documentation of this file.
1
5#include "App.h"
6
7
8#include <hardware/adc.h>
9#include <pico/cyw43_arch.h>
10
13#include "events/GpioEvent.h"
14#include "events/EventManager.h"
16#include "http/HttpFileserver.h"
17#include "http/JsonResponse.h"
18#include "http/Router.h"
19#include "time/TimeManager.h"
20
21#include "GpioController.h"
22#include "DashboardController.h"
23#include "DashboardView.h"
24
25// #include <iostream>
26
27App::App(int port) : FrameworkApp(port, "AppTask", 1024, 3)
28{
29
30
31}
32
34{
35 // This method is called by the base class to initialize HTTP routes.
36 // You can add your application's routes here.
37 // All FrameWorkController instances will have their initRoutes called
38 // when the application starts, so you can add routes in your controllers.
39 // See the GpioController and DashboardController classes for examples.
40 // Add a simple route for testing
41 router.addRoute("GET", "/", [](HttpRequest &req, HttpResponse &res, const auto &)
42 { res.send(DashboardView()); });
43 router.addRoute("GET", "/hello", [](HttpRequest &req, HttpResponse &res, const auto &)
44 { res.send("Welcome to PicoFramework!"); });
45 // Return the contents of the directory
46 router.addRoute("GET", "/ls(.*)", [](HttpRequest &req, HttpResponse &res, const auto &match) {
47 std::vector<FileInfo> files;
48 AppContext::get<StorageManager>()->listDirectory(match.ordered[0], files);
49 res.json(files);
50 });
51}
52
54{
55 // Call the base class to ensure the framework starts correctly.
57
58 pico.onStart(); // Initialize the PicoModel, which handles GPIO and other hardware interactions
59
60 // These are two controllers derived from FrameworkController that add event support to the FrameworkTask base class.
61 // They are started here to ensure they are ready to handle events and HTTP requests.
62 std::cout << "[App] Initializing application..." << std::endl;
63
64 static GpioController gpioController(router, pico);
65 gpioController.start();
66 static DashboardController dashboardController(router, pico);
67 dashboardController.start();
68
69 // Here we are setting up event handlers - we get the EventManager and GpioEventManager from the AppContext.
72
73 // Subscribe to GPIO change events
74 // This will call onEvent() in this App class when a GPIO change event occurs.
75 // Note: The GpioEventManager will call the gpio_event_handler() function when a GPIO interrupt occurs.
76 // The gpio_event_handler() will then post an Event to the EventManager, which posts to the FRameworkController event queue.
77 // FrameworkController has a waitAndDispatch function that polls the queue and will call onEvent() in this App class.
78 // Events can be SystemNotification or UserNotification types, which are defined in enum class UserNotification (see the App.h file).
80 gpioEventManager->enableInterrupt(16, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL);
81 gpioEventManager->enableInterrupt(17, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL);
82
84
85 std::cout << "[App] Waiting for network..." << std::endl;
86 // Wait for the network to be ready before starting services
87 // This is a blocking call that waits for the NetworkReady notification
88 // You could use a non-blocking wait if you want to do other work in the meantime
89 // waitfor is provided by the FrameworkTask base class and has a timeout parameter, unused here
90 // The underlying imlementation uses FreeRTOS notifications
91 //waitFor(SystemNotification::NetworkReady);
92
93 //std::cout << "[App] Network ready. Starting services..." << std::endl;
94 // Now that the network is ready, we can start services that depend on it
95 // For example, you might want to start an HTTP server or other network services here
96 //server.start();
97 eventManager->subscribe(
104 ),
105 this);
106}
107
108void App::onEvent(const Event &e)
109{
110 // This method is called when an event is posted to the App's event queue.
111 // It is called by the FrameworkController base class when an event is received.
112 // You can handle different types of events here based on the notification kind.
113 // For example, you can handle GPIO change events or user-defined events.
114 // You subscribe for events in the onStart() method (for example), so this will be called
115 // when an event is posted to the App's event queue. The Eventmanager operates as a true
116 // publish-subscribe system, so you can post events from anywhere in the application
117 // and they will be delivered to ALL subscribers that have registered for that event type.
118
120 {
121 switch (e.notification.system)
122 {
124 {
125 printf("[App] GpioChange received\n");
126 printf("[App] Pin = %u, Edge = 0x%X\n", e.gpioEvent.pin, e.gpioEvent.edge);
127
128 const GpioEvent &data = e.gpioEvent;
129 printf("[App] GPIO changed - pin %u: %s\n",
130 data.pin,
131 (data.edge & GPIO_IRQ_EDGE_RISE) ? "rising" : (data.edge & GPIO_IRQ_EDGE_FALL) ? "falling" : "unknown");
132 break;
133 }
134
136 std::cout << "[App] Network ready. Starting services..." << std::endl;
137 pico.onNetworkReady(); // Notify the PicoModel that the network is ready
138 printf("[App] Network ready. Starting HTTP server...\n");
139 server.start();
140 break;
141
143 std::cout << "[App] Time is valid." << std::endl;
144 // at this point local time may equal UTC time or it may be the local time zone
145 // depending on whether the local timezone has been acquired (async)
146 // This example turns on that example, it is off by default
147 std::string localTime = AppContext::get<TimeManager>()->formatTimeWithZone();
148 printf("[App] UTC time: %s\n", localTime.c_str());
149 break;
150 }
151
153 // This event is sent when the local time zone has been acquired
154 // It will not occur if the DETECT_LOCAL_TIMEZONE flag is not set
155 // in framework_user_config.h
156 std::cout << "[App] Local Time is valid." << std::endl;
157 std::string localTime = AppContext::get<TimeManager>()->formatTimeWithZone();
158 printf("[App] Local time: %s\n", localTime.c_str());
159 break;
160 }
161
163 std::cout << "[App] SNTP Time Sync event." << std::endl;
164 // No need to do anything here, the time is valid - these occur every hour
165 // SNTP time sync events are sent every hour by default
166 // You can change the interval in framework_user_config.h
167 // by setting the SNTP_SYNC_INTERVAL to a different value
168 break;
169
171 std::cout << "[App] Time is invalid. Running in degraded mode." << std::endl;
172 // handle degraded state if needed
173 break;
174
175 default:
176 break;
177 }
178 }
179
181 e.notification.user_code == static_cast<uint8_t>(UserNotification::Heartbeat))
182 {
183 printf("[App] Heartbeat user event received\n");
184 }
185}
186
187
189{
190 static int count = 0;
191 if (count == 0) {
192 printf("[App] Starting main polling loop...\n");
193 }
194 count++;
195 vTaskDelay(pdMS_TO_TICKS(100)); // Yield to other tasks
196 // This function is called continuously (non-blocking) from the App task.
197 // Use RUN_EVERY to do periodic background work:
198
199 runEvery(15000, [&]()
200 {
201 printf("[App] Running main polling loop...\n");
202 Event userEvt(static_cast<uint8_t>(UserNotification::Heartbeat));
203 AppContext::get<EventManager>()->postEvent(userEvt);
204 // this yield is not essential, but without yielding you can miss events
205 vTaskDelay(pdMS_TO_TICKS(1)); }, "logLoop"); // <-- Unique ID for this timer (enables it to be cancelled)
206}
Event pub/sub manager for embedded applications using FreeRTOS.
Posts GPIO change events (rising/falling edge) via EventManager.
HTTP file server and file handling helpers for static content.
Utility functions to send standard JSON responses using nlohmann::json.
constexpr uint32_t eventMask(Enum e)
Helper function to create an event mask from an enum value.
HTTP routing with middleware and optional JWT-based authorization. Part of the PicoFramework HTTP ser...
Abstract interface for file and directory storage backends.
static constexpr std::uintptr_t getTypeKey()
Definition AppContext.h:91
void initRoutes() override
Define the application's HTTP routes.
Definition app.cpp:33
void onEvent(const Event &e) override
Called when an event is dispatched to this controller.
Definition app.cpp:108
void onStart() override
Called once at task start before entering the main loop.
Definition app.cpp:53
PicoModel pico
Definition app.h:38
App(int port)
Definition app.cpp:27
void poll() override
Called during every loop iteration for non-blocking background logic.
Definition app.cpp:188
Manages the system-wide event queue and subscriptions.
void subscribe(uint32_t eventMask, FrameworkController *controller)
Subscribe a task to specific event types.
Base class for applications using the framework.
HttpServer server
Embedded HTTP server instance.
Router router
Router instance for handling HTTP routes.
void onStart() override
Starts the Framework Manager.
void runEvery(uint32_t intervalMs, const std::function< void()> &fn, const char *id)
Run a function periodically with millisecond resolution.
bool start()
Starts the task via FreeRTOS.
@fileGpioController.cpp
GpioEventManager registers interrupts and posts GpioChange events to multiple listeners per pin.
void enableInterrupt(uint pin, uint32_t edgeMask)
Enable GPIO interrupts for a specific pin and edge mask.
Forward declaration for potential routing needs.
Definition HttpRequest.h:32
Represents an HTTP response object.
HttpResponse & json(const std::string &jsonString)
Send a JSON string/object with correct content type.
void send(const std::string &body)
Send a full response including headers and body.
bool start()
Start the HTTP server as a FreeRTOS task.
void onStart()
Definition PicoModel.cpp:18
void onNetworkReady()
Definition PicoModel.cpp:86
void addRoute(const std::string &method, const std::string &path, RouteHandler handler, std::vector< Middleware > middleware={})
Register a route with optional middleware.
Definition Router.cpp:144
Represents a framework event, optionally carrying payload data.
Definition Event.h:24
Notification notification
Notification identifier (system or user)
Definition Event.h:25
GpioEvent gpioEvent
Inline data if GpioChange.
Definition Event.h:27
Structure representing a GPIO event.
Definition GpioEvent.h:11
uint16_t pin
Definition GpioEvent.h:12
uint16_t edge
Definition GpioEvent.h:13
SystemNotification system
NotificationKind kind
uint8_t user_code