#web_server v3 -- home assistant styling

1 messages ยท Page 1 of 1 (latest)

proper pawn
#

Just a small show off what I am working on - as for now as an external component.

Key improvements::

  • web server styling resembles to the home assistant entitites card theme
  • icons are sent for all entitites
  • entity_categories are introduced and entities are grouped by sensor+control/config/diag
  • device uptime experiment from ping
  • you need to host the www.js file to try this
  • auto fallback for a very minimal web_server in case you are offline

config:

web_server:
  port: 80
  ota: false
  js_url: https://attilafarago.hu/smarthome/esphome_web_server/www.js

feel free to check out: https://github.com/afarago/esphome/tree/webserver-improvements
optionally: https://github.com/afarago/esphome-webserver/tree/ha-styling

According to my tests the new webserver consumes same RAM, and 1k additional flash.

Please comment what are your ideas, comments, hints and what would you be happy to see.

rotund willow
#

how does the *auto fallback for a very minimal web_server in case you are offline look like?

proper pawn
#

if index.html does not detect the js being loaded the js redirects to ?redirect where web_server renders a minimal js compiled from server_index_fallback.h
(entitites + update from the eventsource)

#

with gz the fallback is 511 bytes total in addition

rotund willow
#

that's just showing states?

proper pawn
#

yep, at the moment i did a minimal implementation
https://github.com/afarago/esphome-webserver/blob/ha-styling/v2fallback/index.html
could be reduced even further if needed ๐Ÿ™‚

<script>
(() => {
  window.s = new EventSource('events');

  let entities = [];
  let uptime = -1;
  let config = {};

  window.s?.addEventListener("ping", (e) => {
    uptime = e.lastEventId;

    if (e.data) {
      const data = JSON.parse(e.data);
      config = data;

      let div = document.createElement("tr");
      div.innerHTML = `<th colspan=2>${data.title} - ${data.comment}</th>`;
      const main = document.getElementById("m");
      main.insertBefore(div, main.firstChild);
    }
  });

  window.s?.addEventListener("state", (e) => {
    uptime = e.lastEventId;

    const data = JSON.parse(e.data);
    let idx = entities.findIndex((x) => x.id === data.id);
    if (idx === -1 && data.id) {
      entities.push(data);
      let tr1 = document.createElement("tr");
      tr1.id = data.id;
      tr1.innerHTML = `<td>${data.name.replace(config.title,`<n>${config.title}</n>`)}</td><td >${data.value??''}</td>`;
      const main = document.getElementById("m");
      main.append(tr1);
    } else {
      document.querySelector(`#${data.id} .v`).innerHTML = data.value;
    }
  });
})();
</script>

<style>html,td{font-family:Calibri} n{font-size:smaller;color:lightgray} td:first-child{padding-right:2em}</style>
<table id="m">
</table>
supple heart
#

I like this very much ๐Ÿ˜‰

#

I tend to use the webserver a lot on some devices, I swapped over to this version yesterday and I am already used to its layout and like the design and layout

supple heart
#

lol i went thro all the sensors and made icons for them all now ๐Ÿ˜‰

rotund willow
#

would be nice to be able to host the resurces locally. Not necessarily locally to the node, but locally to the network, eg. in the dashboard's webserver or in a custom folder under www in HA.

frozen rain
#

Is it possible to add more light controls (rgb)

proper pawn
proper pawn
frozen rain
#

For lights, you only get brightness control on the web server page.
Could you also add color temperature or rgb sliders?

rotund willow
#

A color picker

proper pawn
#

I'd prefer the SHelly solution, but cannot find any js libs for that.

inland relic
#

Looks nice, great work

vast gull
#

cant you just use the color picker built into the browser?

rotund willow
#

Just make sure it's mobile friendly though

proper pawn
rotund willow
#

This has to be handled. So if the .js is locally hosted the UI should still be usable without the icons if they are not accessible.

#

Not the read-only fallback, as that doesn't allow interactivity. Or simply fallback to something like webserver v1 which is still interactive at a degree. (Switches, Covers etc)

proper pawn
#

Checked it.
Basically the client device (your browser / mobile) is requesting the iconify resources. If they are unavailable fallback is that no icon is rendered.
I think this is quite OK.

proper pawn
vast gull
#

nice to use the browsers built ins but its crazy how different they are between browsers ๐Ÿ˜…

#

so i like that youre overhauling the frontend of what esphome webserver serves, but would it be a good idea, as a separate project, to have an web app/pwa that esphome hosts or you can host locally that would just interact with the device/sensors via a rest api or whatever api. that would keep the on device storage use to nothing and allow you to get as fancy as you want for the frontend. you would go to this frontend and point it at all of your devices type thing.

supple heart
#

great work

proper pawn
vast gull
proper pawn
# vast gull ya i guess my question is, how do you feel about making an external frontend to ...

Apologies - still I might not follow completely. ๐Ÿ˜„
This is an external frontend. Backend is the ESP node, FE is hosted on an external site (e.g. https://oi.esphome.io/v2/www.js), ESP node server a lightweight FE, primarily for including the www.js (and in my case adding a fallback mechanism for an ESP hosted fallback JS).

If you refer to creating a complete backend+separate frontend - I'd suggest e.g. an AppDaemon under HA.

vast gull
#

oh i thought you were overhauling the stock esphome web server component frontend.

rotund willow
#

Since it's fundamentally pretty different, this should be named as web_server v3 - to avoid confusion later

#

v2 is still something which can be 100% offline and run from the node, can be configured so no external resources would needed

proper pawn
rotund willow
#

Think of the user perspective.
v1, v2, you have controls r/w all offline from internet. If you embed js, you get everything afaik.

With your pack, when you're offline, you fallback to a r/o status page. You can embed the js without the icons.

It's a small step back functionally, a big step ahead visually (if you're online).

That's why I say pack it as v3, one can choose whichever he/she wants...

#

But maybe I misunderstand smth.

supple heart
#

maybe Jesse and Keith need to have a look at this

proper pawn
# rotund willow Think of the user perspective. v1, v2, you have controls r/w all offline from in...

You are right, I agree that from the theoretical perspective this introduces a visible degradation (inability to fully embed as local).
I would think that as the graceful degradation is in place and there is no big difference of not having icons with the local js option.

Yet I must admit that I am too engaged with the new look and feel and my vision might be shaded to form a real opinion of my own ๐Ÿ˜„

So whichever option is decided I am happy with it, just let me know the repo owner preference. @spark crown

spark crown
#

I think it would be fine to keep v2 with an updated style like this

dawn basin
#

Need to see the sliders

proper pawn
dawn basin
# proper pawn would you care to add more details?

Brightness sliders on lights along with colour selection tools. I posted this before reading the recent messages in this thread. Value selection could be great along with the brightness slider to manually meter brightness/colour value in text box.

dawn basin
#

first one with this

#

