Display wifi icon based on wifi connection

Hi,

I’m trying to display an icon based on wifi.connected.

interval:
  - interval: 10s
    then:
      if:
        condition:
          wifi.connected:
        then:
          - lambda: 'id(affichage).printf(20, 20, id(icons), id(my_red), "\U000F05A9");'
        else:
          - lambda: 'id(affichage).printf(20, 20, id(icons), id(my_red), "\U000F05AA");'

I don’t get any errors on the log, the code complies properly, but the icon doesn’t show up. This is my display component, on which lambda is working properly :

display:
  - platform: ili9341
    id: affichage
    model: TFT 2.4
    rotation: 180
    cs_pin: 5
    dc_pin: 4
    led_pin: 15
    reset_pin: 22
    lambda: |-
       ...

And icons :

  - file: 'materialdesignicons-webfont.ttf'
    id: icons
    size: 36
    glyphs:
      - "\U000F05A9" #mdi:wifi
      - "\U000F05AA" #mdi:wifi-off
      - "\U000F0769" #mdi:ceiling-light
      - "\U000F17C7" #mdi:ceiling-light-outline
      - "\U000F06B5" #mdi:lamp
      - "\U000F17D0" #mdi:lamp-outline
      - "\U000F0CCC" #mdi:shield-lock-outline
      - "\U000F099C" #mdi:shield-off-outline
      - "\U000F0CCB" #mdi:shield-home-outline
      - "\U000F1829" #mdi:shield-moon-outline

Any ideas?

Thanks

Could it be that you are missing spaces?

  - file: 'materialdesignicons-webfont.ttf'
    id: icons
    size: 36
    glyphs:
      - "\U000F05A9" # mdi:wifi
      - "\U000F05AA" # mdi:wifi-off
      - "\U000F0769" # mdi:ceiling-light
      - "\U000F17C7" # mdi:ceiling-light-outline
      - "\U000F06B5" # mdi:lamp
      - "\U000F17D0" # mdi:lamp-outline
      - "\U000F0CCC" # mdi:shield-lock-outline
      - "\U000F099C" # mdi:shield-off-outline
      - "\U000F0CCB" # mdi:shield-home-outline
      - "\U000F1829" # mdi:shield-moon-outline

If you talk about what’s after ‘#’, these are just comments.

I do this but in a slightly different way. I go here Material Design Icons and click on the actual icon I want (not the code), it copies it to clipboard.
Then, I paste in the glyphs list, it looks like this:

  - file: 'materialdesignicons-webfont.ttf'
    id: icon_font_20
    size: 20
    glyphs: [
      "󰖩", # mdi-wifi
      "󰶑", # mdi-motion-sensor
      "󰠜", # mdi-door-open
      "󰌵", # mdi-lightbulb
      "󰛚" # mdi-garage-open
      ]

Thanks to @makai:

Ah! Of course…
Sorry about that.

Hii, I display wifi icon based on the wifi state like this, I created a template switch that checks for every 10s if wifi is connected. The state of the template switch is used to display whether the wifi is connected.

interval:

  - interval: 10s

    then:

      - if:

          condition:

            wifi.connected:

          then:

            - switch.turn_on: vk5

          else:

            - switch.turn_off: vk5
switch:

  - platform: template

    name: "Wifi font"

    id: vk5

    optimistic: true

    restore_state: False

display: 
  - platform: ssd1306_i2c

    model: "SSD1306 128x64"

    address: 0x3C

    pages:

      - id: page1

        lambda: |-

          it.printf(10, 2, id(icon_font), TextAlign::TOP_LEFT, "%s", id(vk5).state ? "\U000F05A9" : "\U000F05AA");

font:
  - file: "_fonts/materialdesignicons-webfont.ttf"

    id: icon_font

    size: 20

    glyphs: [

      "\U000F05A9", #wifi
      "\U000F05AA", #no wifi

    ]

Hope this Helps :grin:

1 Like

@VarunKumaran30 - Thank you for sharing your YAML. While it worked, I did not want to use or expose a switch to HA and figured I’d try using a variable instead to do the same thing. It appears to work… this is what I did:

Declaring the global variable:

#https://esphome.io/guides/automations.html?highlight=restore_value#bonus-2-global-variables
globals: ##to set default reboot behavior
  - id: wifi_connection
    type: bool
    restore_value: no
    initial_value: "false"

Code to set variable every 10 seconds:

interval:
  - interval: 10s
    then:
      - if:
          condition:
            wifi.connected:
          then:
            - lambda: |-
                id(wifi_connection) = true;
          else:
            - lambda: |-
                id(wifi_connection) = false;

Fonts code:

font:
  - file: "fonts/materialdesignicons-webfont.ttf"
    id: icon_font
    size: 12
    glyphs: [
      "\U000F05A9", #wifi
      "\U000F05AA", #no wifi
      ]

Speaking of fonts, I searched the icon font file on google, found the github, downloaded the file, and placed it in a new fonts folder with this path: \HASS_IP\config\esphome\fonts

Code to display the icon in the top right of the 64x128 screen:

it.printf(110, 2, id(icon_font), "%s", id(wifi_connection) ? "\U000F05A9" : "\U000F05AA");

