From 136ef75ad2efc8a5dc84b3f825e5c05dba6c2ca0 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 21 Oct 2024 20:18:03 +0200 Subject: [PATCH 01/11] mdifont: almost double the font size --- src/front-lvgl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/front-lvgl.cpp b/src/front-lvgl.cpp index 03de543..25f0fec 100644 --- a/src/front-lvgl.cpp +++ b/src/front-lvgl.cpp @@ -243,7 +243,7 @@ void uithread(int _argc, char* _argv[]) lv_style_init(&voorkant::lvgl::b612style); lv_style_set_text_font(&voorkant::lvgl::b612style, voorkant::lvgl::b612font); - voorkant::lvgl::mdifont = lv_tiny_ttf_create_data_ex(mdi_ttf, mdi_ttf_len, 16, LV_FONT_KERNING_NORMAL, 1024); + voorkant::lvgl::mdifont = lv_tiny_ttf_create_data_ex(mdi_ttf, mdi_ttf_len, 30, LV_FONT_KERNING_NORMAL, 1024); lv_style_init(&voorkant::lvgl::mdistyle); lv_style_set_text_font(&voorkant::lvgl::mdistyle, voorkant::lvgl::mdifont); From ccb2a950e210e1a320c7625aed3d7cf56457b28d Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 21 Oct 2024 20:18:22 +0200 Subject: [PATCH 02/11] add (static) icon to UISensor --- src/uicomponents/UIComponents.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/uicomponents/UIComponents.cpp b/src/uicomponents/UIComponents.cpp index 7fd902b..e5fd1f4 100644 --- a/src/uicomponents/UIComponents.cpp +++ b/src/uicomponents/UIComponents.cpp @@ -1,7 +1,9 @@ #include "UIComponents.hpp" #include "logger.hpp" #include +#include #include +#include lv_obj_t* UIComponent::createLabel(lv_obj_t* _parent, std::string _text) { @@ -186,16 +188,33 @@ UISensor::UISensor(std::shared_ptr _entity, lv_obj_t* _parent) : lv_obj_set_height(flowpanel, LV_SIZE_CONTENT); lv_obj_set_style_pad_all(flowpanel, 5, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_align(flowpanel, LV_ALIGN_CENTER); - lv_obj_set_flex_flow(flowpanel, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_flow(flowpanel, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(flowpanel, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START); lv_obj_add_event_cb(flowpanel, UISensor::clickCB, LV_EVENT_CLICKED, reinterpret_cast(&entity)); - lv_obj_t* label = createLabel(flowpanel, entity->name); + lv_obj_t* iconpart = lv_label_create(flowpanel); + lv_obj_set_width(iconpart, 30); + lv_obj_set_height(iconpart, LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(iconpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(iconpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_label_set_text(iconpart, MDI_WAZE); + lv_obj_add_style(iconpart, &voorkant::lvgl::mdistyle, 0); + lv_obj_set_style_text_align(iconpart, LV_TEXT_ALIGN_CENTER, 0); + + lv_obj_t* textpart = lv_obj_create(flowpanel); + lv_obj_set_width(textpart, uiEntityWidth - 55); + lv_obj_set_height(textpart, LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(textpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(textpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_flex_flow(textpart, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(textpart, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START); + + lv_obj_t* label = createLabel(textpart, entity->name); lv_obj_set_width(label, LV_PCT(100)); lv_obj_set_align(label, LV_ALIGN_LEFT_MID); lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN); - extratext2 = createLabel(flowpanel, "State:"); + extratext2 = createLabel(textpart, "State:"); lv_obj_set_width(extratext2, LV_PCT(100)); lv_obj_set_align(extratext2, LV_ALIGN_RIGHT_MID); lv_obj_set_style_text_align(extratext2, LV_TEXT_ALIGN_RIGHT, LV_PART_MAIN); @@ -203,7 +222,7 @@ UISensor::UISensor(std::shared_ptr _entity, lv_obj_t* _parent) : const auto& services = _entity->getServices(); for (const auto& service : services) { string txt = "Service: "; - lv_obj_t* servicelabel = createLabel(flowpanel, txt.append(service->name)); + lv_obj_t* servicelabel = createLabel(textpart, txt.append(service->name)); lv_obj_set_width(servicelabel, LV_PCT(100)); lv_obj_set_align(servicelabel, LV_ALIGN_LEFT_MID); } From d3d37140069a3d07bc8fb6640b8376e93e3f4853 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Sun, 10 Nov 2024 21:23:33 +0100 Subject: [PATCH 03/11] adjust to new mdi name map --- src/uicomponents/UIComponents.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uicomponents/UIComponents.cpp b/src/uicomponents/UIComponents.cpp index e5fd1f4..26727c7 100644 --- a/src/uicomponents/UIComponents.cpp +++ b/src/uicomponents/UIComponents.cpp @@ -1,4 +1,5 @@ #include "UIComponents.hpp" +#include "mdimap.hpp" #include "logger.hpp" #include #include @@ -197,7 +198,7 @@ UISensor::UISensor(std::shared_ptr _entity, lv_obj_t* _parent) : lv_obj_set_height(iconpart, LV_SIZE_CONTENT); lv_obj_set_style_pad_all(iconpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(iconpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_label_set_text(iconpart, MDI_WAZE); + lv_label_set_text(iconpart, voorkant::mdi::name2id("waze").data()); lv_obj_add_style(iconpart, &voorkant::lvgl::mdistyle, 0); lv_obj_set_style_text_align(iconpart, LV_TEXT_ALIGN_CENTER, 0); From 185425ce048f4a2ff1af1113394b4f5fe35b0e9d Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 18 Nov 2024 19:52:26 +0100 Subject: [PATCH 04/11] pick up "icon" attribute when it is there --- src/uicomponents/UIComponents.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/uicomponents/UIComponents.cpp b/src/uicomponents/UIComponents.cpp index 26727c7..90e4f81 100644 --- a/src/uicomponents/UIComponents.cpp +++ b/src/uicomponents/UIComponents.cpp @@ -198,7 +198,15 @@ UISensor::UISensor(std::shared_ptr _entity, lv_obj_t* _parent) : lv_obj_set_height(iconpart, LV_SIZE_CONTENT); lv_obj_set_style_pad_all(iconpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(iconpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); - lv_label_set_text(iconpart, voorkant::mdi::name2id("waze").data()); + string icon = _entity->getJsonState()["attributes"].value("icon", "mdi:border-none-variant"); + + if (icon.substr(0, 4) == "mdi:") { + icon = icon.substr(4); + } else { + icon = "border-none-variant"; + } + + lv_label_set_text(iconpart, voorkant::mdi::name2id(icon).data()); lv_obj_add_style(iconpart, &voorkant::lvgl::mdistyle, 0); lv_obj_set_style_text_align(iconpart, LV_TEXT_ALIGN_CENTER, 0); From d0dac48278ecb389ec5126a7eea3a3e5ed8c62e5 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 19 Nov 2024 19:35:08 +0100 Subject: [PATCH 05/11] grab list_for_display --- src/Backend.cpp | 17 +++++++++++++++++ src/HAEntity.hpp | 1 + 2 files changed, 18 insertions(+) diff --git a/src/Backend.cpp b/src/Backend.cpp index 06c7054..a078126 100644 --- a/src/Backend.cpp +++ b/src/Backend.cpp @@ -118,6 +118,10 @@ void HABackend::threadrunner() getstates["type"] = "get_states"; wc->send(getstates); + json list_for_display; + list_for_display["type"] = "list_for_display"; + wc->send(list_for_display); + while (true) { auto msg = wc->recv(); @@ -150,6 +154,19 @@ void HABackend::threadrunner() loaded = true; load_cv.notify_all(); } + else if (j["id"] == list_for_display["id"]) { + std::scoped_lock lk(entitieslock); + std::set integrations; + for (auto ent : j["result"]["entities"]) { + auto entity_id = ent["ei"].get(); + auto integration = ent["pl"].get(); + integrations.insert(integration); + entities[entity_id]->integration = integration; + } + for (auto integration : integrations) { + // fetch icons + } + } else if (j["type"] == "event") { std::scoped_lock lk(entitieslock); // something happened! diff --git a/src/HAEntity.hpp b/src/HAEntity.hpp index 86d9d0d..505d9eb 100644 --- a/src/HAEntity.hpp +++ b/src/HAEntity.hpp @@ -58,6 +58,7 @@ class HAEntity : public ISubject string domain; string fullname; string id; + string integration; // HAEntity(json _state); HAEntity(json _state, std::shared_ptr _hadomain, HABackend* _backend); From 113c1c7f4162aec86523459f67a860953f011163 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 19 Nov 2024 23:38:54 +0100 Subject: [PATCH 06/11] iconmap --- src/Backend.cpp | 43 ++++++++++++++++++++++++++++++++++++++----- src/Backend.hpp | 3 +++ src/HAEntity.hpp | 3 ++- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/Backend.cpp b/src/Backend.cpp index a078126..f0b00ce 100644 --- a/src/Backend.cpp +++ b/src/Backend.cpp @@ -118,10 +118,16 @@ void HABackend::threadrunner() getstates["type"] = "get_states"; wc->send(getstates); + // FIXME: -cli, -ftxui don't need list_for_display or get_icons json list_for_display; list_for_display["type"] = "list_for_display"; wc->send(list_for_display); + json get_icons; + get_icons["type"] = "frontend/get_icons"; + get_icons["category"] = "entity"; // wonder what other categories there are. platform? integration? need to find frank somewhere + wc->send(get_icons); + while (true) { auto msg = wc->recv(); @@ -159,12 +165,39 @@ void HABackend::threadrunner() std::set integrations; for (auto ent : j["result"]["entities"]) { auto entity_id = ent["ei"].get(); - auto integration = ent["pl"].get(); - integrations.insert(integration); - entities[entity_id]->integration = integration; + auto platform = ent.value("pl", ""); + auto translation_key = ent.value("tk", ""); + integrations.insert(platform); + entities[entity_id]->platform = platform; + entities[entity_id]->translation_key = translation_key; } - for (auto integration : integrations) { - // fetch icons + } + else if (j["id"] == get_icons["id"]) { + std::scoped_lock lk(entitieslock); + // inside "resources": + // "sun": { + // "sensor": { + // "next_dawn": { + // "default": "mdi:sun-clock" + // }, + // "next_dusk": { + // "default": "mdi:sun-clock" + // }, + + + for (auto [platform, data] : j["result"]["resources"].items()) { + // FIXME: this if skips a lot + if (data.count("sensor")) { + for (auto& [key, data2] : data["sensor"].items()) { + // key: next_dawn, data2: "default": " ... "" + auto icon = data2.value("default", ""); + if (!icon.empty()) { + // platform: sun, key: next_dawn, icon: mdi-sun-clock + iconmap[iconkey{platform, key}] = icon; + cerr<<"iconmap["<> domains; std::mutex domainslock; + + typedef std::pair iconkey; // platform, translation_key + map iconmap; // under entitieslock too }; #endif \ No newline at end of file diff --git a/src/HAEntity.hpp b/src/HAEntity.hpp index 505d9eb..cc770fa 100644 --- a/src/HAEntity.hpp +++ b/src/HAEntity.hpp @@ -58,7 +58,8 @@ class HAEntity : public ISubject string domain; string fullname; string id; - string integration; + string platform; + string translation_key; // HAEntity(json _state); HAEntity(json _state, std::shared_ptr _hadomain, HABackend* _backend); From 4625b4a215d3a0d6e9d08b63ba3cb2488c6a79bf Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 2 Dec 2024 19:26:44 +0100 Subject: [PATCH 07/11] it works! --- src/Backend.cpp | 57 ++++--------------------------- src/Backend.hpp | 2 -- src/front-lvgl.cpp | 53 ++++++++++++++++++++++++++++ src/uicomponents/UIComponents.cpp | 10 +++++- src/uicomponents/UIComponents.hpp | 2 ++ 5 files changed, 71 insertions(+), 53 deletions(-) diff --git a/src/Backend.cpp b/src/Backend.cpp index f0b00ce..47f6b10 100644 --- a/src/Backend.cpp +++ b/src/Backend.cpp @@ -118,16 +118,6 @@ void HABackend::threadrunner() getstates["type"] = "get_states"; wc->send(getstates); - // FIXME: -cli, -ftxui don't need list_for_display or get_icons - json list_for_display; - list_for_display["type"] = "list_for_display"; - wc->send(list_for_display); - - json get_icons; - get_icons["type"] = "frontend/get_icons"; - get_icons["category"] = "entity"; // wonder what other categories there are. platform? integration? need to find frank somewhere - wc->send(get_icons); - while (true) { auto msg = wc->recv(); @@ -160,46 +150,6 @@ void HABackend::threadrunner() loaded = true; load_cv.notify_all(); } - else if (j["id"] == list_for_display["id"]) { - std::scoped_lock lk(entitieslock); - std::set integrations; - for (auto ent : j["result"]["entities"]) { - auto entity_id = ent["ei"].get(); - auto platform = ent.value("pl", ""); - auto translation_key = ent.value("tk", ""); - integrations.insert(platform); - entities[entity_id]->platform = platform; - entities[entity_id]->translation_key = translation_key; - } - } - else if (j["id"] == get_icons["id"]) { - std::scoped_lock lk(entitieslock); - // inside "resources": - // "sun": { - // "sensor": { - // "next_dawn": { - // "default": "mdi:sun-clock" - // }, - // "next_dusk": { - // "default": "mdi:sun-clock" - // }, - - - for (auto [platform, data] : j["result"]["resources"].items()) { - // FIXME: this if skips a lot - if (data.count("sensor")) { - for (auto& [key, data2] : data["sensor"].items()) { - // key: next_dawn, data2: "default": " ... "" - auto icon = data2.value("default", ""); - if (!icon.empty()) { - // platform: sun, key: next_dawn, icon: mdi-sun-clock - iconmap[iconkey{platform, key}] = icon; - cerr<<"iconmap["< HABackend::getEntityByName(const std::string& _name) return entities.at(_name); } +// std::string HABackend::getIcon(const iconkey _iconkey) +// { +// std::scoped_lock lk(entitieslock); + +// return iconmap.at(_iconkey); +// } + json HABackend::getDashboardConfig(const std::string& _dashboard) { json url; diff --git a/src/Backend.hpp b/src/Backend.hpp index 7a053aa..342e67c 100644 --- a/src/Backend.hpp +++ b/src/Backend.hpp @@ -56,8 +56,6 @@ class HABackend : Backend map> domains; std::mutex domainslock; - typedef std::pair iconkey; // platform, translation_key - map iconmap; // under entitieslock too }; #endif \ No newline at end of file diff --git a/src/front-lvgl.cpp b/src/front-lvgl.cpp index 25f0fec..da0ff24 100644 --- a/src/front-lvgl.cpp +++ b/src/front-lvgl.cpp @@ -37,6 +37,7 @@ namespace lvgl lv_style_t b612style; lv_font_t* mdifont; lv_style_t mdistyle; + map iconmap; // will need a lock eventually } } @@ -299,6 +300,58 @@ void uithread(int _argc, char* _argv[]) lv_log_register_print_cb(lvLogCallback); std::vector> uielements; + if (program.is_subcommand_used(entity_command) || program.is_subcommand_used(dashboard_command)) { + // need to collect some data used in both cases + + auto& ha = HABackend::getInstance(); + + // FIXME: -cli, -ftxui don't need list_for_display or get_icons + json list_for_display = ha.doCommand("config/entity_registry/list_for_display", {}); + + cerr< integrations; + for (auto ent : list_for_display["result"]["entities"]) { + auto entity_id = ent["ei"].get(); + auto platform = ent.value("pl", ""); + auto translation_key = ent.value("tk", ""); + integrations.insert(platform); + + auto entity = ha.getEntityByName(entity_id); + entity->platform = platform; + entity->translation_key = translation_key; + } + json get_icons_req; + get_icons_req["category"] = "entity"; // wonder what other categories there are. platform? integration? need to find frank somewhere + + json get_icons = ha.doCommand("frontend/get_icons", get_icons_req); + // inside "resources": + // "sun": { + // "sensor": { + // "next_dawn": { + // "default": "mdi:sun-clock" + // }, + // "next_dusk": { + // "default": "mdi:sun-clock" + // }, + + cerr<getJsonState()["attributes"].value("icon", ""); + + if (icon.empty()) { + voorkant::lvgl::iconkey key = {_entity->platform,_entity->translation_key}; + if (voorkant::lvgl::iconmap.count(key)) { + icon = voorkant::lvgl::iconmap.at(key); + } + } + cerr<<"iconmap[" << _entity->platform << "," << _entity->translation_key << "]=" << voorkant::lvgl::iconmap[{_entity->platform,_entity->translation_key}]< iconkey; // platform, translation_key + extern map iconmap; // will need a lock eventually } } From 6511001d4a5bf3299647556df28f8c3edab39548 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 2 Dec 2024 19:27:44 +0100 Subject: [PATCH 08/11] cleanup --- src/Backend.cpp | 7 ------- src/Backend.hpp | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Backend.cpp b/src/Backend.cpp index 47f6b10..06c7054 100644 --- a/src/Backend.cpp +++ b/src/Backend.cpp @@ -217,13 +217,6 @@ std::shared_ptr HABackend::getEntityByName(const std::string& _name) return entities.at(_name); } -// std::string HABackend::getIcon(const iconkey _iconkey) -// { -// std::scoped_lock lk(entitieslock); - -// return iconmap.at(_iconkey); -// } - json HABackend::getDashboardConfig(const std::string& _dashboard) { json url; diff --git a/src/Backend.hpp b/src/Backend.hpp index 342e67c..8844fe8 100644 --- a/src/Backend.hpp +++ b/src/Backend.hpp @@ -58,4 +58,4 @@ class HABackend : Backend }; -#endif \ No newline at end of file +#endif From 8d0fa581a1c9bcb9d9534f03352f233fa2491032 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 4 Dec 2024 00:28:27 +0100 Subject: [PATCH 09/11] format --- src/Backend.hpp | 1 - src/front-lvgl.cpp | 6 +++--- src/uicomponents/UIComponents.cpp | 7 ++++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Backend.hpp b/src/Backend.hpp index 8844fe8..441ae9d 100644 --- a/src/Backend.hpp +++ b/src/Backend.hpp @@ -55,7 +55,6 @@ class HABackend : Backend std::mutex entitieslock; map> domains; std::mutex domainslock; - }; #endif diff --git a/src/front-lvgl.cpp b/src/front-lvgl.cpp index da0ff24..839f8cc 100644 --- a/src/front-lvgl.cpp +++ b/src/front-lvgl.cpp @@ -308,7 +308,7 @@ void uithread(int _argc, char* _argv[]) // FIXME: -cli, -ftxui don't need list_for_display or get_icons json list_for_display = ha.doCommand("config/entity_registry/list_for_display", {}); - cerr< integrations; for (auto ent : list_for_display["result"]["entities"]) { auto entity_id = ent["ei"].get(); @@ -334,7 +334,7 @@ void uithread(int _argc, char* _argv[]) // "default": "mdi:sun-clock" // }, - cerr<platform,_entity->translation_key}; + voorkant::lvgl::iconkey key = {_entity->platform, _entity->translation_key}; if (voorkant::lvgl::iconmap.count(key)) { icon = voorkant::lvgl::iconmap.at(key); } } - cerr<<"iconmap[" << _entity->platform << "," << _entity->translation_key << "]=" << voorkant::lvgl::iconmap[{_entity->platform,_entity->translation_key}]<platform << "," << _entity->translation_key << "]=" << voorkant::lvgl::iconmap[{_entity->platform, _entity->translation_key}] << endl; if (icon.substr(0, 4) == "mdi:") { icon = icon.substr(4); - } else { + } + else { icon = "border-none-variant"; } From 037eceb63659fe85be91f69067ab1bb1a7d4b036 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 12 Dec 2024 20:29:08 +0100 Subject: [PATCH 10/11] add iconcomponentmap; refactor a bit --- src/front-lvgl.cpp | 6 ++++ src/uicomponents/UIComponents.cpp | 50 ++++++++++++++++++++++++------- src/uicomponents/UIComponents.hpp | 1 + 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/front-lvgl.cpp b/src/front-lvgl.cpp index 839f8cc..7ccadee 100644 --- a/src/front-lvgl.cpp +++ b/src/front-lvgl.cpp @@ -38,6 +38,7 @@ namespace lvgl lv_font_t* mdifont; lv_style_t mdistyle; map iconmap; // will need a lock eventually + json iconcomponentmap; // lock? } } @@ -350,6 +351,11 @@ void uithread(int _argc, char* _argv[]) } } } + + json get_icons_component_req; + get_icons_component_req["category"] = "entity_component"; + + voorkant::lvgl::iconcomponentmap = ha.doCommand("frontend/get_icons", get_icons_component_req)["result"]["resources"]; } if (program.is_subcommand_used(entity_command)) { diff --git a/src/uicomponents/UIComponents.cpp b/src/uicomponents/UIComponents.cpp index 06f4ee4..10b4b73 100644 --- a/src/uicomponents/UIComponents.cpp +++ b/src/uicomponents/UIComponents.cpp @@ -181,6 +181,43 @@ void UIDummy::update() } }; +string getIconFor(std::shared_ptr _entity) // for now, this function -always- returns something that starts with mdi: +{ + json state = _entity->getJsonState(); + + // 1. see if the state simply contains an icon - user might have set it explicitly + string icon = state["attributes"].value("icon", ""); + + if (!icon.empty()) { + return icon; + } + + if (state["attributes"].count("entity_picture")) { + // there is an icon, but it is not in a format we support yet (like SVG) + return "mdi:border-none-variant"; + } + // 2. see if we can find one for platform+translation key + voorkant::lvgl::iconkey key = {_entity->platform, _entity->translation_key}; + if (voorkant::lvgl::iconmap.count(key)) { + return voorkant::lvgl::iconmap.at(key); + } + + // 3. maybe we can find one by domain plus device_class? + auto& domain = _entity->domain; + auto device_class = state["attributes"].value("device_class", "_"); + + if (voorkant::lvgl::iconcomponentmap.count(domain)) { + auto& domaindata = voorkant::lvgl::iconcomponentmap[domain]; + if (domaindata.count(device_class)) { + if (domaindata[device_class].count("default")) { // FIXME: handle state-dependent variants too + return domaindata[device_class]["default"]; + } + } + } + + return "mdi:border-none"; +} + UISensor::UISensor(std::shared_ptr _entity, lv_obj_t* _parent) : UIEntity(_entity, _parent) { @@ -198,21 +235,14 @@ UISensor::UISensor(std::shared_ptr _entity, lv_obj_t* _parent) : lv_obj_set_height(iconpart, LV_SIZE_CONTENT); lv_obj_set_style_pad_all(iconpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(iconpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); - string icon = _entity->getJsonState()["attributes"].value("icon", ""); - - if (icon.empty()) { - voorkant::lvgl::iconkey key = {_entity->platform, _entity->translation_key}; - if (voorkant::lvgl::iconmap.count(key)) { - icon = voorkant::lvgl::iconmap.at(key); - } - } - cerr << "iconmap[" << _entity->platform << "," << _entity->translation_key << "]=" << voorkant::lvgl::iconmap[{_entity->platform, _entity->translation_key}] << endl; + string icon = getIconFor(_entity); + // cerr << "iconmap[" << _entity->platform << "," << _entity->translation_key << "]=" << voorkant::lvgl::iconmap[{_entity->platform, _entity->translation_key}] << endl; if (icon.substr(0, 4) == "mdi:") { icon = icon.substr(4); } else { - icon = "border-none-variant"; + icon = "help"; // as getIconFor currently promises something mdi:, we should never get here } lv_label_set_text(iconpart, voorkant::mdi::name2id(icon).data()); diff --git a/src/uicomponents/UIComponents.hpp b/src/uicomponents/UIComponents.hpp index 81b42b0..ad1fcca 100644 --- a/src/uicomponents/UIComponents.hpp +++ b/src/uicomponents/UIComponents.hpp @@ -21,6 +21,7 @@ namespace lvgl extern lv_style_t mdistyle; typedef std::pair iconkey; // platform, translation_key extern map iconmap; // will need a lock eventually + extern json iconcomponentmap; } } From 38cc13674306bbee90ac2bcf914776693d1db410 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Sun, 15 Dec 2024 00:25:49 +0100 Subject: [PATCH 11/11] pick up icon override from entities card --- src/front-lvgl.cpp | 4 +++- src/uicomponents/UIComponents.cpp | 10 +++++++--- src/uicomponents/UIComponents.hpp | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/front-lvgl.cpp b/src/front-lvgl.cpp index 7ccadee..b5030a1 100644 --- a/src/front-lvgl.cpp +++ b/src/front-lvgl.cpp @@ -84,11 +84,13 @@ void renderCard(std::vector>& uielements, nlohmann::ba auto objs = card["entities"]; for (auto ent : objs) { string entityname; + string icon; if (ent.type() == json::value_t::string) { entityname = ent; } else { entityname = ent["entity"]; + icon = ent.value("icon", ""); } std::shared_ptr entity = HABackend::getInstance().getEntityByName(entityname); if (entity->getEntityType() == EntityType::Light) { @@ -100,7 +102,7 @@ void renderCard(std::vector>& uielements, nlohmann::ba uielements.push_back(std::move(btn)); } else if (entity->getEntityType() == EntityType::Sensor) { - std::unique_ptr sensor = std::make_unique(entity, cont_row); + std::unique_ptr sensor = std::make_unique(entity, cont_row, icon); uielements.push_back(std::move(sensor)); } else { diff --git a/src/uicomponents/UIComponents.cpp b/src/uicomponents/UIComponents.cpp index 10b4b73..068d1d8 100644 --- a/src/uicomponents/UIComponents.cpp +++ b/src/uicomponents/UIComponents.cpp @@ -181,8 +181,12 @@ void UIDummy::update() } }; -string getIconFor(std::shared_ptr _entity) // for now, this function -always- returns something that starts with mdi: +// if _icon is passed, we got one from the dashboard, use that +string getIconFor(std::shared_ptr _entity, std::string _icon) // for now, this function -always- returns something that starts with mdi: { + if (!_icon.empty()) { + return _icon; + } json state = _entity->getJsonState(); // 1. see if the state simply contains an icon - user might have set it explicitly @@ -218,7 +222,7 @@ string getIconFor(std::shared_ptr _entity) // for now, this function - return "mdi:border-none"; } -UISensor::UISensor(std::shared_ptr _entity, lv_obj_t* _parent) : +UISensor::UISensor(std::shared_ptr _entity, lv_obj_t* _parent, std::string _icon) : UIEntity(_entity, _parent) { lv_obj_t* flowpanel = lv_obj_create(_parent); @@ -235,7 +239,7 @@ UISensor::UISensor(std::shared_ptr _entity, lv_obj_t* _parent) : lv_obj_set_height(iconpart, LV_SIZE_CONTENT); lv_obj_set_style_pad_all(iconpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(iconpart, 0, LV_PART_MAIN | LV_STATE_DEFAULT); - string icon = getIconFor(_entity); + string icon = getIconFor(_entity, _icon); // cerr << "iconmap[" << _entity->platform << "," << _entity->translation_key << "]=" << voorkant::lvgl::iconmap[{_entity->platform, _entity->translation_key}] << endl; if (icon.substr(0, 4) == "mdi:") { diff --git a/src/uicomponents/UIComponents.hpp b/src/uicomponents/UIComponents.hpp index ad1fcca..5a1ae01 100644 --- a/src/uicomponents/UIComponents.hpp +++ b/src/uicomponents/UIComponents.hpp @@ -85,7 +85,7 @@ class UIDummy : public UIEntity class UISensor : public UIEntity { public: - UISensor(std::shared_ptr _entity, lv_obj_t* _parent); + UISensor(std::shared_ptr _entity, lv_obj_t* _parent, std::string _icon = ""); void update() override; private: