Smooth graphs, sun path card, skeleton page switches and editor drag & drop
Firmware 0.2.15: trend graphs use a Catmull-Rom curve with a soft fill drawn by the card's draw event; sun.sun gets a wide sun-path card with horizon, arc and the sun at its current position; page switches show the new page's card frames immediately and fill them from a one-shot timer; the navigation is one full-width bar without a divider; the CYD adopts the Guition light palette in styles and overlays. App 0.2.13: pointer-based drag & drop (mouse and touch) to reorder tiles in the mockup and to drop entities from the list, sticky save bar, a new header with explained actions and a three-step guide, clearer firmware dialog. New sun, weather and clock tiles start wide in their best view. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -38,9 +38,10 @@ De firmware en ingebouwde CLI zijn getest met **ESPHome 2026.6.2**.
|
|||||||
- **Speciale kaarten (firmware 0.2.14+):** een **klok** (digitaal of analoog)
|
- **Speciale kaarten (firmware 0.2.14+):** een **klok** (digitaal of analoog)
|
||||||
als ingebouwde tegel, een **weersvoorspelling** met vijf dagen op een
|
als ingebouwde tegel, een **weersvoorspelling** met vijf dagen op een
|
||||||
dubbelbrede kaart, een **grafiek** van de sensorgeschiedenis in de tegel,
|
dubbelbrede kaart, een **grafiek** van de sensorgeschiedenis in de tegel,
|
||||||
**zonsopgang/-ondergang** (`sun.sun`), een **kookwekker** (`timer.*`, tikken
|
een **zonnebaan** (`sun.sun`: horizon met de zon tussen opkomst en
|
||||||
start of pauzeert) en **aanwezigheid** (`person.*`). Kies ze in de kiezer als
|
ondergang), een **kookwekker** (`timer.*`, tikken start of pauzeert) en
|
||||||
elke andere tegel; **Dubbelbreed** is een optie voor iedere tegel.
|
**aanwezigheid** (`person.*`). Kies ze in de kiezer als elke andere tegel of
|
||||||
|
sleep ze direct in de schermmockup; **Dubbelbreed** is een optie voor iedere tegel.
|
||||||
- **Scherminstellingen:** standby-tijd, normale en gedimde helderheid,
|
- **Scherminstellingen:** standby-tijd, normale en gedimde helderheid,
|
||||||
nachturen, klok, terug naar de hoofdpagina en optioneel swipen tussen pagina's.
|
nachturen, klok, terug naar de hoofdpagina en optioneel swipen tussen pagina's.
|
||||||
- **Guition-rotatie:** 0°, 90°, 180° of 270°, direct vanuit de beheerpagina.
|
- **Guition-rotatie:** 0°, 90°, 180° of 270°, direct vanuit de beheerpagina.
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ inline const lv_font_t *mini_icon_font = nullptr;
|
|||||||
inline const lv_font_t *watch_value_font = nullptr, *watch_icon_font = nullptr;
|
inline const lv_font_t *watch_value_font = nullptr, *watch_icon_font = nullptr;
|
||||||
// Big digits for the clock card; the board profile sets it with the local time source.
|
// Big digits for the clock card; the board profile sets it with the local time source.
|
||||||
inline const lv_font_t *clock_font = nullptr;
|
inline const lv_font_t *clock_font = nullptr;
|
||||||
|
inline lv_obj_t *room_label = nullptr; // remembered by render() so page switches can render synchronously
|
||||||
inline std::function<esphome::ESPTime()> now_time;
|
inline std::function<esphome::ESPTime()> now_time;
|
||||||
inline uint32_t now_epoch() { if (!now_time) return 0; auto t = now_time(); return t.is_valid() ? static_cast<uint32_t>(t.timestamp) : 0; }
|
inline uint32_t now_epoch() { if (!now_time) return 0; auto t = now_time(); return t.is_valid() ? static_cast<uint32_t>(t.timestamp) : 0; }
|
||||||
inline void tick();
|
inline void tick();
|
||||||
@@ -75,7 +76,10 @@ struct Widgets {
|
|||||||
int title_x=0,title_y=0,value_x=0,value_y=0; const lv_font_t *value_font{}, *icon_font{};
|
int title_x=0,title_y=0,value_x=0,value_y=0; const lv_font_t *value_font{}, *icon_font{};
|
||||||
// Wide cards span both columns; custom cards (clock, forecast, graph) draw into `extra`.
|
// Wide cards span both columns; custom cards (clock, forecast, graph) draw into `extra`.
|
||||||
bool wide=false; int base_width=0; lv_obj_t *extra{}; std::string extra_mode; std::array<lv_obj_t *, 20> parts{}; lv_point_precise_t *points{};
|
bool wide=false; int base_width=0; lv_obj_t *extra{}; std::string extra_mode; std::array<lv_obj_t *, 20> parts{}; lv_point_precise_t *points{};
|
||||||
|
// Soft area under a polyline (graph, sun path), painted by the extra container's draw event.
|
||||||
|
const lv_point_precise_t *fill_points{}; unsigned fill_count=0; int fill_x=0, fill_y=0, fill_base=0; lv_color_t fill_color{}; lv_opa_t fill_opa=0;
|
||||||
};
|
};
|
||||||
|
constexpr unsigned POINT_BUFFER = 128;
|
||||||
inline std::array<Widgets, 10> widgets;
|
inline std::array<Widgets, 10> widgets;
|
||||||
inline bool fresh() { return model.ready() && esphome::millis() - last_received < 95000; }
|
inline bool fresh() { return model.ready() && esphome::millis() - last_received < 95000; }
|
||||||
inline float number(JsonVariant value, float fallback = NAN) {
|
inline float number(JsonVariant value, float fallback = NAN) {
|
||||||
@@ -640,13 +644,47 @@ inline uint32_t domain_accent(const Tile &t) {
|
|||||||
inline void end_extra(Widgets &w) {
|
inline void end_extra(Widgets &w) {
|
||||||
if(!w.extra)return;
|
if(!w.extra)return;
|
||||||
lv_obj_add_flag(w.extra,LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(w.extra,LV_OBJ_FLAG_HIDDEN);
|
||||||
|
w.fill_points=nullptr;w.fill_count=0;
|
||||||
if(!w.extra_mode.empty()){lv_obj_clean(w.extra);w.parts.fill(nullptr);w.extra_mode.clear();delete[] w.points;w.points=nullptr;}
|
if(!w.extra_mode.empty()){lv_obj_clean(w.extra);w.parts.fill(nullptr);w.extra_mode.clear();delete[] w.points;w.points=nullptr;}
|
||||||
}
|
}
|
||||||
|
// Two triangles per segment between the polyline and its baseline. No canvas
|
||||||
|
// buffer is needed, so the CYD can afford it as well.
|
||||||
|
inline void extra_draw(lv_event_t *e) {
|
||||||
|
auto &w=*static_cast<Widgets *>(lv_event_get_user_data(e));
|
||||||
|
if(!w.fill_points || w.fill_count<2 || !w.fill_opa)return;
|
||||||
|
auto *layer=lv_event_get_layer(e);lv_area_t area;lv_obj_get_coords(w.extra,&area);
|
||||||
|
lv_draw_triangle_dsc_t dsc;lv_draw_triangle_dsc_init(&dsc);dsc.color=w.fill_color;dsc.opa=w.fill_opa;
|
||||||
|
const lv_value_precise_t ox=area.x1+w.fill_x, oy=area.y1+w.fill_y, base=oy+w.fill_base;
|
||||||
|
for(unsigned i=0;i+1<w.fill_count;++i){
|
||||||
|
const auto &a=w.fill_points[i],&b=w.fill_points[i+1];
|
||||||
|
dsc.p[0]={ox+a.x,oy+a.y};dsc.p[1]={ox+b.x,oy+b.y};dsc.p[2]={ox+b.x,base};lv_draw_triangle(layer,&dsc);
|
||||||
|
dsc.p[1]=dsc.p[2];dsc.p[2]={ox+a.x,base};lv_draw_triangle(layer,&dsc);
|
||||||
|
}
|
||||||
|
}
|
||||||
inline void begin_extra(Widgets &w,const char *mode,int width,int height) {
|
inline void begin_extra(Widgets &w,const char *mode,int width,int height) {
|
||||||
if(!w.extra){w.extra=lv_obj_create(w.tile);lv_obj_remove_style_all(w.extra);lv_obj_remove_flag(w.extra,LV_OBJ_FLAG_CLICKABLE);lv_obj_remove_flag(w.extra,LV_OBJ_FLAG_SCROLLABLE);}
|
if(!w.extra){
|
||||||
if(w.extra_mode!=mode){end_extra(w);w.extra_mode=mode;w.points=new lv_point_precise_t[28];w.cached_active=-1;}
|
w.extra=lv_obj_create(w.tile);lv_obj_remove_style_all(w.extra);lv_obj_remove_flag(w.extra,LV_OBJ_FLAG_CLICKABLE);lv_obj_remove_flag(w.extra,LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
lv_obj_add_event_cb(w.extra,extra_draw,LV_EVENT_DRAW_MAIN,&w);
|
||||||
|
}
|
||||||
|
if(w.extra_mode!=mode){end_extra(w);w.extra_mode=mode;w.points=new lv_point_precise_t[POINT_BUFFER];w.cached_active=-1;}
|
||||||
|
w.fill_points=nullptr;w.fill_count=0;
|
||||||
lv_obj_set_pos(w.extra,0,0);lv_obj_set_size(w.extra,width,height);lv_obj_remove_flag(w.extra,LV_OBJ_FLAG_HIDDEN);
|
lv_obj_set_pos(w.extra,0,0);lv_obj_set_size(w.extra,width,height);lv_obj_remove_flag(w.extra,LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
|
// Catmull-Rom curve through the samples: the trend reads smoothly without extra data.
|
||||||
|
inline unsigned smooth(const lv_point_precise_t *in,unsigned n,lv_point_precise_t *out,unsigned capacity,int width,int height) {
|
||||||
|
if(n<2 || capacity<2){for(unsigned i=0;i<n && i<capacity;++i)out[i]=in[i];return n<capacity?n:capacity;}
|
||||||
|
const unsigned steps=4;unsigned count=0;
|
||||||
|
for(unsigned i=0;i+1<n;++i){
|
||||||
|
const auto &p0=in[i?i-1:0],&p1=in[i],&p2=in[i+1],&p3=in[i+2<n?i+2:n-1];
|
||||||
|
for(unsigned s=0;s<steps && count<capacity-1;++s){
|
||||||
|
float t=float(s)/steps,t2=t*t,t3=t2*t;
|
||||||
|
float x=0.5f*(2*p1.x+(-p0.x+p2.x)*t+(2*p0.x-5*p1.x+4*p2.x-p3.x)*t2+(-p0.x+3*p1.x-3*p2.x+p3.x)*t3);
|
||||||
|
float y=0.5f*(2*p1.y+(-p0.y+p2.y)*t+(2*p0.y-5*p1.y+4*p2.y-p3.y)*t2+(-p0.y+3*p1.y-3*p2.y+p3.y)*t3);
|
||||||
|
out[count++]={(lv_value_precise_t)std::clamp(x,0.0f,float(width-1)),(lv_value_precise_t)std::clamp(y,0.0f,float(height-1))};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out[count++]=in[n-1];return count;
|
||||||
|
}
|
||||||
inline lv_obj_t *part_label(Widgets &w,unsigned i,const lv_font_t *font,int x,int y,int width,lv_text_align_t align,const std::string &text) {
|
inline lv_obj_t *part_label(Widgets &w,unsigned i,const lv_font_t *font,int x,int y,int width,lv_text_align_t align,const std::string &text) {
|
||||||
auto *&p=w.parts[i];
|
auto *&p=w.parts[i];
|
||||||
if(!p){p=lv_label_create(w.extra);lv_label_set_long_mode(p,LV_LABEL_LONG_CLIP);lv_obj_remove_flag(p,LV_OBJ_FLAG_CLICKABLE);}
|
if(!p){p=lv_label_create(w.extra);lv_label_set_long_mode(p,LV_LABEL_LONG_CLIP);lv_obj_remove_flag(p,LV_OBJ_FLAG_CLICKABLE);}
|
||||||
@@ -730,21 +768,66 @@ inline void render_forecast(Widgets &w,const Tile &t,bool large,int width,int he
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sparkline of the manager's 24 history samples in the given rectangle.
|
// Smoothed trend of the manager's 24 history samples with a soft fill beneath.
|
||||||
inline void render_graph(Widgets &w,const Tile &t,bool large,int x,int y,int width,int height) {
|
inline void render_graph(Widgets &w,const Tile &t,bool large,int x,int y,int width,int height) {
|
||||||
begin_extra(w,"graph",x+width,y+height);
|
begin_extra(w,"graph",x+width,y+height);
|
||||||
float minimum=INFINITY,maximum=-INFINITY;for(float v:t.history)if(std::isfinite(v)){minimum=std::min(minimum,v);maximum=std::max(maximum,v);}
|
float minimum=INFINITY,maximum=-INFINITY;for(float v:t.history)if(std::isfinite(v)){minimum=std::min(minimum,v);maximum=std::max(maximum,v);}
|
||||||
unsigned n=0;int stroke=large?3:2;
|
lv_point_precise_t raw[24];unsigned n=0;int stroke=large?3:2,top=stroke;
|
||||||
for(unsigned i=0;i<24;++i){
|
for(unsigned i=0;i<24;++i){
|
||||||
if(!std::isfinite(t.history[i]))continue;
|
if(!std::isfinite(t.history[i]))continue;
|
||||||
float level=maximum>minimum?(t.history[i]-minimum)/(maximum-minimum):0.5f;
|
float level=maximum>minimum?(t.history[i]-minimum)/(maximum-minimum):0.5f;
|
||||||
w.points[n++]={(lv_value_precise_t)(stroke/2+i*(width-stroke-1)/23),(lv_value_precise_t)(height-stroke/2-1-level*(height-stroke-2))};
|
raw[n++]={(lv_value_precise_t)(stroke/2+i*(width-stroke-1)/23),(lv_value_precise_t)(height-stroke/2-1-level*(height-stroke-1-top))};
|
||||||
}
|
}
|
||||||
if(n==1){w.points[1]=w.points[0];w.points[1].x=(lv_value_precise_t)(width-1);n=2;}
|
if(n==1){raw[1]=raw[0];raw[1].x=(lv_value_precise_t)(width-1);n=2;}
|
||||||
part_line(w,0,w.points,n,stroke,x,y);
|
unsigned count=smooth(raw,n,w.points,POINT_BUFFER,width,height);
|
||||||
|
part_line(w,0,w.points,count,stroke,x,y);
|
||||||
|
w.fill_points=w.points;w.fill_count=count;w.fill_x=x;w.fill_y=y;w.fill_base=height;w.fill_opa=LV_OPA_20;
|
||||||
|
}
|
||||||
|
// Sun path: horizon, an arc from sunrise to sunset and the sun at the current
|
||||||
|
// position (or below the horizon at night). Wide cards only.
|
||||||
|
inline int minutes_of(const std::string &clock) {
|
||||||
|
unsigned h=0,m=0;return sscanf(clock.c_str(),"%u:%u",&h,&m)==2 && h<24 && m<60 ? int(h*60+m) : -1;
|
||||||
|
}
|
||||||
|
inline void render_sunpath(Widgets &w,const Tile &t,bool large,int width,int height) {
|
||||||
|
begin_extra(w,"sunpath",width,height);
|
||||||
|
const lv_font_t *title_font=lv_obj_get_style_text_font(w.title,LV_PART_MAIN);
|
||||||
|
int title_h=lv_font_get_line_height(title_font),text_h=lv_font_get_line_height(w.value_font);
|
||||||
|
int horizon=height-text_h-(large?4:2),top=title_h+(large?4:2),x0=large?14:8,x1=width-x0;
|
||||||
|
part_label(w,0,title_font,0,0,width,LV_TEXT_ALIGN_LEFT,t.name.empty()?"Zon":t.name);
|
||||||
|
part_label(w,1,w.value_font,0,horizon+(large?3:1),width/2,LV_TEXT_ALIGN_LEFT,"op "+t.sunrise);
|
||||||
|
part_label(w,2,w.value_font,width/2,horizon+(large?3:1),width/2,LV_TEXT_ALIGN_RIGHT,"onder "+t.sunset);
|
||||||
|
auto now=now_time?now_time():esphome::ESPTime{};
|
||||||
|
int rise=minutes_of(t.sunrise),set=minutes_of(t.sunset),minute=now.is_valid()?now.hour*60+now.minute:-1;
|
||||||
|
bool day=t.state=="above_horizon";float fraction=0.5f;
|
||||||
|
if(rise>=0 && set>=0 && minute>=0){
|
||||||
|
if(day){int span=(set-rise+1440)%1440;if(!span)span=1;fraction=std::clamp(float((minute-rise+1440)%1440)/span,0.0f,1.0f);}
|
||||||
|
else{int span=(rise-set+1440)%1440;if(!span)span=1;fraction=std::clamp(float((minute-set+1440)%1440)/span,0.0f,1.0f);}
|
||||||
|
}
|
||||||
|
const unsigned segments=40;float amplitude=day?float(horizon-top):float(height-text_h-horizon-(large?2:1));
|
||||||
|
auto *arc=w.points,*travelled=w.points+segments+1,*line=w.points+2*segments+3;
|
||||||
|
for(unsigned i=0;i<=segments;++i){
|
||||||
|
float a=3.14159265f*i/segments;
|
||||||
|
arc[i]={(lv_value_precise_t)(x0+(x1-x0)*float(i)/segments),(lv_value_precise_t)(day?horizon-sinf(a)*amplitude:horizon+sinf(a)*amplitude)};
|
||||||
|
}
|
||||||
|
unsigned filled=std::min(segments,unsigned(fraction*segments));
|
||||||
|
for(unsigned i=0;i<=filled;++i)travelled[i]=arc[i];
|
||||||
|
float sa=3.14159265f*fraction;
|
||||||
|
lv_point_precise_t sun={(lv_value_precise_t)(x0+(x1-x0)*fraction),(lv_value_precise_t)(day?horizon-sinf(sa)*amplitude:horizon+sinf(sa)*amplitude)};
|
||||||
|
travelled[filled+1]=sun;
|
||||||
|
line[0]={(lv_value_precise_t)0,(lv_value_precise_t)horizon};line[1]={(lv_value_precise_t)(width-1),(lv_value_precise_t)horizon};
|
||||||
|
bool dark_text=light_theme || t.background!=0;
|
||||||
|
uint32_t path=dark_text?0xCFD8DC:0x6B8299, accent=day?0xFF9800:0x5C6BC0, disc=day?0xFFB300:0xB0BEC5;
|
||||||
|
lv_obj_set_style_line_color(part_line(w,3,line,2,2),lv_color_hex(path),0);
|
||||||
|
lv_obj_set_style_line_color(part_line(w,4,arc,segments+1,large?2:1),lv_color_hex(path),0);
|
||||||
|
lv_obj_set_style_line_color(part_line(w,5,travelled,filled+2,large?4:3),lv_color_hex(accent),0);
|
||||||
|
int size=large?18:10,glow=size+(large?12:6);
|
||||||
|
auto *halo=part_dot(w,6,int(sun.x)-glow/2,int(sun.y)-glow/2,glow);lv_obj_set_style_bg_color(halo,lv_color_hex(disc),0);lv_obj_set_style_bg_opa(halo,LV_OPA_30,0);
|
||||||
|
lv_obj_set_style_bg_color(part_dot(w,7,int(sun.x)-size/2,int(sun.y)-size/2,size),lv_color_hex(disc),0);
|
||||||
|
if(day){w.fill_points=travelled;w.fill_count=filled+2;w.fill_x=0;w.fill_y=0;w.fill_base=horizon;w.fill_color=lv_color_hex(0xFFB300);w.fill_opa=LV_OPA_20;}
|
||||||
}
|
}
|
||||||
inline void render(lv_obj_t *room) {
|
inline void render(lv_obj_t *room) {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
|
room_label=room;
|
||||||
label(room, !model.configured ? "Kies tegels in HA" : !model.ready() ? "Tegels laden..." : !fresh() ? "HA niet verbonden" : model.title);
|
label(room, !model.configured ? "Kies tegels in HA" : !model.ready() ? "Tegels laden..." : !fresh() ? "HA niet verbonden" : model.title);
|
||||||
for (size_t slot = 0; slot < 6; ++slot) {
|
for (size_t slot = 0; slot < 6; ++slot) {
|
||||||
auto &w=widgets[slot];
|
auto &w=widgets[slot];
|
||||||
@@ -777,8 +860,9 @@ inline void render(lv_obj_t *room) {
|
|||||||
bool large_tile=lv_obj_get_height(w.tile)>80;
|
bool large_tile=lv_obj_get_height(w.tile)>80;
|
||||||
// Cards that replace the name/status layout entirely.
|
// Cards that replace the name/status layout entirely.
|
||||||
bool clock=t.builtin(), forecast=d=="weather" && t.display=="forecast" && w.wide && t.forecast_count>0 && fresh() && t.available();
|
bool clock=t.builtin(), forecast=d=="weather" && t.display=="forecast" && w.wide && t.forecast_count>0 && fresh() && t.available();
|
||||||
|
bool sunpath=d=="sun" && t.display=="sunpath" && w.wide && !t.sunrise.empty() && !t.sunset.empty() && fresh() && t.available();
|
||||||
bool graph=d=="sensor" && t.display=="graph" && t.has_history && !clock;
|
bool graph=d=="sensor" && t.display=="graph" && t.has_history && !clock;
|
||||||
bool custom=clock||forecast;
|
bool custom=clock||forecast||sunpath;
|
||||||
if(!large_tile){lv_obj_set_style_pad_top(w.tile,watch||custom||graph?2:4,0);lv_obj_set_style_pad_bottom(w.tile,watch||custom||graph?2:4,0);}
|
if(!large_tile){lv_obj_set_style_pad_top(w.tile,watch||custom||graph?2:4,0);lv_obj_set_style_pad_bottom(w.tile,watch||custom||graph?2:4,0);}
|
||||||
lv_obj_set_style_text_font(w.value,watch && watch_value_font ? watch_value_font : w.value_font,0);
|
lv_obj_set_style_text_font(w.value,watch && watch_value_font ? watch_value_font : w.value_font,0);
|
||||||
lv_obj_set_height(w.value,lv_font_get_line_height(lv_obj_get_style_text_font(w.value,LV_PART_MAIN)));
|
lv_obj_set_height(w.value,lv_font_get_line_height(lv_obj_get_style_text_font(w.value,LV_PART_MAIN)));
|
||||||
@@ -787,7 +871,9 @@ inline void render(lv_obj_t *room) {
|
|||||||
for(auto *o:{w.title,w.value,w.circle,w.unit}){if(custom)lv_obj_add_flag(o,LV_OBJ_FLAG_HIDDEN);else lv_obj_remove_flag(o,LV_OBJ_FLAG_HIDDEN);}
|
for(auto *o:{w.title,w.value,w.circle,w.unit}){if(custom)lv_obj_add_flag(o,LV_OBJ_FLAG_HIDDEN);else lv_obj_remove_flag(o,LV_OBJ_FLAG_HIDDEN);}
|
||||||
if(custom){
|
if(custom){
|
||||||
lv_obj_add_flag(w.slider,LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(w.slider,LV_OBJ_FLAG_HIDDEN);
|
||||||
if(clock)render_clock(w,t,large_tile,content_width,content_height);else render_forecast(w,t,large_tile,content_width,content_height);
|
if(clock)render_clock(w,t,large_tile,content_width,content_height);
|
||||||
|
else if(sunpath)render_sunpath(w,t,large_tile,content_width,content_height);
|
||||||
|
else render_forecast(w,t,large_tile,content_width,content_height);
|
||||||
}else{
|
}else{
|
||||||
int title_height=lv_obj_get_height(w.title),value_height=lv_obj_get_height(w.value);
|
int title_height=lv_obj_get_height(w.title),value_height=lv_obj_get_height(w.value);
|
||||||
int line_gap=large_tile?2:1,text_height=title_height+line_gap+value_height;
|
int line_gap=large_tile?2:1,text_height=title_height+line_gap+value_height;
|
||||||
@@ -862,9 +948,13 @@ inline void render(lv_obj_t *room) {
|
|||||||
lv_obj_set_style_text_color(w.title, title_color, 0);
|
lv_obj_set_style_text_color(w.title, title_color, 0);
|
||||||
lv_obj_set_style_text_color(w.value, value_color, 0);
|
lv_obj_set_style_text_color(w.value, value_color, 0);
|
||||||
// Custom parts follow the card palette: text like the title, lines/dots in the accent.
|
// Custom parts follow the card palette: text like the title, lines/dots in the accent.
|
||||||
|
// The sun path sets its own colours on every render.
|
||||||
|
w.fill_color=color;
|
||||||
for(unsigned i=0;i<w.parts.size();++i){
|
for(unsigned i=0;i<w.parts.size();++i){
|
||||||
auto *p=w.parts[i];if(!p)continue;
|
auto *p=w.parts[i];if(!p)continue;
|
||||||
if(lv_obj_check_type(p,&lv_label_class))lv_obj_set_style_text_color(p,w.extra_mode=="forecast" && i>=2 && i%3==2 ? value_color : i==16 ? value_color : title_color,0);
|
bool muted=w.extra_mode=="forecast" ? i>=2 && i%3==2 : w.extra_mode=="sunpath" ? i>=1 : i==16;
|
||||||
|
if(lv_obj_check_type(p,&lv_label_class))lv_obj_set_style_text_color(p,muted?value_color:title_color,0);
|
||||||
|
else if(w.extra_mode=="sunpath")continue;
|
||||||
else if(lv_obj_check_type(p,&lv_line_class))lv_obj_set_style_line_color(p,w.extra_mode=="graph"?color:i==13?icon_color:title_color,0);
|
else if(lv_obj_check_type(p,&lv_line_class))lv_obj_set_style_line_color(p,w.extra_mode=="graph"?color:i==13?icon_color:title_color,0);
|
||||||
else lv_obj_set_style_bg_color(p,i==14?icon_color:value_color,0);
|
else lv_obj_set_style_bg_color(p,i==14?icon_color:value_color,0);
|
||||||
}
|
}
|
||||||
@@ -946,7 +1036,15 @@ inline unsigned page_count() {
|
|||||||
std::array<Placement,MAX_TILES> placement;
|
std::array<Placement,MAX_TILES> placement;
|
||||||
return pack(model.tiles,model.count,placement);
|
return pack(model.tiles,model.count,placement);
|
||||||
}
|
}
|
||||||
inline void show_page(int &page, lv_obj_t *previous, lv_obj_t *next, lv_obj_t *number) {
|
// Page switches feel immediate: the new page's card frames (right widths, no
|
||||||
|
// contents, light skeleton style) appear in the very next frame, and a one-shot
|
||||||
|
// LVGL timer fills them in right after. Keepalives and re-packing on the same
|
||||||
|
// page apply directly. Nothing is allocated, so the CYD stays comfortable.
|
||||||
|
inline lv_obj_t *nav_prev=nullptr,*nav_next=nullptr,*nav_number=nullptr;
|
||||||
|
inline int applied_page=-1,target_page=0;
|
||||||
|
inline lv_timer_t *page_timer=nullptr;
|
||||||
|
// Slot assignment plus card widths and visibility for a page; contents are untouched.
|
||||||
|
inline int place_page(int page) {
|
||||||
std::array<Placement,MAX_TILES> placement;
|
std::array<Placement,MAX_TILES> placement;
|
||||||
int pages=pack(model.tiles,model.count,placement);
|
int pages=pack(model.tiles,model.count,placement);
|
||||||
page=std::clamp(page,0,pages-1);
|
page=std::clamp(page,0,pages-1);
|
||||||
@@ -958,14 +1056,41 @@ inline void show_page(int &page, lv_obj_t *previous, lv_obj_t *next, lv_obj_t *n
|
|||||||
if(slot<SLOTS_PER_PAGE && w.index<model.count){lv_obj_set_width(w.tile,w.wide?wide_width:w.base_width);lv_obj_remove_flag(w.tile,LV_OBJ_FLAG_HIDDEN);}
|
if(slot<SLOTS_PER_PAGE && w.index<model.count){lv_obj_set_width(w.tile,w.wide?wide_width:w.base_width);lv_obj_remove_flag(w.tile,LV_OBJ_FLAG_HIDDEN);}
|
||||||
else{lv_obj_add_flag(w.tile,LV_OBJ_FLAG_HIDDEN);end_extra(w);}
|
else{lv_obj_add_flag(w.tile,LV_OBJ_FLAG_HIDDEN);end_extra(w);}
|
||||||
}
|
}
|
||||||
for(auto *control:{previous,next,number}){
|
for(auto *control:{nav_prev,nav_next,nav_number}){
|
||||||
if(pages>1)lv_obj_remove_flag(control,LV_OBJ_FLAG_HIDDEN);
|
if(pages>1)lv_obj_remove_flag(control,LV_OBJ_FLAG_HIDDEN);
|
||||||
else lv_obj_add_flag(control,LV_OBJ_FLAG_HIDDEN);
|
else lv_obj_add_flag(control,LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
if(page==0)lv_obj_add_state(previous,LV_STATE_DISABLED);else lv_obj_remove_state(previous,LV_STATE_DISABLED);
|
if(page==0)lv_obj_add_state(nav_prev,LV_STATE_DISABLED);else lv_obj_remove_state(nav_prev,LV_STATE_DISABLED);
|
||||||
if(page==pages-1)lv_obj_add_state(next,LV_STATE_DISABLED);else lv_obj_remove_state(next,LV_STATE_DISABLED);
|
if(page==pages-1)lv_obj_add_state(nav_next,LV_STATE_DISABLED);else lv_obj_remove_state(nav_next,LV_STATE_DISABLED);
|
||||||
std::string caption=std::to_string(page+1)+" / "+std::to_string(pages);lv_label_set_text(number,caption.c_str());
|
for(auto *control:{nav_prev,nav_next})if(lv_obj_get_child_count(control))
|
||||||
if(refresh)refresh();
|
lv_obj_set_style_text_opa(lv_obj_get_child(control,0),lv_obj_has_state(control,LV_STATE_DISABLED)?LV_OPA_30:LV_OPA_COVER,0);
|
||||||
|
std::string caption=std::to_string(page+1)+" / "+std::to_string(pages);lv_label_set_text(nav_number,caption.c_str());
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
inline void apply_page(int page) {
|
||||||
|
applied_page=place_page(page);
|
||||||
|
if(room_label)render(room_label);else if(refresh)refresh();
|
||||||
|
}
|
||||||
|
inline void skeleton_page(int page) {
|
||||||
|
place_page(page);
|
||||||
|
uint32_t bg=light_theme?0xF4F5F7:0x4A6076, border=light_theme?0xE3E5E8:0x6F879C;
|
||||||
|
for(size_t slot=0;slot<SLOTS_PER_PAGE;++slot){
|
||||||
|
auto &w=widgets[slot];if(!w.tile || lv_obj_has_flag(w.tile,LV_OBJ_FLAG_HIDDEN))continue;
|
||||||
|
for(auto *o:{w.title,w.value,w.circle,w.unit,w.slider,w.extra})if(o)lv_obj_add_flag(o,LV_OBJ_FLAG_HIDDEN);
|
||||||
|
lv_obj_set_width(w.progress,0);
|
||||||
|
lv_obj_set_style_bg_color(w.tile,lv_color_hex(bg),0);
|
||||||
|
lv_obj_set_style_border_color(w.tile,lv_color_hex(border),0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void page_timer_done(lv_timer_t *) { page_timer=nullptr; apply_page(target_page); }
|
||||||
|
inline void show_page(int &page, lv_obj_t *previous, lv_obj_t *next, lv_obj_t *number) {
|
||||||
|
nav_prev=previous;nav_next=next;nav_number=number;
|
||||||
|
page=std::clamp(page,0,int(page_count())-1);
|
||||||
|
target_page=page;
|
||||||
|
if(applied_page<0 || page==applied_page){if(page_timer){lv_timer_delete(page_timer);page_timer=nullptr;}apply_page(page);return;}
|
||||||
|
skeleton_page(page);
|
||||||
|
if(page_timer)lv_timer_reset(page_timer);
|
||||||
|
else{page_timer=lv_timer_create(page_timer_done,60,nullptr);lv_timer_set_repeat_count(page_timer,1);}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t last_live_second=0;
|
inline uint32_t last_live_second=0;
|
||||||
@@ -991,7 +1116,7 @@ inline void tick() {
|
|||||||
for(size_t slot=0;slot<SLOTS_PER_PAGE;++slot){
|
for(size_t slot=0;slot<SLOTS_PER_PAGE;++slot){
|
||||||
auto &w=widgets[slot];if(!w.tile || w.index>=model.count || lv_obj_has_flag(w.tile,LV_OBJ_FLAG_HIDDEN))continue;
|
auto &w=widgets[slot];if(!w.tile || w.index>=model.count || lv_obj_has_flag(w.tile,LV_OBJ_FLAG_HIDDEN))continue;
|
||||||
const auto &t=model.tiles[w.index];
|
const auto &t=model.tiles[w.index];
|
||||||
if(t.builtin() || (t.domain()=="timer" && t.state=="active"))redraw=true;
|
if(t.builtin() || (t.domain()=="timer" && t.state=="active") || (t.domain()=="sun" && second%60==0))redraw=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(redraw && refresh)refresh();
|
if(redraw && refresh)refresh();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ def demo_layout():
|
|||||||
{'entity': 'sensor.demo_temperatuur', 'name': 'Woonkamer', 'options': {'display': 'graph'}},
|
{'entity': 'sensor.demo_temperatuur', 'name': 'Woonkamer', 'options': {'display': 'graph'}},
|
||||||
{'entity': 'person.demo', 'name': 'Max', 'options': {}},
|
{'entity': 'person.demo', 'name': 'Max', 'options': {}},
|
||||||
{'entity': 'timer.demo', 'name': 'Eieren', 'options': {}},
|
{'entity': 'timer.demo', 'name': 'Eieren', 'options': {}},
|
||||||
{'entity': 'sun.sun', 'name': 'Zon', 'options': {}},
|
{'entity': 'sun.sun', 'name': 'Zon', 'options': {'display': 'sunpath'}},
|
||||||
{'entity': 'sensor.demo_energie', 'name': 'Verbruik vandaag', 'options': {'display': 'graph', 'size': 'wide'}},
|
{'entity': 'sensor.demo_energie', 'name': 'Verbruik vandaag', 'options': {'display': 'graph', 'size': 'wide'}},
|
||||||
{'entity': 'light.demo', 'name': 'Tafellamp', 'options': {'display': 'watch', 'size': 'wide'}},
|
{'entity': 'light.demo', 'name': 'Tafellamp', 'options': {'display': 'watch', 'size': 'wide'}},
|
||||||
{'entity': 'weather.demo_standaard', 'name': 'Weer nu', 'options': {}},
|
{'entity': 'weather.demo_standaard', 'name': 'Weer nu', 'options': {}},
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# App 0.2.13 / firmware 0.2.15 — zonnebaan, gladde grafiek, editor-UX
|
||||||
|
|
||||||
|
## Wijzigingen
|
||||||
|
|
||||||
|
- **Grafiek**: Catmull-Rom-curve door dezelfde 24 historiepunten (vier
|
||||||
|
tussenpunten per segment) met een zachte vulling eronder. De vulling wordt
|
||||||
|
door een `LV_EVENT_DRAW_MAIN`-tekenevent van de kaartcontainer als
|
||||||
|
driehoeken getekend; er is geen canvasbuffer nodig, dus ook de CYD kan het.
|
||||||
|
- **Zonnebaan** (`sun.sun`, `display: sunpath`, altijd dubbelbreed): horizon,
|
||||||
|
boog van opkomst naar ondergang, de zon op de huidige positie met een gloed
|
||||||
|
en een vulling van het afgelegde deel; ’s nachts loopt de zon onder de
|
||||||
|
horizon in indigo. De positie wordt uit de HH:MM-tijden van de manager en
|
||||||
|
de lokale tijd berekend en ververst elke minuut.
|
||||||
|
- **Navigatie**: één onderbalk over de volle breedte met een doorlopende
|
||||||
|
bovenlijn; linkerhelft = vorige, rechterhelft = volgende, paginanummer in
|
||||||
|
het midden. Een uitgeschakelde helft dimt zijn tekst.
|
||||||
|
- **Paginawissel**: `show_page` zet in hetzelfde frame de kaartkaders van de
|
||||||
|
nieuwe pagina neer (juiste breedtes via `pack`, inhoud verborgen, lichte
|
||||||
|
skeletonstijl) en een eenmalige LVGL-timer van 60 ms vult daarna de inhoud
|
||||||
|
synchroon in. Een eerdere fade-variant voelde traag en is vervangen.
|
||||||
|
Keepalives en herpakken op dezelfde pagina passen direct toe.
|
||||||
|
- **CYD-kleuren**: het Guition-schema is overgenomen — vlakke lichtgrijze
|
||||||
|
achtergrond (0xE7E7E7), witte kaarten met 0xDDDDDD-rand, donkere tekst,
|
||||||
|
lichtblauwe iconcirkels — inclusief alle bedieningsoverlays (75 kleurwaarden
|
||||||
|
één-op-één gelijk aan de Guition) en `light_theme` voor de runtimekaarten.
|
||||||
|
- **Navigatie** zonder scheidingslijn: alleen de teksten "< Vorige",
|
||||||
|
"Volgende >" en het paginanummer.
|
||||||
|
- **Editor**: pointer-gebaseerd slepen (muis en touch met kort vasthouden)
|
||||||
|
om tegels in de mockup te ordenen en entiteiten uit de lijst op een plek
|
||||||
|
te laten vallen, met auto-scroll bij de schermranden; sticky opslaan-balk;
|
||||||
|
nieuwe kop met drie uitgelegde acties en een stappenuitleg; verbeterde
|
||||||
|
firmwaredialoog. Zon-, weer- en kloktegels starten dubbelbreed in hun
|
||||||
|
mooiste weergave.
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
- 55 Python-tests en negen C++-testprogramma's geslaagd; `--check` van de
|
||||||
|
pakketgenerator; beide Easy Setup-profielen gebouwd (CYD-flash 72,9 %).
|
||||||
|
- Editor in de browser met een gemockte inventory gecontroleerd: kop, stappen,
|
||||||
|
sticky opslaan-balk, dubbelbrede mockup. Slepen getest met gesimuleerde
|
||||||
|
pointer-events: tegel 4 → positie 1 en een entiteit uit de lijst → positie 2
|
||||||
|
komen op de juiste plek; een sleep telt niet als klik.
|
||||||
|
- Beide borden via USB geflasht; `device_info` meldt 0.2.15. Guition-snapshots
|
||||||
|
van de demo-indeling: zonnebaan met zon op de boog en tijden, gladde
|
||||||
|
gevulde grafiek enkel- en dubbelbreed, nieuwe onderbalk. Demo-renderdiagnose
|
||||||
|
op de Guition 10/10 geslaagd (`count=9`).
|
||||||
|
- De eigenaar bevestigde het uiterlijk op de Guition, meldde tussenframes bij
|
||||||
|
paginawissels (foto met een achtergebleven sparkline) en vond de fade te
|
||||||
|
traag; daarop de skeletonwissel. Renderdiagnose op de echte indelingen van
|
||||||
|
beide borden na de laatste flash: zie hieronder.
|
||||||
|
- Laatste flash (Guition 08:59:18, CYD 09:03:32, beide 0.2.15): renderdiagnose
|
||||||
|
op de echte indelingen geslaagd — Guition 10/10 (`count=6`, heap ~6,46 MB),
|
||||||
|
CYD 10/10 (`count=7`, ~52,5 kB vrij). Beide handmatige profielen compileren.
|
||||||
|
De skeletonwissel en de CYD-kleuren zijn door de eigenaar visueel te
|
||||||
|
beoordelen; er is geen langdurige stabiliteitsproef uitgevoerd.
|
||||||
+32
-20
@@ -1,7 +1,7 @@
|
|||||||
# Guition ESP32-S3-4848S040 / 4-inch EU wallbox, 480x480 IPS + GT911.
|
# Guition ESP32-S3-4848S040 / 4-inch EU wallbox, 480x480 IPS + GT911.
|
||||||
# Use guition-device.yaml; see docs/GUITION.md. CYD hardware is a separate profile.
|
# Use guition-device.yaml; see docs/GUITION.md. CYD hardware is a separate profile.
|
||||||
substitutions:
|
substitutions:
|
||||||
SCREEN_FIRMWARE_VERSION: "0.2.14"
|
SCREEN_FIRMWARE_VERSION: "0.2.15"
|
||||||
DYNAMIC_TILES: "false"
|
DYNAMIC_TILES: "false"
|
||||||
DASHBOARD_INBOX_INTERNAL: "true"
|
DASHBOARD_INBOX_INTERNAL: "true"
|
||||||
DEVICE_NAME: "guition-wallbox"
|
DEVICE_NAME: "guition-wallbox"
|
||||||
@@ -3227,19 +3227,22 @@ lvgl:
|
|||||||
was_on: false
|
was_on: false
|
||||||
|
|
||||||
# ---------- VALUE SLIDER OVERLAY ----------
|
# ---------- VALUE SLIDER OVERLAY ----------
|
||||||
|
# ---------- PAGE NAVIGATION: one full-width bar ----------
|
||||||
- obj:
|
- obj:
|
||||||
id: page_prev
|
id: page_prev
|
||||||
align: BOTTOM_LEFT
|
align: BOTTOM_LEFT
|
||||||
x: 14
|
x: 0
|
||||||
y: -4
|
y: 0
|
||||||
width: 150
|
width: 200
|
||||||
height: 44
|
height: 44
|
||||||
pad_all: 0
|
pad_all: 0
|
||||||
radius: 12
|
radius: 0
|
||||||
bg_color: 0xEEEEEE
|
bg_opa: TRANSP
|
||||||
bg_opa: COVER
|
|
||||||
border_width: 0
|
border_width: 0
|
||||||
scrollable: false
|
scrollable: false
|
||||||
|
pressed:
|
||||||
|
bg_color: 0xE3E3E3
|
||||||
|
bg_opa: COVER
|
||||||
on_short_click:
|
on_short_click:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
@@ -3249,31 +3252,39 @@ lvgl:
|
|||||||
- script.execute: show_tile_page
|
- script.execute: show_tile_page
|
||||||
widgets:
|
widgets:
|
||||||
- label:
|
- label:
|
||||||
align: CENTER
|
align: LEFT_MID
|
||||||
text: "< Vorige"
|
x: 24
|
||||||
text_font: sublabel
|
text: "< Vorige"
|
||||||
|
text_font: label
|
||||||
text_color: 0x1B1B1B
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- label:
|
- label:
|
||||||
id: page_number
|
id: page_number
|
||||||
align: BOTTOM_MID
|
align: BOTTOM_MID
|
||||||
y: -18
|
y: 0
|
||||||
|
width: 80
|
||||||
|
height: 44
|
||||||
|
pad_top: 12
|
||||||
|
border_width: 0
|
||||||
text: "1 / 2"
|
text: "1 / 2"
|
||||||
|
text_align: CENTER
|
||||||
text_font: sublabel
|
text_font: sublabel
|
||||||
text_color: 0x1B1B1B
|
text_color: 0x1B1B1B
|
||||||
- obj:
|
- obj:
|
||||||
id: page_next
|
id: page_next
|
||||||
align: BOTTOM_RIGHT
|
align: BOTTOM_RIGHT
|
||||||
x: -14
|
x: 0
|
||||||
y: -4
|
y: 0
|
||||||
width: 150
|
width: 200
|
||||||
height: 44
|
height: 44
|
||||||
pad_all: 0
|
pad_all: 0
|
||||||
radius: 12
|
radius: 0
|
||||||
bg_color: 0xEEEEEE
|
bg_opa: TRANSP
|
||||||
bg_opa: COVER
|
|
||||||
border_width: 0
|
border_width: 0
|
||||||
scrollable: false
|
scrollable: false
|
||||||
|
pressed:
|
||||||
|
bg_color: 0xE3E3E3
|
||||||
|
bg_opa: COVER
|
||||||
on_short_click:
|
on_short_click:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
@@ -3283,9 +3294,10 @@ lvgl:
|
|||||||
- script.execute: show_tile_page
|
- script.execute: show_tile_page
|
||||||
widgets:
|
widgets:
|
||||||
- label:
|
- label:
|
||||||
align: CENTER
|
align: RIGHT_MID
|
||||||
text: "Volgende >"
|
x: -24
|
||||||
text_font: sublabel
|
text: "Volgende >"
|
||||||
|
text_font: label
|
||||||
text_color: 0x1B1B1B
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
|
|||||||
+120
-103
@@ -58,7 +58,7 @@
|
|||||||
############################################################
|
############################################################
|
||||||
|
|
||||||
substitutions:
|
substitutions:
|
||||||
SCREEN_FIRMWARE_VERSION: "0.2.14"
|
SCREEN_FIRMWARE_VERSION: "0.2.15"
|
||||||
DYNAMIC_TILES: "false"
|
DYNAMIC_TILES: "false"
|
||||||
DASHBOARD_INBOX_INTERNAL: "true"
|
DASHBOARD_INBOX_INTERNAL: "true"
|
||||||
DEVICE_NAME: "cyd-new"
|
DEVICE_NAME: "cyd-new"
|
||||||
@@ -643,8 +643,8 @@ substitutions:
|
|||||||
OVERLAY_SLIDER_W: "96"
|
OVERLAY_SLIDER_W: "96"
|
||||||
OVERLAY_SLIDER_H: "160"
|
OVERLAY_SLIDER_H: "160"
|
||||||
OVERLAY_ICON_Y: "74"
|
OVERLAY_ICON_Y: "74"
|
||||||
BG_TOP_COLOR: "0xAEC4D9" # achtergrond boven (zacht blauw)
|
BG_TOP_COLOR: "0xE7E7E7" # lichte achtergrond, gelijk aan de Guition
|
||||||
BG_BOTTOM_COLOR: "0xD6BB9E" # achtergrond onder (warm zand)
|
BG_BOTTOM_COLOR: "0xE7E7E7"
|
||||||
TILE_ICON_X: "0"
|
TILE_ICON_X: "0"
|
||||||
TILE_ICON_Y: "0"
|
TILE_ICON_Y: "0"
|
||||||
TILE_TITLE_X: "48"
|
TILE_TITLE_X: "48"
|
||||||
@@ -809,6 +809,7 @@ esphome:
|
|||||||
settings.night_start = atoi("${NIGHT_START_HOUR}") * 60;
|
settings.night_start = atoi("${NIGHT_START_HOUR}") * 60;
|
||||||
settings.night_end = atoi("${NIGHT_END_HOUR}") * 60;
|
settings.night_end = atoi("${NIGHT_END_HOUR}") * 60;
|
||||||
settings.night_brightness = atoi("${NIGHT_DIM_BRIGHTNESS}");
|
settings.night_brightness = atoi("${NIGHT_DIM_BRIGHTNESS}");
|
||||||
|
runtime_tiles::light_theme = true;
|
||||||
runtime_tiles::watch_font = id(headline)->get_lv_font();
|
runtime_tiles::watch_font = id(headline)->get_lv_font();
|
||||||
runtime_tiles::watch_value_font = id(watch_value)->get_lv_font();
|
runtime_tiles::watch_value_font = id(watch_value)->get_lv_font();
|
||||||
runtime_tiles::watch_icon_font = id(watch_icon)->get_lv_font();
|
runtime_tiles::watch_icon_font = id(watch_icon)->get_lv_font();
|
||||||
@@ -898,7 +899,7 @@ esphome:
|
|||||||
- lambda: |-
|
- lambda: |-
|
||||||
static const char *entities[] = {"${TILE1_ENTITY}", "${TILE2_ENTITY}", "${TILE3_ENTITY}", "${TILE4_ENTITY}", "${TILE5_ENTITY}", "${TILE6_ENTITY}", "${TILE7_ENTITY}", "${TILE9_ENTITY}"};
|
static const char *entities[] = {"${TILE1_ENTITY}", "${TILE2_ENTITY}", "${TILE3_ENTITY}", "${TILE4_ENTITY}", "${TILE5_ENTITY}", "${TILE6_ENTITY}", "${TILE7_ENTITY}", "${TILE9_ENTITY}"};
|
||||||
if (!runtime_tiles::enabled) light_controls::subscribe(entities, 8);
|
if (!runtime_tiles::enabled) light_controls::subscribe(entities, 8);
|
||||||
light_controls::setup(id(color_detail_overlay), id(sublabel)->get_lv_font(), atoi("${DISPLAY_W}"), atoi("${DISPLAY_H}"));
|
light_controls::setup(id(color_detail_overlay), id(sublabel)->get_lv_font(), atoi("${DISPLAY_W}"), atoi("${DISPLAY_H}"), true);
|
||||||
light_controls::commits[0] = [](int value) { id(set_light_hue).execute(value); };
|
light_controls::commits[0] = [](int value) { id(set_light_hue).execute(value); };
|
||||||
light_controls::commits[1] = [](int value) { id(set_light_color_temperature).execute(value); };
|
light_controls::commits[1] = [](int value) { id(set_light_color_temperature).execute(value); };
|
||||||
light_controls::commits[2] = [](int value) { id(color_brightness_commit).execute(value); };
|
light_controls::commits[2] = [](int value) { id(color_brightness_commit).execute(value); };
|
||||||
@@ -2059,7 +2060,9 @@ lvgl:
|
|||||||
bg_color: 0xFFFFFF
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
radius: 18
|
radius: 18
|
||||||
border_width: 0
|
border_width: 1
|
||||||
|
border_color: 0xDDDDDD
|
||||||
|
border_opa: COVER
|
||||||
pad_left: 8
|
pad_left: 8
|
||||||
pad_right: 8
|
pad_right: 8
|
||||||
pad_top: 8
|
pad_top: 8
|
||||||
@@ -2068,10 +2071,12 @@ lvgl:
|
|||||||
shadow_opa: 40%
|
shadow_opa: 40%
|
||||||
|
|
||||||
- id: style_tile_disabled
|
- id: style_tile_disabled
|
||||||
bg_color: 0x939391
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
radius: 18
|
radius: 18
|
||||||
border_width: 0
|
border_width: 1
|
||||||
|
border_color: 0xDDDDDD
|
||||||
|
border_opa: COVER
|
||||||
pad_left: 8
|
pad_left: 8
|
||||||
pad_right: 8
|
pad_right: 8
|
||||||
pad_top: 8
|
pad_top: 8
|
||||||
@@ -2080,25 +2085,25 @@ lvgl:
|
|||||||
shadow_opa: 25%
|
shadow_opa: 25%
|
||||||
|
|
||||||
- id: style_icon_circle
|
- id: style_icon_circle
|
||||||
bg_color: 0xFEC600
|
bg_color: 0xD5EEFC
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
radius: 999
|
radius: 999
|
||||||
border_width: 0
|
border_width: 0
|
||||||
|
|
||||||
- id: style_icon_circle_disabled
|
- id: style_icon_circle_disabled
|
||||||
bg_color: 0x7B7B6F
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
radius: 999
|
radius: 999
|
||||||
border_width: 0
|
border_width: 0
|
||||||
|
|
||||||
- id: style_room
|
- id: style_room
|
||||||
text_font: headline
|
text_font: headline
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 100%
|
text_opa: 100%
|
||||||
|
|
||||||
- id: style_time
|
- id: style_time
|
||||||
text_font: time_label
|
text_font: time_label
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 100%
|
text_opa: 100%
|
||||||
|
|
||||||
- id: style_title
|
- id: style_title
|
||||||
@@ -2113,17 +2118,17 @@ lvgl:
|
|||||||
|
|
||||||
- id: style_value_big
|
- id: style_value_big
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 80%
|
text_opa: 80%
|
||||||
|
|
||||||
- id: style_title_disabled
|
- id: style_title_disabled
|
||||||
text_font: label
|
text_font: label
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 100%
|
text_opa: 100%
|
||||||
|
|
||||||
- id: style_value_disabled
|
- id: style_value_disabled
|
||||||
text_font: sublabel
|
text_font: sublabel
|
||||||
text_color: 0xD9D9D9
|
text_color: 0x1B1B1B
|
||||||
text_opa: 100%
|
text_opa: 100%
|
||||||
|
|
||||||
pages:
|
pages:
|
||||||
@@ -3364,19 +3369,22 @@ lvgl:
|
|||||||
was_on: false
|
was_on: false
|
||||||
|
|
||||||
# ---------- VALUE SLIDER OVERLAY ----------
|
# ---------- VALUE SLIDER OVERLAY ----------
|
||||||
|
# ---------- PAGE NAVIGATION: one full-width bar ----------
|
||||||
- obj:
|
- obj:
|
||||||
id: page_prev
|
id: page_prev
|
||||||
align: BOTTOM_LEFT
|
align: BOTTOM_LEFT
|
||||||
x: 9
|
x: 0
|
||||||
y: -2
|
y: 0
|
||||||
width: 100
|
width: 130
|
||||||
height: 32
|
height: 32
|
||||||
pad_all: 0
|
pad_all: 0
|
||||||
radius: 8
|
radius: 0
|
||||||
bg_color: 0x3C3C40
|
bg_opa: TRANSP
|
||||||
bg_opa: COVER
|
|
||||||
border_width: 0
|
border_width: 0
|
||||||
scrollable: false
|
scrollable: false
|
||||||
|
pressed:
|
||||||
|
bg_color: 0xE3E3E3
|
||||||
|
bg_opa: COVER
|
||||||
on_short_click:
|
on_short_click:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
@@ -3386,31 +3394,39 @@ lvgl:
|
|||||||
- script.execute: show_tile_page
|
- script.execute: show_tile_page
|
||||||
widgets:
|
widgets:
|
||||||
- label:
|
- label:
|
||||||
align: CENTER
|
align: LEFT_MID
|
||||||
text: "< Vorige"
|
x: 12
|
||||||
text_font: sublabel
|
text: "< Vorige"
|
||||||
text_color: 0xFFFFFF
|
text_font: label
|
||||||
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- label:
|
- label:
|
||||||
id: page_number
|
id: page_number
|
||||||
align: BOTTOM_MID
|
align: BOTTOM_MID
|
||||||
y: -9
|
y: 0
|
||||||
|
width: 60
|
||||||
|
height: 32
|
||||||
|
pad_top: 9
|
||||||
|
border_width: 0
|
||||||
text: "1 / 2"
|
text: "1 / 2"
|
||||||
|
text_align: CENTER
|
||||||
text_font: sublabel
|
text_font: sublabel
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
- obj:
|
- obj:
|
||||||
id: page_next
|
id: page_next
|
||||||
align: BOTTOM_RIGHT
|
align: BOTTOM_RIGHT
|
||||||
x: -9
|
x: 0
|
||||||
y: -2
|
y: 0
|
||||||
width: 100
|
width: 130
|
||||||
height: 32
|
height: 32
|
||||||
pad_all: 0
|
pad_all: 0
|
||||||
radius: 8
|
radius: 0
|
||||||
bg_color: 0x3C3C40
|
bg_opa: TRANSP
|
||||||
bg_opa: COVER
|
|
||||||
border_width: 0
|
border_width: 0
|
||||||
scrollable: false
|
scrollable: false
|
||||||
|
pressed:
|
||||||
|
bg_color: 0xE3E3E3
|
||||||
|
bg_opa: COVER
|
||||||
on_short_click:
|
on_short_click:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
@@ -3420,10 +3436,11 @@ lvgl:
|
|||||||
- script.execute: show_tile_page
|
- script.execute: show_tile_page
|
||||||
widgets:
|
widgets:
|
||||||
- label:
|
- label:
|
||||||
align: CENTER
|
align: RIGHT_MID
|
||||||
text: "Volgende >"
|
x: -12
|
||||||
text_font: sublabel
|
text: "Volgende >"
|
||||||
text_color: 0xFFFFFF
|
text_font: label
|
||||||
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -3460,7 +3477,7 @@ lvgl:
|
|||||||
y: 0
|
y: 0
|
||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
bg_color: 0x000000
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 18%
|
bg_opa: 18%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: false
|
clickable: false
|
||||||
@@ -3491,7 +3508,7 @@ lvgl:
|
|||||||
value: 100
|
value: 100
|
||||||
adv_hittest: false
|
adv_hittest: false
|
||||||
|
|
||||||
bg_color: 0x939391
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 100%
|
bg_opa: 100%
|
||||||
radius: 28
|
radius: 28
|
||||||
# Enige widget met ZOWEL radius ALS een kind (overlay_icon).
|
# Enige widget met ZOWEL radius ALS een kind (overlay_icon).
|
||||||
@@ -3504,7 +3521,7 @@ lvgl:
|
|||||||
border_width: 0
|
border_width: 0
|
||||||
|
|
||||||
indicator:
|
indicator:
|
||||||
bg_color: 0xFEC600
|
bg_color: 0xD5EEFC
|
||||||
bg_opa: 100%
|
bg_opa: 100%
|
||||||
radius: 28
|
radius: 28
|
||||||
|
|
||||||
@@ -3536,7 +3553,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
y: ${OVERLAY_ICON_Y}
|
y: ${OVERLAY_ICON_Y}
|
||||||
text_font: materialdesign_icons
|
text_font: materialdesign_icons
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text: "${TILE1_ICON}"
|
text: "${TILE1_ICON}"
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
@@ -3745,7 +3762,7 @@ lvgl:
|
|||||||
y: 0
|
y: 0
|
||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
bg_color: 0x171719
|
bg_color: 0xF7F7F7
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
hidden: true
|
hidden: true
|
||||||
scrollable: false
|
scrollable: false
|
||||||
@@ -3771,7 +3788,7 @@ lvgl:
|
|||||||
y: 0
|
y: 0
|
||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
bg_color: 0x000000
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 72%
|
bg_opa: 72%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: false
|
clickable: false
|
||||||
@@ -3785,7 +3802,7 @@ lvgl:
|
|||||||
width: 36
|
width: 36
|
||||||
height: 36
|
height: 36
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -3799,7 +3816,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "x"
|
text: "x"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- label:
|
- label:
|
||||||
@@ -3832,7 +3849,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "\U000F012C"
|
text: "\U000F012C"
|
||||||
text_font: materialdesign_icons
|
text_font: materialdesign_icons
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
# ---------- CLIMATE DETAIL OVERLAY ----------
|
# ---------- CLIMATE DETAIL OVERLAY ----------
|
||||||
@@ -3842,7 +3859,7 @@ lvgl:
|
|||||||
y: 0
|
y: 0
|
||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
bg_color: 0x171719
|
bg_color: 0xF7F7F7
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
hidden: true
|
hidden: true
|
||||||
scrollable: false
|
scrollable: false
|
||||||
@@ -3868,7 +3885,7 @@ lvgl:
|
|||||||
y: 0
|
y: 0
|
||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
bg_color: 0x000000
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 62%
|
bg_opa: 62%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: false
|
clickable: false
|
||||||
@@ -3884,7 +3901,7 @@ lvgl:
|
|||||||
width: 44
|
width: 44
|
||||||
height: 44
|
height: 44
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -3898,7 +3915,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "x"
|
text: "x"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -3909,7 +3926,7 @@ lvgl:
|
|||||||
width: 44
|
width: 44
|
||||||
height: 44
|
height: 44
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0xFEC600
|
bg_color: 0xD5EEFC
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -3921,7 +3938,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "\U000F012C"
|
text: "\U000F012C"
|
||||||
text_font: materialdesign_icons
|
text_font: materialdesign_icons
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- label:
|
- label:
|
||||||
@@ -3937,7 +3954,7 @@ lvgl:
|
|||||||
y: 42
|
y: 42
|
||||||
text: "Current: --"
|
text: "Current: --"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xD1E8FF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 85%
|
text_opa: 85%
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
@@ -3988,7 +4005,7 @@ lvgl:
|
|||||||
y: -16
|
y: -16
|
||||||
text: "SET TO"
|
text: "SET TO"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 68%
|
text_opa: 68%
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
@@ -3998,7 +4015,7 @@ lvgl:
|
|||||||
y: 20
|
y: 20
|
||||||
text: "20.0°"
|
text: "20.0°"
|
||||||
text_font: headline
|
text_font: headline
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4009,7 +4026,7 @@ lvgl:
|
|||||||
width: 48
|
width: 48
|
||||||
height: 36
|
height: 36
|
||||||
radius: 18
|
radius: 18
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -4025,7 +4042,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "-"
|
text: "-"
|
||||||
text_font: headline
|
text_font: headline
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4036,7 +4053,7 @@ lvgl:
|
|||||||
width: 48
|
width: 48
|
||||||
height: 36
|
height: 36
|
||||||
radius: 18
|
radius: 18
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -4052,7 +4069,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "+"
|
text: "+"
|
||||||
text_font: headline
|
text_font: headline
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4062,7 +4079,7 @@ lvgl:
|
|||||||
width: 126
|
width: 126
|
||||||
height: 34
|
height: 34
|
||||||
radius: 17
|
radius: 17
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 82%
|
bg_opa: 82%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4075,7 +4092,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Auto"
|
text: "Auto"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
# ---------- CLIMATE MODE PICKER ----------
|
# ---------- CLIMATE MODE PICKER ----------
|
||||||
# Vervangt het doorcyclen van modi. Cyclen stuurt bij elke tik een
|
# Vervangt het doorcyclen van modi. Cyclen stuurt bij elke tik een
|
||||||
@@ -4089,7 +4106,7 @@ lvgl:
|
|||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
hidden: true
|
hidden: true
|
||||||
bg_color: 0x000000
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 90%
|
bg_opa: 90%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4101,7 +4118,7 @@ lvgl:
|
|||||||
y: 16
|
y: 16
|
||||||
text: "Mode"
|
text: "Mode"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
# Flex zorgt dat niet-ondersteunde modi geen gat achterlaten:
|
# Flex zorgt dat niet-ondersteunde modi geen gat achterlaten:
|
||||||
@@ -4128,7 +4145,7 @@ lvgl:
|
|||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4141,14 +4158,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Off"
|
text: "Off"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_heat
|
id: cmode_heat
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4161,14 +4178,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Heat"
|
text: "Heat"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_cool
|
id: cmode_cool
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4181,14 +4198,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Cool"
|
text: "Cool"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_heat_cool
|
id: cmode_heat_cool
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4201,14 +4218,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Heat/Cool"
|
text: "Heat/Cool"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_auto
|
id: cmode_auto
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4221,14 +4238,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Auto"
|
text: "Auto"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_dry
|
id: cmode_dry
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4241,14 +4258,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Dry"
|
text: "Dry"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_fan_only
|
id: cmode_fan_only
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4261,7 +4278,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Fan"
|
text: "Fan"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4272,7 +4289,7 @@ lvgl:
|
|||||||
width: 36
|
width: 36
|
||||||
height: 36
|
height: 36
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -4286,7 +4303,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "x"
|
text: "x"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4297,7 +4314,7 @@ lvgl:
|
|||||||
width: 36
|
width: 36
|
||||||
height: 36
|
height: 36
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0xFEC600
|
bg_color: 0xD5EEFC
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4309,7 +4326,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "\U000F012C"
|
text: "\U000F012C"
|
||||||
text_font: materialdesign_icons
|
text_font: materialdesign_icons
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
# ---------- VACUUM CONTROL ----------
|
# ---------- VACUUM CONTROL ----------
|
||||||
@@ -4322,7 +4339,7 @@ lvgl:
|
|||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
hidden: true
|
hidden: true
|
||||||
bg_color: 0x000000
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 90%
|
bg_opa: 90%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4335,7 +4352,7 @@ lvgl:
|
|||||||
y: 16
|
y: 16
|
||||||
text: "Vacuum"
|
text: "Vacuum"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4360,7 +4377,7 @@ lvgl:
|
|||||||
width: 72
|
width: 72
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4373,14 +4390,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Start"
|
text: "Start"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vac_pause
|
id: vac_pause
|
||||||
width: 72
|
width: 72
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4393,14 +4410,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Pause"
|
text: "Pause"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vac_return_to_base
|
id: vac_return_to_base
|
||||||
width: 72
|
width: 72
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4413,14 +4430,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Dock"
|
text: "Dock"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vac_stop
|
id: vac_stop
|
||||||
width: 72
|
width: 72
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4433,7 +4450,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Stop"
|
text: "Stop"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- label:
|
- label:
|
||||||
@@ -4441,7 +4458,7 @@ lvgl:
|
|||||||
y: 138
|
y: 138
|
||||||
text: "Suction"
|
text: "Suction"
|
||||||
text_font: sublabel
|
text_font: sublabel
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4466,7 +4483,7 @@ lvgl:
|
|||||||
width: 72
|
width: 72
|
||||||
height: 32
|
height: 32
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x1F1F23
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4481,14 +4498,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Quiet"
|
text: "Quiet"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vacspd_balanced
|
id: vacspd_balanced
|
||||||
width: 72
|
width: 72
|
||||||
height: 32
|
height: 32
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x1F1F23
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4503,14 +4520,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Balanced"
|
text: "Balanced"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vacspd_turbo
|
id: vacspd_turbo
|
||||||
width: 72
|
width: 72
|
||||||
height: 32
|
height: 32
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x1F1F23
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4525,14 +4542,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Turbo"
|
text: "Turbo"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vacspd_max
|
id: vacspd_max
|
||||||
width: 72
|
width: 72
|
||||||
height: 32
|
height: 32
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x1F1F23
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4547,7 +4564,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Max"
|
text: "Max"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4558,7 +4575,7 @@ lvgl:
|
|||||||
width: 36
|
width: 36
|
||||||
height: 36
|
height: 36
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -4572,7 +4589,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "x"
|
text: "x"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4583,7 +4600,7 @@ lvgl:
|
|||||||
width: 36
|
width: 36
|
||||||
height: 36
|
height: 36
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0xFEC600
|
bg_color: 0xD5EEFC
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4595,7 +4612,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "\U000F012C"
|
text: "\U000F012C"
|
||||||
text_font: materialdesign_icons
|
text_font: materialdesign_icons
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
# ---------- DIM / WAKE OVERLAY ----------
|
# ---------- DIM / WAKE OVERLAY ----------
|
||||||
|
|||||||
+120
-103
@@ -59,7 +59,7 @@
|
|||||||
############################################################
|
############################################################
|
||||||
|
|
||||||
substitutions:
|
substitutions:
|
||||||
SCREEN_FIRMWARE_VERSION: "0.2.14"
|
SCREEN_FIRMWARE_VERSION: "0.2.15"
|
||||||
DYNAMIC_TILES: "true"
|
DYNAMIC_TILES: "true"
|
||||||
DASHBOARD_INBOX_INTERNAL: "false"
|
DASHBOARD_INBOX_INTERNAL: "false"
|
||||||
DEVICE_NAME: "cyd-new"
|
DEVICE_NAME: "cyd-new"
|
||||||
@@ -644,8 +644,8 @@ substitutions:
|
|||||||
OVERLAY_SLIDER_W: "96"
|
OVERLAY_SLIDER_W: "96"
|
||||||
OVERLAY_SLIDER_H: "160"
|
OVERLAY_SLIDER_H: "160"
|
||||||
OVERLAY_ICON_Y: "74"
|
OVERLAY_ICON_Y: "74"
|
||||||
BG_TOP_COLOR: "0xAEC4D9" # achtergrond boven (zacht blauw)
|
BG_TOP_COLOR: "0xE7E7E7" # lichte achtergrond, gelijk aan de Guition
|
||||||
BG_BOTTOM_COLOR: "0xD6BB9E" # achtergrond onder (warm zand)
|
BG_BOTTOM_COLOR: "0xE7E7E7"
|
||||||
TILE_ICON_X: "0"
|
TILE_ICON_X: "0"
|
||||||
TILE_ICON_Y: "0"
|
TILE_ICON_Y: "0"
|
||||||
TILE_TITLE_X: "48"
|
TILE_TITLE_X: "48"
|
||||||
@@ -813,6 +813,7 @@ esphome:
|
|||||||
settings.night_start = atoi("${NIGHT_START_HOUR}") * 60;
|
settings.night_start = atoi("${NIGHT_START_HOUR}") * 60;
|
||||||
settings.night_end = atoi("${NIGHT_END_HOUR}") * 60;
|
settings.night_end = atoi("${NIGHT_END_HOUR}") * 60;
|
||||||
settings.night_brightness = atoi("${NIGHT_DIM_BRIGHTNESS}");
|
settings.night_brightness = atoi("${NIGHT_DIM_BRIGHTNESS}");
|
||||||
|
runtime_tiles::light_theme = true;
|
||||||
runtime_tiles::watch_font = id(headline)->get_lv_font();
|
runtime_tiles::watch_font = id(headline)->get_lv_font();
|
||||||
runtime_tiles::watch_value_font = id(watch_value)->get_lv_font();
|
runtime_tiles::watch_value_font = id(watch_value)->get_lv_font();
|
||||||
runtime_tiles::watch_icon_font = id(watch_icon)->get_lv_font();
|
runtime_tiles::watch_icon_font = id(watch_icon)->get_lv_font();
|
||||||
@@ -902,7 +903,7 @@ esphome:
|
|||||||
- lambda: |-
|
- lambda: |-
|
||||||
static const char *entities[] = {"${TILE1_ENTITY}", "${TILE2_ENTITY}", "${TILE3_ENTITY}", "${TILE4_ENTITY}", "${TILE5_ENTITY}", "${TILE6_ENTITY}", "${TILE7_ENTITY}", "${TILE9_ENTITY}"};
|
static const char *entities[] = {"${TILE1_ENTITY}", "${TILE2_ENTITY}", "${TILE3_ENTITY}", "${TILE4_ENTITY}", "${TILE5_ENTITY}", "${TILE6_ENTITY}", "${TILE7_ENTITY}", "${TILE9_ENTITY}"};
|
||||||
if (!runtime_tiles::enabled) light_controls::subscribe(entities, 8);
|
if (!runtime_tiles::enabled) light_controls::subscribe(entities, 8);
|
||||||
light_controls::setup(id(color_detail_overlay), id(sublabel)->get_lv_font(), atoi("${DISPLAY_W}"), atoi("${DISPLAY_H}"));
|
light_controls::setup(id(color_detail_overlay), id(sublabel)->get_lv_font(), atoi("${DISPLAY_W}"), atoi("${DISPLAY_H}"), true);
|
||||||
light_controls::commits[0] = [](int value) { id(set_light_hue).execute(value); };
|
light_controls::commits[0] = [](int value) { id(set_light_hue).execute(value); };
|
||||||
light_controls::commits[1] = [](int value) { id(set_light_color_temperature).execute(value); };
|
light_controls::commits[1] = [](int value) { id(set_light_color_temperature).execute(value); };
|
||||||
light_controls::commits[2] = [](int value) { id(color_brightness_commit).execute(value); };
|
light_controls::commits[2] = [](int value) { id(color_brightness_commit).execute(value); };
|
||||||
@@ -1992,7 +1993,9 @@ lvgl:
|
|||||||
bg_color: 0xFFFFFF
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
radius: 18
|
radius: 18
|
||||||
border_width: 0
|
border_width: 1
|
||||||
|
border_color: 0xDDDDDD
|
||||||
|
border_opa: COVER
|
||||||
pad_left: 8
|
pad_left: 8
|
||||||
pad_right: 8
|
pad_right: 8
|
||||||
pad_top: 8
|
pad_top: 8
|
||||||
@@ -2001,10 +2004,12 @@ lvgl:
|
|||||||
shadow_opa: 40%
|
shadow_opa: 40%
|
||||||
|
|
||||||
- id: style_tile_disabled
|
- id: style_tile_disabled
|
||||||
bg_color: 0x939391
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
radius: 18
|
radius: 18
|
||||||
border_width: 0
|
border_width: 1
|
||||||
|
border_color: 0xDDDDDD
|
||||||
|
border_opa: COVER
|
||||||
pad_left: 8
|
pad_left: 8
|
||||||
pad_right: 8
|
pad_right: 8
|
||||||
pad_top: 8
|
pad_top: 8
|
||||||
@@ -2013,25 +2018,25 @@ lvgl:
|
|||||||
shadow_opa: 25%
|
shadow_opa: 25%
|
||||||
|
|
||||||
- id: style_icon_circle
|
- id: style_icon_circle
|
||||||
bg_color: 0xFEC600
|
bg_color: 0xD5EEFC
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
radius: 999
|
radius: 999
|
||||||
border_width: 0
|
border_width: 0
|
||||||
|
|
||||||
- id: style_icon_circle_disabled
|
- id: style_icon_circle_disabled
|
||||||
bg_color: 0x7B7B6F
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
radius: 999
|
radius: 999
|
||||||
border_width: 0
|
border_width: 0
|
||||||
|
|
||||||
- id: style_room
|
- id: style_room
|
||||||
text_font: headline
|
text_font: headline
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 100%
|
text_opa: 100%
|
||||||
|
|
||||||
- id: style_time
|
- id: style_time
|
||||||
text_font: time_label
|
text_font: time_label
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 100%
|
text_opa: 100%
|
||||||
|
|
||||||
- id: style_title
|
- id: style_title
|
||||||
@@ -2046,17 +2051,17 @@ lvgl:
|
|||||||
|
|
||||||
- id: style_value_big
|
- id: style_value_big
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 80%
|
text_opa: 80%
|
||||||
|
|
||||||
- id: style_title_disabled
|
- id: style_title_disabled
|
||||||
text_font: label
|
text_font: label
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 100%
|
text_opa: 100%
|
||||||
|
|
||||||
- id: style_value_disabled
|
- id: style_value_disabled
|
||||||
text_font: sublabel
|
text_font: sublabel
|
||||||
text_color: 0xD9D9D9
|
text_color: 0x1B1B1B
|
||||||
text_opa: 100%
|
text_opa: 100%
|
||||||
|
|
||||||
pages:
|
pages:
|
||||||
@@ -3297,19 +3302,22 @@ lvgl:
|
|||||||
was_on: false
|
was_on: false
|
||||||
|
|
||||||
# ---------- VALUE SLIDER OVERLAY ----------
|
# ---------- VALUE SLIDER OVERLAY ----------
|
||||||
|
# ---------- PAGE NAVIGATION: one full-width bar ----------
|
||||||
- obj:
|
- obj:
|
||||||
id: page_prev
|
id: page_prev
|
||||||
align: BOTTOM_LEFT
|
align: BOTTOM_LEFT
|
||||||
x: 9
|
x: 0
|
||||||
y: -2
|
y: 0
|
||||||
width: 100
|
width: 130
|
||||||
height: 32
|
height: 32
|
||||||
pad_all: 0
|
pad_all: 0
|
||||||
radius: 8
|
radius: 0
|
||||||
bg_color: 0x3C3C40
|
bg_opa: TRANSP
|
||||||
bg_opa: COVER
|
|
||||||
border_width: 0
|
border_width: 0
|
||||||
scrollable: false
|
scrollable: false
|
||||||
|
pressed:
|
||||||
|
bg_color: 0xE3E3E3
|
||||||
|
bg_opa: COVER
|
||||||
on_short_click:
|
on_short_click:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
@@ -3319,31 +3327,39 @@ lvgl:
|
|||||||
- script.execute: show_tile_page
|
- script.execute: show_tile_page
|
||||||
widgets:
|
widgets:
|
||||||
- label:
|
- label:
|
||||||
align: CENTER
|
align: LEFT_MID
|
||||||
text: "< Vorige"
|
x: 12
|
||||||
text_font: sublabel
|
text: "< Vorige"
|
||||||
text_color: 0xFFFFFF
|
text_font: label
|
||||||
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- label:
|
- label:
|
||||||
id: page_number
|
id: page_number
|
||||||
align: BOTTOM_MID
|
align: BOTTOM_MID
|
||||||
y: -9
|
y: 0
|
||||||
|
width: 60
|
||||||
|
height: 32
|
||||||
|
pad_top: 9
|
||||||
|
border_width: 0
|
||||||
text: "1 / 2"
|
text: "1 / 2"
|
||||||
|
text_align: CENTER
|
||||||
text_font: sublabel
|
text_font: sublabel
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
- obj:
|
- obj:
|
||||||
id: page_next
|
id: page_next
|
||||||
align: BOTTOM_RIGHT
|
align: BOTTOM_RIGHT
|
||||||
x: -9
|
x: 0
|
||||||
y: -2
|
y: 0
|
||||||
width: 100
|
width: 130
|
||||||
height: 32
|
height: 32
|
||||||
pad_all: 0
|
pad_all: 0
|
||||||
radius: 8
|
radius: 0
|
||||||
bg_color: 0x3C3C40
|
bg_opa: TRANSP
|
||||||
bg_opa: COVER
|
|
||||||
border_width: 0
|
border_width: 0
|
||||||
scrollable: false
|
scrollable: false
|
||||||
|
pressed:
|
||||||
|
bg_color: 0xE3E3E3
|
||||||
|
bg_opa: COVER
|
||||||
on_short_click:
|
on_short_click:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
@@ -3353,10 +3369,11 @@ lvgl:
|
|||||||
- script.execute: show_tile_page
|
- script.execute: show_tile_page
|
||||||
widgets:
|
widgets:
|
||||||
- label:
|
- label:
|
||||||
align: CENTER
|
align: RIGHT_MID
|
||||||
text: "Volgende >"
|
x: -12
|
||||||
text_font: sublabel
|
text: "Volgende >"
|
||||||
text_color: 0xFFFFFF
|
text_font: label
|
||||||
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -3393,7 +3410,7 @@ lvgl:
|
|||||||
y: 0
|
y: 0
|
||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
bg_color: 0x000000
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 18%
|
bg_opa: 18%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: false
|
clickable: false
|
||||||
@@ -3424,7 +3441,7 @@ lvgl:
|
|||||||
value: 100
|
value: 100
|
||||||
adv_hittest: false
|
adv_hittest: false
|
||||||
|
|
||||||
bg_color: 0x939391
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 100%
|
bg_opa: 100%
|
||||||
radius: 28
|
radius: 28
|
||||||
# Enige widget met ZOWEL radius ALS een kind (overlay_icon).
|
# Enige widget met ZOWEL radius ALS een kind (overlay_icon).
|
||||||
@@ -3437,7 +3454,7 @@ lvgl:
|
|||||||
border_width: 0
|
border_width: 0
|
||||||
|
|
||||||
indicator:
|
indicator:
|
||||||
bg_color: 0xFEC600
|
bg_color: 0xD5EEFC
|
||||||
bg_opa: 100%
|
bg_opa: 100%
|
||||||
radius: 28
|
radius: 28
|
||||||
|
|
||||||
@@ -3469,7 +3486,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
y: ${OVERLAY_ICON_Y}
|
y: ${OVERLAY_ICON_Y}
|
||||||
text_font: materialdesign_icons
|
text_font: materialdesign_icons
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text: "${TILE1_ICON}"
|
text: "${TILE1_ICON}"
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
@@ -3678,7 +3695,7 @@ lvgl:
|
|||||||
y: 0
|
y: 0
|
||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
bg_color: 0x171719
|
bg_color: 0xF7F7F7
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
hidden: true
|
hidden: true
|
||||||
scrollable: false
|
scrollable: false
|
||||||
@@ -3704,7 +3721,7 @@ lvgl:
|
|||||||
y: 0
|
y: 0
|
||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
bg_color: 0x000000
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 72%
|
bg_opa: 72%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: false
|
clickable: false
|
||||||
@@ -3718,7 +3735,7 @@ lvgl:
|
|||||||
width: 36
|
width: 36
|
||||||
height: 36
|
height: 36
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -3732,7 +3749,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "x"
|
text: "x"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- label:
|
- label:
|
||||||
@@ -3765,7 +3782,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "\U000F012C"
|
text: "\U000F012C"
|
||||||
text_font: materialdesign_icons
|
text_font: materialdesign_icons
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
# ---------- CLIMATE DETAIL OVERLAY ----------
|
# ---------- CLIMATE DETAIL OVERLAY ----------
|
||||||
@@ -3775,7 +3792,7 @@ lvgl:
|
|||||||
y: 0
|
y: 0
|
||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
bg_color: 0x171719
|
bg_color: 0xF7F7F7
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
hidden: true
|
hidden: true
|
||||||
scrollable: false
|
scrollable: false
|
||||||
@@ -3801,7 +3818,7 @@ lvgl:
|
|||||||
y: 0
|
y: 0
|
||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
bg_color: 0x000000
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 62%
|
bg_opa: 62%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: false
|
clickable: false
|
||||||
@@ -3817,7 +3834,7 @@ lvgl:
|
|||||||
width: 44
|
width: 44
|
||||||
height: 44
|
height: 44
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -3831,7 +3848,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "x"
|
text: "x"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -3842,7 +3859,7 @@ lvgl:
|
|||||||
width: 44
|
width: 44
|
||||||
height: 44
|
height: 44
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0xFEC600
|
bg_color: 0xD5EEFC
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -3854,7 +3871,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "\U000F012C"
|
text: "\U000F012C"
|
||||||
text_font: materialdesign_icons
|
text_font: materialdesign_icons
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- label:
|
- label:
|
||||||
@@ -3870,7 +3887,7 @@ lvgl:
|
|||||||
y: 42
|
y: 42
|
||||||
text: "Current: --"
|
text: "Current: --"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xD1E8FF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 85%
|
text_opa: 85%
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
@@ -3921,7 +3938,7 @@ lvgl:
|
|||||||
y: -16
|
y: -16
|
||||||
text: "SET TO"
|
text: "SET TO"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
text_opa: 68%
|
text_opa: 68%
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
@@ -3931,7 +3948,7 @@ lvgl:
|
|||||||
y: 20
|
y: 20
|
||||||
text: "20.0°"
|
text: "20.0°"
|
||||||
text_font: headline
|
text_font: headline
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -3942,7 +3959,7 @@ lvgl:
|
|||||||
width: 48
|
width: 48
|
||||||
height: 36
|
height: 36
|
||||||
radius: 18
|
radius: 18
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -3958,7 +3975,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "-"
|
text: "-"
|
||||||
text_font: headline
|
text_font: headline
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -3969,7 +3986,7 @@ lvgl:
|
|||||||
width: 48
|
width: 48
|
||||||
height: 36
|
height: 36
|
||||||
radius: 18
|
radius: 18
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -3985,7 +4002,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "+"
|
text: "+"
|
||||||
text_font: headline
|
text_font: headline
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -3995,7 +4012,7 @@ lvgl:
|
|||||||
width: 126
|
width: 126
|
||||||
height: 34
|
height: 34
|
||||||
radius: 17
|
radius: 17
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 82%
|
bg_opa: 82%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4008,7 +4025,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Auto"
|
text: "Auto"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
# ---------- CLIMATE MODE PICKER ----------
|
# ---------- CLIMATE MODE PICKER ----------
|
||||||
# Vervangt het doorcyclen van modi. Cyclen stuurt bij elke tik een
|
# Vervangt het doorcyclen van modi. Cyclen stuurt bij elke tik een
|
||||||
@@ -4022,7 +4039,7 @@ lvgl:
|
|||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
hidden: true
|
hidden: true
|
||||||
bg_color: 0x000000
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 90%
|
bg_opa: 90%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4034,7 +4051,7 @@ lvgl:
|
|||||||
y: 16
|
y: 16
|
||||||
text: "Mode"
|
text: "Mode"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
# Flex zorgt dat niet-ondersteunde modi geen gat achterlaten:
|
# Flex zorgt dat niet-ondersteunde modi geen gat achterlaten:
|
||||||
@@ -4061,7 +4078,7 @@ lvgl:
|
|||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4074,14 +4091,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Off"
|
text: "Off"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_heat
|
id: cmode_heat
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4094,14 +4111,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Heat"
|
text: "Heat"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_cool
|
id: cmode_cool
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4114,14 +4131,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Cool"
|
text: "Cool"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_heat_cool
|
id: cmode_heat_cool
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4134,14 +4151,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Heat/Cool"
|
text: "Heat/Cool"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_auto
|
id: cmode_auto
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4154,14 +4171,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Auto"
|
text: "Auto"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_dry
|
id: cmode_dry
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4174,14 +4191,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Dry"
|
text: "Dry"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: cmode_fan_only
|
id: cmode_fan_only
|
||||||
width: 132
|
width: 132
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4194,7 +4211,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Fan"
|
text: "Fan"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4205,7 +4222,7 @@ lvgl:
|
|||||||
width: 36
|
width: 36
|
||||||
height: 36
|
height: 36
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -4219,7 +4236,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "x"
|
text: "x"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4230,7 +4247,7 @@ lvgl:
|
|||||||
width: 36
|
width: 36
|
||||||
height: 36
|
height: 36
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0xFEC600
|
bg_color: 0xD5EEFC
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4242,7 +4259,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "\U000F012C"
|
text: "\U000F012C"
|
||||||
text_font: materialdesign_icons
|
text_font: materialdesign_icons
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
# ---------- VACUUM CONTROL ----------
|
# ---------- VACUUM CONTROL ----------
|
||||||
@@ -4255,7 +4272,7 @@ lvgl:
|
|||||||
width: ${DISPLAY_W}
|
width: ${DISPLAY_W}
|
||||||
height: ${DISPLAY_H}
|
height: ${DISPLAY_H}
|
||||||
hidden: true
|
hidden: true
|
||||||
bg_color: 0x000000
|
bg_color: 0xFFFFFF
|
||||||
bg_opa: 90%
|
bg_opa: 90%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4268,7 +4285,7 @@ lvgl:
|
|||||||
y: 16
|
y: 16
|
||||||
text: "Vacuum"
|
text: "Vacuum"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4293,7 +4310,7 @@ lvgl:
|
|||||||
width: 72
|
width: 72
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4306,14 +4323,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Start"
|
text: "Start"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vac_pause
|
id: vac_pause
|
||||||
width: 72
|
width: 72
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4326,14 +4343,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Pause"
|
text: "Pause"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vac_return_to_base
|
id: vac_return_to_base
|
||||||
width: 72
|
width: 72
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4346,14 +4363,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Dock"
|
text: "Dock"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vac_stop
|
id: vac_stop
|
||||||
width: 72
|
width: 72
|
||||||
height: 38
|
height: 38
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x2C2C30
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4366,7 +4383,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Stop"
|
text: "Stop"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- label:
|
- label:
|
||||||
@@ -4374,7 +4391,7 @@ lvgl:
|
|||||||
y: 138
|
y: 138
|
||||||
text: "Suction"
|
text: "Suction"
|
||||||
text_font: sublabel
|
text_font: sublabel
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4399,7 +4416,7 @@ lvgl:
|
|||||||
width: 72
|
width: 72
|
||||||
height: 32
|
height: 32
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x1F1F23
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4414,14 +4431,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Quiet"
|
text: "Quiet"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vacspd_balanced
|
id: vacspd_balanced
|
||||||
width: 72
|
width: 72
|
||||||
height: 32
|
height: 32
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x1F1F23
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4436,14 +4453,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Balanced"
|
text: "Balanced"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vacspd_turbo
|
id: vacspd_turbo
|
||||||
width: 72
|
width: 72
|
||||||
height: 32
|
height: 32
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x1F1F23
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4458,14 +4475,14 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Turbo"
|
text: "Turbo"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- obj:
|
- obj:
|
||||||
id: vacspd_max
|
id: vacspd_max
|
||||||
width: 72
|
width: 72
|
||||||
height: 32
|
height: 32
|
||||||
radius: 19
|
radius: 19
|
||||||
bg_color: 0x1F1F23
|
bg_color: 0xF0F0F0
|
||||||
bg_opa: 92%
|
bg_opa: 92%
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4480,7 +4497,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "Max"
|
text: "Max"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4491,7 +4508,7 @@ lvgl:
|
|||||||
width: 36
|
width: 36
|
||||||
height: 36
|
height: 36
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0x3C3C40
|
bg_color: 0xEEEEEE
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 1
|
border_width: 1
|
||||||
border_color: 0xFFFFFF
|
border_color: 0xFFFFFF
|
||||||
@@ -4505,7 +4522,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "x"
|
text: "x"
|
||||||
text_font: sublabel_big
|
text_font: sublabel_big
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
- obj:
|
- obj:
|
||||||
@@ -4516,7 +4533,7 @@ lvgl:
|
|||||||
width: 36
|
width: 36
|
||||||
height: 36
|
height: 36
|
||||||
radius: 999
|
radius: 999
|
||||||
bg_color: 0xFEC600
|
bg_color: 0xD5EEFC
|
||||||
bg_opa: COVER
|
bg_opa: COVER
|
||||||
border_width: 0
|
border_width: 0
|
||||||
clickable: true
|
clickable: true
|
||||||
@@ -4528,7 +4545,7 @@ lvgl:
|
|||||||
align: CENTER
|
align: CENTER
|
||||||
text: "\U000F012C"
|
text: "\U000F012C"
|
||||||
text_font: materialdesign_icons
|
text_font: materialdesign_icons
|
||||||
text_color: 0xFFFFFF
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
# ---------- DIM / WAKE OVERLAY ----------
|
# ---------- DIM / WAKE OVERLAY ----------
|
||||||
|
|||||||
+32
-20
@@ -2,7 +2,7 @@
|
|||||||
# Guition ESP32-S3-4848S040 / 4-inch EU wallbox, 480x480 IPS + GT911.
|
# Guition ESP32-S3-4848S040 / 4-inch EU wallbox, 480x480 IPS + GT911.
|
||||||
# Use guition-device.yaml; see docs/GUITION.md. CYD hardware is a separate profile.
|
# Use guition-device.yaml; see docs/GUITION.md. CYD hardware is a separate profile.
|
||||||
substitutions:
|
substitutions:
|
||||||
SCREEN_FIRMWARE_VERSION: "0.2.14"
|
SCREEN_FIRMWARE_VERSION: "0.2.15"
|
||||||
DYNAMIC_TILES: "true"
|
DYNAMIC_TILES: "true"
|
||||||
DASHBOARD_INBOX_INTERNAL: "false"
|
DASHBOARD_INBOX_INTERNAL: "false"
|
||||||
DEVICE_NAME: "guition-new"
|
DEVICE_NAME: "guition-new"
|
||||||
@@ -3160,19 +3160,22 @@ lvgl:
|
|||||||
was_on: false
|
was_on: false
|
||||||
|
|
||||||
# ---------- VALUE SLIDER OVERLAY ----------
|
# ---------- VALUE SLIDER OVERLAY ----------
|
||||||
|
# ---------- PAGE NAVIGATION: one full-width bar ----------
|
||||||
- obj:
|
- obj:
|
||||||
id: page_prev
|
id: page_prev
|
||||||
align: BOTTOM_LEFT
|
align: BOTTOM_LEFT
|
||||||
x: 14
|
x: 0
|
||||||
y: -4
|
y: 0
|
||||||
width: 150
|
width: 200
|
||||||
height: 44
|
height: 44
|
||||||
pad_all: 0
|
pad_all: 0
|
||||||
radius: 12
|
radius: 0
|
||||||
bg_color: 0xEEEEEE
|
bg_opa: TRANSP
|
||||||
bg_opa: COVER
|
|
||||||
border_width: 0
|
border_width: 0
|
||||||
scrollable: false
|
scrollable: false
|
||||||
|
pressed:
|
||||||
|
bg_color: 0xE3E3E3
|
||||||
|
bg_opa: COVER
|
||||||
on_short_click:
|
on_short_click:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
@@ -3182,31 +3185,39 @@ lvgl:
|
|||||||
- script.execute: show_tile_page
|
- script.execute: show_tile_page
|
||||||
widgets:
|
widgets:
|
||||||
- label:
|
- label:
|
||||||
align: CENTER
|
align: LEFT_MID
|
||||||
text: "< Vorige"
|
x: 24
|
||||||
text_font: sublabel
|
text: "< Vorige"
|
||||||
|
text_font: label
|
||||||
text_color: 0x1B1B1B
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
- label:
|
- label:
|
||||||
id: page_number
|
id: page_number
|
||||||
align: BOTTOM_MID
|
align: BOTTOM_MID
|
||||||
y: -18
|
y: 0
|
||||||
|
width: 80
|
||||||
|
height: 44
|
||||||
|
pad_top: 12
|
||||||
|
border_width: 0
|
||||||
text: "1 / 2"
|
text: "1 / 2"
|
||||||
|
text_align: CENTER
|
||||||
text_font: sublabel
|
text_font: sublabel
|
||||||
text_color: 0x1B1B1B
|
text_color: 0x1B1B1B
|
||||||
- obj:
|
- obj:
|
||||||
id: page_next
|
id: page_next
|
||||||
align: BOTTOM_RIGHT
|
align: BOTTOM_RIGHT
|
||||||
x: -14
|
x: 0
|
||||||
y: -4
|
y: 0
|
||||||
width: 150
|
width: 200
|
||||||
height: 44
|
height: 44
|
||||||
pad_all: 0
|
pad_all: 0
|
||||||
radius: 12
|
radius: 0
|
||||||
bg_color: 0xEEEEEE
|
bg_opa: TRANSP
|
||||||
bg_opa: COVER
|
|
||||||
border_width: 0
|
border_width: 0
|
||||||
scrollable: false
|
scrollable: false
|
||||||
|
pressed:
|
||||||
|
bg_color: 0xE3E3E3
|
||||||
|
bg_opa: COVER
|
||||||
on_short_click:
|
on_short_click:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
@@ -3216,9 +3227,10 @@ lvgl:
|
|||||||
- script.execute: show_tile_page
|
- script.execute: show_tile_page
|
||||||
widgets:
|
widgets:
|
||||||
- label:
|
- label:
|
||||||
align: CENTER
|
align: RIGHT_MID
|
||||||
text: "Volgende >"
|
x: -24
|
||||||
text_font: sublabel
|
text: "Volgende >"
|
||||||
|
text_font: label
|
||||||
text_color: 0x1B1B1B
|
text_color: 0x1B1B1B
|
||||||
clickable: false
|
clickable: false
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
## 0.2.13 (firmware 0.2.15)
|
||||||
|
|
||||||
|
- Editor: sleep tegels in de schermmockup om te ordenen en sleep entiteiten rechtstreeks uit de lijst naar een plek in de mockup — met muis én touch (even vasthouden). De opslaan-balk blijft altijd in beeld.
|
||||||
|
- Nieuwe kop met duidelijke acties (**Nieuw scherm**, **Firmware & USB**, **Uitleg**) en een korte uitleg in drie stappen; de firmwaredialoog legt profiel, doel en knoppen uit.
|
||||||
|
- **Zonnebaan**: `sun.sun` toont dubbelbreed een horizon met de zon op zijn huidige positie tussen opkomst en ondergang (’s nachts onder de horizon), met beide tijden. Nieuwe zon-, weer- en kloktegels starten meteen dubbelbreed in hun mooiste weergave.
|
||||||
|
- Grafiek: vloeiende curve door dezelfde 24 punten met een zachte vulling eronder, zoals de HA-trendkaart.
|
||||||
|
- Scherm: de paginering is één geïntegreerde onderbalk — links tikken is vorige, rechts is volgende, het paginanummer staat in het midden.
|
||||||
|
- Scherm: bij een paginawissel verschijnen direct de kaartkaders van de nieuwe pagina (skeleton) en vult de inhoud een fractie later; geen oude waarden meer in nieuwe kaders.
|
||||||
|
- CYD: hetzelfde lichte kleurenschema als de Guition — lichtgrijze achtergrond, witte kaarten met een fijne rand, donkere tekst en lichtblauwe accenten, ook in de bedieningskaarten.
|
||||||
|
|
||||||
## 0.2.12 (firmware 0.2.14)
|
## 0.2.12 (firmware 0.2.14)
|
||||||
|
|
||||||
- Nieuwe kaarten in de kiezer: **Klok** (digitaal of analoog, ingebouwd), **weersvoorspelling** met vijf dagen op een dubbelbrede weerkaart, **grafiek** van de sensorgeschiedenis in de tegel, **zon** (`sun.sun`, opkomst en ondergang in je eigen tijdzone), **kookwekker** (`timer.*`, live aftellen; tikken start of pauzeert, lang indrukken annuleert) en **aanwezigheid** (`person.*`).
|
- Nieuwe kaarten in de kiezer: **Klok** (digitaal of analoog, ingebouwd), **weersvoorspelling** met vijf dagen op een dubbelbrede weerkaart, **grafiek** van de sensorgeschiedenis in de tegel, **zon** (`sun.sun`, opkomst en ondergang in je eigen tijdzone), **kookwekker** (`timer.*`, live aftellen; tikken start of pauzeert, lang indrukken annuleert) en **aanwezigheid** (`person.*`).
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ TILE_BACKGROUNDS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Display modes per domain; everything else offers standard and watch (large value).
|
# Display modes per domain; everything else offers standard and watch (large value).
|
||||||
DISPLAYS = {'weather': ('standard', 'watch', 'forecast'), 'sensor': ('standard', 'watch', 'graph'), 'screen': ('digital', 'analog')}
|
DISPLAYS = {'weather': ('standard', 'watch', 'forecast'), 'sensor': ('standard', 'watch', 'graph'), 'screen': ('digital', 'analog'), 'sun': ('standard', 'watch', 'sunpath')}
|
||||||
|
# Displays that only work on a double-width card.
|
||||||
|
WIDE_ONLY = ('forecast', 'sunpath')
|
||||||
|
|
||||||
# Additive schema 1 extension. An absent object retains old firmware/YAML defaults.
|
# Additive schema 1 extension. An absent object retains old firmware/YAML defaults.
|
||||||
SETTING_RULES = {
|
SETTING_RULES = {
|
||||||
@@ -114,8 +116,8 @@ def validate_layout(data):
|
|||||||
for key, allowed in choices.items():
|
for key, allowed in choices.items():
|
||||||
if key in options and options[key] not in allowed:
|
if key in options and options[key] not in allowed:
|
||||||
raise ValueError('Ongeldige tegelinstelling: ' + key)
|
raise ValueError('Ongeldige tegelinstelling: ' + key)
|
||||||
# The five-day strip only fits a double-width card.
|
# The five-day strip and the sun path only fit a double-width card.
|
||||||
if options.get('display') == 'forecast':
|
if options.get('display') in WIDE_ONLY:
|
||||||
options = {**options, 'size': 'wide'}
|
options = {**options, 'size': 'wide'}
|
||||||
if options.get('tap') == 'toggle' and domain not in {'light','switch','input_boolean','fan','media_player'}:
|
if options.get('tap') == 'toggle' and domain not in {'light','switch','input_boolean','fan','media_player'}:
|
||||||
raise ValueError('Deze entiteit ondersteunt geen aan/uit-actie.')
|
raise ValueError('Deze entiteit ondersteunt geen aan/uit-actie.')
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ let inventory = { screens: [], entities: [] },
|
|||||||
layout = null,
|
layout = null,
|
||||||
dirty = false,
|
dirty = false,
|
||||||
filter = "",
|
filter = "",
|
||||||
dragIndex = -1,
|
|
||||||
busy = false,
|
busy = false,
|
||||||
selectedTile = null;
|
selectedTile = null;
|
||||||
const node = (tag, text, cls) => {
|
const node = (tag, text, cls) => {
|
||||||
@@ -225,7 +224,15 @@ const domains = {
|
|||||||
timer: ["Kookwekker", "⏱", "#008577", "#def3ed"],
|
timer: ["Kookwekker", "⏱", "#008577", "#def3ed"],
|
||||||
person: ["Persoon", "☺", "#2f7d32", "#e1f2e2"],
|
person: ["Persoon", "☺", "#2f7d32", "#e1f2e2"],
|
||||||
};
|
};
|
||||||
const displayNames = { standard: "standaard", watch: "grote waarde", forecast: "weersvoorspelling", graph: "grafiek", digital: "digitale klok", analog: "analoge klok" };
|
const displayNames = { standard: "standaard", watch: "grote waarde", forecast: "weersvoorspelling", graph: "grafiek", digital: "digitale klok", analog: "analoge klok", sunpath: "zonnebaan" };
|
||||||
|
// New tiles start with the card that shows the entity best.
|
||||||
|
function defaultOptions(id) {
|
||||||
|
const domain = id.split(".")[0];
|
||||||
|
if (domain === "sun") return { options: { display: "sunpath", size: "wide" } };
|
||||||
|
if (domain === "weather") return { options: { display: "forecast", size: "wide" } };
|
||||||
|
if (domain === "screen") return { options: { display: "digital", size: "wide" } };
|
||||||
|
return {};
|
||||||
|
}
|
||||||
// Same packing as the firmware: wide tiles start in the left column and take a whole row.
|
// Same packing as the firmware: wide tiles start in the left column and take a whole row.
|
||||||
function packTiles(tiles) {
|
function packTiles(tiles) {
|
||||||
let position = 0;
|
let position = 0;
|
||||||
@@ -283,11 +290,8 @@ function renderPreview() {
|
|||||||
if(background)card.style.backgroundColor=background;
|
if(background)card.style.backgroundColor=background;
|
||||||
if (place.wide) card.classList.add("wide");
|
if (place.wide) card.classList.add("wide");
|
||||||
card.append(domainBadge(tile.entity), node("strong", name));
|
card.append(domainBadge(tile.entity), node("strong", name));
|
||||||
card.draggable = true;
|
card.dataset.index = index;
|
||||||
card.ondragstart = (e) => { dragIndex = index; e.dataTransfer.setData("text/plain", String(index)); };
|
enableDrag(card, { kind: "tile", index });
|
||||||
card.ondragend = () => { dragIndex = -1; };
|
|
||||||
card.ondragover = (e) => { if (dragIndex >= 0) e.preventDefault(); };
|
|
||||||
card.ondrop = (e) => { e.preventDefault(); if (dragIndex >= 0) move(dragIndex, index); };
|
|
||||||
card.classList.toggle("chosen", selectedTile === tile.entity);
|
card.classList.toggle("chosen", selectedTile === tile.entity);
|
||||||
card.setAttribute("aria-label", `Tegel ${index + 1}: ${name}, instellen`);
|
card.setAttribute("aria-label", `Tegel ${index + 1}: ${name}, instellen`);
|
||||||
card.onclick = () => {
|
card.onclick = () => {
|
||||||
@@ -322,27 +326,6 @@ function renderTiles() {
|
|||||||
if (i > 0 && placement[i].page !== placement[i - 1].page) $("#tiles").append(node("li", `Pagina ${placement[i].page + 1}`, "page-break"));
|
if (i > 0 && placement[i].page !== placement[i - 1].page) $("#tiles").append(node("li", `Pagina ${placement[i].page + 1}`, "page-break"));
|
||||||
const li = node("li", undefined, "tile");
|
const li = node("li", undefined, "tile");
|
||||||
li.classList.toggle("selected-tile", selectedTile === tile.entity);
|
li.classList.toggle("selected-tile", selectedTile === tile.entity);
|
||||||
li.draggable = true;
|
|
||||||
li.ondragstart = (e) => {
|
|
||||||
if (e.target.closest("input, select, button")) {
|
|
||||||
e.preventDefault();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dragIndex = i;
|
|
||||||
e.dataTransfer.setData("text/plain", String(i));
|
|
||||||
li.classList.add("dragging");
|
|
||||||
};
|
|
||||||
li.ondragend = () => {
|
|
||||||
dragIndex = -1;
|
|
||||||
li.classList.remove("dragging");
|
|
||||||
};
|
|
||||||
li.ondragover = (e) => {
|
|
||||||
if (dragIndex >= 0) e.preventDefault();
|
|
||||||
};
|
|
||||||
li.ondrop = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (dragIndex >= 0) move(dragIndex, i);
|
|
||||||
};
|
|
||||||
const content = node("div"),
|
const content = node("div"),
|
||||||
input = node("input");
|
input = node("input");
|
||||||
input.value = tile.name;
|
input.value = tile.name;
|
||||||
@@ -423,6 +406,7 @@ function renderTiles() {
|
|||||||
: [["standard", "Naam en status"], ["watch", "Grote waarde"]];
|
: [["standard", "Naam en status"], ["watch", "Grote waarde"]];
|
||||||
if (domain === "weather") displays.push(["forecast", "Weersvoorspelling (dubbelbreed)"]);
|
if (domain === "weather") displays.push(["forecast", "Weersvoorspelling (dubbelbreed)"]);
|
||||||
if (domain === "sensor") displays.push(["graph", "Grafiek van de geschiedenis"]);
|
if (domain === "sensor") displays.push(["graph", "Grafiek van de geschiedenis"]);
|
||||||
|
if (domain === "sun") displays.push(["sunpath", "Zonnebaan (dubbelbreed)"]);
|
||||||
const fields = [
|
const fields = [
|
||||||
[
|
[
|
||||||
"tap",
|
"tap",
|
||||||
@@ -498,7 +482,7 @@ function renderTiles() {
|
|||||||
};
|
};
|
||||||
if (key === "display" && input.value === "watch")
|
if (key === "display" && input.value === "watch")
|
||||||
tile.options.inline = "none";
|
tile.options.inline = "none";
|
||||||
if (key === "display" && input.value === "forecast")
|
if (key === "display" && ["forecast", "sunpath"].includes(input.value))
|
||||||
tile.options.size = "wide";
|
tile.options.size = "wide";
|
||||||
if (key === "inline" && input.value === "slider")
|
if (key === "inline" && input.value === "slider")
|
||||||
tile.options.display = "standard";
|
tile.options.display = "standard";
|
||||||
@@ -522,6 +506,97 @@ function renderTiles() {
|
|||||||
$("#tiles").append(li);
|
$("#tiles").append(li);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function addTile(id, at) {
|
||||||
|
if (layout.tiles.some((t) => t.entity === id) || layout.tiles.length >= tileLimit()) return;
|
||||||
|
layout.tiles.splice(Math.min(at, layout.tiles.length), 0, { entity: id, name: "", ...defaultOptions(id) });
|
||||||
|
selectedTile = id;
|
||||||
|
markDirty();
|
||||||
|
renderTiles();
|
||||||
|
renderResults();
|
||||||
|
}
|
||||||
|
// Pointer-based drag & drop: works with mouse and touch, from the picker into
|
||||||
|
// the mockup and between tiles. Touch starts after a short hold so the page
|
||||||
|
// still scrolls; a finished drag never doubles as a click.
|
||||||
|
const drag = { active: false, source: null, element: null, ghost: null, target: null, timer: 0, start: null, offset: null, pointerId: null, suppressUntil: 0, last: null, scroller: 0 };
|
||||||
|
function enableDrag(element, source) {
|
||||||
|
element.addEventListener("pointerdown", (e) => {
|
||||||
|
if (e.button !== 0 || element.disabled) return;
|
||||||
|
Object.assign(drag, { source, element, start: { x: e.clientX, y: e.clientY }, pointerId: e.pointerId, active: false });
|
||||||
|
clearTimeout(drag.timer);
|
||||||
|
if (e.pointerType === "touch") drag.timer = setTimeout(() => beginDrag(e), 260);
|
||||||
|
});
|
||||||
|
element.addEventListener("pointermove", (e) => {
|
||||||
|
if (!drag.start || drag.element !== element) return;
|
||||||
|
const distance = Math.hypot(e.clientX - drag.start.x, e.clientY - drag.start.y);
|
||||||
|
if (!drag.active) {
|
||||||
|
if (e.pointerType === "touch") { if (distance > 10) { clearTimeout(drag.timer); drag.start = null; } return; }
|
||||||
|
if (distance < 6) return;
|
||||||
|
beginDrag(e);
|
||||||
|
}
|
||||||
|
moveDrag(e);
|
||||||
|
});
|
||||||
|
const finish = (e) => {
|
||||||
|
if (drag.element !== element) return;
|
||||||
|
clearTimeout(drag.timer);
|
||||||
|
if (drag.active) endDrag(e.type === "pointerup");
|
||||||
|
drag.start = null;
|
||||||
|
};
|
||||||
|
element.addEventListener("pointerup", finish);
|
||||||
|
element.addEventListener("pointercancel", finish);
|
||||||
|
}
|
||||||
|
function beginDrag(e) {
|
||||||
|
if (drag.active || !drag.start) return;
|
||||||
|
drag.active = true;
|
||||||
|
try { drag.element.setPointerCapture(drag.pointerId); } catch {}
|
||||||
|
const rect = drag.element.getBoundingClientRect();
|
||||||
|
const ghost = drag.element.cloneNode(true);
|
||||||
|
ghost.classList.add("drag-ghost");
|
||||||
|
ghost.style.width = `${rect.width}px`;
|
||||||
|
drag.offset = { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
||||||
|
document.body.append(ghost);
|
||||||
|
drag.ghost = ghost;
|
||||||
|
document.body.classList.add("dragging");
|
||||||
|
document.addEventListener("touchmove", blockScroll, { passive: false });
|
||||||
|
// Near the viewport edges the page scrolls along, so the mockup can be reached on small screens.
|
||||||
|
drag.scroller = setInterval(() => {
|
||||||
|
if (!drag.last) return;
|
||||||
|
const step = drag.last.y < 70 ? -12 : drag.last.y > innerHeight - 70 ? 12 : 0;
|
||||||
|
if (step) { window.scrollBy(0, step); setTarget(document.elementFromPoint(drag.last.x, drag.last.y)?.closest(".preview-tile, .preview-gap, .preview-grid") || null); }
|
||||||
|
}, 16);
|
||||||
|
moveDrag(e);
|
||||||
|
}
|
||||||
|
function blockScroll(e) { if (drag.active) e.preventDefault(); }
|
||||||
|
function moveDrag(e) {
|
||||||
|
if (!drag.ghost) return;
|
||||||
|
drag.last = { x: e.clientX, y: e.clientY };
|
||||||
|
drag.ghost.style.transform = `translate(${e.clientX - drag.offset.x}px, ${e.clientY - drag.offset.y}px)`;
|
||||||
|
const under = document.elementFromPoint(e.clientX, e.clientY);
|
||||||
|
setTarget(under?.closest(".preview-tile, .preview-gap, .preview-grid") || null);
|
||||||
|
}
|
||||||
|
function setTarget(target) {
|
||||||
|
if (drag.target === target) return;
|
||||||
|
drag.target?.classList.remove("drop-target");
|
||||||
|
drag.target = target;
|
||||||
|
drag.target?.classList.add("drop-target");
|
||||||
|
}
|
||||||
|
function endDrag(drop) {
|
||||||
|
const { target, source } = drag;
|
||||||
|
setTarget(null);
|
||||||
|
drag.ghost?.remove();
|
||||||
|
drag.ghost = null;
|
||||||
|
drag.active = false;
|
||||||
|
drag.suppressUntil = Date.now() + 400;
|
||||||
|
clearInterval(drag.scroller);
|
||||||
|
drag.last = null;
|
||||||
|
document.body.classList.remove("dragging");
|
||||||
|
document.removeEventListener("touchmove", blockScroll);
|
||||||
|
try { drag.element.releasePointerCapture(drag.pointerId); } catch {}
|
||||||
|
if (!drop || !target) return;
|
||||||
|
const to = target.dataset.index !== undefined ? Number(target.dataset.index) : layout.tiles.length;
|
||||||
|
if (source.kind === "tile") { if (to !== source.index) move(source.index, to); }
|
||||||
|
else addTile(source.id, to);
|
||||||
|
}
|
||||||
|
window.addEventListener("click", (e) => { if (Date.now() < drag.suppressUntil) { e.stopPropagation(); e.preventDefault(); } }, true);
|
||||||
function renderResults() {
|
function renderResults() {
|
||||||
if (!layout) return;
|
if (!layout) return;
|
||||||
const query = $("#search").value.toLocaleLowerCase();
|
const query = $("#search").value.toLocaleLowerCase();
|
||||||
@@ -550,13 +625,8 @@ function renderResults() {
|
|||||||
node("span", chosen.has(entity.id) ? "✓" : "+", "plus"),
|
node("span", chosen.has(entity.id) ? "✓" : "+", "plus"),
|
||||||
);
|
);
|
||||||
b.disabled = chosen.has(entity.id) || layout.tiles.length >= tileLimit();
|
b.disabled = chosen.has(entity.id) || layout.tiles.length >= tileLimit();
|
||||||
b.onclick = () => {
|
b.onclick = () => addTile(entity.id, layout.tiles.length);
|
||||||
layout.tiles.push({ entity: entity.id, name: "" });
|
if (!b.disabled) enableDrag(b, { kind: "entity", id: entity.id });
|
||||||
selectedTile = entity.id;
|
|
||||||
markDirty();
|
|
||||||
renderTiles();
|
|
||||||
renderResults();
|
|
||||||
};
|
|
||||||
$("#results").append(b);
|
$("#results").append(b);
|
||||||
}
|
}
|
||||||
if (!matches.length)
|
if (!matches.length)
|
||||||
@@ -845,6 +915,7 @@ function openSection(id) {
|
|||||||
section.scrollIntoView({ behavior: "smooth", block: "start" });
|
section.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||||
}
|
}
|
||||||
$("#nav-tiles").onclick = () => openSection("#tile-section");
|
$("#nav-tiles").onclick = () => openSection("#tile-section");
|
||||||
|
$("#open-help").onclick = () => openSection("#help");
|
||||||
$("#nav-settings").onclick = () => openSection("#general-settings");
|
$("#nav-settings").onclick = () => openSection("#general-settings");
|
||||||
$("#nav-inspector").onclick = () => inspect();
|
$("#nav-inspector").onclick = () => inspect();
|
||||||
async function inspect(entity) {
|
async function inspect(entity) {
|
||||||
|
|||||||
@@ -12,11 +12,29 @@
|
|||||||
<div class="brand">
|
<div class="brand">
|
||||||
<span class="mark">▦</span>
|
<span class="mark">▦</span>
|
||||||
<div>
|
<div>
|
||||||
<strong>ESP Screens</strong><small>Je huis. Jouw bediening.</small>
|
<strong>ESP Screens</strong
|
||||||
|
><small>Tegels voor je CYD en Guition, zonder opnieuw flashen</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button id="open-firmware" class="quiet">Firmware & USB</button>
|
<nav class="toolbar" aria-label="Acties">
|
||||||
<button id="new-screen">+ Nieuw scherm</button>
|
<button id="new-screen" class="tool tool-primary">
|
||||||
|
<span class="tool-icon" aria-hidden="true">+</span>
|
||||||
|
<span class="tool-text"
|
||||||
|
><b>Nieuw scherm</b><small>Koppel een CYD of Guition</small></span
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
<button id="open-firmware" class="tool">
|
||||||
|
<span class="tool-icon" aria-hidden="true">⇪</span>
|
||||||
|
<span class="tool-text"
|
||||||
|
><b>Firmware & USB</b
|
||||||
|
><small>Bouwen en installeren via USB of wifi</small></span
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
<button id="open-help" class="tool">
|
||||||
|
<span class="tool-icon" aria-hidden="true">?</span>
|
||||||
|
<span class="tool-text"><b>Uitleg</b><small>Hoe werkt het</small></span>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<div class="intro">
|
<div class="intro">
|
||||||
@@ -27,6 +45,26 @@
|
|||||||
</div>
|
</div>
|
||||||
<span id="connection" role="status" class="badge">Verbinden…</span>
|
<span id="connection" role="status" class="badge">Verbinden…</span>
|
||||||
</div>
|
</div>
|
||||||
|
<ol class="howto" aria-label="Zo werkt het">
|
||||||
|
<li>
|
||||||
|
<b>1 · Koppelen</b><span
|
||||||
|
>Kies <b>Nieuw scherm</b> voor de installatie-YAML met eigen
|
||||||
|
sleutels. Eén keer via USB flashen, daarna gaat alles draadloos.</span
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>2 · Tegels kiezen</b><span
|
||||||
|
>Sleep entiteiten uit de lijst rechts in de schermmockup, of tik
|
||||||
|
op +. Klik op een tegel voor weergave, breedte en kleur.</span
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>3 · Opslaan</b><span
|
||||||
|
>Met <b>Opslaan & naar scherm</b> staat het direct op je scherm.
|
||||||
|
Nieuwe schermfuncties installeer je via <b>Firmware & USB</b>.</span
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
<div class="workspace">
|
<div class="workspace">
|
||||||
<aside>
|
<aside>
|
||||||
<h2>Mijn schermen</h2>
|
<h2>Mijn schermen</h2>
|
||||||
@@ -136,7 +174,7 @@
|
|||||||
<b>Firmware & USB</b> bovenaan. Je bestaande YAML en secrets blijven
|
<b>Firmware & USB</b> bovenaan. Je bestaande YAML en secrets blijven
|
||||||
bewaard.
|
bewaard.
|
||||||
</p>
|
</p>
|
||||||
<details class="help">
|
<details class="help" id="help">
|
||||||
<summary>Hoe werkt het dagelijks?</summary>
|
<summary>Hoe werkt het dagelijks?</summary>
|
||||||
<p>
|
<p>
|
||||||
Zoek een entiteit, voeg deze toe en klik op
|
Zoek een entiteit, voeg deze toe en klik op
|
||||||
@@ -147,9 +185,18 @@
|
|||||||
waarde, mini-schuif of klikgedrag.
|
waarde, mini-schuif of klikgedrag.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Nieuwe firmware bouw en installeer je hier met de ingebouwde ESPHome
|
Speciale kaarten: de <b>Klok</b> staat bovenaan de kiezer; een
|
||||||
CLI. Je tegels blijven in deze app bewaard. Een offline scherm krijgt
|
weerentiteit toont de vijfdaagse voorspelling, <code>sun.sun</code>
|
||||||
de wijzigingen zodra het terug is.
|
de zonnebaan, een sensor een trendgrafiek, een <code>timer</code>
|
||||||
|
telt live af en een <code>person</code> toont thuis/weg. Zet een
|
||||||
|
tegel op <b>Dubbelbreed</b> voor meer ruimte.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Nieuwe firmware bouw en installeer je via <b>Firmware & USB</b> met
|
||||||
|
de ingebouwde ESPHome CLI: kies je eigen profiel, dan een USB-poort of
|
||||||
|
wifi, en klik op <b>Bouwen & installeren</b>. Je tegels blijven in
|
||||||
|
deze app bewaard; een offline scherm krijgt de wijzigingen zodra het
|
||||||
|
terug is.
|
||||||
</p>
|
</p>
|
||||||
</details>
|
</details>
|
||||||
</main>
|
</main>
|
||||||
@@ -271,13 +318,19 @@
|
|||||||
</dialog>
|
</dialog>
|
||||||
<dialog id="firmware-dialog">
|
<dialog id="firmware-dialog">
|
||||||
<div class="dialog-head">
|
<div class="dialog-head">
|
||||||
<h2>Firmware & USB</h2>
|
<div>
|
||||||
<button id="close-firmware" class="quiet">Sluiten</button>
|
<p class="eyebrow">FIRMWARE & USB</p>
|
||||||
|
<h2>Schermfirmware bouwen en installeren</h2>
|
||||||
|
</div>
|
||||||
|
<button id="close-firmware" class="quiet" aria-label="Sluiten">✕</button>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
De ingebouwde ESPHome CLI gebruikt je eigen YAML en secrets. Tegels
|
De ingebouwde ESPHome CLI gebruikt je eigen profiel (YAML met sleutels)
|
||||||
blijven in ESP Screens staan. Op de Raspberry kan de eerste build enkele
|
en secrets. Kies het profiel van het scherm, dan een USB-poort (scherm
|
||||||
minuten duren.
|
aan de Home Assistant-machine) of <b>Wifi / OTA</b> met de hostnaam.
|
||||||
|
<b>Controleren</b> valideert alleen, <b>Alleen bouwen</b> compileert,
|
||||||
|
<b>Bouwen & installeren</b> zet de firmware op het scherm. Je tegels
|
||||||
|
blijven in ESP Screens staan. De eerste build duurt enkele minuten.
|
||||||
</p>
|
</p>
|
||||||
<label>ESPHome-profiel<select id="firmware-file"></select></label>
|
<label>ESPHome-profiel<select id="firmware-file"></select></label>
|
||||||
<label
|
<label
|
||||||
|
|||||||
@@ -184,6 +184,98 @@ aside h2 {
|
|||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
padding: 7px;
|
padding: 7px;
|
||||||
}
|
}
|
||||||
|
.toolbar {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.tool {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 8px 14px 8px 9px;
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: 14px;
|
||||||
|
background: white;
|
||||||
|
color: var(--ink);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.tool:hover {
|
||||||
|
border-color: #b9cbec;
|
||||||
|
box-shadow: 0 3px 10px #202c3c0c;
|
||||||
|
}
|
||||||
|
.tool-icon {
|
||||||
|
width: 34px;
|
||||||
|
height: 34px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: var(--soft);
|
||||||
|
color: var(--accent);
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
font-size: 19px;
|
||||||
|
font-weight: 700;
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
.tool-primary .tool-icon {
|
||||||
|
background: var(--accent);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.tool-text b {
|
||||||
|
display: block;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.tool-text small {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
.howto {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0 26px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.howto li {
|
||||||
|
background: white;
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: 14px;
|
||||||
|
padding: 12px 14px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--muted);
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
.howto li > b {
|
||||||
|
display: block;
|
||||||
|
color: var(--ink);
|
||||||
|
font-size: 13px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
.preview-tile,
|
||||||
|
.result {
|
||||||
|
touch-action: pan-y;
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
.drag-ghost {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.92;
|
||||||
|
box-shadow: 0 14px 32px #202c3c33;
|
||||||
|
background: white;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.drop-target {
|
||||||
|
outline: 2px solid var(--accent);
|
||||||
|
outline-offset: 2px;
|
||||||
|
background: var(--soft) !important;
|
||||||
|
}
|
||||||
|
body.dragging {
|
||||||
|
cursor: grabbing;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
#editor,
|
#editor,
|
||||||
.empty {
|
.empty {
|
||||||
background: white;
|
background: white;
|
||||||
@@ -331,9 +423,15 @@ aside h2 {
|
|||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
.savebar {
|
.savebar {
|
||||||
margin-top: 25px;
|
position: sticky;
|
||||||
padding-top: 20px;
|
bottom: 0;
|
||||||
|
z-index: 6;
|
||||||
|
margin: 25px -27px -27px;
|
||||||
|
padding: 16px 27px;
|
||||||
|
background: #ffffffee;
|
||||||
|
backdrop-filter: blur(6px);
|
||||||
border-top: 1px solid var(--line);
|
border-top: 1px solid var(--line);
|
||||||
|
border-radius: 0 0 18px 18px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -475,10 +573,22 @@ dialog label {
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@media (max-width: 1000px) {
|
||||||
|
.howto {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@media (max-width: 620px) {
|
@media (max-width: 620px) {
|
||||||
main {
|
main {
|
||||||
padding: 25px 16px;
|
padding: 25px 16px;
|
||||||
}
|
}
|
||||||
|
.tool-text small {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.savebar {
|
||||||
|
margin: 25px -18px -18px;
|
||||||
|
padding: 14px 18px;
|
||||||
|
}
|
||||||
.workspace {
|
.workspace {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: ESP Screen Manager
|
name: ESP Screen Manager
|
||||||
version: "0.2.12"
|
version: "0.2.13"
|
||||||
slug: esp_screen_manager
|
slug: esp_screen_manager
|
||||||
description: Kies tegels voor je CYD en Guition touchscreen, zonder opnieuw flashen.
|
description: Kies tegels voor je CYD en Guition touchscreen, zonder opnieuw flashen.
|
||||||
url: https://github.com/MaxGramser/homeassistant_espscreen
|
url: https://github.com/MaxGramser/homeassistant_espscreen
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class SpecialTiles(unittest.TestCase):
|
|||||||
layout=validate_layout({'title':'T','tiles':[{'entity':'screen.clock','options':{'display':'analog','size':'wide'}},{'entity':'sun.sun'},{'entity':'timer.egg'},{'entity':'person.max'},
|
layout=validate_layout({'title':'T','tiles':[{'entity':'screen.clock','options':{'display':'analog','size':'wide'}},{'entity':'sun.sun'},{'entity':'timer.egg'},{'entity':'person.max'},
|
||||||
{'entity':'weather.home','options':{'display':'forecast'}},{'entity':'sensor.t','options':{'display':'graph','size':'wide'}}]})
|
{'entity':'weather.home','options':{'display':'forecast'}},{'entity':'sensor.t','options':{'display':'graph','size':'wide'}}]})
|
||||||
self.assertEqual(layout['tiles'][4]['options'],{'display':'forecast','size':'wide'},'forecast forces a wide card')
|
self.assertEqual(layout['tiles'][4]['options'],{'display':'forecast','size':'wide'},'forecast forces a wide card')
|
||||||
|
self.assertEqual(validate_layout({'title':'T','tiles':[{'entity':'sun.sun','options':{'display':'sunpath'}}]})['tiles'][0]['options'],{'display':'sunpath','size':'wide'})
|
||||||
self.assertEqual(layout['tiles'][0]['options']['display'],'analog')
|
self.assertEqual(layout['tiles'][0]['options']['display'],'analog')
|
||||||
for tile in [{'entity':'screen.other'},{'entity':'light.a','options':{'size':'double'}},{'entity':'light.a','options':{'display':'graph'}},
|
for tile in [{'entity':'screen.other'},{'entity':'light.a','options':{'size':'double'}},{'entity':'light.a','options':{'display':'graph'}},
|
||||||
{'entity':'sensor.a','options':{'display':'forecast'}},{'entity':'screen.clock','options':{'display':'watch'}}]:
|
{'entity':'sensor.a','options':{'display':'forecast'}},{'entity':'screen.clock','options':{'display':'watch'}}]:
|
||||||
|
|||||||
Reference in New Issue
Block a user