OTA option is missing from this dashboard ```yaml
esp8266:
board: esp01_1m

#

colour picker ๐Ÿ˜

#

effects menu

dawn basin
#

effects changes when we click away from the selection

crimson pilot
#

Is it possible to have multiple color selectors?
For example if I have multiple WS2812 strips or one is indicator/status and the other is the LED strip

#

Great work btw!

fleet cloak
crimson pilot
#

Am I missing something or the current implementation only supports one color picker?

crimson pilot
#

What is an indicator?
If I have a single WS2812 LED on the board that is used as an indicator (ie. red -> bad, green->good, teal-> active etc)

fleet cloak
crimson pilot
#
# Example configuration entry
light:
  - platform: neopixelbus
    id: StatusLED
    variant: SK6812
    type: GRBW
    pin: GPIO10
    method:
      type: esp32_rmt
      channel : 0
    num_leds: 1
    name: "Status"
  - platform: neopixelbus
    id: LedsStrip
    variant: WS2812
    type: GRB
    pin: GPIO6
    method:
      type: esp32_rmt
      channel : 1
    num_leds: 60
    name: "LEDs"
fleet cloak
#

Ok

dawn basin
proper pawn
crimson pilot
crimson pilot
crimson pilot
# proper pawn You have two variants. Could you please open upe the eventstream and post it her...

Here is the output of the the /events

retry: 30000
id: 121753
event: ping
data: {"title":"sk-esp32c3-test","comment":"","ota":true,"log":true,"lang":"en"}

event: state
data: {"id":"light-status","name":"Status","state":"ON","effect":"None","color_mode":"rgbw","brightness":119,"color":{"r":255,"g":255,"b":255,"w":255},"white_value":255,"effects":["None","Random","Random Effect With Custom Values"]}

event: state
data: {"id":"light-leds","name":"LEDs","state":"OFF","effect":"None","color_mode":"rgb","brightness":255,"color":{"r":255,"g":255,"b":255},"effects":["None","Random","Random Effect With Custom Values"]}

retry: 30000
id: 130669
event: ping
data: 

retry: 30000
id: 140670
event: ping
data: 

retry: 30000
id: 150672
event: ping
data: 

retry: 30000
id: 160668
event: ping
data: 

retry: 30000
id: 170667
event: ping
data: 

retry: 30000
id: 180674
event: ping
data: 
#

I changed the config to test random effects but otherwise it's the same as the one I posted before

#

@proper pawn So if I change the other LED from GRBW to GRB both of them have color picker.
I guess at some point it would be nice if we could use color selector for RGBW as well. ๐Ÿ™‚

dawn basin
#

there are other beside RGB eg GRB and BRG etc etc too

fleet cloak
fleet cloak
#

yes

#

Although I've never heard of RGW before. ๐Ÿ™‚

dawn basin
proper pawn
#

I can simply use the same system color picker perhaps. Would that be good here?

crimson pilot
proper pawn
crimson pilot
#

Probably it makes most sense to keep the color picker always the same.
In the "background" you could detect if you have RGB or RGBW and do the "correction" with white channel.

#

The W can also be warm-white and cool-white... but at some point you should draw the line and say this is an edge case, we can cover it if there is a really good use-case for it.
For my usage; even just having the color picker for both RGB and RGBW and completely ignoring the W channel would be enough.
I just want the user to be able to select a custom color through UI. If W channel is not used, it's not as bad as if the entire color picker is missing. ๐Ÿ™‚

proper pawn
#

OK, for the time being I am fine to add it, let's see if that gets approved, merged ๐Ÿ˜„

crimson pilot
#

Awesome, thank you!

proper pawn
#

We need to just wait for the official review and merge of the two PRs on esphome and esphome-webserver patiently ๐Ÿ˜„

frozen rain
supple heart
#

just add this ^^

frozen rain
#

am i missing something? i don't see the color picker

proper pawn
frozen rain
# proper pawn No idea, we are blind without the config and the eventstream. Please add your ya...

For events

retry: 30000
id: 12261392
event: ping
data: {"title":"treatlife-corner","comment":"","ota":false,"log":true,"lang":"en"}

event: state
data: {"id":"light-treatlife-corner","name":"treatlife-corner","state":"ON","color_mode":"cwww","brightness":209,"color":{"c":255,"w":0},"effects":["None"]}

retry: 30000
id: 12262148
event: ping
data: 

retry: 30000
id: 12272152
event: ping
data: 

retry: 30000
id: 12282148
event: ping
data: 

retry: 30000
id: 12292148
event: ping
data: 

id: 12292778
event: log
data: [D][dgr:687]: Sending corner1 message to network: seq=2, flags=64

retry: 30000
id: 12302152
event: ping
data: 

id: 12311182
event: log
data: [D][dgr:687]: Received corner1 message from 192.168.1.33: seq=138, flags=64

retry: 30000
id: 12312150
event: ping
data: 

retry: 30000
id: 12322148
event: ping
data: 

retry: 30000
id: 12332148
event: ping
data: 

retry: 30000
id: 12342152
event: ping
data: 

retry: 30000
id: 12352148
event: ping
data: 

id: 12355526
event: log
data: [D][dgr:687]: Sending corner1 message to network: seq=2, flags=64

retry: 30000
id: 12362148
event: ping
data: 

retry: 30000
id: 12372152
event: ping
data: 

retry: 30000
id: 12382148
event: ping
data: 

event: state
data: {"id":"light-treatlife-corner","name":"treatlife-corner","state":"ON","color_mode":"cwww","brightness":209,"color":{"c":255,"w":0},"effects":["None"]}
crimson pilot
proper pawn
#

cwww color model?
The control reports color as "color":{"c":255,"w":0}
No idea what should I do after the color picker returns RGB in this case.
Any ideas?

#

At the moment I am adding the ones I'm sure will work. If there is a more general solution, happy to add it ๐Ÿ˜‰

frozen rain
frozen rain
dawn basin
#

if we could input numbers for the sliders,, that could be awrsome

#

and presence Icons

hot tulip
proper pawn
#

OK, I promise once we get an approve and an official merge from the esphome team I will put effort to add all color models supported.

fleet cloak
proper pawn
# fleet cloak I thought there already was an approval of it in general. It would be better to...

Yes, as I understood as well in general both parts (esphome, esphome-webserver) are OK to go.

Webserver code can be enhanced to an infinity, and the key concept of the PR is not adding more control but to move it to a HomeAssistant styled upgrade.
Before investing endless amount of time to add controls and improvements I do want to wait for the merge. This is my first PR for these repos and would like to avoid adding too big and complex increments at once.

dawn basin
dawn basin
#

uptime time doesn't update unless you refresh the page

proper pawn
dawn basin
#

In my screenshot actual uptime is 1904s =/= 21mins

proper pawn
dawn basin
proper pawn
dawn basin
#

I am on Mobile and this node is running

dawn basin
#

on the node I noticed it

proper pawn
proper pawn
# dawn basin

Hi! Your screenshot shows th 8min 38sec mark, while the log show 337 s (5min) mark. I have no idea, but happy to debug - if you could please create a screenshot of the problem and add the respective eventsource listing for the same/overlapping interval - I could have a chance.

dawn basin
#
retry: 30000
id: 2313483
event: ping
data: {"title":"esps2","comment":"","ota":false,"log":true,"lang":"en"}

event: state
data: {"id":"light-sys_status","name":"sys_status","state":"OFF","color_mode":"onoff","color":{},"effects":["None"]}

event: state
data: {"id":"sensor-uptime_sensor","name":"Uptime Sensor","value":2256.583984,"state":"2257 s","icon":"mdi:timer-outline"}

event: state
data: {"id":"sensor-wifi_signal_db","name":"WiFi Signal dB","value":-47,"state":"-47 dBm","icon":""}

event: state
data: {"id":"sensor-bme280_temperature","name":"BME280 Temperature","value":null,"state":"NA","icon":""}

event: state
data: {"id":"sensor-bme280_pressure","name":"BME280 Pressure","value":null,"state":"NA","icon":""}

event: state
data: {"id":"sensor-bme280_humidity","name":"BME280 Humidity","value":null,"state":"NA","icon":""}

event: state
data: {"id":"sensor-wifi_signal_percent","name":"WiFi Signal Percent","value":100,"state":"100 Signal %","icon":""}

event: state
data: {"id":"sensor-a_uptime_sensor","name":"A Uptime Sensor","value":2280.39209,"state":"2280 s","icon":"mdi:timer-outline"}

event: state
data: {"id":"button-s2__restart","name":"S2  restart"}

event: state
data: {"id":"button-s2_restart__safe_mode_","name":"S2 Restart (Safe Mode)"}

event: state
data: {"id":"text_sensor-device_info","name":"Device Info","value":"2023.12.0-dev|Chip: ESP32-S2 Features:WIFI_BGN, Cores:1 Revision:0|ESP-IDF: 4.4.5|EFuse MAC: 48:27:E2:59:EB:E8|Reset: Software Reset Digital Core|Wakeup: Unknown","state":"2023.12.0-dev|Chip: ESP32-S2 Features:WIFI_BGN, Cores:1 Revision:0|ESP-IDF: 4.4.5|EFuse MAC: 48:27:E2:59:EB:E8|Reset: Software Reset Digital Core|Wakeup: Unknown","icon":"mdi:chip"}


id: 2316588
event: log
data: [D][sensor:094]: 'Uptime Sensor': Sending state 2316.58691 s with 0 decimals of accuracy

event: state
data: {"id":"sensor-uptime_sensor","value":2316.586914,"state":"2317 s"}

retry: 30000
id: 2317356
event: ping
#

event: state
data: {"id":"text_sensor-reset_reason","name":"Reset Reason","value":"Software Reset Digital Core","state":"Software Reset Digital Core","icon":"mdi:restart"}

event: state
data: {"id":"text_sensor-a_uptime_human_readable","name":"A Uptime Human Readable","value":"38m 0s","state":"38m 0s","icon":"mdi:clock-start"}

event: state
data: {"id":"text_sensor-esphome_version","name":"ESPHome Version","value":"2023.12.0-dev Dec 12 2023, 07:48:59","state":"2023.12.0-dev Dec 12 2023, 07:48:59","icon":"mdi:new-box"}

#

events and screenshot from same device at same time/just took the time for the screenshot

#

during this 1 hour I did flashed this node. which means top uptime is calculated from the moment this node is powered up. while internal esphome uptime sensor calculates from the last boot

dawn basin
#
retry: 30000
id: 724883
event: ping
data: {"title":"esps2","comment":"","ota":false,"log":true,"lang":"en"}

event: state
data: {"id":"light-sys_status","name":"sys_status","state":"OFF","color_mode":"onoff","color":{},"effects":["None"]}

event: state
data: {"id":"sensor-uptime_sensor","name":"Uptime Sensor","value":706.875,"state":"707 s","icon":"mdi:timer-outline"}

event: state
data: {"id":"sensor-wifi_signal_db","name":"WiFi Signal dB","value":-48,"state":"-48 dBm","icon":""}

event: state
data: {"id":"sensor-bme280_temperature","name":"BME280 Temperature","value":null,"state":"NA","icon":""}

event: state
data: {"id":"sensor-bme280_pressure","name":"BME280 Pressure","value":null,"state":"NA","icon":""}

event: state
data: {"id":"sensor-bme280_humidity","name":"BME280 Humidity","value":null,"state":"NA","icon":""}

event: state
data: {"id":"sensor-wifi_signal_percent","name":"WiFi Signal Percent","value":100,"state":"100 Signal %","icon":""}

event: state
data: {"id":"sensor-a_uptime_sensor","name":"A Uptime Sensor","value":697.7509766,"state":"698 s","icon":"mdi:timer-outline"}

event: state
data: {"id":"button-s2__restart","name":"S2  restart"}

event: state
data: {"id":"button-s2_restart__safe_mode_","name":"S2 Restart (Safe Mode)"}

event: state
data: {"id":"text_sensor-device_info","name":"Device Info","value":"2023.12.0-dev|Chip: ESP32-S2 Features:WIFI_BGN, Cores:1 Revision:0|ESP-IDF: 4.4.5|EFuse MAC: 48:27:E2:59:EB:E8|Reset: Power On Reset|Wakeup: Unknown","state":"2023.12.0-dev|Chip: ESP32-S2 Features:WIFI_BGN, Cores:1 Revision:0|ESP-IDF: 4.4.5|EFuse MAC: 48:27:E2:59:EB:E8|Reset: Power On Reset|Wakeup: Unknown","icon":"mdi:chip"}

event: state
data: {"id":"text_sensor-reset_reason","name":"Reset Reason","value":"Power On Reset","state":"Power On Reset","icon":"mdi:restart"}

event: state
data: {"id":"text_sensor-a_uptime_human_readable","name":"A Uptime Human Readable","value":"11m 38s","state":"11m 38s","icon":"mdi:clock-start"}

#

situation in reverse

proper pawn
# dawn basin ``` retry: 30000 id: 2313483 event: ping data: {"title":"esps2","comment":"","ot...

Thanks -- your logs seems to be complete and OK.

id: 2316588
event: log
data: [D][sensor:094]: 'Uptime Sensor': Sending state 2316.58691 s with 0 decimals of accuracy

event: state
data: {"id":"sensor-uptime_sensor","value":2316.586914,"state":"2317 s"}

retry: 30000
id: 2317356
event: ping
  • Does the heart icon do the "beat" animation
  • opening the dev tools (F12), no errors on the console?
  • which browser, version & op system w version are you using?
  • info: the time is updated on the ping event, using the id (https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/lastEventId) in ms
  • when looking at the event log, you do see ping messages coming in at regular pace? (~10s if I recall right)
dawn basin
dawn basin
#

heart only beats when refreshed

#

time on sensor and in logs does updates regularly

#

WIndows 11 beta

#
13:28:02
[I]
[ota:117]
Boot seems successful, resetting boot loop counter.
13:28:02
[D]
[esp32.preferences:114]
Saving 1 preferences to flash...
13:28:02
[D]
[esp32.preferences:143]
Saving 1 preferences to flash: 0 cached, 1 written, 0 failed
13:28:07
[D]
[sensor:094]
'WiFi Signal dB': Sending state -59.00000 dBm with 0 decimals of accuracy
13:28:07
[D]
[sensor:094]
'WiFi Signal Percent': Sending state 82.00000 Signal % with 0 decimals of accuracy
13:28:44
[D]
[sensor:094]
'Uptime Sensor': Sending state 342.31400 s with 0 decimals of accuracy
13:28:49
[D]
[text_sensor:064]
'A Uptime Human Readable': Sending state '5m 48s'
13:28:49
[D]
[sensor:094]
'A Uptime Sensor': Sending state 347.89600 s with 0 decimals of accuracy
13:29:07
[D]
[sensor:094]
'WiFi Signal dB': Sending state -58.00000 dBm with 0 decimals of accuracy
13:29:07
[D]
[sensor:094]
'WiFi Signal Percent': Sending state 84.00000 Signal % with 0 decimals of accuracy
13:29:44
[D]
[sensor:094]
'Uptime Sensor': Sending state 402.31400 s with 0 decimals of accuracy
13:29:49
[D]
[text_sensor:064]
'A Uptime Human Readable': Sending state '6m 48s'
13:29:49
[D]
[sensor:094]
'A Uptime Sensor': Sending state 407.89600 s with 0 decimals of accuracy
13:30:07
[D]
[sensor:094]
'WiFi Signal dB': Sending state -57.00000 dBm with 0 decimals of accuracy
13:30:07
[D]
[sensor:094]
'WiFi Signal Percent': Sending state 86.00000 Signal % with 0 decimals of accuracy
13:30:44
[D]
[sensor:094]
'Uptime Sensor': Sending state 462.31000 s with 0 decimals of accuracy
13:30:50
[D]
[text_sensor:064]
'A Uptime Human Readable': Sending state '7m 48s'
13:30:50
[D]
[sensor:094]
'A Uptime Sensor': Sending state 467.89600 s with 0 decimals of accuracy
13:31:07
[D]
proper pawn
# dawn basin ```yaml 13:28:02 [I] [ota:117] Boot seems successful, resetting boot loop counte...

I think I got it. You are using esp-idf framework, while I use Arduino.
For some reason esp-idf does not send the ping regularly for the eventstream. Please raise a ticket for esphome/web_server_idf component owner is @little lotus .

I will do a workaround and update the "uptime header" not only for ping, but for all incoming event messages that has the id field set (that is log messages). It seems that state updates miss this field.

proper pawn
dawn basin
#

got some new

#

if this is some kind of graph in webpage it will be a awesome feature

#

Live graphs I am loving it ๐Ÿ˜ป

dawn basin
dawn basin
#

most useful on ith presnce radars

supple heart
#

I am getting that instead of the heart icon for the heartbeat

dawn basin
supple heart
#

strange - it worked on the other versions of the js

dawn basin
supple heart
#

yes fine

proper pawn
supple heart
#

win10, Opera + Firefox

proper pawn
#

Strange: on my win11+ff 120.0.1 it shows perfectly.

inland relic
#

Is there a option to switch between dark mode and light mode in the portal page?

#

The page works great, graphs are a nice addition

wispy flame
#

have you ever thought about building 2 versions, one with human readable javascript and one with minimized javascript. Minimized could save 30%+ in final size
I tried to put your code into the following but it has a bunch of errors for javascript standard notations
https://jscompress.com/

proper pawn
dawn basin
#

working fine with bk231n

#

would it possbile to add a relay/button history graph?

dawn basin
#

old web

fleet cloak
#

The new one doesn't have a state column, so the unit needs to get combined with the slider.

fleet cloak
#

I would expect so.

grand bone
proper pawn
# grand bone I love the graph, but wonder if there is a way to save some historical values in...

Would be a nice idea, yet I have not clue were this from architecture perspective could fit into esphome.
Sensors do not store this, and would be awkward on webserver side.
I was playing around with a similar idea to store the last X log strings and already show it on reload (also making sure that already connected client do not get that from the eventstream).
Any ideas/hints?

Is the code owner of web_server also OttoWinter? (only web_server_base has CODEOWNERS)

grand bone
#

I presume you collect values via the events channel. Do you time stamp them when they arrive, or do they come with the timestamp in the event?

#

Iโ€™m wondering whether one could add an optionally compiled โ€œhistory: count: 96 interval: 15m type: averageโ€ to the sensor entity. That could also support local displays that want to show a graph, which is an existing use case with a not-entirely satisfactory solution.

#

Then, on connection to the web server, either the server spams the event stream with time stamped entity values which you can collect, or they can be requested

proper pawn
# grand bone I presume you collect values via the events channel. Do you time stamp them when...

This is not working like this.
Eventstream is an incremental thing, client only sees thing after it is connected (e.g. web page loaded). For an initial load there is a one time initial payload (e.g. effects, entity icon etc) that could convey this data.
Yet esphome would need to store it somewhere to emit the data once a client is connected.
I have no idea where this would fit into the current esphome architecture.

grand bone
#

As I was saying, it could be included as an optional part of the sensor entity. Space would be allocated for it only if a history: node was configured for the sensor, and some details provided about how large to make the history, and how to update that history. That could conditionally make a getHistory() function available, that returns a list of timestamped float values, or else a set of int getHistoryCount(), int getHistoryInterval(), float getHistoricalValue(int n) would also allow the necessary information to be calculated within esphome.

proper pawn
#

Help needed -- I have implemented a local_fallback option to the web_server.
https://github.com/esphome/esphome/pull/5853

I received a quite correct request to create the build process for the fallback page - where I am short on knowledge.
(minify html+js, gzip, encode to hex, create .h file)

Is someone willing to give some guidance or a helping hand on this?

manual steps:

  1. minify https://www.toptal.com/developers/html-minifier
  2. rename to something short (gzip stores name) - like "p"
  3. gzip with max/9 setting
  4. encode to hex https://tomeko.net/online_tools/file_to_hex.php?lang=en
proper pawn
proper pawn
grand bone
#

Also not seeing how to switch between light and dark mode?

dawn basin
dawn basin
#

I will check chart. Js for more examples

grand bone
#

trying to figure out the best way to define the history variable in sensor.h. Ideally, the variable size should be compiled in, to benefit from warnings/errors when compiling the firmware, rather than running out of memory trying to allocate the memory after the firmware is installed.

I'm a novice at C++, unfortunately, even though I can generally manage to cargo-cult my way around! ๐Ÿ™‚

rotund willow
#

Adding SD card as sink for such data has been a feature request for a long time

#

There are many ESP32 boards equipped with SD card slots and ESPHome never used them

grand bone
#

I mean, sure, thatโ€™s fine for long term/persistent storage, but thatโ€™s quite a different thing to what I am proposing.

dawn basin
#

more organization

grand bone
#

config file snippet:

binary_sensor:
  - platform: wireguard
    status:
      name: 'WireGuard Status'
      entity_category: diagnostic

text_sensor:
  - platform: template
    name: "Status 1A"
    icon: mdi:eye
    entity_category: diagnostic
    update_interval: 10s
#

I also noted that in your initial (or early) video, you could click on the header tab or "Debug Log" tab to expand that portion of the screen. It doesn't seem to work for me.

#

Snippet from /events:

retry: 30000
id: 2365791
event: ping
data: {"title":"growatt","comment":"","ota":true,"log":true,"lang":"en"}

event: state
data: {"id":"binary_sensor-wireguard_status","name":"WireGuard Status","value":true,"state":"ON"}

event: state
data: {"id":"sensor-uptime_sensor","name":"Uptime Sensor","value":2333.512,"state":"2334s","icon":"mdi:timer-outline"}
#

For some reason, doesn't seem to include the entity_category field in the Wireguard Status entity?

dawn basin
#

not working on my older nodes, which weren't flashed yesterday

dawn basin
#

flashed today and now tabs are working fine

#

with dark and light mode also

#

these just visible and animated graphs ๐Ÿ˜ป

grand bone
#

Odd, will try reflash and see. I assumed that the URL was not changing even though the contents were, and would not need to be reflashed to benefit from any updates. Just a refresh in the browser should do it?

#

talking about light and dark mode, should there not be a cookie or similar to record the preferred display mode? If I refresh, I go back to light mode by default. (This could possibly be affected by a Third Party Cookies setting I have disabled in Chrome, though?)

dawn basin
#

mine are all on dark mode

dawn basin
#

working with 7231n chips too, on device energy graphs ๐Ÿ˜ป

grand bone
#

Nice!

proper pawn
proper pawn
grand bone
#

Give me a moment. I may need to pull the latest dev version.

proper pawn
#

OK, going to theatre, will check back in the night.
Just make sure you add a sample full config if sg is not working as a pastebin reference.

grand bone
#

ok, will do

#

My config has a bunch of modbus values in it, which I think I can can safely leave out.

grand bone
#

Yeah, it was just the sync'ing of forks that was the problem. All looks beautiful now!

proper pawn
proper pawn
#

Hey @spark crown could I ask for a little bit of help? I seem to be a bit lost in the PR process.
https://github.com/esphome/esphome-webserver/pull/49 seems to be in blocked status, yet I am unsure if I do have any pending actions on my side.
I have made the requested change.

fleet cloak
proper pawn
#

Ok thanks for the reply, take the time, no hurry.

wintry wyvern
#

@proper pawn thanks for your work. It looks great.
I downloaded your repo to build the js file, but it seems that some files are missing

The following dependencies are imported but could not be resolved:

iconify-icon (imported by C:/Users/Matt/Documents/Git/esphome-webserver/v2/esp-entity-table.ts)
chart.js (imported by C:/Users/Matt/Documents/Git/esphome-webserver/v2/esp-entity-chart.ts)

proper pawn
wintry wyvern
#

ah my bad. I didn`t re install it once loaded your repo

#

Do you have any plans on adding sorting of the entities? I guess this would get a bit more involved since it can not easily done on the webserver side only

proper pawn
wintry wyvern
proper pawn
#

ESPHome entitites do not store such information, so would be quite troublesome from esphome perspective.
(web_server component takes the data from the entity components themselves)

grand bone
#

Store order in localstorage, perhaps?

#

drag and drop to get your preferred sorting, and store the details in the browser's localstorage, I mean.

#

won't carry to other browsers, but that's about the best you will get.

#

Especially since sort order is not really a thing that translates well into Home Assistant at large, it is unlikely that a patch implementing it would be accepted into ESPHome.

wintry wyvern
grand bone
#

Because the name is also sent to Home Assistant or any other API/MQTT clients

wintry wyvern
#

We would only use the special char sequenz if we use the webserver, so i dont see any conflict.

grand bone
#

Eh, I don't care enough about the topic, I'm not going to comment further.

inland relic
inland relic
dawn basin
inland relic
#

Find it, i install it on a other esp32 with more sensors and it works now

proper pawn
inland relic
#

Would it also be possible to add an background picture as a option like this example

#

Maybe ask a review in the dev channel? ( i think more people can accept the change now)

dawn basin
proper pawn
# inland relic

This would imply a more complex config in the yaml file, right? How would you envision this?

grand bone
grand bone
#

Literally just a background image?

#

No live updates to portions of it, etc?

#

Probably not too complex (from the non-javascript developer), but you would also need to think about things like how it appears on PC vs mobile devices, etc

fleet cloak
grand bone
#

Not sure if that is actually a requirement. Given the wled example, perhaps just a pretty/distinguishing background is enough.

fleet cloak
#

If the values aren't included, then the background picture doesn't really make sense.

grand bone
#

certainly not the one shown, no

proper pawn
#

The whole web_server component architecture comes down to three pillars

  • user config yaml file with all the sensor and binary_sensor etc components that have their own predefined and hard-to-influence data structures. These are iterated, listed and change-watched in the web_server component (esphome core project)
  • user config yaml file with the web_server: component, that might include any further config keys (esphome core project)
  • web_server lit frontend (html/js/css) (esphome-webserver project) that is hosted either on esphome.io by default or anywhere else if you configure your own - this is loaded into your browser does literally know ~nothing about the ESP, has a narrow info interface through the eventstream

aspect to consider: where is the "thing" we want to add resides in configuration, memory, get connunicated, and runs and gets hosted (if applicable).

Key challenge is that many changes influence both esphome core and esphome-webserver project.
Also components cannot and maybe should not be extended for the sake of the web_server (unless we start a very cumbersome decorator pattern).

In the above example of background image it seems pretty doable:

This implies two PR changes: one in esphome/esphome and one in esphome/esphome-webserver project.

#

I have a similar struggle with icons.
Icons are part of the sensor configuration and are optional.
If I set them it is possible to convey the config to the frontend web_app via the eventstream and show on the web_server interface.

However this implies that they will be fixed -- that is problematic in case of a binary motion sensor.

  1. If an esphome a binary motion sensor has no icon configured, HA assigns one and also changes based on the state (detected/not detected) - yet web_server will not be able to show any icons.
  2. If an esphome a binary motion sensor has an icon configured, HA takes that as fixed and displays it no matter what the state is - yet web_server will show at least that fixed icon.

It would be possible to "decorate" sensors, like so

binary_sensor:
  - id: first
    # icon: mdi:motion-sensor # no icon so that HA will assign it automatically

web_server:
  custom_entity_decorations:
    - entity_id: first
      icon: mdi:motion-sensor

But that would be quite hard to follow and unpleasant...

rotund willow
#

you should draw an endline...
in the end you'll end up re-developing HA functionalities - completely useless imho.
just fancy good lookin' things which apart from design, have little real functionality.
a waste of resources.
for such things, there's a dedicated tool, it's called Home Assistant or whatever other home automation tool you'd like.

fleet cloak
#

There have been requests to allow the icon to change at runtime. That would be useful for both HA and the web server.

drifting yarrow
#

I agree about drawing a line. give web_server a project scope and stick to it. is it a end user daily use tool, or an initial config/test/diag tool?

for the latter, it's great as it is, in fact it's wonderful. the only improvement I personally would like is branding, like either replacing the top logo or adding a branded one with it. I know this can be done by hosting my own copy of the files, but then I'd have to keep patching it.

dawn basin
#

can we have icons for the binary sensors? e.g window/light/power icons?

proper pawn
#

What is the practical use to draw a clear end line for this project?
I completely agree that re-developing HA functionalities makes little sense, yet esphome is a great open source project that gets features on demand and popularity based on the community.

At the moment there is no energy / community to expand the web-server further, yet I think many of us would see more functionality as long as it does not have drawbacks (performance / flash / RAM) and someone invests the time to develop them.
I personally love to think on esphome as potential part of the HA ecosystem that is fully functional and capable on its own as a low-code Arduino alternative.

We still have the above improvements pending as far as I see anyhow.

dawn basin
wintry wyvern
#

@proper pawn on mobile devices the time component of the log gets cut after the hour value. Displaying the minutes or even the seconds too would be nice

wintry wyvern
proper pawn
#

No idea, this is my first PR for esphome repos yet.

dawn basin
#

love the comments section

#

just below the title

grand bone
#

This is a bit odd, not sure if I need to flash a new version or not? Firstly, the upper value of the range of the number is not to the right of the slider, it ends up below it? And the actual value that the number is set to is not displayed anywhere, not even if I hover over the slider handle.

wintry wyvern
wintry wyvern
#

@proper pawn maybe it would be a good idea to allow the user to decide if he wants to use v2 or your v2+
Because it seems your version takes up a lot more space on PROGMEM when the js is included and not loaded from the internet than v2

With your PR v2 is simply replaced with your v2+. Maybe it would be better to add a config to let the user choose if he wants v2 or v2+

proper pawn
wintry wyvern
fleet cloak
#

It could even be v3. That makes it an easy change.

proper pawn
#

I understand all the ideas and with many I can agree, with some I can accept, even would implement some of them for the sake of the community receiving a next step in the web_server. Yet for each decision there needs to be a codeowner who considers and completes that decision.

It could be an option that Jesse creates a forum to collect input and discuss future of webserver and ultimately decides on what to accomplish.
I am happy to actively accompany this awesome project on that route, yet - sorry to say- just changing the PR indefinitely without a clear end-goal is Balaam's donkey that just is a waste of effort .

I think we would need a next step from @spark crown on the future of this project.

fleet cloak
#

My vote is V3. @torn relic ?

torn relic
#

oh, I have a lot of catching up to do...

#

what are we trying to decide exactly?

fleet cloak
#

Should this new web client option replace V2 or be added as V3.

#

It's much nicer, but it's also somewhat larger.

supple heart
#

I think its past V2 now and should be V3 with ofc option to choose

torn relic
#

I don't use the web server...I might not be the best person to ask ๐Ÿ˜…
that said, I think the ability to choose what's in use would be good -- no webserver, a "lite" webserver and a "full" webserver, for example

#

if we are distinguishing what features/functionality will be available to the user, "v1", "v2" and "v3" probably isn't the best nomenclature...

supple heart
#

i think we are just going along with what its called now

torn relic
#

that's fair. ๐Ÿ™‚

supple heart
#

the current default one is V2

torn relic
#

yeah, as I'm catching up, I'm leaning towards a "v3", too

#

maybe once it's merged & available, we can look at rebranding them so the differences are more clear

grand bone
#

According to my tests the new webserver consumes same RAM, and 1k additional flash.

#

Is it really worth it for 1k flash?

#

That comment was in the original post, fwiw, not my observation

torn relic
#

if it's really just 1K, that's not bad, unless maybe you are unforunate enough to have an ESP with < 1 MB of flash, haha

fleet cloak
#

Is the web server being changed as well? I thought it was just the client.

grand bone
#

the bulk of it is externally hosted anyway, isn't it? Unless you choose to build it in because your browser has no internet connection, or you don't trust external resources.

#

There have been changes to the C++ code, mainly to support a fallback javascript if the external resource can't be loaded. This take the majority of the 1k mentioned above.

#

and a few other tweaks, it seems

spark crown
#

There have been a few supporting changes merged on the device side. But it's mostly just the frontend.

I'm fine with it being a v3. Sorry it hasn't gone anywhere officially yet, i have been overseas for the past 2 months working on and off.
As for reviewing the actual webserver frontend, I have almost no idea about frontend code ๐Ÿ˜…

#

If we change the webserver code to become a v3 subfolder of the repo, then it's a lot easier to merge and allow people to use without altering the V2 experience

wintry wyvern
inland relic
proper pawn
#

I am all OK with any additional requests from the codeowner as long as there is clear decision. It might worth a broader discussion if there is a longer debate needed or just a simple decision.
As a next step I would ask @spark crown - would you please help me and add any further list of requested changes to the PR directly that allows the PR to be merged & closed.

If I see a full list of further requests, I can do it in one go. I would like to avoid us having much delay, and reiteration before the merge.
Is this OK this way?

dawn basin
spark crown
dawn basin
#

we are really inpatient ๐Ÿซฃ

torn relic
#

it might be a bit tight to get into this coming release. Jesse is going to be away for a few days and I'm probably lacking sufficient background to approve ๐Ÿ˜‡

dawn basin
#

or we can coincide it with 2024.3 release and call this V3

#

90% of nodes are running this webserver now

grand bone
#

90% of which nodes?

spark crown
grand bone
#

yes, exactly

#

Was wondering how he could see which nodes are not referring to the JS on his web server.

wintry wyvern
dawn basin
#

my 90% nodes are on v3, obviously, I don't know esphome stats

dawn basin
#

@proper pawn included in beta

proper pawn
#

Happy about the enabling PR is making it to esphome.
Yes this is though, as webserver Lit-HTML is definitely not part of the esphome core ecosystem, still many of us love it and use it, so should be a quite conscious decision which direction to go.

Honestly I had some time to think, also looking at some projects and alternatives and definitely there is a lot of improvement potential.
Today this thread shows that while there is a zillion of ideas and requests, it will be tough to agree.

Still from visual perspective many improvements might do it to the codebase and thus will evolve/change significanty what we know and love as webserver V2.

Thus my suggestion to would be to accept the request and go for a new version, that for the time will not be default, but could be a non-default version: 2plus or version: 3.
Here more exploration and brave changes could be done as a bleeding edge.

Alternative cost: Ultimately this version would still be hosted remotely, and would even make less sense to include/build statically. As long as a user is OK with that I think this is OK. (33k->200k due to graph component)
We might add a minimal built-in fallback version to prep for no-internet situation.
Could worth researching later if there is a smaller graph library for Lit - probably there is.

Some interesting links:

dawn basin
#

this one looks nice

proper pawn
# dawn basin this one looks nice

Nice, but giving so much space for one entity is not a good option for me.
For an energy meter (Slimmelezer+) unit I have 20ish entities.

dawn basin
proper pawn
hazy lion
#

the current values of sliders is not reported. (only the values corresponding to slider endpoints are displayed)

grand bone
#

Yeah, I reported this as well. Also the upper value is often wrapped to below the slider

grand bone
#

I see in your case, the lower value forces the slider onto the next line too.

hazy lion
grand bone
#

yeah

proper pawn
# hazy lion the current values of sliders is not reported. (only the values corresponding to...

You are right, for the slider the current value is to be added.
I wonder what is the real value of 56.79999924 as a max value of the slider. Also do not see how this could be shown in a friendly way.
Frontend dows not parse the values, and it has no right-knowledge what is the adequate precision.
So I would say, that we leave X% space there and assume that a few digits fit there.

I would not want to fit all 3 values there (too much space), still thinking of a good solution.
Any hints?

I just paused making changes until we see a review and decision on where / how to move on with the refresh of the web_server frontend. Currently it is pending on esphome.

grand bone
fleet cloak
grand bone
fleet cloak
#

I wonder if the value is sent as a number or as text.

#

If it's text, then it should be rounded properly before being sent.

grand bone
#

look slike it should be:

std::string WebServer::sensor_json(sensor::Sensor *obj, float value, JsonDetail start_config) {
  return json::build_json([obj, value, start_config](JsonObject root) {
    std::string state;
    if (std::isnan(value)) {
      state = "NA";
    } else {
      state = value_accuracy_to_string(value, obj->get_accuracy_decimals());
      if (!obj->get_unit_of_measurement().empty())
        state += " " + obj->get_unit_of_measurement();
    }
    set_json_icon_state_value(root, obj, "sensor-" + obj->get_object_id(), state, value, start_config);
    if (start_config == DETAIL_ALL) {
      if (!obj->get_unit_of_measurement().empty())
        root["uom"] = obj->get_unit_of_measurement();
    }
  });
}
#
std::string value_accuracy_to_string(float value, int8_t accuracy_decimals) {
  if (accuracy_decimals < 0) {
    auto multiplier = powf(10.0f, accuracy_decimals);
    value = roundf(value * multiplier) / multiplier;
    accuracy_decimals = 0;
  }
  char tmp[32];  // should be enough, but we should maybe improve this at some point.
  snprintf(tmp, sizeof(tmp), "%.*f", accuracy_decimals, value);
  return std::string(tmp);
}
#

Seems like there needs to be a truncation to that number of decimals after the separator?

#

I suspect I don't understand the format string specifier, though.

#

Seems like maybe the browser is converting the string back to a floating point representation, and losing the "accuracy" conveyed. Perhaps leaving it as a string would be a better approach?

fleet cloak
grand bone
#

So, fixable inside this component, at any rate ๐Ÿ™‚

fleet cloak
#

I expect so.

hazy lion
# proper pawn You are right, for the slider the current value is to be added. I wonder what is...
- platform: template
    name: "${name} Bulk voltage"
    id: "bulk_voltage"
    step: 0.1
    min_value: 54
    max_value: 56.8
    mode: slider
    initial_value: "${bulk_v}"
    unit_of_measurement: V
    icon: mdi:battery-charging
    optimistic: true
  - platform: template
    name: "${name} Float voltage"
    id: "float_voltage"
    step: 0.1
    min_value: 52.8
    max_value: 54
    mode: slider
    initial_value: "${float_v}"
    unit_of_measurement: V
    icon: mdi:battery-charging
    optimistic: true

This is the corresponding code for the sliders.

#

I would not want to fit all 3 values there (too much space), still thinking of a good solution.
Any hints?
Showing current values and the endpoint values is bare minimum functionality. This is the only thing preventing me from using this js for my Solar battery node.

I just paused making changes until we see a review and decision on where / how to move on with the refresh of the web_server frontend. Currently it is pending on esphome.

grand bone
#

I think more important than the lower and upper values is the current actual value, in my opinion

hazy lion
wintry wyvern
proper pawn
# wintry wyvern If you change your PR to revert the V2 files and make your version V3 merging wo...

I will get back to this project after the February release is out as mentioned above.

In the meantime if someone has time to rework the complete build process it would be nice.

@wintry wyvern would you want to make the split on a branch?
At the moment v2 build is performed in a single vite step that does not seem to be flexible enough for any additional build artifacts.

I have started this work back in December, but had no time to finish (more details on this branch).
https://github.com/afarago/esphome-webserver/tree/build-restructure-with-fallback

mortal river
#

I mostly do web stuff and am interested in helping. While I don't understand the current problem or goal just yet, I'll have a look and see if I can help out.

mortal river
#

Circled back this evening, read through the thread and associated code a bit, and have a better understanding of the scenario. I agree with the sentiment that v2 should likely remain as it was and v3 should probably be a modified copy. While a v3 fork of sorts means that fixes to v2 may also need to be made to v3, that isn't as bad as never being able to update v2 again.

mortal river
#

Although I'm learning vite on the fly, it is all familiar concepts and one in particular we should leverage: chunking. The memory concerns and considerations are fair points for the device targets and chart.js is an excellent example of a bundle chunk that should be broken out. That way, this large dependency will only be loaded if/when necessary.

grand bone
#

Is that something that would have a separate config setting in the YAML? i.e. allow the main JS to be compiled into the firmware with the associated storage costs, so that people can benefit from the new look/feel, but still load the graph.js stuff externally or even skip it totally if it is not something that is needed.

mortal river
#

As I'm new to web_server as well, do I understand correctly that embedding via local, js_include, and/or css_include requires you to provide your own copy of those assets or does it implicitly use the remotely hosted assets normaly in use?

#

The default remotely loaded assets can benefit from chunking with minimal changes, but offline copies may require different bundles to be made and explicitly included (e.g. minimal vs everything)

grand bone
#

as I understand it, the JS is normally loaded from an internet-accessible webserver. There is an option (local: true) to compile the JS and other resources (downloaded from the internet URL, or whatever URL/file you tell it to use) into the firmware image that is written to the device, for the cases where internet access is undesirable (e..g closed network, self-contained, bitrot-prevention, etc).

mortal river
#

Aha so local: true supports essentially downloading/embedding js_url or js_include can be a URL as opposed to a local file? Suppose that either way, there will need to be separate bundles created since no internet means inability to dynamically load chunks, so, additional chunks would need to be embedded or not by choice.

grand bone
#

yes, I believe so. Haven't tested it, but the docs appear to say that. I imagine for v3, we could do something like local_graph: false which defaults to the same value as local: if not specified.

mortal river
#

This generally needs a bit more thought for sure. To start, we should probably go all in, but I'm keen on these sorts of optimizations and options absolutely.

supple heart
#
web_server:
  port: 80
  js_url: http://homeassistant.local:8123/local/www.js
#

is the way i load it locally from the HA "www" folder

mortal river
#

Ah yah, but that requires the devices to at minimum connected to wifi and for HA to be accessible. I think Rogan is talking about the offline access options local, js_include, and css_include

supple heart
#

ahh right i didnt read up enough ๐Ÿ˜‰

grand bone
#

so I think that if you add local: true to that, whatever is there will be downloaded and built into the image, so that e.g. it is usable when the device is in AP mode, for example

#

although a lot of mobile devices will use GSM for internet access, even when WiFi is attached to a closed network. Doesn't help when your js_url points to something that is not internet-accessible!

#

etc

mortal river
#

it is an interesting prospect and definitely see why keeping the size down is important when you're already pressed for space

#

or even if you're not since you could be pressed for it in the future heh

mortal river
#

https://github.com/afarago/esphome-webserver/pull/4

wintry wyvern
mortal river
#

Not certain if it just me, but when you interact with switches and such, it seems to be very latent. Are updates queued and flushed periodically or something?

dawn basin
#

got it... it is awaiting merge

mortal river
#

Iโ€™m not certain what is hosted there currently, but Iโ€™m guessing the stuff I did likely isnโ€™t too much different. What I was doing is mostly getting things to a place where it could be merged while leaving v2 as it was and making the new goodies available at an ESPHome hosted v3 endpoint. This is still pending in a couple ways, but you could host the latest locally on your machine/network

wintry wyvern
mortal river
#

Should be yup yup. Based on local testing, _static/v3/www.js and the other goodies are created

#

The v3 approach also has the benefit that we can do a little beta testing before updating the other documentation which recommends the v2 assets and then it is more of an opt-in from that point forward as opposed to forcing everyone over. Might also be good to buy some time to continue to iterate and improve (e.g. exploring chunking more) and then basically only peoples on this thread know about the new version.

proper pawn
# mortal river Next steps are for <@587748673300201494> to consider accepting my pull request (...

The reason I have done but stopped at a point with the split and multi vite build is that I am not confident about that tool and build env. So my branch seems to be working but even I am not 100% sure.

Me reviewing and accepting your pull request is not adding too much value.

If you have more insights, it would be best that you directly submit a v1-v2-v3 split to the origin. Once it is there I can take over V3 if Jesse supports that.

An initial spotting - I was experimenting with this split with the fallback version in mind. It is not discussed/agreed, this should not be part of any PR posted to the origin repo.

What do you think? Does that sound cool to you?

mortal river
#

From what I could gather, there were a couple issues that prevented your branch from working appropriately. More specifically these paths: https://github.com/afarago/esphome-webserver/pull/4/commits/a25fd1cfa16c7dc5f0e22419d01096eb173c55b0#diff-09d021e5a5d4bcf75d0f5a6ac7d5e675b7a871e3c2cd2544d11d799ef1970866

Prior to making modifications based on your branch, I did attempt an alternate approach or two and the summary is that Vite is making it challenging to have/build more than one "app". v1 + v2 works because v1 is just copying files while v2 is the actual app, so, adding v3 is essentially another app that creates the challenge. I didn't look too much at the fallback and that seems fine to remove and potentially consider at a later time, but this approach did afford the ability to create more than one version build/app thingie.

#

So, I could try to spend more time trying again, but breaking things up where each verson is essentially its own vite app did seem like a reasonable approach. Bit of Vite issues, posts, and otherwise that indicate much the same issue with varying levels of hacks and things that I couldn't get working in totality. For example, two other approaches would dump index.html in _static/v2/v2/index.html while another approach would dump public assets in _static instead of _static/v2.

#

Ah, are you saying that you think your work to split the versions up in to packages should potentially be pull requested to the esphome repo separately and then you'll bring v3 in to the new arrangement? I sleepie now, will check back tomorrow morning.

wintry wyvern
#

We would also need some changes to the
Docs to let people know that there is this great v3.

mortal river
wintry wyvern
#

Detault is still set to v2 in my PR

mortal river
#

Roger roger. Probably would be best to make it opt-in for some period.

mortal river
wintry wyvern
# grand bone Seems like there needs to be a truncation to that number of decimals after the s...

the problem seems to be on the js side.
this will fix it

  private _range(
    entity: entityConfig,
    action: string,
    opt: string,
    value: string,
    min: number | undefined,
    max: number | undefined,
    step: number | undefined
  ) {
    let valueString = step.toString();
    let numDecimalPlaces = 0  
    if (valueString.indexOf('.') !== -1) {
        numDecimalPlaces = valueString.split('.')[1].length;
    }
    console.log(numDecimalPlaces)
    return html`<div class="range">
      <label>${min || 0}</label>
      <input
        type="${entity.mode == 1 ? "number" : "range"}"
        name="${entity.unique_id}"
        id="${entity.unique_id}"
        step="${step || 1}"
        min="${min || Math.min(0, Number(value))}"
        max="${max || Math.max(10, Number(value))}"
        .value="${(Number(value).toFixed(numDecimalPlaces))}"
        @change="${(e: Event) => {
          const val = (<HTMLTextAreaElement>e.target)?.value;
          this.actioner?.restAction(entity, `${action}?${opt}=${val}`);
        }}"
      />
      <label>${max || 100}</label>
    </div>`;
  }

wintry wyvern
#

if you click fast on the controls the tab will expand.
I am not a web guy, but there should be a way to detect where you click and if it is a control item clicking them should not count as double clicking to expand the tab

spark crown
wintry wyvern
#

double clicking on the sensor/control side will colaps the debug log and the sensor/control side will tke up the whole screen

double clicking the debug log will do the same but reverse

#

if i want to change some values with the arrow buttons and click to fast it will trigger this feature

spark crown
#

Oh, this is a feature of the v3?

#

I have not actually tried it yet

#

haha

wintry wyvern
#

yep ๐Ÿ™‚

mortal river
#

If you'd like to give it a whirl:

web_server:
  port: 80
  js_url: https://deploy-preview-49--esphome-webserver.netlify.app/v2/www.js
#

Some areas also expand on single click it seems

mortal river
#

Ideally we'd merge packages/workspaces, rebase v3 on top of that, and then continue making improvements such as this. Is there an owner of esphome-webserver that might be able to help us make progress? If not, I'd be interested in helping as a maintainer.

wintry wyvern
mortal river
#

Yes, that is the deployed endpoint from afaragoโ€™s pull request. Iโ€™d need to open a new pull request that duplicates his so that I can make changes

wintry wyvern
mortal river
#

(I canโ€™t push to his personal repo)

wintry wyvern
mortal river
#

Nah just a way for Jesse or anyone else to easily test the current code

wintry wyvern
#

I tried out your version-packages and it seems to do what it is supposed to do.
beeing able to build v1 and v2 separately.
v3 is not in there on purpose i guess?

wintry wyvern
#

@spark crown it's seems that we would really need someone responsible for the esphome-webserver repo.
By looking at the history of the repo it looks like there is nobody besides you responsible for it and it seems you are already quite involved with the main repo. Would it be possible to grand @mortal river some permissions on the esphome-webserver repo so we could get somewhere with this?

dawn basin
#

@torn relic might be able to do this

mortal river
#

:yayfrog: thanks so much!

#

I'll work on a fork / rebase of the actual work based on main

spark crown
#

๐Ÿ‘

mortal river
spark crown
mortal river
#

Roger, I'll fix in the other pull request

mortal river
#

npm run build from the root appears to create all 3 versions successfully, have a couple questions in the pull request for @proper pawn but otherwise looks like we're pretty close to being able to land this sweetness

#

Would be great if those on this thread familiar with the expectations of this change set could verify that all is well while using the above config that is representative of what would be deployed.

mortal river
# spark crown Conflict on #50

Doh, right, conflict created by the workspaces moving things around. @wintry wyvern want to re-do that change based on the current main branch (instead of the root v2/esp-entity-table.ts file it is packages/v2/src/esp-entity-table.ts) or I can just include it as part of #54, just didn't want to steal your fix

spark crown
mortal river
#

Lovely stuff! Yeah, an easier solve given access ability heh. #54 was a fun one to resolve conflicts on.

mortal river
dawn basin
#

ended up with ``` Unknown value '3', valid options are '1', '2'.
version: 3

wintry wyvern
#

The Main pr for v3 on esphome-webserver didn't get merged yet.
Also the pr on esphome-esphome which will make version: 3 a valide option, same thing.

mortal river
#

Oops. In other words, the PR deployed endpoint should work if you omit version or make it 2. Maybe.

#

Guessing that normally just dictates which production hosted endpoint to use when not specifying js_url

hazy lion
#

I don't use version and it works for me

spark crown
#

The difference between 2 and 3 in the version field just sets the js_url AFAICT so it doesnt matter for now since you are specifying it yourself

proper pawn
mortal river
#

Sweeeet, no problem and thank you for all the other important bits.

#

Makes sense on the version vs js_url -- I'll edit/update references appropriately.

#

@hazy lion @dawn basin just to make sure since you are likely familiar with the baseline expectations: all seems to look and work like you know and love?

wintry wyvern
#

@mortal river how hard would it be to update the page without reloading it after changing some components to internal = true and vice versa, so they are either displayed or not?

I would like to create a UI that displays inputs based on the seleced index on a select

fleet cloak
wintry wyvern
#

i dont think a reboot is needed after id(test_text).set_internal(true);
A simple reload of the page will fetch the new data and not display the test_text.
But i guess what i has hoping to do is not easily done since the components a instantiated once on event: state and there is no way to detect if a component got set to internal = true

fleet cloak
#

oh, you're hacking... ๐Ÿ˜›

mortal river
#

I'll have a looksee. We've also got the double click improvement pending and seeing about potentially leveraging dynamic imports to reduce memory overhead.

#

just guessing, but presumably the internal property is passed along and can be used as a render exemption

#

Unrelated, have contemplated adjusting the periodically pulsing heart to a simple green/red dot for node status (EDIT: or assume it is always online and only show "OFFLINE" or something when it isn't reachable)

#

Speaking of dynamic imports and potentially personal preference: should be a way for us to make the base goodies extensible

hazy lion
mortal river
#

Sorry about that, surely lost as part of conflict resolution when rebasing. Will try to find and restore those bits indeed.

mortal river
#

Fixed a potentially broken CSS selector due to a missing closing } in the declaration above html * that looks like it could have a visual effect that may potentially restore transitions to all the things: https://github.com/esphome/esphome-webserver/pull/54/commits/2060c36eba39dac382fd3ab5f4154cf57752d560#diff-28a1bb373f2f8df807bfee1bd78d3a2a3c2352a49a5d95503003bfcc5dc3e4d6R80
Also possible that CSS engines still interpreted this correctly and that there will be no observable change, but this was uncorrect in v2 as well.

proper pawn
#

@mortal river - Thank you for your work, code seems to be OK, also seems to be working OK for all my devices.

mortal river
#

No problem at all and lovely stuff.

grand bone
#

Was the fan entity considered/included when developing this PR? Have a kids project to build with multiple hbridge fans, and the direction property doesnโ€™t seem to be exposed on either classic web server or this pr

mortal river
spark crown
spark crown
#

web_server v3 -- home assistant styling

mortal river
#

Yayay! It is strange that the br files went missing and while commenting out gzipping didn't make sense as an explanation, was only seemingly pertinent thing. I'll have a looksee.

#

Now I see. The plugin above what was previously commented out was creating br and that extension got changed to gz

spark crown
#

Well its easier to review/merge smaller PRs now ๐Ÿ™‚

#

date has also been added to esphome including sending the state and requests for web_server

#

I am working on time entities too atm

mortal river
spark crown
#

That works, it downloads in my browser

mortal river
#

yup same

#

For those following along at home: you should probably change over to the official endpoint so that you can receive additional fixes and improvements.

web_server:
  port: 80
  js_url: https://oi.esphome.io/v3/www.js
mortal river
grand bone
#

Any chance of fan support now that this is merged? i.e. direction, speed, on/off?

#

congratulations, by the way, and thanks for pushing it through!

#

๐ŸŽ†

mortal river
#

I've added it to the to list. Possible to provide me with an example config that produces the missing bits?

grand bone
#
output:
  - platform: ledc
    id: globe_motor_forward_pin
    pin: GPIO12
  - platform: ledc
    id: globe_motor_reverse_pin
    pin: GPIO13

fan:
  - platform: hbridge
    id: globe_motor
    name: "Globe Motor"
    pin_a: globe_motor_forward_pin
    pin_b: globe_motor_reverse_pin
    # enable_pin: motor_enable
    decay_mode: slow   # slow decay mode (coasting) or fast decay (braking).
#

This fan should be capable of speeds at 1% resolution, allegedly, as well as forward and reverse.

#

in practice, the motor only starts spinning at around 20%, but that's more an implementation detail.

#

There is also an option to specify the number of steps available:

speed_count (Optional, int): Set the number of supported discrete speed levels. The value is used to calculate the percentages for each speed. E.g. 2 means that you have 50% and 100% while 100 will allow 1% increments in the output. Defaults to 100.

as well as a number of presets:

preset_modes (Optional): A list of preset modes for this fan. Preset modes can be used in automations (i.e. on_preset_set).
mortal river
#

@grand bone roger roger, will have a looksee. Brought over the seemingly related fix previously provided by rfdarter.

wintry wyvern
#

So what is needed to get #6203 merged?

mortal river
#

The lack of a slider value should be visible when I work on the fan issue? Guessing maybe just any slider such as a number template might also show this issue?

spark crown
#

correct

mortal river
#

I can take care of that if you like. Curious if we're feeling good about v3 as is to release it to the wild or if we should give folks on this thread some time to play with it? Suppose there has been a bit of time via previous pull requests and we can always keep making remote improvements since it doesn't ship in stone (unless embedded/offline)

#

Right, we've still got time and would target the docs update to the next version since documentation availability is dependent on an ESPHome release

wintry wyvern
#

just tested with

web_server:
  port: 80
  js_url: https://oi.esphome.io/v3/www.js```
#

slider is not showing the current value

#

ha is showing a overlay on hover with the current value. Would loo nice, but how would we handle mobile devides?

mortal river
wintry wyvern
#

yep

mortal river
#

Interesting. I pasted in every file from the pull request, perhaps it was in the other branch afarago was working on. Do you by chance have any other reference message, screen shot, or change set that shows how it was working?

wintry wyvern
#

I dont think the current value was ever shown in ha-styling

mortal river
#

Oh, that perhaps explains it then, though shvm indicated that maybe it was a change that was left behind. I'll add that to the list and work on it.

spark crown
#

I know this seems like something very minor, but to get 3 into the esphome release today, I need to put it into a beta which needs the docs to be updated as well...
I will be making the next beta in about an hour or so, then the final release a couple of hours after that...

mild pond
#

@proper pawn I recall some discussion about an RGB color picker, and seeing some mockups/trials. Looks like that didn't make it into the release. Is that still being planned?

mild pond
dawn basin
#

OTA updates added to v3?

rough bough
#

Hi ! I've just tested webserver V3 and it's nice ! But, do you think it could be possible to add code to re-order components ? for example by giving a weight to each components in yaml or to give an order list with ids in webserver components ?

#

I've seen that @wintry wyvern is renaming entities with 1., 2., ... but, perhaps we could have a better solution...

wintry wyvern
# rough bough Hi ! I've just tested webserver V3 and it's nice ! But, do you think it could be...

I was thinking about how to do that for some time now.

The neatest solution would be adding a Index variable to the entity base.
But that is not fesable to add that overhead just for the web_server.

My next idea was to "transmit" the Index in the name like name: "[z=1]My Number" and [z=1] would be cut out on the webserver part.
Also not a good solution since on HA the name would remain [z=1]My Number

What i am thinking about right now is to add a config option to the webserver component like ```
webserver:

  • id: my_number1
    index: 1
  • id: my_select1
    index: 2
  • id: my_number2
    Index: 3
    .
    ...
@mortal river if the webserver part on the esp would send a sorting index to the js side it would be easy to sort the enitiys right?
rough bough
#

i think that's the best solution, because after, we could add more options to configure each component

wintry wyvern
#

That way we could also add custom grouping

webserver: 
  -id: my_number
   group: "My custom Group"
   index:1
rough bough
#

yes !

#

instead of index, we could use the word "weight", default is 0, so you can add -10 to get it down or multiple with 10

#

don't know if you could understand me...

hazy lion
grand bone
#

Or simply provide a webserver: option to trim any leading digits from the name, AFTER sorting.

#
webserver:
  trim_sort_key: true
wintry wyvern
#
webserver: 
  - group:
    name: "My Group Nr. 1"
    weight: -100
  - group:
    id: my_group2
    name: "My Group Nr. 2"
    weight : -99
  - id: my_number1 
    group_id: my_group1
    weight: -10
  - id: my_number2
    group_id: my_group1
    weight: -9
  - id: my_number3
    group_id: my_group2
    weight: -10
  -id: my_number4
    group_id: my_group2
    weight: -9
rough bough
#

I think that Rogan is more easy to code but your solution is more intuitive and flexible...

rough bough
#

I would like to try to develop this feature... I've fork esphome and clone it locally, but now, i need to do the same for esphome-webserver respository ?

#

i don't understand how this repository is included and use from esphome...

#

Thanks for help ๐Ÿ™‚

rough bough
#

Ok, i think that i've understand that a npm build on packages/v2 generate code in _static directory. But, after, how is it integrated in esphome/components/web_server/server_index.h INDEX_GZ[] PROGMEM variable ?

dawn basin
#

So you guys wants drag and drop one esphome webserver too

wintry wyvern
inland relic
wintry wyvern
rough bough
spark crown
rough bough
#

@spark crown you think it's better to implements it on each component (entity) instead of configuring webserver: ?

spark crown
#

It probably doesnt matter too much, that was just my feedback for not bloating the EntityBase for webserver only because I know how its dont for mqtt ๐Ÿ™‚

#

I dont use the webserver personally

rough bough
#

ok, thanks

mortal river
#

Interesting idea for sure and I'm down to provide support for adhering to a customized sort order. The only thing I do not know offhand and may be a consideration on the device implementation: are webserver properties exposed? Not familiar enough to know where the best place might be to make it available to the frontend.

#

Related concept that would be a nice addition is also allowing end-users to customize the sort order while retaining it in localStorage on the user's browser.

fleet cloak
mortal river
#

Lovely stuff!

mortal river
# rough bough Ok, i think that i've understand that a npm build on packages/v2 generate code i...

Just in case you've not figured this portion out yet: you can provide the js_url property under webserver which is the URL to the network hosted static www.js file. This isn't as straightforward currently as it could be and I'll look at improving the following.

  • Start out in the latest version at ./packages/v3 and run PROXY_TARGET=http://device-name.local npm run build to generate the static bundles pointing at a particular device-name (or IP address) available on the network
  • This will generate the www.js bundle at ../../_static/v3 which I believe you've already located (aka ./_static/v3)
  • I've been using the serve global module, but any static file web server will work just as well https://www.npmjs.com/package/serve
  • Main key is to serve static files from a path that you reflect in the js_url appropriately
  • For example, cd ./_static/v3 && serve -p 8000 would make your js_url: http://192.168.1.123:8000/www.js while providing the IP address of your computer (ifconfig or ipconfig will output options)
  • You can leave a window open serving the static files and in a new window run build again to make changes without having to restart the server
rough bough
mortal river
#

No worries. Good development workflow / potential contribution thought exercise for me on something to document and improve.

rough bough
#

Are you the developer of web_server v3 ?

#

oh, yes, i've seen it on git, thanks for your good work !!

#

I have these categories :

  private static ENTITY_CATEGORIES = [
    "Sensor and Control",
    "Configuration",
    "Diagnostic",
  ];
#

What is going in Configuration and Diagnotic ?

spark crown
rough bough
#

Sure, but, do you have examples ?

spark crown
#

Uptime sensor is diagnostic by default

#

version text sensors, wifi signal sensors etc are all diagnostic

#

restart/shutdown/factory reset buttons are all configuration

rough bough
#

nice, thak you !

spark crown
#

the categories are all set by default, but can be overriden in yaml for any entity

rough bough
#

ok, tx

#

or is it forbidden with esphome ?

grand bone
#

The only possible mechanism that I can see being used for that would be to create an internal template number: named something like order_<entity_name> (convention), that refers to the numerical position of the relevant entity. Dragging and dropping the main entity could then update the associated number (and others which get shifted due to movement), which could be saved in EEPROM/FLASH using restore_value: true. Whether internal entities are exposed to the webserver: and hence the browser is an open question.

grand bone
#

I see that there is a include_internal: option for web_server: to control display of internal entities, but that doesn't necessarily mean that it is impossible to query internal entities if you know (or can guess) their names/identifiers, even if the attribute is false. That would allow you to define the entities as internal to not show them, but they could still be used to hold the position of the related entity.

rough bough
#

Ok, so, that is not a good solution IMO

grand bone
#

Sure, it's a hack ๐Ÿ™‚

spark crown
grand bone
#

Solution is probably to make two lists of entities (internal/not internal), and only ever allow the web_server: or api: etc components to interact with the not-internal list.

#

Or a canonical list of all entities, and a "public" list that points to the relevant entry in the canonical list.

#

Of course, it would be simpler (less memory) to just check the internal flag in each "external" component (web_server:, api:, mqtt: etc), but there is the risk that that doesn't happen in all access paths.

wintry wyvern
#

The js side could simply contruct a data structure on any drag and drop Event and send it back to the webserver which will store it and send it to the client on future requests

wintry wyvern
rough bough
#

Sorry, i can't find how YAML config is get from esp-app.ts (for example how to see if log: false)
I think that is here

const conf = document.querySelector("script#config");
#

But can't find this script in HTML

wintry wyvern
#

The js side has no connection to the yaml at all
The `web_server' sends Events to the clients.
If logging is off the webserver simply never sends any log events

rough bough
#

oh, yes, sorry for that question...

mortal river
#

Regarding persisting sort order to the device, it should probably be optional. Iโ€™m picturing two or more people arguing over the remote

spark crown
rough bough
#

