• Du musst dich registrieren, bevor du Beiträge verfassen kannst. Klicke auf Jetzt registrieren!, um den Registrierungsprozess zu starten. Registrierte User surfen werbefrei, können Suchen durchführen und sehen die volle Darstellung des Forums mit vielen anderen Unterforen!!!

Otto Wilde G32 | Smarthome

Hey Zusammen,
kurz ne andere "Smarthome" Frage, hat sich von euch schon einer Gedanken gemacht, quasi nen eigenen GasBuddy zu bauen? Ich hab ne seperate Gasflasche für den C16 sowie O.F.B. Wäre cool, wenn ich von dieser Gasflasche auch den Füllstand hätte. Hat da jemand Erfahrung mit ESP HX711 und Drucksensoren ... ?!
 
vielen lieben Dank für die tolle Arbeit :-)

Unter ioBroker läuft Euer Code genauso.
Hatte heute endlich Zeit einen kleinen View für mein Smarthome Display zu erstellen.
Die Temperaturen der externen Fühler werden nur angezeigt wenn diese eingesteckt sind.
Je nach Haubenstand ändert sich dann das Bild vom G32.
Anhang anzeigen 3388628
Anhang anzeigen 3388629
Das ist Mega!
Meine Frage:
könntest Du die VIS (VIS2) Online stellen?
Ich würde das so gerne auch haben wollen. Das ist einfach klasse!
Alternativ wäre evtuell eine kurze Beschreibung möglich? Finde ich im IOB Forum vielleicht noch weitere Infos, oder auf Github?
Über eine Antwort würde ich mich sehr freuen.
Danke
Michael
 
Das ist Mega!
Meine Frage:
könntest Du die VIS (VIS2) Online stellen?
Ich würde das so gerne auch haben wollen. Das ist einfach klasse!
Alternativ wäre evtuell eine kurze Beschreibung möglich? Finde ich im IOB Forum vielleicht noch weitere Infos, oder auf Github?
Über eine Antwort würde ich mich sehr freuen.
Danke
Michael
gerne, ich lade die Sachen morgen hoch
Ist für VIS
 

Anhänge

Ich möchte Euch aus gegebenem Anlass noch einmal mein grafisches Display zum G32 vorstellen:
PXL_20250521_124623094.MP~2.jpg


Bild ist unscharf und hat Spiegelungen, aber ich denke man erkennt alles. Das Display ist bei Aliexpress oft für unter 20€ zu bekommen und wird zuerst einmal über USB-C mit Spannung versorgt (und grund-programmiert). Darstellung ist sehr schön scharf und hell, deutlich besser als bei meinem alten Display. Anschluss mit Ladeschaltung für Lithium-Batterien ist auch vorhanden und noch einige weitere Schnittstellen. Man würde dann noch ein Gehäuse mit EIN/AUS-Schalter benötigen und dann wäre es perfekt als 'Grillbuddy'.

Warum ich das noch einmal heraushole? Bei meinen ersten Versuchen noch mit einem anderen Display habe ich das Projekt unter Arduino mit Hilfe von LVGL (Grafikbibliothek) aufwändig selbst programmiert. Das Zusammenladen der notwendigen Bibliotheken und die korrekte Einbindung waren komplex, um es vorsichtig auszudrücken ... hätte ich hier niemals zusammen mit allen Sourcen präsentieren können. Beim 'Nachbau' hätte es mit Sicherheit Probleme gegeben ...

Mit dem neuen Display (JC3248W535C) ist es aber möglich, das Ganze unter ESPHome zu programmieren und das kann dann jeder, der einen Home Assistant am Laufen hat. Updates laufen dann OTA, das Ganze ist extrem einfach. Der Code für ESPHome ist nur ca. 800 Zeilen lang, den kann ich ohne Probleme hier anhängen.

Man könnte noch viel hinzufügen, das Display hat z.B. auch Touch. Für mich reicht es aber so erst einmal. Es kann aber auch jeder selbst damit herumspielen. Würde mich freuen, wenn es irgendjemandem hilft ...

Gruß, Jörg.

PS: die Daten vom G32 landen natürlich alle auch im Home Assistant, wie bei ESPHome üblich.

YAML:
substitutions:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# bitte nur in diesen nächsten Zeilen Änderungen vornehmen                    #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Name des ESPHome Geräts (kann frei gewählt werden, keine Sonderzeichen) 
  name: g32-display
  device_description: "Monitor OW G32 Grill"
# Bluetooth MAC des G32 (z.B. zu finden mit der App nrf_Connect) 
  ble_mac_address: 94:E6:86:0A:27:52
# Credentials des eigenen Wifi Netzwerks  
  wifi_ssid: Finkenbusch 43
  wifi_password: 123456

# hier die Daten aus dem neu erstellten ESPHome Gerät einfügen
  ota_password: 39825aefe87449c0928189f9fb2e701a
  ha_api_key: E1fyywUUE1DWzu0OzhDkyc4yAnfGwyEfsVNvhytrU6k=
  ap_ssid: G32 Display Fallback Hotspot
  ap_password: 4Lytxfy25DNh  

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# ab hier bitte nur Änderungen vornehmen, wenn man weiß, was man tut und will #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
esphome:
  name: ${name}
  platformio_options:
    upload_speed: 921600
    board_build.flash_mode: dio
    board_build.f_flash: 80000000L
    board_build.f_cpu: 240000000L

esp32:
  board: esp32-s3-devkitc-1
  flash_size: 16MB
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y"
      CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
      CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
      CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
      CONFIG_SPIRAM_RODATA: y

psram:
  mode: octal
  speed: 80MHz # 120mhz is not supported and falls back to 40mhz

# Enable logging
logger:
  baud_rate: 921600

# Enable Home Assistant API
api:
  encryption:
    key: ${ha_api_key}

ota:
  - platform: esphome
    password: ${ota_password}

wifi:
  ssid: ${wifi_ssid}
  password: ${wifi_password}
  fast_connect: True
  on_connect:
    then:
      - lvgl.widget.show: wifi_connect_label
  on_disconnect:
    then:
      - lvgl.widget.hide: wifi_connect_label

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${ap_ssid}
    password: ${ap_password}

ble_client:
  - mac_address: ${ble_mac_address}
    id: ow_g32
    on_connect:
      then:
        - lvgl.widget.show: bt_connect_label
    on_disconnect:
      then:
        - lvgl.widget.hide: bt_connect_label
        - lvgl.widget.hide: [zone1_label, zone2_label, zone3_label, zone4_label]
        - lvgl.widget.hide: [sensor1_label, sensor2_label, sensor3_label, sensor4_label]
        - lvgl.widget.hide: [gas_percent_label, gas_weight_label, gas_percent_bar]
spi:
  id: display_qspi
  type: quad
  clk_pin: 47
  data_pins: [21, 48, 40, 39]

i2c:
  sda: 4
  scl: 8
  id: touchscreen_bus

output:
  - id: gpio_backlight_pwm
    platform: ledc
    pin: 1

light:
  - id: backlight
    name: Backlight
    platform: monochromatic
    output: gpio_backlight_pwm
    restore_mode: ALWAYS_ON

display:
  - platform: qspi_dbi
    model: axs15231
    data_rate: 40MHz
    id: my_display
    spi_id: display_qspi
    dimensions:
      height: 480
      width: 320
    cs_pin:
      number: 45
      ignore_strapping_warning: true
#    rotation: 0  #  0 for portrait
    rotation: 90 # 90 for landscape
    auto_clear_enabled: false

touchscreen:
  - platform: axs15231
    id: my_touch
    display: my_display
    i2c_id: touchscreen_bus
    calibration:
      x_min: 14
      x_max: 461
      y_min: 12
      y_max: 310
    transform:
      swap_xy: true
      mirror_x: false
      mirror_y: true
    on_touch:
      - lambda: |-
          ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
            touch.x,
            touch.y,
            touch.x_raw,
            touch.y_raw
          );

lvgl:
  #full_refresh: true # not needed any longer
  draw_rounding: 8 # necessary for the axs15231 display controller
  displays: my_display
  touchscreens: my_touch
  bg_color: 0
  border_width: 0
  outline_width: 0
  theme:
    label:
      text_color: 0xFFFFFF
      bg_color: 0
      bg_opa: TRANSP
      width: 120
      text_align: center
    bar:
      radius: 5
      indicator:
        radius: 5
        arc_color: red
    arc:
      radius: 5
      arc_color: 0x333333
      indicator:
        radius: 5
  style_definitions:
    - id: main_font_style
      text_font: MONTSERRAT_18
    - id: big_font_style
      text_font: MONTSERRAT_26
    - id: zone_arc_style
      width: 100
      height: 120       
    - id: sensor_arc_style
      width: 100
      height: 120       
  pages:
    - id: main_page
      widgets:
# fixed objects (will not change during runtime)
        - label:
            x: 0
            y: 4 # distance down from top
            styles: main_font_style
            text: 'T 1'

        - label:
            x: 120
            y: 4 # distance down from top
            styles: main_font_style
            text: 'T 2'

        - label:
            x: 240
            y: 4 # distance down from top
            styles: main_font_style
            text: 'T 3'

        - label:
            x: 360
            y: 4 # distance down from top
            styles: main_font_style
            text: 'T 4'

        - label:
            x: 0
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 1'

        - label:
            x: 120
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 2'

        - label:
            x: 240
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 3'

        - label:
            x: 360
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 4'

        - label:
            x: 0
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 120
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 240
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 360
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 0
            y:  250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 120
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 240
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 360
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 24
            y: 294 # distance down from top
            styles: main_font_style
            text_align: LEFT
            text: 'Gas:'