Sharing your code with my modifications as an alternative in case it helps others :slight_smile:

1 Like

This was very helpful… thank you.

Hi,
I’m trying to use global variables to be able to perform some string concatenations as follows:

globals:
  - id: valve_icon
    type: std::string
    restore_value: no
    initial_value: '"\U000F058F"'

  - id: wifi_icon
    type: std::string
    restore_value: no
    initial_value: '"\U000F05A9"'

  - id: lineprint
    type: std::string
    restore_value: no

font:
  - file: "/config/esphome/Fonts/materialdesignicons-webfont.ttf"
    id: icon_font_16
    size: 16
    glyphs: [
      "\U000F05A9", # mdi-wifi
      "\U000F05AA", # mdi-wifi-off
      "\U000F058F", # mdi-water-pump
    ]

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    id: screen
    pages:
      - id: intialval
        lambda: |-
          it.printf(3, 2, id(icon_font_16), "%s", id(lineprint));

interval:
  - interval: 10s
    then:
      - if:
          condition:
            wifi.connected:
          then:
            - lambda: |-
                id(wifi_status) = true;
                id(lineprint) = id(wifi_icon) + id(level_icon);
          else:
            - lambda: |-
                id(wifi_status) = false;
                id(lineprint) = id(wifi_icon) + id(level_icon);

but I keep getting the following in the log:

[display:267] Encountered character without representation in font: '&'
01:00:24	[W]	[display:267] Encountered character without representation in font: '�'

and this:

[01:35:15][W][display:267]: Encountered character without representation in font: '\xcc'
[01:35:15][W][display:267]: Encountered character without representation in font: '&'
[01:35:15][W][display:267]: Encountered character without representation in font: '\xfb'
[01:35:15][W][display:267]: Encountered character without representation in font: '?'
[01:35:15][W][display:267]: Encountered character without representation in font: ''

For anyone still looking for a solution, here is mine which is quite simple and also handles displaying the wifi strength in mdi icons

wifi_icon.h

const char * wifi_icon(float wifi_strength) {
    if (isnan(wifi_strength))
			return "󰤮"; // No-wifi
	else if (wifi_strength < 10)
			return "󰤯";  // low-wifi
	else if (wifi_strength < 30)
			return "󰤟"; // wifi-1
	else if (wifi_strength < 50)
			return "󰤢"; // wifi-2
	else if (wifi_strength < 75)
			return "󰤥"; // wifi-3
	else
			return "󰤨"; // wifi-4
}
esphome:
    includes:
        - wifi_icon.h

sensor:
  - platform: wifi_signal # Reports the WiFi signal strength in %
    name: "WiFi Signal Percent"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "Signal %"
    id: wifi_signal_pct
    update_interval: 60s
    entity_category: "diagnostic"
#...    
display:
# ...
    lambda: |-
      it.print(0, 0, id(mdi_medium), wifi_icon(id(wifi_signal_pct).state));

font:
  - file: "fonts/materialdesignicons.ttf"
    id: mdi_medium
    size: 36
    glyphs: [
        "󰤮", # no-wifi
        "󰤯", # low-wifi
        "󰤟", # wifi-1
        "󰤢", # wifi-2
        "󰤥", # wifi-3
        "󰤨", # wifi-4
     ]
1 Like

@Tofandel, I’d like to use your code with one of my ESP32 projects. Problem is, due to the way the code snippet displays in your post, I can’t tell what (mdi?) characters should be referenced.

Is it safe for me to assume the code should read something like this;

const char * wifi_icon(float wifi_strength) {
    if (isnan(wifi_strength))
			return "\U000F092B"; // No-wifi
	else if (wifi_strength < 10)
			return "\U000F0920";  // low-wifi
	else if (wifi_strength < 30)
			return "\U000F091F"; // wifi-1
	else if (wifi_strength < 50)
			return "\U000F0922"; // wifi-2
	else if (wifi_strength < 75)
			return "\U000F0925"; // wifi-3
	else
			return "\U000F0928"; // wifi-4
}

and this;

  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_mdi_small
    size: 24
    glyphs:
      - "\U000F0928" # wifi-4
      - "\U000F0925" # wifi-3 
      - "\U000F0922" # wifi-2
      - "\U000F091F" # wifi-1
      - "\U000F0920" # Low-wifi
      - "\U000F092B" # No-wifi

The "󰤮" symbol being replaced with the associated mdi: code.

Edit - I took a chance and added the above file (wifi_icon.h) and code to my configuration. I’m happy to report all is working well. Now all I need to do is figure out how to associate a colour with each WiFi strength. Then I could show green for Hi strength, yellow for Medium and red for Low for no connectivity.

My IDE supports displaying those mdi fonts (phpstorm)

You can just copy paste them straight away from my code and they will work, it preserves the encoding

I simply copied the glyphs from https://pictogrammers.com/library/mdi/icon/wifi-strength-outline/

I’m not sure about the unicode of those

I wasn’t aware of that. Learned something new today. Thank you.

what is wifi_icon.h
and how is it uploaded to esphome?

It’s already in the code I posted

It’s just a C header file, which allows you to define C functions that you can use in your lambdas

Ok I’ll rephrase. Your code contains 2x boxes. The 2nd one is esphome code.
What do I do with the first code box?