Skip to content

Commit e576dc7

Browse files
committed
v1.2.57
- **New:** Dashboard activities are now configurable, allowing users to define the sequence and parameters of displayed activities via terminal settings. - **New:** Added system settings for screen saver timeout and display brightness, configurable via HomeGenie Panel and terminal. - **Fixed:** Resolved an issue in `AnalogClockActivity` for improved stability/accuracy. - **Fixed:** `CameraDisplayActivity` now correctly processes and displays custom HTTP JPEG image feed URLs.
1 parent c22827e commit e576dc7

21 files changed

Lines changed: 477 additions & 242 deletions

examples/smart-sensor-display/README.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,47 @@ For default GPIO# values used by the display driver see `ui/drivers/RoundDisplay
3535
`ui/drivers/StandardDisplay.h` files.
3636

3737

38-
## UI Activities configuration
38+
### Display configuration
3939

4040

41+
| Key | Description | Default |
42+
|--------------|--------------------------------|---------------------|
43+
| `disp-bri` | Set the display brightness | 64 (range 1 - 127) |
44+
| `dsbrd-ssts` | Screen saver timeout (seconds) | 15 (0 = disabled) |
45+
46+
47+
### Configuring activities
48+
49+
To set the activities that will be available on the smart display UI use the `dashboard` option:
50+
51+
```
52+
#SET:dashboard SensorValues,CameraDisplay:V1,CameraDisplay:V2,LevelControl:M1,ColorControl:H1,ColorControl:H2,DigitalClock
53+
```
54+
55+
which is basically the comma-separated list of activity names followed eventually by a `:` to specify the module address
56+
or other options where applicable.
57+
58+
To configure the title of an activity:
59+
4160
| Key | Description | Default |
4261
|----------------------|------------------------------------|-----------------------|
4362
| `title-<address>` | Displayed title/name | |
44-
| `rcam-<address>` | Remote camera JPEG images feed URL | |
45-
| `rcam-res-<address>` | Camera resolution (1 to 17) | "3" remote, "5" local |
46-
| `rcam-qlt-<address>` | Camera resolution (10 to 63) | "10" |
4763

4864
Where `<address>` is the address assigned to the associated Activity module
4965
(e.g. `D1`, `M1`, `V1`...).
5066
These values can also be easily configured using the *HomeGenie Panel* app.
5167

68+
Options available for `CameraDisplayActivity` configuration:
69+
70+
| Key | Description | Default |
71+
|----------------------|------------------------------------|-----------------------|
72+
| `title-<address>` | Displayed title/name | |
73+
| `rcam-<address>` | Remote camera JPEG images feed URL | |
74+
| `rcam-res-<address>` | Camera resolution (1 to 17) | "3" remote, "5" local |
75+
| `rcam-qlt-<address>` | Camera resolution (10 to 63) | "10" |
5276

5377

54-
### Manual build and install
78+
## Manual build and install
5579