# variable objects (may change at runtime)
        - label:
            id: wifi_connect_label
            x: 0
            y: 4
            styles: main_font_style
            text_color: 0x00ff00
            text_align: LEFT
            width: 20
            text: "\uF1EB"
            hidden: true

        - label:
            id: battery_empty_label
            x: 220
            y: 4
            styles: main_font_style
            text_color: 0xff0000
            text_align: CENTER
            width: 40
            text: "\uF243"
            hidden: true

        - label:
            id: bt_connect_label
            x: 459
            y: 4
            styles: main_font_style
            text_color: 0x00ff00
            text_align: LEFT
            width: 20
            text: "\uF293"
            hidden: true

        - label:
            id: gas_percent_label
            x: 260
            y: 294 # distance down from top
            styles: main_font_style
            text: '-- %'
            hidden: true

        - label:
            id: gas_weight_label
            x: 360
            y: 294 # distance down from top
            styles: main_font_style
            text: '--- g'
            hidden: true

        - label:
            id: zone1_label
            x: 0
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: zone2_label
            x: 120
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: zone3_label
            x: 240
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: zone4_label
            x: 360
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: sensor1_label
            x: 0
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: sensor2_label
            x: 120
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: sensor3_label
            x: 240
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: sensor4_label
            x: 360
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - bar:
            id: gas_percent_bar
            x: 80
            y: 299
            height: 12
            width: 200
            radius: 5
            min_value: 1
            max_value: 100
            bg_color: 0xffffff
            indicator:
              bg_color: 0x00ff00
            value: 0
            hidden: true

        - arc:
            id: zone1_arc
            x: 10
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: zone_arc_style 
            value: 0

        - arc:
            id: zone2_arc
            x: 130
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: zone_arc_style 
            value: 0

        - arc:
            id: zone3_arc
            x: 250
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: zone_arc_style 
            value: 0

        - arc:
            id: zone4_arc
            x: 370
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: zone_arc_style 
            value: 0

        - arc:
            id: sensor1_arc
            x: 10
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: sensor_arc_style 
            value: 0

        - arc:
            id: sensor2_arc
            x: 130
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: sensor_arc_style 
            value: 0

        - arc:
            id: sensor3_arc
            x: 250
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: sensor_arc_style 
            value: 0

        - arc:
            id: sensor4_arc
            x: 370
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: sensor_arc_style 
            value: 0

sensor:
#  - platform: adc
#    pin: 5
#    name: "Battery Voltage"
#    unit_of_measurement: "V"
#    state_class: measurement
#    attenuation: 12db
#    accuracy_decimals: 2
#    samples: 16
#    filters:
#      - multiply: 1.72
#      - sliding_window_moving_average:
#          window_size: 15
  - platform: adc
    pin: 5
    name: "Battery SOC"
    unit_of_measurement: "%"
    state_class: measurement
    device_class: battery
    attenuation: 12db
    accuracy_decimals: 0
    samples: 16
    filters:
      - multiply: 1.72
      - sliding_window_moving_average:
          window_size: 15
      - calibrate_linear:
          method: exact
          datapoints:
            - 3.00 ->   0.0
            - 3.36 ->   5.0
            - 3.41 ->  10.0
            - 3.48 ->  20.0
            - 3.52 ->  30.0
            - 3.56 ->  40.0
            - 3.61 ->  50.0
            - 3.70 ->  60.0
            - 3.79 ->  70.0
            - 3.89 ->  80.0
            - 4.00 ->  90.0
            - 4.05 -> 100.0
      - clamp:
          min_value: 0.0
          max_value: 100.0
    update_interval: 4s
    on_value_range:
      - below: 20.0
        then:
          - lvgl.widget.show: battery_empty_label
      - above: 20.0
        then:
          - lvgl.widget.hide: battery_empty_label

  - platform: ble_rssi
    mac_address: ${ble_mac_address}
    name: "BT Signalstärke"
  - platform: wifi_signal
    name: "WiFi Signal ESP G32"
    update_interval: 10s
  - platform: internal_temperature 
    name: "CPU Temperatur ESP G32"
    update_interval: 10s

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 1"
    id: g32_T_1
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 10s
    lambda: |-
      return (x[6]*10.0+x[7]/10.0);
    on_value:
      - lvgl.label.update:
          id: zone1_label
          hidden: false
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();     
      - lvgl.arc.update:
          id: zone1_arc
          value: !lambda |-
            return (x);     

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 2"
    id: g32_T_2
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3000s
    lambda: |-
      return (x[8]*10.0+x[9]/10.0);
    on_value:
      - lvgl.label.update:
          id: zone2_label
          hidden: false
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();     
      - lvgl.arc.update:
          id: zone2_arc
          value: !lambda |-
            return (x);     

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 3"
    id: g32_T_3
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3001s
    lambda: |-
      return (x[10]*10.0+x[11]/10.0);
    on_value:
      - lvgl.label.update:
          id: zone3_label
          hidden: false
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();     
      - lvgl.arc.update:
          id: zone3_arc
          value: !lambda |-
            return (x);     

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 4"
    id: g32_T_4
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3002s
    lambda: |-
      return (x[12]*10.0+x[13]/10.0);
    on_value:
      - lvgl.label.update:
          id: zone4_label
          hidden: false
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();     
      - lvgl.arc.update:
          id: zone4_arc
          value: !lambda |-
            return (x);     

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 1"
    id: g32_Ext_1
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3003s
    lambda: |-
      return (x[14]*100.0+x[15])/10;
    on_value:
      - lvgl.label.update:
          id: sensor1_label
          hidden: false
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: sensor1_arc
          value: !lambda |-
            return (x);     

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 2"
    id: g32_Ext_2
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3003s
    lambda: |-
      return (x[16]*100.0+x[17])/10;
    on_value:
      - lvgl.label.update:
          id: sensor2_label
          hidden: false
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: sensor2_arc
          value: !lambda |-
            if(x == 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 3"
    id: g32_Ext_3
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3004s
    lambda: |-
      return (x[18]*100.0+x[19])/10;
    on_value:
      - lvgl.label.update:
          id: sensor3_label
          hidden: false
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: sensor3_arc
          value: !lambda |-
            if(x == 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 4"
    id: g32_Ext_4
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3005s
    lambda: |-
      return (x[20]*100.0+x[21])/10;
    on_value:
      - lvgl.label.update:
          id: sensor4_label
          hidden: false
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: sensor4_arc
          value: !lambda |-
            if(x == 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    type: characteristic
    name: "G32 Gasbuddy Füllstand in g"
    id: g32_Gas_g
    device_class: weight
    state_class: measurement
    unit_of_measurement: g
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3006s
    lambda: |-
      return (x[22]*256+x[23]);
    on_value:
      - lvgl.label.update:
          id: gas_weight_label
          hidden: false
          text: !lambda |-
            return (to_string(static_cast<int>(x)) + " g").c_str();     

  - platform: ble_client
    type: characteristic
    name: "G32 Gasbuddy Füllstand in %"
    state_class: measurement
    unit_of_measurement: "%"
    id: g32_Gas
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3007s
    lambda: |-
      return (x[31]);
    on_value:
      - lvgl.label.update:
          id: gas_percent_label
          hidden: false
          text: !lambda |-
            return (to_string(static_cast<int>(x)) + " %").c_str();     
      - lvgl.bar.update:
          id: gas_percent_bar
          hidden: false
          value: !lambda |-
            return (x);     

  - platform: ble_client
    type: characteristic
    name: "G32 Haube"
    id: g32_Haube
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3008s
    lambda: |-
      return (x[24]);

  - platform: ble_client
    type: characteristic
    name: "G32 Licht"
    id: g32_Licht
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3009s
    lambda: |-
      return (x[25]);


binary_sensor:
  - platform: status
    name: "Status ESP G32"

  - platform: template
    name: "G32 Licht"
    icon: "mdi:light-flood-down"
    lambda: |-
     if (id(g32_Licht).state == 1) {
     // G32 Haubenlicht ist AN.
     return true;
     } else {
     // G32 Haubenlicht ist AUS.
     return false;
     }

  - platform: template
    name: "G32 Haube"
    device_class: "door"
    icon: "mdi:door"
    lambda: |-
     if (id(g32_Haube).state == 1) {
     // G32 Haube ist offen.
     return true;
     } else {
     // G32 Haube ist geschlossen.
     return false;
     }
 
Ich möchte Euch aus gegebenem Anlass noch einmal mein grafisches Display zum G32 vorstellen:
Anhang anzeigen 3641865

Bild ist unscharf und hat Spiegelungen, aber ich denke man erkennt alles. Das Display ist bei Aliexpress oft für unter 20€ zu bekommen und wird zuerst einmal über USB-C mit Spannung versorgt (und grund-programmiert). Darstellung ist sehr schön scharf und hell, deutlich besser als bei meinem alten Display. Anschluss mit Ladeschaltung für Lithium-Batterien ist auch vorhanden und noch einige weitere Schnittstellen. Man würde dann noch ein Gehäuse mit EIN/AUS-Schalter benötigen und dann wäre es perfekt als 'Grillbuddy'.

Warum ich das noch einmal heraushole? Bei meinen ersten Versuchen habe ich das Projekt unter Arduino mit Hilfe von LVGL (Grafikbibliothek) aufwändig selbst programmiert. Das Zusammenladen der notwendigen Bibliotheken und die korrekte Einbindung waren komplex, um es vorsichtig auszudrücken ... hätte ich hier niemals zusammen mit allen Sourcen präsentieren können. Beim 'Nachbau' hätte es mit Sicherheit Probleme gegeben ...

Mit dem neuen Display (JC3248W535C) ist es aber möglich, das Ganze unter ESPHome zu programmieren und das kann dann jeder, der einen Home Assistant am Laufen hat. Updates laufen dann OTA, das Ganze ist extrem einfach. Der Code für ESPHome ist nur ca. 730 Zeilen lang, den kann ich ohne Probleme hier anhängen.

Man könnte noch viel hinzufügen, das Display hat z.B. auch Touch. Für mich reicht es aber so erst einmal. Es kann aber auch jeder selbst damit herumspielen. Würde mich freuen, wenn es irgendjemandem hilft ...

Gruß, Jörg.

PS: die Daten vom G32 landen natürlich alle auch im Home Assistant, wie bei ESPHome üblich.

YAML:
esphome:
  name: g32_jc3248w535
  friendly_name: Guition 320x480 JC3248W535 Native
  platformio_options:
    upload_speed: 921600
    board_build.flash_mode: dio
    board_build.f_flash: 80000000L
    board_build.f_cpu: 240000000L

esp32:
  board: esp32-s3-devkitc-1
  flash_size: 16MB
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y"
      CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
      CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
      CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
      CONFIG_SPIRAM_RODATA: y

psram:
  mode: octal
  speed: 80MHz # 120mhz is not supported and falls back to 40mhz

# Enable logging
logger:
  baud_rate: 921600

# Enable Home Assistant API
api:
  encryption:
    key: "E1fyywUUE1DWzu0OzhDkyc4yAnfGwyEfsVNvhytrU6k="

ota:
  - platform: esphome
    password: "39825aefe87449c0928189f9fb2e701a"

# hier die eigenen Daten einsetzen!
wifi:
  ssid: "Finkenbusch43"
  password: "123456"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Test320X480 Fallback Hotspot"
    password: "4Lytxfy25DNh"

# hier die eigenen Daten einsetzen! MAC vom G32 bekommt man z.B. über die App nrF
ble_client:
  - mac_address: 94:E6:86:0A:27:52
    id: OWG_G32C_2750

spi:
  id: display_qspi
  type: quad
  clk_pin: 47
  data_pins: [21, 48, 40, 39]

i2c:
  sda: 4
  scl: 8
  id: touchscreen_bus

display:
  - platform: qspi_dbi
    model: axs15231
    data_rate: 40MHz
    id: my_display
    spi_id: display_qspi
    dimensions:
      height: 480
      width: 320
    cs_pin: 45
#    rotation: 0  #  0 for portrait
    rotation: 90 # 90 for landscape
    #update_interval: never
    auto_clear_enabled: false
    #show_test_card: true # must enable update_interval, auto_clear_enable

output:
  - platform: ledc
    pin: GPIO1
    id: backlight

light:
  - platform: monochromatic
    output: backlight
    name: "backlight Light"
    restore_mode: ALWAYS_ON

touchscreen:
  - platform: axs15231
    id: my_touch
    display: my_display
    i2c_id: touchscreen_bus
    transform:
      swap_xy: true
      mirror_y: true
    on_touch:
      - lambda: |-
          ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
            touch.x,
            touch.y,
            touch.x_raw,
            touch.y_raw
          );

lvgl:
  #full_refresh: true # not needed any longer
  draw_rounding: 8 # necessary for the axs15231 display controller
  displays: my_display
  touchscreens: my_touch
  bg_color: 0
  border_width: 0
  outline_width: 0
  style_definitions:
    - id: main_font_style
      text_font: MONTSERRAT_18
      text_color: 0xFFFFFF
      bg_color: 0
      bg_opa: TRANSP
      width: 120
      text_align: CENTER
    - id: big_font_style
      text_font: MONTSERRAT_26
      text_color: 0xFFFFFF
      bg_color: 0
      bg_opa: TRANSP
      width: 120
      text_align: CENTER
    - id: main_arc_style
      width: 100
      height: 120     
      arc_color: 0x333333
    - id: details_style
      text_font: MONTSERRAT_16
      text_color: 0xFFFFFF
      bg_color: 0
      bg_opa: TRANSP 
  theme:
    bar:
      radius: 0
      indicator:
        radius: 0
        arc_color: red
  pages:
    - id: main_page
      widgets:
# fixed objects (will not change during runtime)
        - label:
            x: 0
            y: 4 # distance down from top
            styles: main_font_style
            text: 'Zone 1'

        - label:
            x: 120
            y: 4 # distance down from top
            styles: main_font_style
            text: 'Zone 2'

        - label:
            x: 240
            y: 4 # distance down from top
            styles: main_font_style
            text: 'Zone 3'

        - label:
            x: 360
            y: 4 # distance down from top
            styles: main_font_style
            text: 'Zone 4'

        - label:
            x: 0
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 1'

        - label:
            x: 120
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 2'

        - label:
            x: 240
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 3'

        - label:
            x: 360
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 4'

        - label:
            x: 0
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 120
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 240
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 360
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 0
            y:  250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 120
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 240
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 360
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 24
            y: 294 # distance down from top
            styles: main_font_style
            text_align: LEFT
            text: 'Gas:'

# variable objects (may change at runtime)
        - label:
            id: bt_present_label
            x: 464
            y: 4
            styles: main_font_style
            text_align: LEFT
            width: 12
            text: "\uF293"

        - label:
            id: gas_percent_label
            x: 260
            y: 294 # distance down from top
            styles: main_font_style
            text: '-- %'

        - label:
            id: gas_weight_label
            x: 360
            y: 294 # distance down from top
            styles: main_font_style
            text: '--- g'

        - label:
            id: temp1_label
            x: 0
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: temp2_label
            x: 120
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: temp3_label
            x: 240
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: temp4_label
            x: 360
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: sensor1_label
            x: 0
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: sensor2_label
            x: 120
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: sensor3_label
            x: 240
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: sensor4_label
            x: 360
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'

        - bar:
            id: gas_bar
            x: 80
            y: 299
            height: 12
            width: 200
            radius: 5
            min_value: 1
            max_value: 100
            bg_color: 0xffffff
            indicator:
              bg_color: 0x00ff00
            value: 0

        - arc:
            id: zone1_arc
            x: 10
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: main_arc_style
            value: 0

        - arc:
            id: zone2_arc
            x: 130
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: main_arc_style
            value: 0

        - arc:
            id: zone3_arc
            x: 250
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: main_arc_style
            value: 0

        - arc:
            id: zone4_arc
            x: 370
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: main_arc_style
            value: 0

        - arc:
            id: sensor1_arc
            x: 10
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: main_arc_style
            value: 0

        - arc:
            id: sensor2_arc
            x: 130
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: main_arc_style
            value: 0

        - arc:
            id: sensor3_arc
            x: 250
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: main_arc_style
            value: 0

        - arc:
            id: sensor4_arc
            x: 370
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: main_arc_style
            value: 0


#interval:
#  - interval: 1s
#    then:
#      - lvgl.widget.redraw:

sensor:
  - platform: ble_rssi
    mac_address: 94:E6:86:0A:27:52
    name: "BT Signalstärke"
  - platform: wifi_signal
    name: "WiFi Signal ESP G32"
    update_interval: 300s
  - platform: internal_temperature
    name: "CPU Temperatur ESP G32"
    update_interval: 300s

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 1"
    id: g32_T_1
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 10s
    lambda: |-
      return (x[6]*10.0+x[7]/10.0);
    on_value:
      - lvgl.label.update:
          id: temp1_label
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();   
      - lvgl.arc.update:
          id: zone1_arc
          value: !lambda |-
            return (x);   

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 2"
    id: g32_T_2
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3000s
    lambda: |-
      return (x[8]*10.0+x[9]/10.0);
    on_value:
      - lvgl.label.update:
          id: temp2_label
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();   
      - lvgl.arc.update:
          id: zone2_arc
          value: !lambda |-
            return (x);   

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 3"
    id: g32_T_3
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3001s
    lambda: |-
      return (x[10]*10.0+x[11]/10.0);
    on_value:
      - lvgl.label.update:
          id: temp3_label
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();   
      - lvgl.arc.update:
          id: zone3_arc
          value: !lambda |-
            return (x);   

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 4"
    id: g32_T_4
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3002s
    lambda: |-
      return (x[12]*10.0+x[13]/10.0);
    on_value:
      - lvgl.label.update:
          id: temp4_label
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();   
      - lvgl.arc.update:
          id: zone4_arc
          value: !lambda |-
            return (x);   

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 1"
    id: g32_Ext_1
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3003s
    lambda: |-
      return (x[14]*100.0+x[15])/10;
    on_value:
      - lvgl.label.update:
          id: sensor1_label
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };   
      - lvgl.arc.update:
          id: sensor1_arc
          value: !lambda |-
            return (x);   

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 2"
    id: g32_Ext_2
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3003s
    lambda: |-
      return (x[16]*100.0+x[17])/10;
    on_value:
      - lvgl.label.update:
          id: sensor2_label
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };   
      - lvgl.arc.update:
          id: sensor2_arc
          value: !lambda |-
            if(x == 1500) {return (0);
            } else {
            return (x);
            };   

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 3"
    id: g32_Ext_3
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3004s
    lambda: |-
      return (x[18]*100.0+x[19])/10;
    on_value:
      - lvgl.label.update:
          id: sensor3_label
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };   
      - lvgl.arc.update:
          id: sensor3_arc
          value: !lambda |-
            if(x == 1500) {return (0);
            } else {
            return (x);
            };   

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 4"
    id: g32_Ext_4
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3005s
    lambda: |-
      return (x[20]*100.0+x[21])/10;
    on_value:
      - lvgl.label.update:
          id: sensor4_label
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };   
      - lvgl.arc.update:
          id: sensor4_arc
          value: !lambda |-
            if(x == 1500) {return (0);
            } else {
            return (x);
            };   

  - platform: ble_client
    type: characteristic
    name: "G32 Gasbuddy Füllstand in g"
    id: g32_Gas_g
    device_class: weight
    state_class: measurement
    unit_of_measurement: g
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3006s
    lambda: |-
      return (x[22]*256+x[23]);
    on_value:
      - lvgl.label.update:
          id: gas_weight_label
          text: !lambda |-
            return (to_string(static_cast<int>(x)) + " g").c_str();   

  - platform: ble_client
    type: characteristic
    name: "G32 Gasbuddy Füllstand in %"
    state_class: measurement
    unit_of_measurement: "%"
    id: g32_Gas
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3007s
    lambda: |-
      return (x[31]);
    on_value:
      - lvgl.label.update:
          id: gas_percent_label
          text: !lambda |-
            return (to_string(static_cast<int>(x)) + " %").c_str();   
      - lvgl.bar.update:
          id: gas_bar
          value: !lambda |-
            return (x);   

  - platform: ble_client
    type: characteristic
    name: "G32 Haube"
    id: g32_Haube
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3008s
    lambda: |-
      return (x[24]);

  - platform: ble_client
    type: characteristic
    name: "G32 Licht"
    id: g32_Licht
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3009s
    lambda: |-
      return (x[25]);


binary_sensor:
  - platform: status
    name: "Status ESP G32"

  - platform: template
    name: "G32 Licht"
    icon: "mdi:light-flood-down"
    lambda: |-
     if (id(g32_Licht).state == 1) {
     // G32 Haubenlicht ist AN.
     return true;
     } else {
     // G32 Haubenlicht ist AUS.
     return false;
     }

  - platform: template
    name: "G32 Haube"
    device_class: "door"
    icon: "mdi:door"
    lambda: |-
     if (id(g32_Haube).state == 1) {
     // G32 Haube ist offen.
     return true;
     } else {
     // G32 Haube ist geschlossen.
     return false;
     }
Mega 👍🏼

Hast du noch einen Link zu deinem bestellten Display? Bin nicht so der Aliexpress-Besteller und habe immer das Gefühl, nie das richtige zu finden.

Würde ich dann einfach mal versuchen nachzubauen 👍🏼
 
Ich weiß nicht, ob Links hier so gerne gesehen werden ...
Gib einfach JC3248W535C ein, dann kommen schon einige Angebote von AliExpress. Amazon liefert es wohl momentan nicht.
Grüße, Jörg.
PS: habe meines von hier: JC3248W535
 
Ich weiß nicht, ob Links hier so gerne gesehen werden ...
Gib einfach JC3248W535 ein, dann kommen schon einige Angebote von AliExpress. Amazon liefert es wohl momentan nicht.
Grüße, Jörg.
Es ist echt unnormal, der Laden ist mir unheimlich.

Habe das als Suchbegriff auf aliexpress.de eingegeben, es kam genau 1 Treffer. Den habe ich jetzt bestellt, mal sehen ob es das richtige ist 😬 Hat jetzt nur 9 Euro gekostet, kommt mir schon wieder spanisch vor.

Screenshot_20250521-164859~2.png
 
Es ist echt unnormal, der Laden ist mir unheimlich.

Habe das als Suchbegriff auf aliexpress.de eingegeben, es kam genau 1 Treffer. Den habe ich jetzt bestellt, mal sehen ob es das richtige ist 😬 Hat jetzt nur 9 Euro gekostet, kommt mir schon wieder spanisch vor.

Anhang anzeigen 3641987
Ist auf jeden Fall das richtige Display. Ich habe den Link zu dem von mir bestellten jetzt noch oben eingefügt. Wenn nicht erlaubt, dann bitte löschen ...
Mit JC3248W535C kommen mehr Resultate!?! Es gibt solche Displays (die sich für ESPHome eignen, z.B. von Guition) auch mit 480x480 Punkten, habe ich auch schon bestellt, aber das angegebene ist eigentlich schon super gut für unsere Zwecke geeignet.
 
Ich möchte Euch aus gegebenem Anlass noch einmal mein grafisches Display zum G32 vorstellen:
Anhang anzeigen 3641865

Bild ist unscharf und hat Spiegelungen, aber ich denke man erkennt alles. Das Display ist bei Aliexpress oft für unter 20€ zu bekommen und wird zuerst einmal über USB-C mit Spannung versorgt (und grund-programmiert). Darstellung ist sehr schön scharf und hell, deutlich besser als bei meinem alten Display. Anschluss mit Ladeschaltung für Lithium-Batterien ist auch vorhanden und noch einige weitere Schnittstellen. Man würde dann noch ein Gehäuse mit EIN/AUS-Schalter benötigen und dann wäre es perfekt als 'Grillbuddy'.

Warum ich das noch einmal heraushole? Bei meinen ersten Versuchen noch mit einem anderen Display habe ich das Projekt unter Arduino mit Hilfe von LVGL (Grafikbibliothek) aufwändig selbst programmiert. Das Zusammenladen der notwendigen Bibliotheken und die korrekte Einbindung waren komplex, um es vorsichtig auszudrücken ... hätte ich hier niemals zusammen mit allen Sourcen präsentieren können. Beim 'Nachbau' hätte es mit Sicherheit Probleme gegeben ...

Mit dem neuen Display (JC3248W535C) ist es aber möglich, das Ganze unter ESPHome zu programmieren und das kann dann jeder, der einen Home Assistant am Laufen hat. Updates laufen dann OTA, das Ganze ist extrem einfach. Der Code für ESPHome ist nur ca. 800 Zeilen lang, den kann ich ohne Probleme hier anhängen.

Man könnte noch viel hinzufügen, das Display hat z.B. auch Touch. Für mich reicht es aber so erst einmal. Es kann aber auch jeder selbst damit herumspielen. Würde mich freuen, wenn es irgendjemandem hilft ...

Gruß, Jörg.

PS: die Daten vom G32 landen natürlich alle auch im Home Assistant, wie bei ESPHome üblich.

YAML:
esphome:
  name: g32_jc3248w535
  friendly_name: Guition 320x480 JC3248W535 Native
  platformio_options:
    upload_speed: 921600
    board_build.flash_mode: dio
    board_build.f_flash: 80000000L
    board_build.f_cpu: 240000000L

esp32:
  board: esp32-s3-devkitc-1
  flash_size: 16MB
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y"
      CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
      CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
      CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
      CONFIG_SPIRAM_RODATA: y

psram:
  mode: octal
  speed: 80MHz # 120mhz is not supported and falls back to 40mhz

# Enable logging
logger:
  baud_rate: 921600

# Enable Home Assistant API
api:
  encryption:
    key: "E1fyywUUE1DWzu0OzhDkyc4yAnfGwyEfsVNvhytrU6k="

ota:
  - platform: esphome
    password: "39825aefe87449c0928189f9fb2e701a"

# hier die eigenen Daten einsetzen!
wifi:
  ssid: "Finkenbusch43"
  password: "123456"
  fast_connect: True
  on_connect:
    then:
      - lvgl.widget.show: wifi_connect_label
  on_disconnect:
    then:
      - lvgl.widget.hide: wifi_connect_label

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Test320X480 Fallback Hotspot"
    password: "4Lytxfy25DNh"

# hier die eigenen Daten einsetzen! MAC vom G32 bekommt man z.B. über die App 'nrF Connect'
ble_client:
  - mac_address: 94:E6:86:0A:27:52
    id: OWG_G32C_2750
    on_connect:
      then:
        - lvgl.widget.show: bt_connect_label
    on_disconnect:
      then:
        - lvgl.widget.hide: bt_connect_label

spi:
  id: display_qspi
  type: quad
  clk_pin: 47
  data_pins: [21, 48, 40, 39]

i2c:
  sda: 4
  scl: 8
  id: touchscreen_bus

display:
  - platform: qspi_dbi
    model: axs15231
    data_rate: 40MHz
    id: my_display
    spi_id: display_qspi
    dimensions:
      height: 480
      width: 320
    cs_pin: 45
#    rotation: 0  #  0 for portrait
    rotation: 90 # 90 for landscape
    #update_interval: never
    auto_clear_enabled: false
    #show_test_card: true # must enable update_interval, auto_clear_enable

output:
  - platform: ledc
    pin: GPIO1
    id: backlight

light:
  - platform: monochromatic
    output: backlight
    name: "backlight Light"
    restore_mode: ALWAYS_ON

touchscreen:
  - platform: axs15231
    id: my_touch
    display: my_display
    i2c_id: touchscreen_bus
    calibration:
      x_min: 14
      x_max: 461
      y_min: 12
      y_max: 310
    transform:
      swap_xy: true
      mirror_x: false
      mirror_y: true
    on_touch:
      - lambda: |-
          ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
            touch.x,
            touch.y,
            touch.x_raw,
            touch.y_raw
          );


lvgl:
  #full_refresh: true # not needed any longer
  draw_rounding: 8 # necessary for the axs15231 display controller
  displays: my_display
  touchscreens: my_touch
  bg_color: 0
  border_width: 0
  outline_width: 0
  style_definitions:
    - id: main_font_style
      text_font: MONTSERRAT_18
      text_color: 0xFFFFFF
      bg_color: 0
      bg_opa: TRANSP
      width: 120
      text_align: CENTER
    - id: big_font_style
      text_font: MONTSERRAT_26
      text_color: 0xFFFFFF
      bg_color: 0
      bg_opa: TRANSP
      width: 120
      text_align: CENTER
    - id: main_arc_style
      width: 100
      height: 120
      arc_color: 0x333333
    - id: details_style
      text_font: MONTSERRAT_16
      text_color: 0xFFFFFF
      bg_color: 0
      bg_opa: TRANSP
  theme:
    bar:
      radius: 0
      indicator:
        radius: 0
        arc_color: red
  pages:
    - id: main_page
      widgets:
# fixed objects (will not change during runtime)
        - label:
            x: 0
            y: 4 # distance down from top
            styles: main_font_style
            text: 'Zone 1'

        - label:
            x: 120
            y: 4 # distance down from top
            styles: main_font_style
            text: 'Zone 2'

        - label:
            x: 240
            y: 4 # distance down from top
            styles: main_font_style
            text: 'Zone 3'

        - label:
            x: 360
            y: 4 # distance down from top
            styles: main_font_style
            text: 'Zone 4'

        - label:
            x: 0
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 1'

        - label:
            x: 120
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 2'

        - label:
            x: 240
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 3'

        - label:
            x: 360
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 4'

        - label:
            x: 0
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 120
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 240
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 360
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 0
            y:  250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 120
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 240
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 360
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 24
            y: 294 # distance down from top
            styles: main_font_style
            text_align: LEFT
            text: 'Gas:'