Today, i'm trying again to sort components. I've many things to understand, but i move forward step by step ๐Ÿ™‚
In the file esp-entity-table.ts, i have

    window.source.addEventListener("state", (e: Event) => {
#

Where is defined this "state" event ?

#

Tx

fleet cloak
rough bough
#

I mean, where this state is created ?

fleet cloak
#

I think it's an event that comes from the web server.

wintry wyvern
#

I got it working so that you will be able to set a weight and group directly on the component if the web_server component is set in the config and store it together with the hash of the id of the component in a list in the web_server.
I am currently trying to figure out what would be the best way to send it to the client.
Looping through that list and comparing the hash of the ids on every state update seems not very efficient.
But I have not yet found a way to link that list to the entity's on setup

#

Maybe doing it on DETAIL_ALL would be fine???

fleet cloak
#

Doesn't the web server send a list of all the entities at first?

wintry wyvern
# fleet cloak Doesn't the web server send a list of all the entities at first?

https://github.com/esphome/esphome/blob/2345e7606a1ef2d1ec89e36d487666e9be8b2496/esphome/components/web_server/web_server.cpp#L132
Seems so.
And then send a json with DETAIL_ALL of every entity.

Do you think it would be a good practice to compare the the id's a that point?

https://github.com/esphome/esphome/blob/2345e7606a1ef2d1ec89e36d487666e9be8b2496/esphome/components/web_server/web_server.cpp#L442

So I would loop through the list of entitys to sort , compare the id's and on match send the weight and group?

fleet cloak
#

That would be the place to do it.

wintry wyvern
#

should we call it webserver_weight instead of weight in the config?

#
number:
  - platform: template
    name: Anzahl Hรผhner
    min_value: 0
    max_value: 100
    step: 1
    mode: box
    optimistic: True
    initial_value: 20
    weight: 12
    group: "Test Gruppe"
    on_value:
      then:
        lambda: id(chicken_in_coop_count).publish_state(x);
fleet cloak
#

I think it does need a better name to distinguish it. That's also a highly possible name for a component to use normally.

wintry wyvern
fleet cloak
#

not off-hand...

wintry wyvern
rough bough
#

@wintry wyvern I will take a look at this. Thanks for your work !

rough bough
#

Even text components for example ?

wintry wyvern
rough bough
#

So, do you think it will work on a text_sensor for example ?

spark crown
#

Left some comments

rough bough
#

And i've the message "Component not found: web_server."

#

Sorry, it's the first time i'm testing PR in esphome...
Perhaps it's better to test it in another way...

spark crown
rough bough
#

Oh, yes, you're right :
ImportError: cannot import name 'CONF_WEB_SERVER_SORTING_GROUP' from 'esphome.const' (/home/desktop/esphome-dev/esphome/esphome/const.py)

spark crown
#

Can't be used as an external component

wintry wyvern
wintry wyvern
rough bough
wintry wyvern
#

that will not work since i made some changes to /esphome/const.py which will not be updated using the external component feature

rough bough
#

i understand, i will get a copy...

wintry wyvern
wintry wyvern
#

would that be an acceptable way off declaring groups?

web_server:
  groups:
    - name: "My Group 1"
      weight: 1
    - name: "My Group 2"
      weight: 2

if so, does someone see a possible way of validating the provided web_server_sorting_group name on the component with the one specified in the web_server?

number:
  - platform: template
    name: "My Number z"
    id: my_number_1
    min_value: 0
    max_value: 100
    step: 1
    mode: box
    optimistic: True
    initial_value: 2
    web_server_sorting_weight: 2
    web_server_sorting_group: "My Group 1"
rough bough
#

Perhaps it could be better to provide an id for groups ?

#
web_server:
  groups:
    - name: "My Group 1"
      weight: 1
      id: my_group_1
    - name: "My Group 2"
      weight: 2
      id: my_group_2
number:
  - platform: template
    name: "My Number z"
    id: my_number_1
    min_value: 0
    max_value: 100
    step: 1
    mode: box
    optimistic: True
    initial_value: 2
    web_server_sorting_weight: 2
    web_server_sorting_group: my_group_1
grand bone
#

Why would you need a weight in both places?

#

is that the weight within the group, while the web_server: groups: weight would be the weight of each group relative to each other?

rough bough
#

you have the weight of the group and the weight of each component...

wintry wyvern
wintry wyvern
rough bough
#

I've copy your yaml file, checkout PR #6445 in esphome and checkout PR #58 in esphome-web

rough bough
#

Perhaps i'm wrong somewhere ?

wintry wyvern
#

Or did you build it and include the build js file in the yaml?

rough bough
#

i include the js...

#

could you post a screenshot ?

#

but, i've this error when i compile firmware :

Traceback (most recent call last):
  File "/home/desktop/esphome-dev/esphome.orig/venv/lib/python3.11/site-packages/tornado/web.py", line 1790, in _execute
    result = await result
             ^^^^^^^^^^^^
  File "/home/desktop/esphome-dev/esphome.orig/esphome/dashboard/web_server.py", line 807, in get
    self.write(entry.storage.to_json())
               ^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'to_json'

#

here is my conf of my webserver :

#
web_server:
  js_url: http://192.168.1.15:4173/www.js  
wintry wyvern
wintry wyvern
#
web_server:
  js_url: https://deploy-preview-58--esphome-webserver.netlify.app/v3/www.js

should work too

wintry wyvern
spark crown
#

Lets keep it simple and drop it for now and it can be picked up again in the future, simplifies the PR reviews too to get basic ordering in

ancient wedge
#

ordering > grouping

rough bough
#

@wintry wyvern perhaps you could add comments to your PR's and describe what is working and what is missing...

wintry wyvern
rough bough
#

Yes, it works now for me ๐Ÿ™‚ Sorry, i haven't told you...
good luck for tonight ๐Ÿ™‚

wintry wyvern
#

All components should now be sort-able

wintry wyvern
wintry wyvern
#

slider current value work in progress

wintry wyvern
supple heart
#

eggcellent!

wintry wyvern
#

How should we handle cases like this, where we have different decimal places?
Should we let the width of the slider be dynamically adjusted or should we make the slider smaller to account for let's say 2 digest after the dot before we shrink the slider?

grand bone
#

If the number of decimals goes up, a slider is likely not the right interface. If it is important to be able to select 15.27, you're never going to do that with a slider

#

a text box becomes the only way

#

maaaybe being able to switch between a slider and a text box?

#

don't like to overcomplicate things

mortal river
#

Especially on mobile, sometimes it is really difficult to get a slider to the value that you actually want. Always having the option to input the exact value you'd like sounds like a sweet option and suppose an implementation could display the number's default with an option to switch to the inverse alternative?

#

Regarding slider width relative to available space vs values, this is mostly a CSS layout consideration. Couple options there, but I want to say keeping the slider a constant width would look best. If you'd like to propose your changes as is, I'll pull them down and try some things out.

wintry wyvern
wintry wyvern
wintry wyvern
wintry wyvern
#

Works on mobile devices

spark crown
wintry wyvern
#
event: state
data: {"id":"number-cell_voltage_4","name":"Cell Voltage 4","icon":"","entity_category":0,"min_value":0,"max_value":5,"step":0.100000001,"mode":2,"value":3.299999952,"state":"3.3"}

I always thought the rounding error would come from the js side.
But it seams like the web_server already sends the wrong values.
My method to fix it assumed we would get the right data and uses the step to set the decimal places, but since the step already contains the error it will not work.

grand bone
#

Sounds like the web_server: needs to convert the step to a string with the correct number of decimal places. I think that code is already there, just needs to be invoked accordingly. does something like multiply by 10^(decimal places), rounds to an integer, converts to string, then inserts the decimal in the right place. (I think)

wintry wyvern
# wintry wyvern

the strange thing is I tested the slider with this and there was no issue at all.
Why would it sometimes get these errors and sometimes not?

spark crown
wintry wyvern
wintry wyvern
#

the problem seems to exist the other way around too

the js clearly sends

http://bms-faker-master.local/number/total_voltage/set?value=42.9

and that is the log

[22:29:28][D][number:054]: 'Total Voltage' - Setting number value
[22:29:28][D][number:113]:   New number value: 42.900002
[22:29:28][D][number:012]: 'Total Voltage': Sending state 42.900002
grand bone
#

not surprising that the esphome code parses the string into a float, since the Number's internal representation is a float.

#

and floats are well known to have this problem

wintry wyvern
grand bone
grand bone
#

Ok, I just got a bit confused when you talked about "parsed with a accuracy", since the problem is not in the parsing, it's the internal representation.

wintry wyvern
grand bone
#

fair enough then! ๐Ÿ˜„

mortal river
# wintry wyvern ```js interface entityConfig { unique_id: string; domain: string; id: stri...

JS can be loosey goosey when it comes to intermingling types, but what you showed here is a TypeScript interface which mostly just helps with enforcing expectations during development and compilation. What actually happens with a remotely provided value is not enforced by TS during runtime, so, usually need to add specific runtime checks and handling for potentially important bits like this.

#

Seems like a number is being received and we could String(num), num.toString(), or `${num}` to ensure it is always parsed as a string. Also, query parameters are always a key/value pair of strings (?value=42.9 ) [edited to include backticks for ${num}]

toxic frost
#

I am loving the new look and behaviour! Has anyone been looking at he design for Climate Control components? They could do with a bit of attention on mobile. I'd be willing to take a look if not

lyric totem
#

Are there plans to optimize/reduce the size of the JS for v3? I was doing some testing and noticed that it's roughly 6.5x (โ€ผ๏ธ๐Ÿ˜ณ) the size of v2, even gzipped

 33748 v2.js
219172 v3.js

219172-33748 = 185424
219172/33748 = 6.49



 11501 v2.js.gz
 75362 v3.js.gz

75362-11501 = 63861
75362/11501 = 6.55

I prefer to keep the assets local, but currently v3 will eat up a lot of additional space ๐Ÿ˜•

I see the code is already (at least somewhat) minified, but I'm not sure if things like removing unreachable code have also already been done.

spark crown
#

Something must be wrong there. The code was not that much larger

#

Ok nvm, it is way larger

grand bone
#

Most of that is likely the graphing library

wintry wyvern
lyric totem
wintry wyvern
#

Or are they pulled from remote?

lyric totem
#

If you're referring to the icons along the left of the "Sensors and Controls" entities, those are pulled from remote (e.g. https://api.iconify.design/mdi.json?icons=water-percent) in this case. There are some embedded SVGs for things like the home icon, but those are in v2 as well.

toxic frost
#

This is my thoughts for the climate. To reflect what is seen in HA?
This includes current preset, current mode, current state, current temperature, and target temperature.
It's "read only" currently so you wouldn't be able to change the temperature targets, but it looks a lot cleaner. It could also have a graph to represent the current temperature?

grand bone
#

That looks good to me. Would be nice to be able to graph the current temperature like the other sensors.

#

I wonder how hard it would be to pull the actual HA html/javascript to use in the web server interface?

wintry wyvern
wintry wyvern
toxic frost
toxic frost
wintry wyvern
#

In case you missed it. A long click on the current value of the slider will Pop up a input field so you can Typ in a precice value.

toxic frost
#

The other thing is you can change the Mode and Preset in the HA UI (drop-down) so should consider that too

wintry wyvern
#

I guess a + and - button to change the target would work as well

wintry wyvern
toxic frost
#

Mode only, with radio buttons to select the desired mode. Presets are not displayed at all

toxic frost
#

I'll spin up a dev environment later and try getting the "read only" bit working first

lyric totem
# wintry wyvern I see. So where does the doubling of the size come from?

There is generally more actual source code (packages/v2/src is 60K while packages/v3/src is 104K), and v3 includes the iconify-icon, which seems to use quite a lot of space considering it doesn't actually contain the icons. ๐Ÿคจ

60K iconify-icon.cjs
10K iconify-icon.d.ts
63K iconify-icon.js
22K iconify-icon.min.js
59K iconify-icon.mjs

I'm guessing/hoping only iconify-icon.min.js is actually bundled, but that still seems like an awful lot of space for essentially turning <iconify-icon icon="blah"/> into a request to https://api.iconify.design/mdi.json?icons=blah ๐Ÿง

spark crown
#

Please see #devs message

toxic frost
#

Managed to get the graph working for Climate

toxic frost
#

Need to resolve the width issue, I know this is an ongoing discussion about how best to use the screen space. Any suggestions?
Think I'd also like to sort the capitalisation and replace the underscore to match HA

wintry wyvern
fleet cloak
#

Different components have different numbers of modes I think.

wintry wyvern
#

on v2 the mode can be choosen via a select

toxic frost
#

Correct, and the Preset is the same. It's not changeable in V2 but it's just as valid as an option

toxic frost
#

I'm almost there with controls for climate, just need to make it look nice now. Issue I've got is any input components over the graph trigger the expand! I know someone flagged it - is it being looked at or is that something I should focus on first?

lyric totem
wintry wyvern
# toxic frost I'm almost there with controls for climate, just need to make it look nice now. ...

Do you mind sharing your work as a draft PR?


  _handleEntityRowClick(e: any) {
    if (e?.currentTarget?.domain === "sensor") {
      if (!e?.ctrlKey) e.stopPropagation();
      e?.currentTarget?.classList.toggle(
        "expanded",
        !e.ctrlKey ? undefined : true
      );
    }
  }
}

You mean a single click? Like on any Sensor?
Seems strange to me that it would also expand it on your control for the climate since it checks if its type sensor, but i guess it depends on how you got the graph implemented

toxic frost
wintry wyvern
#

@lyric totem did you get anywhere with modifying the flex to allow more space for the control and truncate long names?

wintry wyvern
#

give it a try with

web_server:
  js_url: https://deploy-preview-81--esphome-webserver.netlify.app/v3/www.js
#

then we could expand the sensor graph with a double click instead of a single click

lyric totem
#

Some of it's definitely still pretty broken, like extremely this narrow column

toxic frost
toxic frost
lyric totem
#

Eh I actually like sliders in general. Like if I want to change a light from 20% to 80% I don't want to have to wail on up/down arrows or type the value in

#

In this particular case I haven't actually done anything to adjust how they resize, just made the label collapse to give them max space. Definitely possible to improve with flex box, I just don't really know it well enough to do it yet without more research

toxic frost
#

Yeah that's a fair point on the lights front, I'd forgotten about those ๐Ÿ™ˆ

wintry wyvern
wintry wyvern
lyric totem
wintry wyvern
#

i will probably never use the climate component, but i think it gets annoying quickly if you want to change the temp by lets say 3 decrees and you would have to push a button 30 times.

wintry wyvern
wintry wyvern
#

Would still need a way to show the full name on hover, but only if the name is shortend i would prefer.
How could we handle mobile device in that regard?

toxic frost
toxic frost
wintry wyvern
#

After locking at it today, i think we could actually get way with shortening the name some more and give the control side even more space

toxic frost
#

Font size I was thinking specifically on mobile. Feels quite sizable in comparison to the HA app for example.

toxic frost
# wintry wyvern I think the font size is about right as it is. Moving the log to the bottom migh...

Most controls are quite small and fit nicely next to the name, but there's a few that could benefit from being on a separate line in the row. Number for example could have the top line with name and current number, then the slider full width below?
Fan/Lock components would benefit similarly, with their current state being the top line (which is currently missing) and the controls on the second line?

wintry wyvern
dawn basin
#

OTA not possible on it yet?

acoustic edge
#

to answer my own question it seems like there is only 2 options entity_category: "config" Anyway to make a custom category?

spark crown
#

categories and device classes are separate things.

#

No you cannot make a custom one

acoustic edge
#

how would I override the category?

spark crown
#

in yaml

#

you can set it to "", "diagnostic" or "config"

acoustic edge
#

Oh I misread you, so as I wrote

#

Why wasn't the sorting/ordering PR pushed?

spark crown
#

No, the docs are not done, and when looking at them I realised it needs a validation too because sorting weight is only valid for v3

acoustic edge
#

Gotcha.
If there are any other components that potentially may use the same sorting weight, it perhaps shouldn't haveweb_server in the name

spark crown
#

I doubt there are any

wintry wyvern
wintry wyvern
acoustic edge
dawn basin
#

this option

wintry wyvern
#

Is not there? Are you not able to choose the file? What is the problem?

wintry wyvern
#

Ota configuered in the config?
V3 has a Bug where ota is displayed even if not specifided in the config

wintry wyvern
dawn basin
#

can you share the code for v3 which one to use

wintry wyvern
#
ota:

web_server:
  version: 3 

Should work just fine

dawn basin
#

with esp-idf too?

spark crown
dawn basin
acoustic edge
#

@wintry wyvern what's the idea of this circle on the top right?

fleet cloak
#

Is that the replacement for the heartbeat indicator?

acoustic edge
#

Seems like it, what was that for?

fleet cloak
#

To indicate that you're actually still connected to a running device.

acoustic edge
#

Anyway to make it more subtle/March the design better?

#

It seems to only pulse for a second then it stops, not sure if that's by design

acoustic edge
#

I'm noticing when the device isn't active the symbol changes. Can we just have that symbol and keep it blank when it alive?

wintry wyvern
acoustic edge
#

I vote remove unless we are offline. It otherwise looks very clean

supple heart
#

I think the heart is better because it also denotes what it is and its function

rotund willow
#

It's over-complicated with heart bumping and circles etc.
It should simply display mdi:close-network-outline when disconnected. That would be in sync with standard HA UI, which uses the same icon for the status binary sensor

#

it shouldn't display anything when connected, or mdi:check-network-outline.

wintry wyvern
mortal river
#

I think, but am not sure, that I may have added the "Adjust beating heart to a green dot or only display an offline indicator" line item to the fixes and feature requests issue being used to track feedback and action items from this thread.

pzich kindly adjusted it to a green dot and I'll have a look at adjusting it to only appear when offline. Since there seems to be a sort of a split of preference here, would this be a good candidate for a configuration option of sorts?

mortal river
#

Working on improving the local development workflow and readme currently, curious which of these "Near future" checklist items may already be complete:

- [ ] Support for compressed files in flash for Standalone no internet nodes
- [ ] Add Climate
- [x] Add Select drop list
- [ ] Add Number editing
- [ ] Potentially use an optional card layout instead of a table

I want to say Climate and Number editing may be, but I could easily be wrong or missing others. I was going to migrate this list to issue #56 for easier editing and additions while also suggesting opening a separate Issue for a problem or feature request.

inland relic
#

I think valve support can also be added to the list

mortal river
inland relic
rotund willow
#

Valve is just a new kind of Cover

#

Internally is mostly the same

mortal river
mortal river
#

I've had the only display a disconnected icon change awhile ago, but been a bit lost in the weeds on trying to understand why it seems like once a device goes offline that it never comes back online. Anyone else observed the same? Will resume after sleepies.

mortal river
#

Think I figured out why and have a solve. Like HA, we should probably disable interactable elements when disconnected otherwise you might get the false impression that changing something might actually work.

wintry wyvern
mortal river
#

Is an online/offline icon necessary if interactable elements are disabled? Thatโ€™s the HA approach as well?

acoustic edge
#

An indicator for offline can't hurt

#

Also a device can technically not have any shown entities

mortal river
#

Makes sense. Was also wondering if a grayed offline indicator may be too subtle and if it should possibly be red. Also, relatively random icons without context are often confusing for users, so perhaps will add a tooltip on click tap. I did add a "last seen" concept for "30 seconds ago" that I could adjust to say "Offline for 30 seconds" instead.

spark crown
#

The webui is useless when not connected right? Just blur the entire page and add a disconnected "dialog"

dawn basin
#

api will not be connected in that case

spark crown
#

It has nothing to do with api

#

It's just the ping between the browser and device

dawn basin
acoustic edge
wintry wyvern
#

did we make some changes that could effect a switch recently?
Whatever the state of the swich is currently it always sends the rest action turn_on

spark crown
#

v2 is working correctly, so something has gone wrong in v3

#

But light switches work correctly

wintry wyvern
# spark crown Im seeing this, its not always sending turn_on, but the opposite of the state of...

It only works once. Then i breaks. Reloading the page will get it working again one time.

  toggle(ev: Event): void {
    console.log(this.state);
    const newState = this.isOn() ? this.stateOff : this.stateOn;
    let event = new CustomEvent("state", {
      detail: {
        state: newState,
        id: this.id,
      },
    });
    this.dispatchEvent(event);
  }

toggle is called fine, but the state is always the same, even the switch on the website is cleary changing its state

spark crown
#

I tried to take a wuick look at the webserver code this morning but I am way too unfamiliar with it

wintry wyvern
#

but I cant see any commit that could have affected it.
which browser did you use? did chrome get an update?

wintry wyvern
#

PR #86 broke it

#

There is no historic value for a switch, so
let history = [...this.entities[idx].value_numeric_history];
fails and
Object.assign(this.entities[idx], data);
is never called to update the switch

        let history = [...this.entities[idx].value_numeric_history];
        if (typeof data.value === "number") {
          history.push(data.value);
        } else if (data.current_temperature) {
          history.push(Number(data.current_temperature));
        }
        this.entities[idx].value_numeric_history = history.splice(-50);
#

can we revert that PR?

#

or do i need to open a PR ot revert it?

fleet cloak
#

I think everything needs a PR.

spark crown
#

what pr added that?

#

I think that was just part of the v3 initial code, so its not exactly reverting it, but it needs to be fixed

wintry wyvern
wintry wyvern
spark crown
#

I don't think we should revert that entire pr.

wintry wyvern
lyric totem
#

I think you could also just make that

let history = [...this.entities[idx]?.value_numeric_history ?? []];

so that an empty history array gets created if value_numeric_history doesn't exist

toxic frost
spark crown
spark crown
toxic frost
spark crown
#

@wintry wyvern your revert PR also reverts another PR?
Did you not just create the revert PR in github (It can be done with two clicks ๐Ÿ˜„)

wintry wyvern
spark crown
#

I did already and released it ๐Ÿ™‚

mortal river
#

Can anyone confirm that a device can go online/offline/online successfully?

  • Target a device or otherwise load a device's page and wait for it show as online
  • Remove power from the device and wait for it to go offline per the device page
  • Re-add power to the device and ensure that it does (or does not) come back online per the device page
wintry wyvern
mortal river
#

Thanks for the early confirmation and much appreciate the sanity check. Must be something about the development workflow / proxy dealio. Wondering if a reconnection routine type improvement there might still be goods.

wintry wyvern
mortal river
wintry wyvern
rough bough
#

Hi ! Does V3 have documentation ? is it possible to see it ?

fleet cloak
#

What kind of documentation?

rough bough
wintry wyvern
#

Strange, i thought we changed the docs to let the user know version: 3 is an option know.

rough bough
#

do you think it's lost ?

wintry wyvern
#

Ah is see i only changed it in my PR for entiy sorthing which is not merged yet.

#

Feel free to open a pr

rough bough
#

where is ou PR ? on your local repository ?

wintry wyvern
#

webserver_sorting and the docs for it should be ready. I hope we can get it into the next beta and start working on grouping

spark crown
wintry wyvern
#

yep, i just saw that you requested some changes to the docs

spark crown
#

Both code and docs PRs are failing CI too

#

Probably why I have not come back to them...haha
My PR list filters out draft prs or PRs with failing CI runs ๐Ÿ˜…

wintry wyvern
#

hmm, doc is failing bc of the size of the image for v3, but v1 and 2 are also using bigger images

wintry wyvern
#

seems like merging dev broke it, but i cant see the issue

#

found it, i messed up the manual merge from dev

lyric totem
#

Any thoughts on using websockets (or some other type of bidirectional socket) for web_server I/O? I'm not sure how much overhead that adds, but I've noticed that while the POST requests for setting values are generally fast, they sometimes take an absurdly long amount of time.

I'm guessing this will only get worse / more frequent when building things that require higher frequency input/POSTs.

Right now a socket is already being kept open for the EventStream stuff, but it's solely for output. If this was replaced with a websocket, it could be used for both.

fleet cloak
#

That seems like a network issue of some kind. It's very unlikely that the ESP is taking that long to respond.

lyric totem
#

I believe it's other network requests in flight (since I think the async server can only handle ~4 at a time, and there's already one occupied persistently by each EventStream)

