MDI Glyph Substitutions

I made a substitution file that makes including mdi icons in fonts easier and friendlier. The glyphs can be added using substitutions, which also means you do not have to remember which icon a certain unicode represents.

The yaml file can be downloaded from the gist here:

To use it, include the substitutions into your yaml file in the following way:

substitutions:
  name: bluetooth-proxy
  <<: !include mdi_glyph_substitutions.yaml

Which extendends the substitutions with the entire file (you will notice some slowdown when esphome reads out your config).

You still need to include the mdi font and the glyphs as is described. When esphome prints your config, you will also notice the unicode is used instead of the icon name.

font:
  - file: "fonts/materialdesignicons-webfont.ttf"
    id: mdi_icon
    size: 20
    glyphs: 
      - ${mdi_wifi}
      - ${mdi_wifi_remove}
      - ${mdi_thermometer}

Using it in, for example, an lvgl label:

    - label:
        text: ${mdi_wifi_remove}
        id: lbl_hastatus
        text_font: mdi_icon
        align: top_mid

If you use the mdi vscode intellisens extension (Material Design Icons Intellisense - Visual Studio Marketplace), you can add this matcher so it correctly identifies them as icons:

        {
            "match": "\\bmdi_{snake}\\b",
            "insert": "mdi_{snake}",
            "displayName": "ESPHome Substitutions",
            "name": "esphome"
        },

And lastly, the python code used to generate it:

import mdi_pil
import yaml

yaml_dict = {}
IDENTIFIER = "mdi_"
HEX_PREFIX = r"\U000"
file = "mdi_glyph_substitutions.yaml"

for icon, hex in mdi_pil.mdi_icons.items():
    icon: str
    icon_id = IDENTIFIER + icon.replace("-","_")
    icon_unicode : str = HEX_PREFIX + hex
    yaml_dict[icon_id] = icon_unicode.encode().decode('unicode_escape')

def quoted_presenter(dumper, data : str):
    if data.startswith(HEX_PREFIX):
        data = data.encode().decode('unicode_escape')
        return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"')
    return dumper.represent_scalar('tag:yaml.org,2002:str', data)

with open(file,"w") as f:
    yaml.dump(yaml_dict, f, indent=4, default_flow_style=False, explicit_start=True)
1 Like