Skip to content

Configuration

Michal Zaniewicz edited this page Jun 19, 2026 · 5 revisions

Configuration & modifications

Your settings live in the thin guition-va.yaml (entities, control tiles, which screens compile in). Deeper, code-level changes live in the firmware that file pulls from GitHub - the core is base/core.yaml and each screen is base/screens/*.yaml in the repo. After changing anything, re-flash (OTA is fine after the first USB flash); run esphome clean guition-va.yaml first to force a fresh pull of the remote firmware.

Device name & core entities (substitutions:)

Top of guition-va.yaml:

substitutions:
  name: voice-knob            # ESPHome node name (also the entity_id prefix)
  friendly_name: "Voice Knob" # shown in HA; also the LED ring's friendly name
  timezone: "Europe/Warsaw"   # IANA zone for the clock (DST automatic)
  ha_base_url: "http://homeassistant.local:8123"
  player_entity: media_player.voice_knob_player
  wake_word: "alexa"                            # on-device wake word (see below)
  weather_entity: weather.home
  room_temp_entity: sensor.temperature_...
  room_hum_entity: sensor.humidity_...
  forecast_entity: sensor.va_weekly_forecast    # weather screen (HA helper, see below)
  climate_entity: climate.living_room           # thermostat screen target

player_entity is this device's own speaker media player (named from name). If you rename the node, update player_entity to match.

Control tiles (the swipe-up tiles)

The four tiles are fully configured in substitutions: - no code editing. Each tile is any HA entity (toggled via homeassistant.toggle, so any toggleable domain works: light, switch, fan, input_boolean, ...), plus an icon and a label:

  tile1_entity: light.living_room
  tile1_icon: "bulb"
  tile1_name: "Light"
  tile2_entity: switch.desk_neon
  tile2_icon: "flash"
  tile2_name: "Neon"
  tile3_entity: light.led_strip
  tile3_icon: "led"
  tile3_name: "LED strip"
  tile4_entity: switch.power_socket
  tile4_icon: "power"
  tile4_name: "Socket"

Each tile's colour reflects the live on/off state.

Tile icon names

tileN_icon takes a name from this built-in set (the glyphs are baked into the font):

bulb · lamp · led · power · plug · switch · fan · ac · heater · thermometer · lock · unlock · door · blinds · tv · speaker · bell · wifi · home · flash

The same icon may repeat across tiles. For an icon outside the set, paste a raw glyph or a "\U000Fxxxx" codepoint from pictogrammers.com as the value (it is used as-is).

Choosing which screens compile in

In the packages: block of guition-va.yaml:

packages:
  core:
    url: https://github.com/MichalZaniewicz/esphome-guition-jc3636k718c-va
    ref: main                  # or a tag to pin a version, or "beta" for the dev branch
    files:
      - base/core.yaml         # always on (clock + control tiles + settings)
      - base/screens/player.yaml
      - base/screens/timer.yaml
      - base/screens/cool-cars.yaml
      - base/screens/space-wars.yaml
      - base/screens/snake.yaml
      - base/screens/weather.yaml
      - base/screens/thermostat.yaml
      - base/screens/sensors.yaml
      - base/screens/demo.yaml
      - base/watchfaces/neon.yaml   # optional home watchfaces (see below)
      - base/watchfaces/demo.yaml
    refresh: 0s
  • Comment out a base/screens/*.yaml line to drop that screen - its page, scripts, globals and carousel slot are simply not compiled.
  • Set the left-to-right carousel order with the screen_order substitution (e.g. "clock,player,timer,cars,space,snake,weather,thermostat,sensors,demo"). Names you don't include in files: are skipped automatically; clock is always present.

Watchfaces

The home screen's look is a watchface. Classic is built into the core and is always available (and is the fallback). Other faces are optional packages in base/watchfaces/ - enable them in the same files: list (shown above):

      - base/watchfaces/neon.yaml      # big two-tone digits + neon rings
      - base/watchfaces/demo.yaml      # minimal template to copy

Pick the active one at runtime in Settings → Home screen → Watchface - a live full-screen picker (knob switches, tap keeps). If the saved face's file is later removed, it falls back to Classic automatically.

Make your own: copy base/watchfaces/demo.yaml to base/watchfaces/<name>.yaml, change the four spots marked >>> EDIT <<< (a unique face id + name, the page id, the two id checks, the render script id), design your page, and add the file to files:. The template is heavily commented and lists every value you can read from the core (time, weather, room temp/humidity, battery, the Display toggles) - no core edits needed.

Weather screen (forecast helper)

The weather screen shows today + a 7-day radial dial. Home Assistant no longer exposes the forecast as an entity attribute, so the device reads it from a small template sensor you add to HA, which publishes a compact "cond,hi,lo,Day|..." string. The ready-made helper is in the repo at base/screens/weather.ha-helper.yaml - copy it into your HA config and point forecast_entity at the sensor it creates.

Switch the dial between Celsius and Fahrenheit in Settings → Widgets → Weather → Fahrenheit.

Thermostat screen

A round dial for a Home Assistant climate.* entity - set it with the climate_entity substitution. Turn the knob to change the target temperature (by the entity's target_temp_step); the new value is sent to HA about 0.6 s after you stop turning, so HA isn't spammed mid-adjust. Tap toggles the climate on/off (climate.turn_on / climate.turn_off). The dial reads current_temperature, temperature, hvac_action, current_humidity and the mode from the entity, and the accent colour follows the action (orange heating / blue cooling / teal idle / grey off). It needs no settings entries.

Running without Music Assistant

Music Assistant is optional. The device exposes a standard speaker media player (media_player.<name>_player); you can play to it from any HA media source, TTS, or automation. What you get:

  • Album art comes from the player entity's entity_picture (handled by the media_pic text sensor + online_image). With a plain media player that has no artwork, the player page just shows the dimmed background - everything else works.
  • If you don't want the player screen at all, comment out base/screens/player.yaml in the files: list (volume control via the knob stays in the core regardless).

Wake word

Set the on-device wake word with the wake_word substitution (default alexa). Built-in models: alexa, okay_nabu, hey_jarvis, hey_mycroft.

  wake_word: "okay_nabu"

Wake word only runs while connected to HA. Toggle it at runtime in Settings → Voice Assistant → Wake word, and the wake beep in Voice Assistant → Beep on wake.

Besides the wake word, you can press and hold anywhere on the screen to start the assistant (works on any screen). Turn this off in Settings → Assistant → Hold to talk if you trigger it by accident; the wake word keeps working regardless.

LED ring

# in base/core.yaml
- platform: esp32_rmt_led_strip
  id: ring_light
  pin: GPIO0
  num_leds: 13          # change if your ring has a different count
  rgb_order: GRB
  chipset: WS2812
  • Colors / speed of the reactions live in the effects: lambdas (Listen / Think / Speak / Volume / Alarm / Timer) - tweak the Color(...) values and update_interval.
  • Which reactions are enabled is user-controlled in Settings → LED Ring and stored persistently (g_ring_va, g_ring_timer, g_ring_alarm, g_ring_vol_en).
  • Default power-on state is RESTORE_DEFAULT_OFF (ring off until HA or a reaction turns it on).

Defaults (brightness, night mode, etc.)

These are globals with restore_value: yes (persist across reboots) and can be changed live in the UI. The Factory reset action (Settings → System) restores: brightness 100%, night mode off, weather/climate off, watchface back to Classic, wake word on, beep on, hold-to-talk on, default timer 60 min, night 22:00-07:00, screen-off "Never", high scores cleared.

Timezone & clock

Set your zone with the timezone substitution (IANA name, e.g. Europe/Warsaw, America/New_York); DST is handled automatically. Home Assistant's time platform does not push its zone to the device, so this is required - without it the clock falls back to the build host's zone (often UTC). The day-of-week abbreviations are an English array in the 1 s interval lambda of base/core.yaml ({"","Su","Mo",...}).

ESPHome can also reset the device's timezone to UTC at runtime (e.g. when a log/API client reconnects, or after a restart), which briefly showed the clock 1-2 h off until the next sync. To prevent this the core captures the resolved zone at boot and re-applies it every second, so the clock no longer drifts to UTC.

Battery calibration

The percentage curve is two arrays in the adc sensor's on_value lambda in base/core.yaml (vt[] = voltages, st[] = matching %). See Troubleshooting before changing them.

Performance knobs (don't remove without reason)

In base/core.yaml:

  • lvgl: buffer_size: 24% - keeps the draw buffer in fast internal RAM.
  • display: data_rate: 80MHz - QSPI speed.
  • logger: level: INFO - DEBUG is very noisy during voice.
  • Heavy full-screen effects (a rotating HUD image, an animated radial equalizer) were tried and rejected as too laggy on this S3 + QSPI combo. Re-add only with a very light method.