fleet cloak
#

Is something else connecting to the ESP?

#

I guess you would have to do some network sniffing to see where the issue is.

mortal river
#

WebSockets isn't a terrible idea to consider as we are indeed essentially doing bidirectional communication (Server-Sent Events for state updates and XHR requests to change state). One limitation of SSE is that it indeed shares the same pool of browser-limited concurrent connections which varies per-browser, but I agree that the latency you observed was probably not a browser request concurrency limit (e.g. EventStream, downloading an image, turning something off, and something else(s) all in parallel). The image you shared would have to have 4+ requests overlapping for it to potentially be a concurrency issue.

#

However, one potential problem with considering WebSockets currently is that the ESPHome web server itself would have to support WebSockets. If not already supported, that would mean that someone would have to add support for the server side equivalent. If we've got or could add server side support, I'd be happy to help replace SSE with WS on the client side.

fleet cloak
#

Exactly, that's the big issue right there.

#

Btw, this thread is now in the wrong section. ๐Ÿคฃ It's no longer "external".

mortal river
#

Fair point, but losing all the subscribers would be somewhat of a bummer. Would a new channel under the Development category be a good option to keep it topical? Suppose #device-builder nor #devices-website is the right place

fleet cloak
#

It's fine for now. I just thought it was kind of funny. But actually, since there's so much interest now, a new channel would be good.

#

What should it be called?

mortal river
#

Dashboard refers to the ESPHome devices dashboard for logs, installing, etc correct? I'm not sure what terminology HA uses for their device dashboards, but perhaps #devices-dashboard?

#

To be honest, I've found it a little confusing previously that the device page thingie is in the esphome-webserver repo since "web server" often refers to the thing serving web pages as opposed to the web page itself

#

but this is more a javascript bundle being served by the device?

fleet cloak
#

They are somewhat connected, but yes.

mortal river
#

*javascript bundle being loaded by the page that the device is serving?

#

optionally embedded and also being served by the device

#

OH right, esphome-webserver is in fact the repo for the actual ESPHome web server that is also serving the javascript bundles. It has just clicked.

fleet cloak
#

Actually, no. ๐Ÿ™‚ It's only the front end.

#

A Lit Element web component frontend for the ESPHome web_server.

mortal river
#

Doh. But something in ESPHome's infrastructure is serving JS bundles resulting from compilation from this repo, suppose maybe just for local development it is also the web server.

fleet cloak
#

I think that's github with a CDN in front.

#

But the device web server can serve the bundle if set to local.

mortal river
#

Roger roger. Repo naming convention aside, not certain what may be best and surely someone else while chime in with a yay, nay, or other idea.

fleet cloak
#

I'll wait for a bit more discussion before creating the channel.

spark crown
spark crown
fleet cloak
#

Basically what this channel has become. Discussions about the web interface for the device.

#

esphome/web-server ๐Ÿ™‚

spark crown
#

web_server?

#

lol

#

device-webserver

fleet cloak
#

I was thinking that might as well be it. It could definitely include changes to the web server itself, like the websockets mentioned earlier.

spark crown
#
frontends:
  - home-assistant
  - mqtt
  - webserver
fleet cloak
#

How would you represent that as channels?

spark crown
#

frontends being the category

#

#device-webserver

mortal river
#

Yay! Separate threads will be useful for various webbie topics. Much appreciated.