# variable objects (may change at runtime)
        - label:
            id: wifi_connect_label
            x: 0
            y: 4
            styles: main_font_style
            text_align: LEFT
            width: 20
            text: "\uF1EB"
            hidden: true

        - label:
            id: bt_connect_label
            x: 459
            y: 4
            styles: main_font_style
            text_align: LEFT
            width: 20
            text: "\uF293"
            hidden: true

        - label:
            id: gas_percent_label
            x: 260
            y: 294 # distance down from top
            styles: main_font_style
            text: '-- %'

        - label:
            id: gas_weight_label
            x: 360
            y: 294 # distance down from top
            styles: main_font_style
            text: '--- g'

        - label:
            id: temp1_label
            x: 0
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: temp2_label
            x: 120
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: temp3_label
            x: 240
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: temp4_label
            x: 360
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: sensor1_label
            x: 0
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: sensor2_label
            x: 120
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: sensor3_label
            x: 240
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'

        - label:
            id: sensor4_label
            x: 360
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'

        - bar:
            id: gas_bar
            x: 80
            y: 299
            height: 12
            width: 200
            radius: 5
            min_value: 1
            max_value: 100
            bg_color: 0xffffff
            indicator:
              bg_color: 0x00ff00
            value: 0

        - arc:
            id: zone1_arc
            x: 10
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: main_arc_style
            value: 0

        - arc:
            id: zone2_arc
            x: 130
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: main_arc_style
            value: 0

        - arc:
            id: zone3_arc
            x: 250
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: main_arc_style
            value: 0

        - arc:
            id: zone4_arc
            x: 370
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: main_arc_style
            value: 0

        - arc:
            id: sensor1_arc
            x: 10
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: main_arc_style
            value: 0

        - arc:
            id: sensor2_arc
            x: 130
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: main_arc_style
            value: 0

        - arc:
            id: sensor3_arc
            x: 250
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: main_arc_style
            value: 0

        - arc:
            id: sensor4_arc
            x: 370
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: main_arc_style
            value: 0


#interval:
#  - interval: 1s
#    then:
#      - lvgl.widget.redraw:

sensor:
  - platform: adc
    pin: 5
    name: "Battery SOC"
    unit_of_measurement: "%"
    state_class: measurement
    device_class: battery
    attenuation: 12db
    accuracy_decimals: 0
    samples: 16
    filters:
      - multiply: 1.72
      - sliding_window_moving_average:
          window_size: 15
      - calibrate_linear:
          method: exact
          datapoints:
            - 3.00 ->   0.0
            - 3.20 ->  10.0
            - 3.40 ->  30.0
            - 3.60 ->  50.0
            - 3.80 ->  70.0
            - 3.90 ->  80.0
            - 4.00 ->  90.0
            - 4.10 -> 100.0
      - clamp:
          min_value: 0.0
          max_value: 100.0
    update_interval: 20s
    on_value_range:
      - below: 20.0
        then:
          - lvgl.widget.show: battery_empty_label
      - above: 20.0
        then:
          - lvgl.widget.hide: battery_empty_label

  - platform: ble_rssi
    mac_address: 94:E6:86:0A:27:52
    name: "BT Signalstärke"
  - platform: wifi_signal
    name: "WiFi Signal ESP G32"
    update_interval: 300s
  - platform: internal_temperature
    name: "CPU Temperatur ESP G32"
    update_interval: 300s

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 1"
    id: g32_T_1
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 10s
    lambda: |-
      return (x[6]*10.0+x[7]/10.0);
    on_value:
      - lvgl.label.update:
          id: temp1_label
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();
      - lvgl.arc.update:
          id: zone1_arc
          value: !lambda |-
            return (x);

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 2"
    id: g32_T_2
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3000s
    lambda: |-
      return (x[8]*10.0+x[9]/10.0);
    on_value:
      - lvgl.label.update:
          id: temp2_label
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();
      - lvgl.arc.update:
          id: zone2_arc
          value: !lambda |-
            return (x);

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 3"
    id: g32_T_3
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3001s
    lambda: |-
      return (x[10]*10.0+x[11]/10.0);
    on_value:
      - lvgl.label.update:
          id: temp3_label
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();
      - lvgl.arc.update:
          id: zone3_arc
          value: !lambda |-
            return (x);

  - platform: ble_client
    type: characteristic
    name: "G32 Zone 4"
    id: g32_T_4
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3002s
    lambda: |-
      return (x[12]*10.0+x[13]/10.0);
    on_value:
      - lvgl.label.update:
          id: temp4_label
          text: !lambda |-
            return (to_string(static_cast<int>(x))).c_str();
      - lvgl.arc.update:
          id: zone4_arc
          value: !lambda |-
            return (x);

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 1"
    id: g32_Ext_1
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3003s
    lambda: |-
      return (x[14]*100.0+x[15])/10;
    on_value:
      - lvgl.label.update:
          id: sensor1_label
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };
      - lvgl.arc.update:
          id: sensor1_arc
          value: !lambda |-
            return (x);

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 2"
    id: g32_Ext_2
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3003s
    lambda: |-
      return (x[16]*100.0+x[17])/10;
    on_value:
      - lvgl.label.update:
          id: sensor2_label
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };
      - lvgl.arc.update:
          id: sensor2_arc
          value: !lambda |-
            if(x == 1500) {return (0);
            } else {
            return (x);
            };

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 3"
    id: g32_Ext_3
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3004s
    lambda: |-
      return (x[18]*100.0+x[19])/10;
    on_value:
      - lvgl.label.update:
          id: sensor3_label
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };
      - lvgl.arc.update:
          id: sensor3_arc
          value: !lambda |-
            if(x == 1500) {return (0);
            } else {
            return (x);
            };

  - platform: ble_client
    type: characteristic
    name: "G32 Sensor 4"
    id: g32_Ext_4
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3005s
    lambda: |-
      return (x[20]*100.0+x[21])/10;
    on_value:
      - lvgl.label.update:
          id: sensor4_label
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };
      - lvgl.arc.update:
          id: sensor4_arc
          value: !lambda |-
            if(x == 1500) {return (0);
            } else {
            return (x);
            };

  - platform: ble_client
    type: characteristic
    name: "G32 Gasbuddy Füllstand in g"
    id: g32_Gas_g
    device_class: weight
    state_class: measurement
    unit_of_measurement: g
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3006s
    lambda: |-
      return (x[22]*256+x[23]);
    on_value:
      - lvgl.label.update:
          id: gas_weight_label
          text: !lambda |-
            return (to_string(static_cast<int>(x)) + " g").c_str();

  - platform: ble_client
    type: characteristic
    name: "G32 Gasbuddy Füllstand in %"
    state_class: measurement
    unit_of_measurement: "%"
    id: g32_Gas
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3007s
    lambda: |-
      return (x[31]);
    on_value:
      - lvgl.label.update:
          id: gas_percent_label
          text: !lambda |-
            return (to_string(static_cast<int>(x)) + " %").c_str();
      - lvgl.bar.update:
          id: gas_bar
          value: !lambda |-
            return (x);

  - platform: ble_client
    type: characteristic
    name: "G32 Haube"
    id: g32_Haube
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3008s
    lambda: |-
      return (x[24]);

  - platform: ble_client
    type: characteristic
    name: "G32 Licht"
    id: g32_Licht
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3009s
    lambda: |-
      return (x[25]);


binary_sensor:
  - platform: status
    name: "Status ESP G32"

  - platform: template
    name: "G32 Licht"
    icon: "mdi:light-flood-down"
    lambda: |-
     if (id(g32_Licht).state == 1) {
     // G32 Haubenlicht ist AN.
     return true;
     } else {
     // G32 Haubenlicht ist AUS.
     return false;
     }

  - platform: template
    name: "G32 Haube"
    device_class: "door"
    icon: "mdi:door"
    lambda: |-
     if (id(g32_Haube).state == 1) {
     // G32 Haube ist offen.
     return true;
     } else {
     // G32 Haube ist geschlossen.
     return false;
     }

Mein Display ist angekommen :thumb1:

PXL_20250527_122415510.jpg
PXL_20250527_122403836.jpg
PXL_20250527_122357728.jpg
PXL_20250527_122313731.jpg


Kurze Anleitung:
- ESP Home in Home Assistant installieren
- Display per USB am HA-Server anschließen
- Gerät in ESP Home hinzufügen und eine mit den eigenen Daten zum Netzwerk und G32 angepassten YAML-Datei erstellen.
- fertig.

Ist das so in etwa korrekt?
Ich schaue mal, wann ich die Zeit finde.
 
Super! Bin mal gespannt.
Ja, natürlich zuerst ESPHome im HA installieren, dürfte absolut problemlos sein.
Dann das Display per USB-C an einem PC im Netzwerk anschließen (muss nicht der HA-Server sein!), an dem, auf dem Du per Webinterface mit dem HA kommunizierst.
Zuerst das Display in den Programmiermodus versetzen. Da sind im Display zwei Taster BOOT und RESET (durch ein Langloch hinten im Deckel sichtbar). BOOT gedrückt halten, Reset kurz drücken und loslassen, dann BOOT loslassen. Dann ist der ESP32 im Boot-Modus (Display bleibt dauerhaft schwarz, da das vom Werk aufgespielte Programm nicht startet!).
Neues Gerät in ESPHome anlegen (Prozessor ist ein ESP32 S3, wird irgendwo abgefragt), Namen eingeben, dann CONNECT drücken und mit dem Display verbinden (er sucht dabei nach verbundenen Geräten und sollte den ESP32 finden). Dann installieren lassen, dauert eventuell mehrere Minuten, nicht nervös werden. Wenn der ESP32 im BOOT-Modus war, dann wird irgendwann die Firmware installiert sein (wird alles angezeigt). Sollte es nicht klappen, noch einmal versuchen, ggf. hat man BOOT und RESET verwechselt (dann wäre aber das Werks-Programm gestartet worden ...).
Wenn das ein Mal funktioniert hat, dann geht alles Weitere per OTA über Wifi, man benötigt also keine Verbindung zum PC mehr über USB!

Jetzt hat man in ESPHome ein Gerät mit einer grundlegenden YAML, in der die für dieses Gerät spezifischen Daten schon gesetzt sind. Jetzt in dieser YAML den von mir geposteten Code selektiv einfügen! Also alle redundanten Daten weglassen und meine persönlichen Daten ersetzen. Sollte relativ offensichtlich sein. Im Endeffekt sollte der Code exakt die gleichen Zeilen enthalten, nur in den ersten ca. 60 Zeilen mit Deinen spezifischen Daten.

Das erste Kompilieren kann sehr lange dauern, durchaus 10 Minuten (ich habe einen Mini-PC mit N4000 Prozessor). Es werden alle notwendigen Pakete automatisch installiert und kompiliert.

