Change the humidity in the iot dashboard to random values every four seconds

This commit is contained in:
Simon Hausmann 2021-05-18 13:07:24 +02:00
parent 73c396ed7a
commit 25d0b604e9
4 changed files with 97 additions and 32 deletions

View file

@ -62,30 +62,17 @@ std::string WidgetLocation::location_bindings() const
void DashboardBuilder::add_grid_widget(WidgetPtr widget, const WidgetLocation &location)
{
auto widget_name = register_widget(widget);
main_grid.append(fmt::format(
R"60(
{0} := {1} {{
{2}
}}
)60",
widget_name, widget->type_name(), location.location_bindings()));
auto widget_id = register_widget(widget);
grid_widgets.push_back({ widget_id, location });
}
void DashboardBuilder::add_top_bar_widget(WidgetPtr widget)
{
auto widget_name = register_widget(widget);
top_bar.append(fmt::format(
R"60(
{0} := {1} {{
}}
)60",
widget_name, widget->type_name()));
auto widget_id = register_widget(widget);
top_bar_widgets.push_back(widget_id);
}
std::string DashboardBuilder::register_widget(WidgetPtr widget)
std::size_t DashboardBuilder::register_widget(WidgetPtr widget)
{
auto widget_type_name = widget->type_name();
widgets_used.insert(widget_type_name);
@ -93,7 +80,7 @@ std::string DashboardBuilder::register_widget(WidgetPtr widget)
auto widget_id = widgets.size();
auto widget_name = fmt::format("widget_{}", widget_id);
widgets.push_back({ widget_name, widget });
return widget_name;
return widget_id;
}
std::optional<sixtyfps::ComponentHandle<sixtyfps::interpreter::ComponentInstance>>
@ -112,19 +99,59 @@ DashboardBuilder::build(sixtyfps::interpreter::ComponentCompiler &compiler) cons
widget_imports = fmt::format("import {{ {} }} from \"iot-dashboard.60\";", widget_imports);
}
// Vector of name/type_name of properties forwarded through the MainContent {} element.
std::string main_content_properties;
std::string main_grid;
std::string top_bar;
std::string exposed_properties;
for (const auto &entry : widgets) {
auto [widget_name, widget_ptr] = entry;
for (const auto &[widget_id, location] : grid_widgets) {
const auto &[widget_name, widget_ptr] = widgets[widget_id];
main_grid.append(fmt::format(
R"60(
{0} := {1} {{
{2}
}}
)60",
widget_name, widget_ptr->type_name(), location.location_bindings()));
std::string properties_prefix = widget_name;
properties_prefix += "__";
properties_prefix.append("__");
for (const auto &property : widget_ptr->properties()) {
std::string qualified_prop_name = properties_prefix + property.name;
exposed_properties +=
fmt::format("property <{0}> {1} <=> {2}.{3};\n", property.type_name,
qualified_prop_name, widget_name, property.name);
std::string forwarded_property_name = properties_prefix;
forwarded_property_name.append(property.name);
main_content_properties.append(fmt::format("property <{0}> {1} <=> {2}.{3};\n",
property.type_name, forwarded_property_name,
widget_name, property.name));
exposed_properties.append(fmt::format("property <{0}> {1} <=> main_content.{1};\n",
property.type_name, forwarded_property_name));
}
}
for (const auto widget_id : top_bar_widgets) {
const auto &[widget_name, widget_ptr] = widgets[widget_id];
top_bar.append(fmt::format(
R"60(
{0} := {1} {{
}}
)60",
widget_name, widget_ptr->type_name()));
std::string properties_prefix = widget_name;
properties_prefix.append("__");
for (const auto &property : widget_ptr->properties()) {
std::string forwarded_property_name = properties_prefix;
forwarded_property_name.append(property.name);
exposed_properties.append(fmt::format("property <{0}> {1} <=> {2}.{3};\n",
property.type_name, forwarded_property_name,
widget_name, property.name));
}
}
@ -134,6 +161,8 @@ DashboardBuilder::build(sixtyfps::interpreter::ComponentCompiler &compiler) cons
{0}
MainContent := VerticalLayout {{
{4}
spacing: 24px;
TopBar {{
@children
@ -160,13 +189,13 @@ MainWindow := Window {{
padding: 0; spacing: 0;
MenuBar {{
}}
MainContent {{
main_content := MainContent {{
{1}
}}
}}
}}
)60",
widget_imports, top_bar, main_grid, exposed_properties);
widget_imports, top_bar, main_grid, exposed_properties, main_content_properties);
auto definition = compiler.build_from_source(source_code, SOURCE_DIR);

View file

@ -63,6 +63,9 @@ public:
void connect_ui(const sixtyfps::ComponentHandle<sixtyfps::interpreter::ComponentInstance> &ui,
std::string_view properties_prefix);
std::pair<std::string, std::vector<PropertyDeclaration>>
generate_forwarding_two_way_property_bindings(std::string_view widget_name) const;
private:
std::string qualified_property_name(std::string_view name) const;
@ -96,11 +99,11 @@ struct DashboardBuilder
build(sixtyfps::interpreter::ComponentCompiler &compiler) const;
private:
std::string register_widget(WidgetPtr widget);
std::size_t register_widget(WidgetPtr widget);
std::unordered_set<std::string> widgets_used = { "TopBar", "MenuBar" };
std::string top_bar;
std::string main_grid;
std::vector<int> top_bar_widgets;
std::vector<std::pair<int, WidgetLocation>> grid_widgets;
std::vector<std::pair<std::string, WidgetPtr>> widgets;
};