5680
You can also manually build and install the firmware from source code
5781
as explained in the [Getting started](../../getting-started#custom-firmware) page
Lines changed: 263 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,268 @@
1-
//
2-
// Created by gene on 13/05/25.
3-
//
1+
/*
2+
* HomeGenie-Mini (c) 2018-2025 G-Labs
3+
*
4+
*
5+
* This file is part of HomeGenie-Mini (HGM).
6+
*
7+
* HomeGenie-Mini is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* HomeGenie-Mini is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with HomeGenie-Mini. If not, see <http://www.gnu.org/licenses/>.
19+
*
20+
*
21+
* Authors:
22+
* - Generoso Martello <gene@homegenie.it>
23+
*
24+
*/
425

526
#ifndef HOMEGENIE_MINI_CONFIGURATION_H
627
#define HOMEGENIE_MINI_CONFIGURATION_H
728

29+
#include "defs.h"
30+
31+
#include <ui/Dashboard.h>
32+
#include <ui/drivers/RoundDisplay.h>
33+
#include <ui/drivers/StandardDisplay.h>
34+
#include <ui/activities/utilities/SystemInfoActivity.h>
35+
36+
#ifdef BOARD_HAS_PSRAM
37+
#include <ui/activities/control/SwitchControlActivity.h>
38+
#ifndef DISABLE_LVGL
39+
#include <ui/activities/control/ColorControlActivity.h>
40+
#include <ui/activities/control/LevelControlActivity.h>
41+
#endif
42+
#include <ui/activities/examples/AnalogClockActivity.h>
43+
#include <ui/activities/examples/GaugeExampleActivity.h>
44+
#include <ui/activities/monitor/CameraDisplayActivity.h>
45+
#include <ui/activities/utilities/DigitalClockActivity.h>
46+
#endif
47+
48+
#include "smart-sensor/CommonSensors.h"
49+
#include "display/activities/SensorValuesActivity.h"
50+
51+
//#include "io/BatterySensor.h"
52+
#include "io/InertialSensor.h"
53+
54+
55+
using namespace Service;
56+
#ifdef BOARD_HAS_PSRAM
57+
using namespace UI::Activities::Control;
58+
using namespace UI::Activities::Examples;
59+
using namespace UI::Activities::Monitor;
60+
#endif
61+
using namespace UI::Activities::Utilities;
62+
63+
namespace DisplayConfig = DisplayApi::Configuration;
64+
namespace DisplayOption = DisplayApi::Options;
65+
66+
67+
Dashboard* dashboard;
68+
69+
70+
// UI options update listener
71+
static class : public ModuleParameter::UpdateListener {
72+
public:
73+
void onUpdate(ModuleParameter* option) override {
74+
#ifdef ENABLE_SCREEN_SAVER
75+
if (option->is(DisplayOption::Display_ScreenSaverTimeout)) {
76+
dashboard->setScreenSaverTimeout(option->value.toInt() * 1000);
77+
}
78+
#endif
79+
if (option->is(DisplayOption::Display_Brightness)) {
80+
dashboard->setBrightness(option->value.toInt());
81+
}
82+
}
83+
} dashboardOptionUpdateListener;
84+
85+
86+
void initDashboard(DisplayDriver* displayDriver, Module* module) {
87+
dashboard = new Dashboard(displayDriver);
88+
#ifdef ENABLE_SCREEN_SAVER
89+
auto timeoutMs = Config::getSetting(DisplayConfig::ScreenSaver::TimeoutSeconds, "15");
90+
int screenSaverTimeoutMs = timeoutMs.toInt() * 1000;
91+
dashboard->setScreenSaverTimeout(screenSaverTimeoutMs);
92+
module->addWidgetOption(
93+
// name, value
94+
DisplayOption::Display_ScreenSaverTimeout, timeoutMs.c_str(),
95+
// type
96+
UI_WIDGETS_FIELD_TYPE_SLIDER
97+
// label
98+
":screensaver_timeout"
99+
// min:max:default
100+
":0:120:15"
101+
)->withConfigKey(DisplayConfig::ScreenSaver::TimeoutSeconds)->addUpdateListener(&dashboardOptionUpdateListener);
102+
#endif
103+
module->addWidgetOption(
104+
// name, value
105+
DisplayOption::Display_Brightness, timeoutMs.c_str(),
106+
// type
107+
UI_WIDGETS_FIELD_TYPE_SLIDER
108+
// label
109+
":display_brightness"
110+
// min:max:default
111+
":1:127:64"
112+
)->withConfigKey(DisplayConfig::Display::Brightness)->addUpdateListener(&dashboardOptionUpdateListener);
113+
}
114+
115+
void addDashboardActivities(String &list) {
116+
int currentIndex = 0;
117+
int nextCommaIndex = 0;
118+
119+
while (currentIndex < list.length()) {
120+
nextCommaIndex = list.indexOf(',', currentIndex);
121+
122+
String currentElement;
123+
if (nextCommaIndex == -1) {
124+
currentElement = list.substring(currentIndex);
125+
currentIndex = list.length(); // exit loop
126+
} else {
127+
currentElement = list.substring(currentIndex, nextCommaIndex);
128+
currentIndex = nextCommaIndex + 1;
129+
}
130+
currentElement.trim();
131+
if (currentElement.length() > 0) {
132+
133+
String elementName;
134+
String elementOptions = "";
135+
int colonIndex = currentElement.indexOf(':');
136+
if (colonIndex == -1) {
137+
elementName = currentElement;
138+
} else {
139+
elementName = currentElement.substring(0, colonIndex);
140+
elementOptions = currentElement.substring(colonIndex + 1);
141+
}
142+
elementName.trim();
143+
elementOptions.trim();
144+
145+
// This Activity shows basic system info
146+
// and buttons to rotate the display
147+
// or reconfigure the device connection
148+
static int systemInfoCount = 0;
149+
if (elementName == "SystemInfo") {
150+
// single instance activity
151+
if (systemInfoCount++ == 0) {
152+
auto systemInfo = new SystemInfoActivity();
153+
dashboard->addActivity(systemInfo);
154+
}
155+
}
156+
157+
// This Activity shows device name, date/time and
158+
// temperature + humidity if DHT sensor is enabled
159+
static int sensorValuesCount = 0;
160+
if (elementName == "SensorValues") {
161+
// single instance activity
162+
if (sensorValuesCount++ == 0) {
163+
auto miniModule = HomeGenie::getInstance()->getDefaultModule();
164+
auto sensorValues = new SensorValuesActivity(miniModule);
165+
dashboard->addActivity(sensorValues);
166+
}
167+
}
168+
169+
#ifdef BOARD_HAS_PSRAM
170+
// A cute "pac-man" clock
171+
static int digitalClockCount = 0;
172+
if (elementName == "DigitalClock") {
173+
// single instance activity
174+
if (digitalClockCount++ == 0) {
175+
auto digitalClock = new DigitalClockActivity();
176+
dashboard->addActivity(digitalClock);
177+
}
178+
}
179+
180+
// UI control to switch on/off or set level of
181+
// user-definable devices. Each button emits events
182+
// that can be automated using the device Scheduler.
183+
// It can be configured using HomeGenie Panel app.
184+
if (elementName == "SwitchControl") {
185+
String address = "D1";
186+
if (elementOptions.length() > 0) {
187+
address = elementOptions;
188+
}
189+
auto switchControl = new SwitchControlActivity(address.c_str());
190+
dashboard->addActivity(switchControl);
191+
#ifndef DISABLE_AUTOMATION
192+
// Adds scheduler programs to handle Level events
193+
setupLevelControlActivitySchedule(&switchControl->module);
194+
#endif
195+
}
196+
197+
#ifndef DISABLE_LVGL
198+
// Similar to the SwitchControl but using LVGL
199+
if (elementName == "LevelControl") {
200+
String address = "M1";
201+
if (elementOptions.length() > 0) {
202+
address = elementOptions;
203+
}
204+
auto levelControl = new LevelControlActivity(address.c_str());
205+
dashboard->addActivity(levelControl);
206+
#ifndef DISABLE_AUTOMATION
207+
// Adds scheduler programs to handle Level events
208+
setupLevelControlActivitySchedule(&levelControl->module);
209+
#endif
210+
}
211+
// Color control
212+
if (elementName == "ColorControl") {
213+
String address = "H1";
214+
if (elementOptions.length() > 0) {
215+
address = elementOptions;
216+
}
217+
auto colorControl = new ColorControlActivity(address.c_str());
218+
dashboard->addActivity(colorControl);
219+
#ifndef DISABLE_AUTOMATION
220+
// Adds scheduler programs to handle ColorHsv events
221+
setupColorControlActivitySchedule(&colorControl->module);
222+
#endif
223+
}
224+
#endif // DISABLE_LVGL
225+
// Displays a remote camera via HTTP images feed,
226+
// or local camera directly connected to the ESP32.
227+
static int cameraDisplayCount = 0;
228+
if (elementName == "CameraDisplay") {
229+
String address = "V1";
230+
if (elementOptions.length() > 0) {
231+
address = elementOptions;
232+
}
233+
auto cameraDisplay = new CameraDisplayActivity(address.c_str());
234+
if (cameraDisplayCount++ == 0) {
235+
// The first instance is reserved for
236+
// onboard ESP32 camera module if enabled
237+
if (Config::getSetting(Camera_Sensor::SensorType).equals("esp32-cam")) {
238+
cameraDisplay->isEsp32Camera = true;
239+
}
240+
}
241+
dashboard->addActivity(cameraDisplay);
242+
}
243+
244+
// UI examples adapted from LovyanGFX library
245+
static int analogClockCount = 0;
246+
if (elementName == "AnalogClock") {
247+
// single instance activity
248+
if (analogClockCount++ == 0) {
249+
auto analogClock = new AnalogClockActivity();
250+
dashboard->addActivity(analogClock);
251+
}
252+
}
253+
static int gaugeExampleCount = 0;
254+
if (elementName == "GaugeExample") {
255+
// single instance activity
256+
if (gaugeExampleCount++ == 0) {
257+
auto gaugeExample = new GaugeExampleActivity();
258+
dashboard->addActivity(gaugeExample);
259+
}
260+
}
261+
262+
#endif // BOARD_HAS_PSRAM
263+
}
264+
}
265+
266+
}
267+
8268
#endif //HOMEGENIE_MINI_CONFIGURATION_H

examples/smart-sensor-display/display/activities/SensorValuesActivity.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,6 @@ SensorValuesActivity::SensorValuesActivity(Module *module) {
3535
sensorModule = module;
3636
}
3737

38-
void SensorValuesActivity::onResume() {
39-
}
40-
41-
void SensorValuesActivity::onPause() {
42-
}
43-
4438
void SensorValuesActivity::onDraw()
4539
{
4640
// Activity width and height

examples/smart-sensor-display/display/activities/SensorValuesActivity.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ class SensorValuesActivity: public Activity {
4040
public:
4141
explicit SensorValuesActivity(Module* module);
4242

43-
void onResume() override;
44-
void onPause() override;
4543
void onDraw() override;
4644

4745
private:

0 commit comments

Comments
 (0)