Danach sollte das Display schon laufen. Zuerst wird nach einem Start die leere Oberfläche angezeigt, dann sollte nach wenigen Sekunden links oben in der Ecke das Wifi-Symbol erscheinen. Das bedeutet, dass sich das Display mit Deinem Wlan verbunden hat (wenn die Daten stimmen).
Weitere 20-30 Sekunden später sollte rechts oben in der Ecke das Bluetooth-Symbol erscheinen. Dann hat das Display den G32 gefunden und sich verbunden. Wenige Sekunden später erscheinen dann die Daten.
Das Ganze wird im Terminal von ESPHome geloggt, man sieht also eigentlich recht gut, was passiert und wo es ggf. klemmt.

Wenn Du einen Akku anschließt (JST 2 1.25mm Stecker!), dann wird auch dieser überwacht und der SOC im HA angezeigt. Im Display erscheint bei einem SOC von <20% oben in der Mitte ein Symbol mit einer leeren Batterie (in rot). Die % Anzeige stimmt nur im Entlademodus ungefähr, beim Laden nicht.
Ich benutze einen 2000mAh Akku, der hält etwa 7 Stunden.
 
Wow, danke.

Ich habe meinen HomeAssistant lange nicht mehr aktiv genutzt, muss mich erstmal wieder zurecht finden.
Ich melde mich nach hoffentlich erfolgreicher Durchführung :D
 
Wie geil ist das denn bitte? :thumb1:
@JBecker hier auch nochmal danke für den ganzen Support per PM. Jetzt noch einen Akku, einen Schalter und ein kleines Gehäuse und man hat den Grillbuddy in geil :)

PXL_20250528_104236773.jpg
 
PXL_20250531_101818315.MP~2.jpg


Kleines Update. Ich habe jetzt mal einen Meater+ eingebunden.

Allen einen schönen Vatertag und erfolgreiches Grillen!

Gruß, Jörg.

EDIT: ich hänge den Code hier mal an (kann den ersten Post zum Thema nicht mehr bearbeiten). Ein Meater+ (den habe ich, zu anderen Versionen kann ich nichts sagen) blendet sich automatisch an Stelle der Sensoren 3 und 4 ein (und aus). Wenn man keinen hat, muss man nichts ändern, wenn man einen hat, die Bluetooth MAC oben eintragen (die MACs von in der Umgebung gefundenen G32 und Meater+ Geräten werden in den Logs angezeigt, man benötigt also keine weiteren Hilfsmittel mehr, wie z.B. die 'nrf Connect' App):

YAML:
substitutions:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# bitte nur in diesen nächsten Zeilen Änderungen vornehmen                    #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Name des ESPHome Geräts (kann frei gewählt werden, keine Sonderzeichen) 
  name: g32-display
  device_description: "Monitor an OW G32 grill"
# Bluetooth MAC des G32 (z.B. zu finden mit der App nrf_Connect)
# oder zum Auslesen unten den 'esp32_ble_tracker:' entkommentieren 
  g32_mac_address: 94:E6:86:0A:27:52
# Bluetooth MAC des Meater (z.B. zu finden mit der App nrf_Connect)
# oder zum Auslesen unten den 'esp32_ble_tracker:' entkommentieren 
  mt_mac_address: B8:1F:5E:BF:A6:9E
# Credentials des eigenen Wifi Netzwerks  
  wifi_ssid: Finkenbusch43
  wifi_password: 123456

# hier die Daten aus dem neu erstellten ESPHome Gerät einfügen. Beispiel:
# Enable Home Assistant API
# api:
#   encryption:
#     key: "OZNMBo2xusQ+BIzO1pfIQepp72VCfBzCWO/pSttPCQg="
#
# ota:
#   - platform: esphome
#     password: "7fdf9f656d36180bfba92d596c9e7db3"
#
# wifi:
#   ssid: !secret wifi_ssid
#   password: !secret wifi_password
#
#   # Enable fallback hotspot (captive portal) in case wifi connection fails
#   ap:
#     ssid: "Hztht Fallback Hotspot"
#     password: "rXlU1NZRut9K"
  api_encryption_key: E1fyywUUE1DWzu0OzhDkyc4yAnfGwyEfsVNvhytrU6k=
  ota_password: 39825aefe87449c0928189f9fb2e701a
  ap_ssid: G32 Display Fallback Hotspot
  ap_password: 4Lytxfy25DNh  


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# ab hier bitte nur Änderungen vornehmen, wenn man weiß, was man tut und will #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
esphome:
  name: ${name}
  platformio_options:
    upload_speed: 921600
    board_build.flash_mode: dio
    board_build.f_flash: 80000000L
    board_build.f_cpu: 240000000L

esp32:
  board: esp32-s3-devkitc-1
  flash_size: 16MB
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y"
      CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
      CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
      CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
      CONFIG_SPIRAM_RODATA: y

psram:
  mode: octal
  speed: 80MHz # 120mhz is not supported and falls back to 40mhz

# Enable logging
logger:
  baud_rate: 921600

# Enable Home Assistant API
api:
  encryption:
    key: ${api_encryption_key}

ota:
  - platform: esphome
    password: ${ota_password}

wifi:
  ssid: ${wifi_ssid}
  password: ${wifi_password}
  fast_connect: True
  on_connect:
    then:
      - lvgl.widget.show: wifi_connect_label
      - rtttl.play: 'Pling1:d=16,o=6,b=140:d6,32p,e6'
      - globals.set:
          id: wifi_connected
          value: 'true'
  on_disconnect:
    then:
      - lvgl.widget.hide: wifi_connect_label
      - rtttl.play: 'siren:d=8,o=5,b=100:d,e,d,e,d,e,d,e'
      - globals.set:
          id: wifi_connected
          value: 'false'

# Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${ap_ssid}
    password: ${ap_password}

#esp32_ble_tracker:
#  on_ble_advertise:
#    then:
#      - lambda: |-
#          if (x.get_name().rfind("OWG-G32C", 0) == 0) {
#            ESP_LOGI("ble_adv", "G32 gefunden");
#            ESP_LOGI("ble_adv", "  Name: %s", x.get_name().c_str());
#            ESP_LOGI("ble_adv", "  MAC address: %s", x.address_str().c_str());
#          }
#          if (x.get_name().rfind("MEATER+", 0) == 0) {
#            ESP_LOGI("ble_adv", "Meater+ gefunden");
#            ESP_LOGI("ble_adv", "  Name: %s", x.get_name().c_str());
#            ESP_LOGI("ble_adv", "  MAC address: %s", x.address_str().c_str());
#          }

ble_client:
  - mac_address: ${g32_mac_address}
    id: ow_g32
    on_connect:
      then:
        - lvgl.widget.show: g32_connect_label
        - rtttl.play: 'Pling2:d=16,o=6,b=140:e6,32p,d6'
        - globals.set:
            id: g32_connected
            value: 'true'
    on_disconnect:
      then:
        - lvgl.widget.hide: g32_connect_label
        - lvgl.widget.hide: [zone1_label, zone2_label, zone3_label, zone4_label]
        - lvgl.widget.hide: [sensor1_label, sensor2_label, sensor3_label, sensor4_label]
        - lvgl.widget.hide: [gas_percent_label, gas_weight_label, gas_percent_bar]
        - rtttl.play: 'siren:d=8,o=5,b=100:d,e,d,e,d,e,d,e'
        - globals.set:
            id: g32_connected
            value: 'false'

  - mac_address: ${mt_mac_address}
    id: meater
    on_connect:
      then:
        - lvgl.widget.show: meater_connect_label
        - lvgl.widget.show: [meater1_arc, meater2_arc]
#        - lvgl.widget.show: [meater1_arc, meater2_arc, meater1_label, meater2_label]
        - lvgl.widget.hide: [sensor3_arc, sensor4_arc, sensor3_label, sensor4_label]
        - lvgl.widget.hide: [sensor3_text, sensor4_text]
        - lvgl.widget.show: meater_text
        - output.turn_off: helper_low
        - rtttl.play: 'Pling3:d=16,o=6,b=140:d6,32p,e6,32p,d6'
#        - rtttl.play: 'star_wars:d=16,o=5,b=100:4e,4e,4e,8c,p,g,4e,8c,p,g,4e,4p,4b,4b,4b,8c6,p,g,4d#,8c,p,g,4e,8p'
        - globals.set:
            id: meater_connected
            value: 'true'
    on_disconnect:
      then:
        - lvgl.widget.hide: meater_connect_label
        - lvgl.widget.hide: [meater1_arc, meater2_arc, meater1_label, meater2_label]
        - lvgl.widget.show: [sensor3_arc, sensor4_arc]
        - lvgl.widget.show: [sensor3_arc, sensor4_arc, sensor3_label, sensor4_label]
        - lvgl.widget.show: [sensor3_text, sensor4_text]
        - lvgl.widget.hide: meater_text
        - rtttl.play: 'siren:d=8,o=5,b=100:d,e,d,e,d,e,d,e'
        - globals.set:
            id: meater_connected
            value: 'false'

#-------------------------------------------
# Display qspi
#-------------------------------------------
spi:
  id: display_qspi
  type: quad
  clk_pin: 47
  data_pins: [21, 48, 40, 39]

display:
  - platform: qspi_dbi
    model: axs15231
    data_rate: 40MHz
    id: my_display
    spi_id: display_qspi
    dimensions:
      height: 480
      width: 320
    cs_pin:
      number: 45
      ignore_strapping_warning: true
#    rotation: 0  #  0 for portrait
    rotation: 90 # 90 for landscape
    auto_clear_enabled: false

#-------------------------------------------
# Touchscreen gt911 i2c
#-------------------------------------------
i2c:
  sda: 4
  scl: 8
  id: touchscreen_bus

touchscreen:
  - platform: axs15231
    id: my_touch
    display: my_display
    i2c_id: touchscreen_bus
    calibration:
      x_min: 14
      x_max: 461
      y_min: 12
      y_max: 310
    transform:
      swap_xy: true
      mirror_x: false
      mirror_y: true
    on_touch:
      - lambda: |-
          ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
            touch.x,
            touch.y,
            touch.x_raw,
            touch.y_raw
          );
    on_release:
      - if:
          condition: lvgl.is_paused
          then:
            - logger.log: "Display is resuming"
            - lvgl.resume:
            - lvgl.widget.redraw:
            - light.turn_on: backlight         