View file

@ -265,6 +265,7 @@ export IndoorTemperature := BoxWithButtons {
isBright: true;
}
export Humidity := BoxWithButtons {
property <string> humidity_percent <=> value;
title_: "Humidity";
iconFile: @image-url("images/humidity.png");
value: "30%";

View file

@ -9,10 +9,13 @@
LICENSE END */
#include "dashboard.h"
#include <chrono>
#include <sixtyfps_interpreter.h>
#include <fmt/core.h>
#include <fmt/chrono.h>
#include <random>
#include <time.h>
class PlaceholderWidget : public Widget
{
@ -52,13 +55,42 @@ void ClockWidget::update_clock()
set_property("time", sixtyfps::SharedString(current_time));
}
class HumidityWidget : public Widget
{
public:
HumidityWidget();
std::string type_name() const override { return "Humidity"; }
std::vector<PropertyDeclaration> properties() const override
{
return { PropertyDeclaration { "humidity_percent", "string" } };
}
private:
void update_fake_humidity();
sixtyfps::Timer fake_humidity_update_timer;
std::default_random_engine rng;
};
HumidityWidget::HumidityWidget()
: fake_humidity_update_timer(std::chrono::seconds(5), [=]() { update_fake_humidity(); }),
rng(std::chrono::system_clock::now().time_since_epoch().count())
{
}
void HumidityWidget::update_fake_humidity()
{
std::uniform_int_distribution<> humidity_range(20, 150);
int humidity_percent = humidity_range(rng);
set_property("humidity_percent", sixtyfps::SharedString(fmt::format("{}%", humidity_percent)));
}
int main()
{
DashboardBuilder builder;
builder.add_top_bar_widget(std::make_shared<ClockWidget>());
builder.add_grid_widget(std::make_shared<PlaceholderWidget>("Usage"), { 0, 0, 2 });
builder.add_grid_widget(std::make_shared<PlaceholderWidget>("IndoorTemperature"), { 0, 1 });
builder.add_grid_widget(std::make_shared<PlaceholderWidget>("Humidity"), { 1, 1 });
builder.add_grid_widget(std::make_shared<HumidityWidget>(), { 1, 1 });
builder.add_grid_widget(std::make_shared<PlaceholderWidget>("MyDevices"), { 0, 2, 2 });
builder.add_grid_widget(std::make_shared<PlaceholderWidget>("UsageDiagram"), { 2, 0, {}, 2 });
builder.add_grid_widget(std::make_shared<PlaceholderWidget>("LightIntensity"), { 2, 2 });