#-------------------------------------------
# Internal outputs
#-------------------------------------------
output:
  - id: gpio_backlight_pwm
    platform: ledc
    pin: 1

  - id: helper_low
    platform: ledc
    pin: 14

  - platform: ledc
    pin: 9
    id: rtttl_out

#-------------------------------------------
# Internal lights
#-------------------------------------------
light:
  - id: backlight
    name: Backlight
    platform: monochromatic
    output: gpio_backlight_pwm
    restore_mode: ALWAYS_ON

#-------------------------------------------
# Internal RTTTL speaker
#-------------------------------------------
rtttl:
  output: rtttl_out
  gain: 0.8

globals:
  - id: wifi_connected
    type: bool
    initial_value: 'false'
  - id: g32_connected
    type: bool
    initial_value: 'false'
  - id: meater_connected
    type: bool
    initial_value: 'false'

number:
  - platform: template
    name: Screen timeout
    optimistic: true
    id: display_timeout
    unit_of_measurement: "s"
    initial_value: 300
    restore_value: true
    min_value: 0 # 0 means 'no timeout'
    max_value: 3600
    step: 5
    mode: box

lvgl:
  #full_refresh: true # not needed any longer
  draw_rounding: 8 # necessary for the axs15231 display controller
  displays: my_display
  touchscreens: my_touch
  bg_color: 0
  border_width: 0
  outline_width: 0
  theme:
    label:
      text_color: 0xFFFFFF
      bg_color: 0
      bg_opa: TRANSP
      width: 120
      text_align: center
    bar:
      radius: 5
      indicator:
        radius: 5
        arc_color: red
    arc:
      radius: 5
      arc_color: 0x333333
      indicator:
        radius: 5
  style_definitions:
    - id: main_font_style
      text_font: MONTSERRAT_18
    - id: big_font_style
      text_font: MONTSERRAT_26
    - id: zone_arc_style
      width: 100
      height: 120       
    - id: sensor_arc_style
      width: 100
      height: 120       
  on_idle:
    timeout: !lambda "return(id(display_timeout).state * 1000);"
    then:
    - if:
        condition:
        - lambda: "return id(display_timeout).state > 0;"
        then:
          - logger.log: "Display is idle"
          - light.turn_off: backlight
          - lvgl.pause:
  pages:
    - id: main_page
      widgets:
# fixed objects (will not change during runtime)
        - label:
            x: 0
            y: 4 # distance down from top
            styles: main_font_style
            text: 'T 1'

        - label:
            x: 120
            y: 4 # distance down from top
            styles: main_font_style
            text: 'T 2'

        - label:
            x: 240
            y: 4 # distance down from top
            styles: main_font_style
            text: 'T 3'

        - label:
            x: 360
            y: 4 # distance down from top
            styles: main_font_style
            text: 'T 4'

        - label:
            x: 0
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 1'

        - label:
            x: 120
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 2'

        - label:
            id: sensor3_text
            x: 240
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 3'

        - label:
            id: sensor4_text
            x: 360
            y: 150 # distance down from top
            styles: main_font_style
            text: 'Sensor 4'

        - label:
            id: meater_text
            x: 240
            y: 150 # distance down from top
            styles: main_font_style
            width: 240
            text: 'KT   Meater   GT'
            hidden: true

        - label:
            x: 0
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 120
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 240
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 360
            y: 104 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 0
            y:  250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 120
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 240
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 360
            y: 250 # distance down from top
            styles: main_font_style
            text: '°C'

        - label:
            x: 24
            y: 294 # distance down from top
            styles: main_font_style
            text_align: LEFT
            text: 'Gas:'

# variable objects (may change at runtime)
        - label:
            id: wifi_connect_label
            x: 0
            y: 4
            styles: main_font_style
            text_color: 0x00ff00
            text_align: LEFT
            width: 20
            text: "\uF1EB"
            hidden: true

        - label:
            id: battery_empty_label
            x: 220
            y: 4
            styles: main_font_style
            text_color: 0xff0000
            text_align: CENTER
            width: 40
            text: "\uF243"
            hidden: true

        - label:
            id: g32_connect_label
            x: 459
            y: 4
            styles: main_font_style
            text_color: 0x00ff00
            text_align: LEFT
            width: 20
            text: "\uF293"
            hidden: true

        - label:
            id: meater_connect_label
            x: 350
            y: 180
            styles: main_font_style
            text_color: 0x00ff00
            text_align: CENTER
            width: 20
            text: "\uF293"
            hidden: true

        - label:
            id: gas_percent_label
            x: 260
            y: 294 # distance down from top
            styles: main_font_style
            text: '-- %'
            hidden: true

        - label:
            id: gas_weight_label
            x: 360
            y: 294 # distance down from top
            styles: main_font_style
            text: '--- g'
            hidden: true

        - label:
            id: zone1_label
            x: 0
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: zone2_label
            x: 120
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: zone3_label
            x: 240
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: zone4_label
            x: 360
            y: 64 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: sensor1_label
            x: 0
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: sensor2_label
            x: 120
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: sensor3_label
            x: 240
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: sensor4_label
            x: 360
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: meater1_label
            x: 240
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - label:
            id: meater2_label
            x: 360
            y: 210 # distance down from top
            styles: big_font_style
            text: '---'
            hidden: true

        - bar:
            id: gas_percent_bar
            x: 80
            y: 299
            height: 12
            width: 200
            radius: 5
            min_value: 1
            max_value: 100
            bg_color: 0xffffff
            indicator:
              bg_color: 0x00ff00
            value: 0
            hidden: true

        - arc:
            id: zone1_arc
            x: 10
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: zone_arc_style 
            value: 0

        - arc:
            id: zone2_arc
            x: 130
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: zone_arc_style 
            value: 0

        - arc:
            id: zone3_arc
            x: 250
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: zone_arc_style 
            value: 0

        - arc:
            id: zone4_arc
            x: 370
            y: 30
            min_value: 1
            max_value: 500
            indicator:
              arc_color: 0xff0000
            styles: zone_arc_style 
            value: 0

        - arc:
            id: sensor1_arc
            x: 10
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: sensor_arc_style 
            value: 0

        - arc:
            id: sensor2_arc
            x: 130
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xff0000
            styles: sensor_arc_style 
            value: 0

        - arc:
            id: sensor3_arc
            x: 250
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: sensor_arc_style 
            value: 0

        - arc:
            id: sensor4_arc
            x: 370
            y: 176
            min_value: 1
            max_value: 300
            indicator:
              arc_color: 0xffff00
            styles: sensor_arc_style 
            value: 0

        - arc:
            id: meater1_arc
            x: 250
            y: 176
            min_value: 1
            max_value: 100
            indicator:
              arc_color: 0xffff00
            styles: sensor_arc_style 
            value: 0
            hidden: true

        - arc:
            id: meater2_arc
            x: 370
            y: 176
            min_value: 1
            max_value: 275
            indicator:
              arc_color: 0xff0000
            styles: sensor_arc_style 
            value: 0
            hidden: true

sensor:
#  - platform: adc
#    pin: 5
#    name: "Battery Voltage"
#    unit_of_measurement: "V"
#    state_class: measurement
#    attenuation: 12db
#    accuracy_decimals: 2
#    samples: 16
#    filters:
#      - multiply: 1.72
#      - sliding_window_moving_average:
#          window_size: 15
  - platform: adc
    pin: 5
    name: "Battery SOC"
    unit_of_measurement: "%"
    state_class: measurement
    device_class: battery
    attenuation: 12db
    accuracy_decimals: 0
    samples: 16
    filters:
      - multiply: 1.72
      - sliding_window_moving_average:
          window_size: 15
      - calibrate_linear:
          method: exact
          datapoints:
            - 3.00 ->   0.0
            - 3.36 ->   5.0
            - 3.41 ->  10.0
            - 3.48 ->  20.0
            - 3.52 ->  30.0
            - 3.56 ->  40.0
            - 3.61 ->  50.0
            - 3.70 ->  60.0
            - 3.79 ->  70.0
            - 3.89 ->  80.0
            - 4.00 ->  90.0
            - 4.05 -> 100.0
      - clamp:
          min_value: 0.0
          max_value: 100.0
    update_interval: 4s
    on_value_range:
      - below: 20.0
        then:
          - lvgl.widget.show: battery_empty_label
      - above: 20.0
        then:
          - lvgl.widget.hide: battery_empty_label

  - platform: ble_client
    ble_client_id: meater
    type: characteristic
    name: "Meater T1"
    id: meater_t1
    service_uuid: 'a75cc7fc-c956-488f-ac2a-2dbc08b63a04'
    characteristic_uuid: '7edda774-045e-4bbf-909b-45d1991a2876'
    device_class: "temperature"
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    update_interval: 10s
    lambda: |-
      return ((x[0]+x[1]*256.0)/16.0);
    on_value:
      - lvgl.label.update:
          id: meater1_label
          hidden: false
          text: !lambda |-
            if(x == 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: meater1_arc
          value: !lambda |-
            if(x == 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    ble_client_id: meater
    type: characteristic
    name: "Meater T2"
    id: meater_t2
    service_uuid: 'a75cc7fc-c956-488f-ac2a-2dbc08b63a04'
    characteristic_uuid: '7edda774-045e-4bbf-909b-45d1991a2876'
    device_class: "temperature"
    unit_of_measurement: "°C"
    accuracy_decimals: 0
    update_interval: 10s
    lambda: |-
      if ((x[2]+x[3]*256.0) >= 33) {
        return (((x[0]+x[1]*256.0)/16.0)+(((x[2]+x[3]*256.0)-33.0)/2.5));
      } else {
        return (1500);
      };
    on_value:
      - lvgl.label.update:
          id: meater2_label
          hidden: false
          text: !lambda |-
            if(x >= 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: meater2_arc
          value: !lambda |-
            if(x >= 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_rssi
    mac_address: ${g32_mac_address}
    name: "BT Signalstärke"
  - platform: wifi_signal
    name: "WiFi Signal ESP G32"
    update_interval: 10s
  - platform: internal_temperature 
    name: "CPU Temperatur ESP G32"
    update_interval: 10s

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Zone 1"
    id: g32_T_1
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 10s
    lambda: |-
      return (x[6]*10.0+x[7]/10.0);
    on_value:
      - lvgl.label.update:
          id: zone1_label
          hidden: false
          text: !lambda |-
            if(x >= 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: zone1_arc
          value: !lambda |-
            if(x >= 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Zone 2"
    id: g32_T_2
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3000s
    lambda: |-
      return (x[8]*10.0+x[9]/10.0);
    on_value:
      - lvgl.label.update:
          id: zone2_label
          hidden: false
          text: !lambda |-
            if(x >= 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: zone2_arc
          value: !lambda |-
            if(x >= 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Zone 3"
    id: g32_T_3
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3001s
    lambda: |-
      return (x[10]*10.0+x[11]/10.0);
    on_value:
      - lvgl.label.update:
          id: zone3_label
          hidden: false
          text: !lambda |-
            if(x >= 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: zone3_arc
          value: !lambda |-
            if(x >= 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Zone 4"
    id: g32_T_4
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3002s
    lambda: |-
      return (x[12]*10.0+x[13]/10.0);
    on_value:
      - lvgl.label.update:
          id: zone4_label
          hidden: false
          text: !lambda |-
            if(x >= 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: zone4_arc
          value: !lambda |-
            if(x >= 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Sensor 1"
    id: g32_Ext_1
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3003s
    lambda: |-
      return (x[14]*100.0+x[15])/10;
    on_value:
      - lvgl.label.update:
          id: sensor1_label
          hidden: false
          text: !lambda |-
            if(x >= 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: sensor1_arc
          value: !lambda |-
            if(x >= 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Sensor 2"
    id: g32_Ext_2
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3003s
    lambda: |-
      return (x[16]*100.0+x[17])/10;
    on_value:
      - lvgl.label.update:
          id: sensor2_label
          hidden: false
          text: !lambda |-
            if(x >= 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: sensor2_arc
          value: !lambda |-
            if(x >= 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Sensor 3"
    id: g32_Ext_3
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3004s
    lambda: |-
      return (x[18]*100.0+x[19])/10;
    on_value:
      - lvgl.label.update:
          id: sensor3_label
          hidden: !lambda return id(meater_connected) == true;
          text: !lambda |-
            if(x >= 1500) {
            return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: sensor3_arc
          value: !lambda |-
            if(x >= 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Sensor 4"
    id: g32_Ext_4
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    device_class: "temperature"
    unit_of_measurement: "°C"
    update_interval: 3005s
    lambda: |-
      return (x[20]*100.0+x[21])/10;
    on_value:
      - lvgl.label.update:
          id: sensor4_label
          hidden: !lambda return id(meater_connected) == true;
          text: !lambda |-
            if(x >= 1500) {return ("---");
            } else {
            return (to_string(static_cast<int>(x))).c_str();
            };     
      - lvgl.arc.update:
          id: sensor4_arc
          value: !lambda |-
            if(x >= 1500) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Gasbuddy Füllstand in g"
    id: g32_Gas_g
    device_class: weight
    state_class: measurement
    unit_of_measurement: g
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3006s
    lambda: |-
      return (x[22]*256+x[23]);
    on_value:
      - lvgl.label.update:
          id: gas_weight_label
          hidden: false
          text: !lambda |-
            if(x >= 20000) {return ("---");
            } else {
            return (to_string(static_cast<int>(x)) + " g").c_str();     
            };     

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Gasbuddy Füllstand in %"
    state_class: measurement
    unit_of_measurement: "%"
    id: g32_Gas
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3007s
    lambda: |-
      return (x[31]);
    on_value:
      - lvgl.label.update:
          id: gas_percent_label
          hidden: false
          text: !lambda |-
            if(x > 100) {return ("---");
            } else {
            return (to_string(static_cast<int>(x)) + " %").c_str();     
            };
      - lvgl.bar.update:
          id: gas_percent_bar
          hidden: false
          value: !lambda |-
            if(x > 100) {return (0);
            } else {
            return (x);
            };     

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Haube"
    id: g32_Haube
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3008s
    lambda: |-
      return (x[24]);

  - platform: ble_client
    ble_client_id: ow_g32
    type: characteristic
    name: "G32 Licht"
    id: g32_Licht
    service_uuid: 'dc0f41ea-b6ae-46a8-a19e-1a3bf4342bcb'
    characteristic_uuid: 'dc0f41e2-b6ae-46a8-a19e-1a3bf4342bcb'
    update_interval: 3009s
    lambda: |-
      return (x[25]);


binary_sensor:
  - platform: status
    name: "Status ESP G32"

  - platform: template
    name: "G32 Licht"
    icon: "mdi:light-flood-down"
    lambda: |-
     if (id(g32_Licht).state == 1) {
     // G32 Haubenlicht ist AN.
     return true;
     } else {
     // G32 Haubenlicht ist AUS.
     return false;
     }

  - platform: template
    name: "G32 Haube"
    device_class: "door"
    icon: "mdi:door"
    lambda: |-
     if (id(g32_Haube).state == 1) {
     // G32 Haube ist offen.
     return true;
     } else {
     // G32 Haube ist geschlossen.
     return false;
     }
 
Erst einmal herzlichen Dank an alle, die sich in dieses Projekt mit eingebracht haben. Ich halte mich zwar für einigermaßen Home Assistant erfahren, allerdings habe ich mich mit dem Thema ESP32 bisher noch nicht beschäftigt.

Dank dieses Themas hier habe ich aber das Display zum Leben erwecken können. Gleichzeitig auch noch die Werte vom Grill als Entitäten in HA, so hatte ich mir das vorgestellt.

Jetzt wollte ich euch mal fragen, wir ihr das Thema Außeneinsatz umsetzt. Gibt es schon ein passendes Gehäuse oder vielleicht schon eine 3D Druckvorlage. Ich favorisiere die dauerhafte Stromversorgung, würde dann allerdings mit Ein/Aus Schalter arbeiten wollen. Jetzt ist mir jedoch aufgefallen, dass (zumindest beim mir) nach Trennung und Wiederherstellung der Stromversorgung "das System" nicht wieder automatisch hochfährt. Ich kann zwar per WLAN auf das Gerät zugreifen, das Display bleibt jedoch dunkel und die Entitäten in HA unbekannt. Ich muss ein Update anschieben, damit ich wieder was sehen kann. Wie löst ihr das?

Viele Grüße und nochmals vielen Dank für die sehr gut nachvollziehbare Anleitung. Das war ein tolles Vatertagsprojekt. :thumb1:
 
Erst einmal herzlichen Dank an alle, die sich in dieses Projekt mit eingebracht haben. Ich halte mich zwar für einigermaßen Home Assistant erfahren, allerdings habe ich mich mit dem Thema ESP32 bisher noch nicht beschäftigt.

Dank dieses Themas hier habe ich aber das Display zum Leben erwecken können. Gleichzeitig auch noch die Werte vom Grill als Entitäten in HA, so hatte ich mir das vorgestellt.

Jetzt wollte ich euch mal fragen, wir ihr das Thema Außeneinsatz umsetzt. Gibt es schon ein passendes Gehäuse oder vielleicht schon eine 3D Druckvorlage. Ich favorisiere die dauerhafte Stromversorgung, würde dann allerdings mit Ein/Aus Schalter arbeiten wollen. Jetzt ist mir jedoch aufgefallen, dass (zumindest beim mir) nach Trennung und Wiederherstellung der Stromversorgung "das System" nicht wieder automatisch hochfährt. Ich kann zwar per WLAN auf das Gerät zugreifen, das Display bleibt jedoch dunkel und die Entitäten in HA unbekannt. Ich muss ein Update anschieben, damit ich wieder was sehen kann. Wie löst ihr das?

Viele Grüße und nochmals vielen Dank für die sehr gut nachvollziehbare Anleitung. Das war ein tolles Vatertagsprojekt. :thumb1:
Du hast das JC3248W535 Display und nach Ab- und Anstecken der USB-C Versorgung startet das Display nicht wieder?
Oder benutzt Du einen Akku? Dann müsstest Du den Taster neben dem Akkustecker kurz drücken.
 
Ich habe genau das von dir beschriebene und hier abgebildete Display erworben. Nach dem Ab- und Anstecken der USB-C Stromversorgung sehe ich das Gerät im WLAN (im Log wird das auch protokolliert), allerdings wird offenbar keine Bluetooth Verbindung aufgebaut und das Display bleibt dunkel.
Ich versuche jetzt einfach nochmal neu zu kompilieren. Vielleicht hilft das ja schon.
 
Ich habe genau das von dir beschriebene und hier abgebildete Display erworben. Nach dem Ab- und Anstecken der USB-C Stromversorgung sehe ich das Gerät im WLAN (im Log wird das auch protokolliert), allerdings wird offenbar keine Bluetooth Verbindung aufgebaut und das Display bleibt dunkel.
Ich versuche jetzt einfach nochmal neu zu kompilieren. Vielleicht hilft das ja schon.
Nach einem Neustart wird eigentlich zuerst die Bildschirm-Maske aufgebaut und erst dann die Wlan Verbindung!
Da stimmt also irgendetwas nicht!
Kannst mir gerne mal die YAML schicken wenn Du den Fehler nicht findest.
 
Bin gerade bei der Gartenarbeit. Melde mich heute Abend.
 
Jetzt wollte ich euch mal fragen, wir ihr das Thema Außeneinsatz umsetzt. Gibt es schon ein passendes Gehäuse oder vielleicht schon eine 3D Druckvorlage. Ich favorisiere die dauerhafte Stromversorgung, würde dann allerdings mit Ein/Aus Schalter arbeiten wollen.
Das hier sieht recht brauchbar aus. Damit ist zwar das Problem der Stromversorgung noch nicht ganz gelöst, aber könnte ein guter Anfang sein.
 
Zurück
Oben Unten