·        Powered by an ESP32-P4 SoC, with 16MB of flash memory and 32MB of PSRAM. This makes it the device with the most memory we have integrated into Home Assistant to date.

·        It features a generous 5″ TFT touchscreen (1280×720), compatible with LVGL.

·        Includes a front-facing 2 MP SC2356 camera (1600×1200) for capturing images and video.

·        Equipped with one USB-A port, one USB-C port, and a Micro SD card slot (card not included).

·        It has two expansion ports for external sensors (GROVE and M5BUS) and a connector for a LoRa antenna.

·        Features two microphones, a speaker, and a 3.5mm jack, meaning you can also use it to control Assist.

·        If you chose the "TAB5 Kit," it comes with a Li-ion battery that you can easily replace (allowing you to have a spare one charged and ready).

 

In short, these characteristics make it the perfect candidate for a portable, autonomous control device with great tactile feedback. Additionally, as it is based on an ESP32-P4, the M5Stack TAB5 can be integrated into HA via ESPHome.

 

Prerequisites

To integrate the M5Stack TAB5 into HA, you will first need:

·        Your M5Stack Tab5 (with or without the battery).

·        To have ESPHome installed in Home Assistant.

·        A USB-C DATA cable to power the board (you will not be able to install the software with a charge-only cable).

 

Configuration in ESPHome

Follow these steps to integrate the M5Stack TAB5 into HA:

1. In Home Assistant, go to your ESPHome add-on and click on New device > Continue > New Device Setup.

2. Give your device a name (for example, “M5stack Tab5”) and click “Next.”

3. For the device type, select “ESP32-C6.” You will notice in the background that a new block has been created for your device.

4. Click “Skip” and then click “Edit” on your device's block. Copy the code that appears and save it, as you will need parts of it later.

5. Copy the following code and use it to replace the previous code in ESPHome.

 

substitutions:

# Device customization
# Personalización del dispositivo

  name: m5stack-tab5
  friendly_name: M5stack Tab5

####################################

esphome:
  name: ${name}
  friendly_name: ${friendly_name}

esp32:
  board: esp32-p4-evboard
  flash_size: 16MB
  framework:
    type: esp-idf
    advanced:
      enable_idf_experimental_features: true

esp32_hosted:
  variant: esp32c6
  active_high: true
  clk_pin: GPIO12
  cmd_pin: GPIO13
  d0_pin: GPIO11
  d1_pin: GPIO10
  d2_pin: GPIO9
  d3_pin: GPIO8
  reset_pin: GPIO15
  slot: 1

logger:
  hardware_uart: USB_SERIAL_JTAG

psram:
  mode: hex
  speed: 200MHz

api:
  encryption:
    key: "F8WsdfddfKt1XvQV9pU32443dsfdsf"

ota:
  - platform: esphome
    password: "sdffds23b12747edfq43543"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "M5Stack-Tab5 Fallback Hotspot"
    password: "sdfdMtQR34rfww"

# Sensors configuration
# Configuración de sensores

binary_sensor:
  - platform: gpio
    id: charging
    name: "Charging Status"
    pin:
      pi4ioe5v6408: pi4ioe2
      number: 6
      mode: INPUT_PULLDOWN

  - platform: gpio
    id: headphone_detect
    name: "Headphone Detect"
    pin:
      pi4ioe5v6408: pi4ioe1
      number: 7

i2c:
  - id: bsp_bus
    sda: GPIO31
    scl: GPIO32
    frequency: 400kHz

pi4ioe5v6408:
  - id: pi4ioe1
    address: 0x43
    # 0: O - wifi_antenna_int_ext
    # 1: O - speaker_enable
    # 2: O - external_5v_power
    # 3: NC
    # 4: O - lcd reset
    # 5: O - touch panel reset
    # 6: O - camera reset
    # 7: I - headphone detect
  - id: pi4ioe2
    address: 0x44
    # 0: O - wifi_power
    # 1: NC
    # 2: NC
    # 3: O - usb_5v_power
    # 4: O - poweroff pulse
    # 5: O - quick charge enable (inverted)
    # 6: I - charging status
    # 7: O - charge enable

select:
  - platform: template
    id: wifi_antenna_select
    name: "WiFi Antenna"
    options:
      - "Internal"
      - "External"
    optimistic: true
    on_value:
      - if:
          condition:
            lambda: return i == 0;
          then:
            - switch.turn_off: wifi_antenna_int_ext
          else:
            - switch.turn_on: wifi_antenna_int_ext

# The DAC Output select needs to be manually (or with an automation) changed to `LINE1` for the onboard speaker
  - platform: es8388
    dac_output:
      name: DAC Output
    adc_input_mic:
      name: ADC Input Mic

sensor:
  - platform: ina226
    address: 0x41
    adc_averaging: 16
    max_current: 8.192A
    shunt_resistance: 0.005ohm
    bus_voltage:
      name: Battery Voltage
    current:
      name: Battery Current
      # Positive means discharging
      # Negative means charging

switch:
  - platform: gpio
    id: wifi_power
    name: "WiFi Power"
    pin:
      pi4ioe5v6408: pi4ioe2
      number: 0
    restore_mode: ALWAYS_ON
  - platform: gpio
    id: usb_5v_power
    name: "USB Power"
    pin:
      pi4ioe5v6408: pi4ioe2
      number: 3
  - platform: gpio
    id: quick_charge
    name: "Quick Charge"
    pin:
      pi4ioe5v6408: pi4ioe2
      number: 5
      inverted: true
  - platform: gpio
    id: charge_enable
    name: "Charge Enable"
    pin:
      pi4ioe5v6408: pi4ioe2
      number: 7
  - platform: gpio
    id: wifi_antenna_int_ext
    pin:
      pi4ioe5v6408: pi4ioe1
      number: 0
  - platform: gpio
    id: speaker_enable
    name: "Speaker Enable"
    pin:
      pi4ioe5v6408: pi4ioe1
      number: 1
    restore_mode: ALWAYS_ON
  - platform: gpio
    id: external_5v_power
    name: "External 5V Power"
    pin:
      pi4ioe5v6408: pi4ioe1
      number: 2

# Display configuration
# Configuración de la pantalla

esp_ldo:
  - voltage: 2.5V
    channel: 3

font:
  - file: "gfonts://Kanit"
    id: font_title
    size: 100

light:
  - platform: monochromatic
    output: backlight_pwm
    name: "Display Backlight"
    id: backlight
    restore_mode: RESTORE_DEFAULT_ON
    default_transition_length: 250ms

output:
  - platform: ledc
    pin: GPIO22
    id: backlight_pwm
    frequency: 1000Hz

touchscreen:
  - platform: gt911
    interrupt_pin: GPIO23
    update_interval: never
    reset_pin:
      pi4ioe5v6408: pi4ioe1
      number: 5
    calibration:
      x_min: 0
      x_max: 720
      y_min: 0
      y_max: 1280
    id: touch

display:
  - platform: mipi_dsi
    dimensions:
      height: 1280
      width: 720
    model: M5Stack-Tab5
    reset_pin:
      pi4ioe5v6408: pi4ioe1
      number: 4
    show_test_card: true
    rotation: 90

lvgl:
  touchscreens: touch
  buffer_size: 100%
  style_definitions:
    - id: style_title
      align: CENTER
      text_font: font_title
  widgets:
    - label:
        styles: style_title
        text: 'Hola Aguacater@s!!'

# Media configuration and voice assistant
# Configuración multimedia y asistente de voz

audio_dac:
  - platform: es8388
    id: es8388_dac

audio_adc:
  - platform: es7210
    id: es7210_adc
    bits_per_sample: 16bit
    sample_rate: 16000

i2s_audio:
  - id: mic_bus
    i2s_lrclk_pin: GPIO29
    i2s_bclk_pin: GPIO27
    i2s_mclk_pin: GPIO30

media_player:
  - platform: speaker
    name: None
    id: speaker_player
    announcement_pipeline:
      speaker: tab5_speaker
      format: FLAC
      sample_rate: 48000
      num_channels: 1
    on_announcement:
      # Stop the wake word (mWW or VA) if the mic is capturing
      - if:
          condition:
            - microphone.is_capturing:
          then:
            - micro_wake_word.stop:
    on_idle:
      # Since VA isn't running, this is the end of user-intiated media playback. Restart the wake word.
      - if:
          condition:
            not:
              voice_assistant.is_running:
          then:
            - micro_wake_word.start:

micro_wake_word:
  id: mww
  models:
    - okay_nabu
    - hey_mycroft
    - hey_jarvis
  on_wake_word_detected:
    - voice_assistant.start:
        wake_word: !lambda return wake_word;

microphone:
  - platform: i2s_audio
    id: tab5_microphone
    i2s_din_pin: GPIO28
    sample_rate: 16000
    bits_per_sample: 16bit
    adc_type: external

# Commented out to avoid duplicates (see above)
# Comentado para evitar duplicidades (ver arriba)
#select:
# The DAC Output select needs to be manually (or with an automation) changed to `LINE1` for the onboard speaker
#  - platform: es8388
#    dac_output:
#      name: DAC Output
#    adc_input_mic:
#      name: ADC Input Mic

speaker:
  - platform: i2s_audio
    id: tab5_speaker
    i2s_dout_pin: GPIO26
    audio_dac: es8388_dac
    dac_type: external
    channel: mono
    buffer_duration: 100ms
    bits_per_sample: 16bit
    sample_rate: 48000

voice_assistant:
  id: va
  microphone: tab5_microphone
  media_player: speaker_player
  micro_wake_word: mww
  on_end:
    # Wait a short amount of time to see if an announcement starts
    - wait_until:
        condition:
          - media_player.is_announcing:
        timeout: 0.5s
    # Announcement is finished and the I2S bus is free
    - wait_until:
        - and:
            - not:
                media_player.is_announcing:
            - not:
                speaker.is_playing:
    - micro_wake_word.start:
  on_client_connected:
    - micro_wake_word.start:
  on_client_disconnected:
    - micro_wake_word.stop:

6. Important note: This code does not include the credentials required for the device to connect to your WiFi and your Home Assistant instance, so you must add them manually. Specifically, I am referring to the following lines from the code you copied in step 4.

 

# Enable Home Assistant API
api:
  encryption:
    key: "bg6hash6sjdjsdjk02hh0qnQeYVwm123vdfKE8BP5"

ota:
  - platform: esphome
    password: "asddasda27aab65a48484502b332f"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

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

7. What you need to do is find the corresponding lines in the code (at the beginning) and add the relevant information.

8. Now, click "Save" and "Install." Select "Manual download" and wait for the code to compile.

9. Once finished, select the "Modern format" option to download the corresponding '.bin' file.

10. Connect the M5Stack TAB5 to your computer using the USB-C data cable via the side port.

11. Now go to the ESPHome Web page and click "Connect." In the pop-up window, select your board and click "Connect."

12. Now click "Install" and select the '.bin' file obtained in step 9. Click "Install" once more.

13. Return to Home Assistant and go to Settings > Devices & Services. Your device should normally be discovered and appear at the top, simply waiting for you to click the "Configure" button. Otherwise, click the "Add Integration" button, search for "ESPHome," and enter your board's IP address in the "Host" field. As always, I recommend that you assign a static IP in your router to avoid future issues if it changes.

14. Finally, go to Settings > Devices & Services > ESPHome. Click the "Configure" link for your device. In the pop-up window, check the box "Allow the device to perform Home Assistant actions" and click "Submit." This will allow us to control our devices directly from the screen.

 

If everything went well, you should see the following on your screen:

 

Additionally, with this code, you will be able to:

·        Control and monitor the device's sensors in Home Assistant (such as battery percentage, activating the speaker, turning on the screen…).

·        Use the screen to create your control dashboard and manage your devices.

·        Expose your M5Stack Tab5 as a media player entity, allowing you to use it to play audio notifications or the radio.

·        Use it as a voice assistant if you have already configured Assist.

🏷️ Tips:

Each part in the code has been labeled, so any sections you are not interested in can be removed. 

From here on, the way you use the panel depends on your imagination!

Source: AguacaTEC

Author: TitoTB

-->

Turn M5Stack Tab5 into a Portable Home Assistant Control Panel

M5Stack Cardputer-Adv, The Limitless Computer

Understanding M5-Bus and DIP Switches: A Practical Guide for M5Stack Modules

From Hardware to Voice Intelligence: Building Your Own Home Assistant Voice Assistant with M5Stack CoreS3

1.      Manually download the program and upload it to raspberrypi5, or pull the model repository with the following command.

If git lfs is not installed, first refer to git lfs installation guide for installation.
git clone https://huggingface.co/AXERA-TECH/immich

File Description:

m5stack@raspberrypi:~/rsp/immich $ ls -lh
total 421M
drwxrwxr-x 2 m5stack m5stack 4.0K Oct 10 09:12 asset
-rw-rw-r-- 1 m5stack m5stack 421M Oct 10 09:20 ax-immich-server-aarch64.tar.gz
-rw-rw-r-- 1 m5stack m5stack    0 Oct 10 09:12 config.json
-rw-rw-r-- 1 m5stack m5stack 7.6K Oct 10 09:12 docker-deploy.zip
-rw-rw-r-- 1 m5stack m5stack 104K Oct 10 09:12 immich_ml-1.129.0-py3-none-any.whl
-rw-rw-r-- 1 m5stack m5stack 9.4K Oct 10 09:12 README.md
-rw-rw-r-- 1 m5stack m5stack  177 Oct 10 09:12 requirements.txt

2.     Import the docker image

If docker is not installed, please refer to RaspberryPi docker installation guide to install it first.
cd immich
docker load -i ax-immich-server-aarch64.tar.gz
3. Prepare the working directory

unzip docker-deploy.zip 
cp example.env .env

4.    Start the container

docker compose -f docker-compose.yml -f docker-compose.override.yml up -d

If started successfully, the information is as follows:

m5stack@raspberrypi:~/rsp/immich $ docker compose -f docker-compose.yml -f docker-compose.override.yml up -d
WARN[0000] /home/m5stack/rsp/immich/docker-compose.override.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion 
[+] Running 3/3
 ✔ Container immich_postgres  Started                                      1.0s 
 ✔ Container immich_redis     Started                                      0.9s 
 ✔ Container immich_server    Started                                      0.9s 

5.     Create a virtual environment

python -m venv mich

6.     Activate the virtual environment

source mich/bin/activate 

7.     Install dependency packages

pip install https://github.com/AXERA-TECH/pyaxengine/releases/download/0.1.3.rc1/axengine-0.1.3-py3-none-any.whl
pip install -r requirements.txt
pip install immich_ml-1.129.0-py3-none-any.whl # Precompiled package may be upgraded; use the actual file name.

8.     Start the immich_ml service

python -m immich_ml 

After running, you should see:

(mich) m5stack@raspberrypi:~/rsp/immich $ python -m immich_ml
[10/10/25 09:50:12] INFO     Starting gunicorn 23.0.0                           
[10/10/25 09:50:12] INFO     Listening at: http://[::]:3003 (8698)              
[10/10/25 09:50:12] INFO     Using worker: immich_ml.config.CustomUvicornWorker 
[10/10/25 09:50:12] INFO     Booting worker with pid: 8699                      
2025-10-10 09:50:13.589360675 [W:onnxruntime:Default, device_discovery.cc:164 DiscoverDevicesForPlatform] GPU device discovery failed: device_discovery.cc:89 ReadFileContents Failed to open file: "/sys/class/drm/card1/device/vendor"
[INFO] Available providers:  ['AXCLRTExecutionProvider']
/home/m5stack/rsp/immich/mich/lib/python3.11/site-packages/immich_ml/models/clip/cn_vocab.txt
[10/10/25 09:50:16] INFO     Started server process [8699]                      
[10/10/25 09:50:16] INFO     Waiting for application startup.                   
[10/10/25 09:50:16] INFO     Created in-memory cache with unloading after 300s  
                             of inactivity.                                     
[10/10/25 09:50:16] INFO     Initialized request thread pool with 4 threads.    
[10/10/25 09:50:16] INFO     Application startup complete.  

In your browser, enter the Raspberry Pi IP address and port 3003, for example: 192.168.20.27:3003

Note: The first visit requires registering an administrator account; the account and password are saved locally.

Once configured, you can upload images.

The first time, you need to configure the machine learning server. Refer to the diagram below to enter the configuration.

Set the URL to the Raspberry Pi IP address and port 3003, e.g., 192.168.20.27:3003.

If using Chinese search for the CLIP model, set it to ViT-L-14-336-CN__axera; for English search, set it to ViT-L-14-336__axera.

After setup, save the configuration.

The first time, you need to manually go to the Jobs tab and trigger SMART SEARCH.

Enter the description of the image in the search bar to retrieve relevant images.

Through this hands-on project, we’ve not only built a powerful smart photo album platform, but also experienced the exceptional performance of the M5Stack LLM‑8850 Card in edge AI computing. Whether setting up a private photo album on your Raspberry Pi or deploying intelligent image processing in security scenarios, the M5Stack LLM‑8850 Card delivers efficient, stable computing power you can rely on.


It brings AI closer to where your data resides, enabling faster, more secure processing and turning your ideas into reality. If you’re looking for a solution for on-device AI inference, give M5Stack LLM‑8850 Card a try — it might just become the core engine of your next project.

-->

LLM‑8850 Card in Action: Creating an AI‑Powered Photo Management Platform with Immich

l  What is LoRa and how does it work?

l  Prerequisites

l  Mounting and configuring the LoRa Gateway

l  LoRa node configuration

l  Check the communication

l  Sending information

l  Customize your Gateway

l  Acknowledgments

What is LoRa and how does it work?

LoRa (an acronym for "Long Range") is a radio frequency communication protocol that enables long-distance data transmission (up to 10 km in open fields) with very low power consumption. Therefore, it offers two major advantages:

  • It has a much greater range than the protocols we commonly use (WiFi, Bluetooth, Zigbee, etc.). This makes it the ideal choice for remote sensors (storage rooms, mailboxes, large gardens, etc.).
  • It doesn't rely on the telephone or electrical network to transmit information, so different LoRa devices can communicate even during a power outage.

However, it also has its limitations, as its data transfer speed is slow. In practice, this means it's perfect for sending simple data (commands to our devices, numbers, or text strings), but it's not a suitable protocol for transmitting photos or videos.

Additionally, you should consider the frequency LoRa uses in your geographic area. For example, in Europe it's 868 MHz, while in the US and most of Latin America it's 915 MHz.

Prerequisites

To integrate LoRa into Home Assistant, you will need the following components:

  • A LoRa gateway that receives information from the various nodes and transmits it to Home Assistant. In this case, we're going to create a gateway with the M5Stack Core S3 SE (yes, the same one we already used to Activate Assist ), combined with the LoRa868 modules and an external battery (this is optional).
  • A LoRa node that collects and sends information (e.g., a connected sensor). In this case, we're going to use a board with the integrated SX1276 chip (which would also be a valid device to act as a LoRa gateway).
  • A  USB cable to power the DATA board  (  with a charging cable, you will not be able to install the software).
  • Having installed  ESPHome in Home Assistant.

Mounting and configuring the LoRa Gateway

We are going to be using the M5Stack Core S3 SE along with the LoRa868 V1.1 module (now the LoRa868 v1.2 module is available). This is a modular device that's very easy to expand by simply assembling the components.

Something important to keep in mind is that the LoRa module has some small switches on the back ('DIP switches') that modify the pin assignment, and logically, it must match what we indicate in the ESPHome code.

To do this, make sure the switches are in the following position (2, 6 and 7 on and the rest off).

From here, the process will be similar for any compatible motherboard (adapting the steps and connection diagram to the specifications of your device). The steps we followed are as follows:

1.      In Home Assistant, go to your ESPHome plugin  , tap “New device” and “Continue.”

2.    Give your device a name  (for example, “LoRa Gateway” )  and click “Next”.

3.    Select “ESP32-S3” as the device type . You'll notice that a new block has been created for your device in the background.

4.   Click “Skip” and click “Edit” above your device block.

5.    Add the following lines to the end of your code (which come directly from the ESPHome SX127x component, adapted to our device).

captive_portal:

spi:
  clk_pin: GPIO36 
  mosi_pin: GPIO37 
  miso_pin: GPIO35 

sx127x:
  cs_pin: GPIO6 
  rst_pin: GPIO7 
  dio0_pin: GPIO10 
  pa_pin: BOOST
  pa_power: 14
  bandwidth: 125_0kHz
  crc_enable: true
  frequency: 868920000
  modulation: LORA
  rx_start: true
  sync_value: 0x12
  spreading_factor: 7
  coding_rate: CR_4_5
  preamble_size: 8
  on_packet:
    then:
      - lambda: |-
          ESP_LOGD("lambda", "packet %s", format_hex(x).c_str());
          ESP_LOGD("lambda", "rssi %.2f", rssi);
          ESP_LOGD("lambda", "snr %.2f", snr);

button:
  - platform: template
    name: "Transmit Packet"
    on_press:
      then:
        - sx127x.send_packet:
            data: [0xC5, 0x51, 0x78, 0x82, 0xB7, 0xF9, 0x9C, 0x5C]

6.   Click “Save” and “Install.” Select “Manual download” and wait for the code to compile. 

7.   When finished, select the “Modern format” option to download the corresponding '.bin' file.

8.   Connect the M5Stack Core S3 SE to your computer using the USB-C data cable via the port on the side.

9.   Now go to the ESPHome page   and click "Connect." In the pop-up window,  select your board  and click "Connect."

10.   Now click on “Install” and select the '.bin' file obtained in step 7. Again, click on  “Install”.

11.  Return to Home Assistant and go to  Settings > Devices & Services. Your device should have been discovered and appear at the top, waiting for you to press the  "Configure" button. Otherwise, click the "Add integration" button, search for "ESPHome," and enter your board's IP address in the "Host" field. As always, we recommend assigning a static IP address to your router to avoid future issues if it changes.

LoRa node configuration

Now that we have our LoRa gateway, let's configure a node to send information to it. To do this, we'll follow steps very similar to those in the previous section:

1.      In Home Assistant, go to your ESPHome plugin  , tap  “New device”  and “Continue.”

2.    Give your device a name  (for example,  “LoRa Node” )  and click “Next”.

3.    Select “ESP32” as the device type  . You'll notice a new block has been created for your device in the background.

4.   Click “Skip” and click “Edit” above your device block.

5.    Add the following lines to the end of your code  (which in this case match the example of the  SX127x component of ESPHome).

captive_portal:

spi:
  clk_pin: GPIO5
  mosi_pin: GPIO27
  miso_pin: GPIO19

# Example configuration entry
sx127x:
  cs_pin: GPIO18
  rst_pin: GPIO23
  dio0_pin: GPIO26
  pa_pin: BOOST
  pa_power: 14
  bandwidth: 125_0kHz
  crc_enable: true
  frequency: 868920000
  modulation: LORA
  rx_start: true
  sync_value: 0x12
  spreading_factor: 7
  coding_rate: CR_4_5
  preamble_size: 8
  on_packet:
    then:
      - lambda: |-
          ESP_LOGD("lambda", "packet %s", format_hex(x).c_str());
          ESP_LOGD("lambda", "rssi %.2f", rssi);
          ESP_LOGD("lambda", "snr %.2f", snr);

button:
  - platform: template
    name: "Transmit Packet"
    on_press:
      then:
        - sx127x.send_packet:
            data: [0xC5, 0x51, 0x78, 0x82, 0xB7, 0xF9, 0x9C, 0x5C]

6.   Note that the pin assignment is different (because we're using a different device than the one we used for the Gateway), but the rest of the configuration is exactly the same as in the previous section. This is important so they can communicate with each other.

7.   Click “Save” and “Install.” Select  “Manual download”  and wait for the code to compile. 

8.   When finished, select the “Modern format” option to download the corresponding '.bin' file.

9.   Connect the board to your computer using the Micro USB data cable through the port on the side.

10.   Now go to the ESPHome page   and click "Connect." In the pop-up window,  select your board  and click "Connect."

11.  Now click on “Install” and select the '.bin' file obtained in step 8. Again, click on  “Install”.

12.    Return to Home Assistant and go to  Settings > Devices & Services . Your device should have been discovered and appear at the top, waiting for you to press the  "Configure" button . Otherwise, click the "Add integration" button, search for "ESPHome," and enter your board's IP address in the "Host" field. As always, we recommend assigning a static IP address to your router to avoid future issues if it changes.

Check the communication

Let's do a little test to check that both devices are communicating correctly (the Gateway and the node) .

1.      Make sure both devices are turned on and are online in Home Assistant and ESPHome.

2.    From Home Assistant, go to Settings > Devices & Services > ESPHome and access one of them (for example, the Gateway).

3.    Open a new window (without closing the previous one), enter the ESPHome plugin and access the logs of the other device (in this case, the node).

4.   In the Home Assistant window, click the "Transmit Packet" button. You'll immediately see the logs from the second device recording the incoming packet.

You can perform a reverse test to verify that communication is working both ways. If everything went well, your devices are now communicating.

Sending information

Logically, the point of integrating LoRa into Home Assistant is to send some kind of useful information (such as the value of a sensor connected to the node).

1.      The first step is to add the sensor you're interested in to the node board. For example, we're going to add a PIR sensor to get the long-awaited motion sensor on the mailbox. To do this, we've added the following code snippet:

binary_sensor:
  - platform: gpio
    pin: GPIO34
    name: "PIR Sensor"
    device_class: motion
    id: pir_sensor

2.    If you look at the code above, it's the same one we would use in any "normal" scenario. However, to send the information to our LoRa Gateway, we need to add something extra using the 'Packet Transport' component.

packet_transport:
  platform: sx127x
  update_interval: 5s
  encryption: "password"
  rolling_code_enable: true
  binary_sensors:
    - pir_sensor

3.    Analyze the code above and observe the following:

·        In the 'encryption' attribute, you have to indicate the encryption key for your message (whatever you want), so that it cannot be received by anyone on the same frequency.

·        We've identified the ID of the sensor we want to send (in this case, the binary sensor with the ID "pir_sensor") . You can add any other sensors you're interested in here.

4.   Now we are going to add the following to the code of our LoRa Gateway, so that it receives the information.

packet_transport:
  platform: sx127x
  update_interval: 5s
  providers:
    - name: lora-node
      encryption: "password"

binary_sensor:
  - platform: packet_transport
    id: pir_sensor
    provider: lora-node

  - platform: template
    name: "Buzón"
    device_class: motion
    lambda: return id(pir_sensor).state;

5.    Now we’re going to add the following to the code of our LoRa Gateway, so it can receive the information.

Again, analyze the code and note the following:

l We have specified the ESPHome device name of our LoRa node as the data provider.

l In the ‘encryption’ attribute, we have indicated exactly the same key as in the node.

l To transform the information received into a gateway sensor, we used the “packet_transport” platform. We assigned it an “id” (you can choose any) and again indicated the LoRa node name as the provider. This is an internal ESPHome sensor.

l To display this information in Home Assistant, we created a template sensor of the same type, assigning it the value of the internal sensor created in the previous step.

6.   And that's it! If you now check your gateway device in Home Assistant, you’ll see that it already shows the information from the node.

Customize your Gateway

Since we used the M5Stack Core S3 SE to integrate LoRa into Home Assistant, we can take advantage of its other features to customize it! Below, we're leaving you the full code to create a screen that notifies you when you receive letters in your mailbox!

esphome:
  name: lora-gateway
  friendly_name: LoRa Gateway
  libraries:
    - m5stack/M5GFX@^0.1.11
    - m5stack/M5Unified@^0.1.11

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: esp-idf

psram:
  mode: octal
  speed: 80MHz

external_components:
  - source:
      type: git
      url: https://github.com/m5stack/M5CoreS3-Esphome
    components: [ m5cores3_display ]
    refresh: 0s

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "1QrsXUgryxlF6OGsIwLj7eijyy/OMhSobQQHYWPvpb0="

ota:
  - platform: esphome
    password: "4844c4205ab6ab665c2d1a4be82deb57"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Lora-Gateway Fallback Hotspot"
    password: "6BRaaV17Iebb"

captive_portal:

spi:
  clk_pin: GPIO36 
  mosi_pin: GPIO37 
  miso_pin: GPIO35 

sx127x:
  cs_pin: GPIO6 
  rst_pin: GPIO7 
  dio0_pin: GPIO10 
  pa_pin: BOOST
  pa_power: 14
  bandwidth: 125_0kHz
  crc_enable: true
  frequency: 868920000
  modulation: LORA
  rx_start: true
  sync_value: 0x12
  spreading_factor: 7
  coding_rate: CR_4_5
  preamble_size: 8
  on_packet:
    then:
      - lambda: |-
          ESP_LOGD("lambda", "packet %s", format_hex(x).c_str());
          ESP_LOGD("lambda", "rssi %.2f", rssi);
          ESP_LOGD("lambda", "snr %.2f", snr);

packet_transport:
  platform: sx127x
  update_interval: 5s
  providers:
    - name: lora-node
      encryption: "password"

binary_sensor:
  - platform: packet_transport
    id: pir_sensor
    provider: lora-node

  - platform: template
    name: "Buzón"
    device_class: motion
    lambda: return id(pir_sensor).state;

color:
  - id: green
    hex: 'bfea11'
  - id: red
    hex: 'ff0000'

font:
  - file: "gfonts://Roboto"
    id: font_title
    size: 18
  - file: "gfonts://Roboto"
    id: font_text
    size: 16

image:
  - file: mdi:mailbox
    id: buzon_off
    resize: 100x100
    type: grayscale
    transparency: alpha_channel
  - file: mdi:email-alert
    id: buzon_on
    resize: 100x100
    type: grayscale
    transparency: alpha_channel

display:
  - platform: m5cores3_display
    model: ILI9342
    dc_pin: 15
    update_interval: 1s
    id: m5cores3_lcd
    lambda: |-
      // Obtener dimensiones de la pantalla
      int screen_width = it.get_width();
      int screen_height = it.get_height();
      
      // Título en la parte superior con margen de 20px
      it.print(screen_width/2, 20, id(font_title), id(green), TextAlign::TOP_CENTER, "LoRa Gateway by Aguacatec");
      
      // Obtener estado del sensor del buzón
      bool mailbox_open = id(pir_sensor).state;
            
      if (mailbox_open) {
        // Buzón abierto - icono rojo
        it.image(110, 70, id(buzon_on), id(red));
        it.print(screen_width/2, 200, id(font_text), id(red), TextAlign::CENTER, "Carta recibida!!");
      } else {
        // Buzón cerrado - icono verde
        it.image(110, 70, id(buzon_off), id(green));
        it.print(screen_width/2, 200, id(font_text), id(green), TextAlign::CENTER, "No hay correspondencia");
      }

Acknowledgements

To prepare this post, this video by our friend Miguel Ángel (from La Choza Digital) was extremely helpful! 

Source: AguacaTEC

Author: TitoTB

-->

Build a Long‑Range LoRa Gateway for Home Assistant with M5Stack

UIFlow2 Officially Supports LVGL: Enabling Greater Flexibility in Hardware UI Development

Integrating M5Atom Lite into Home Assistant Using ESPHome

How to Integrate the M5Stack Dial with Home Assistant (Full ESPHome Guide)

All You Need to Know about M5StickC Plus2

How to Build Your Own Meshtastic Device

DIY a ChatGPT Voice Assistant Using ESP32-Based Hardware — AtomS3R and Atomic Echo Base

M5Stack Releases AI Pyramid: High-Performance Edge AI PC for Developers and Makers

Feb. 6, 2026 – M5Stack, a global leader in modular IoT and embedded development platforms, today announced the release of AI Pyramid series, comprising two...

M5Stack Launches StickS3: An Enhanced Compact Controller for IoT Projects

Jan. 23, 2026 – M5Stack, a global leader in modular IoT and embedded development platforms, today announced the launch of StickS3, the latest addition to...

M5Stack Completes SquareLine Vision Integration to Accelerate UI Development

Jan.2026, M5Stack officially announced its collaboration with SquareLine Vision, a next-generation UI design platform built to simplify and accelerate graphical interface development for embedded systems. As...

StackChan by M5Stack Now Available on Kickstarter

Jan. 13, 2026 — M5Stack, a global leader in modular IoT and embedded development platforms, today launched StackChan, the first community-co-created open-source AI desktop robot, built on a...

Build, share, and connect! M5Stack Open Day 2025

On November 17, 2025, M5Stack once again hosted its annual Open Day, welcoming global users and enthusiasts. This year’s event reached a new milestone, bringing...

Arduino and M5Stack Introduce Nesso  N1: The Future of IoT in the Palm of Your Hand

Nov. 12, 2025–M5Stack, a global leader in modular IoT and embedded development platforms, today announced Arduino Nesso N1, a compact and powerful development kit co‑engineered with Arduino,...

Innovation Meets Design: M5Stack Series Honored with 2025 Good Design Award

With the outstanding modular design, excellent user experience, and innovative integration of hardware and software ecosystems, the M5Stack Series was honored with the 2025 Good...

M5Stack Unveils Innovative IoT and LoRa Solutions at The Things Conference 2025

M5Stack showcased its latest breakthroughs in modular IoT, edge computing, and smart automation at The Things Conference 2025, held at De Kromhouthal, Amsterdam — the...

M5Stack Launches Cardputer-Adv: Upgraded Card-Sized Computer for Rapid IoT Development

September 5, 2025 – M5Stack, a global leader in modular IoT and embedded development platforms, today announced the launch of Cardputer‑Adv, the upgraded model of...

M5Stack Unveils Tab5 – A Powerful, ESP32-P4 Based Industrial Touch Terminal with Multimedia, Multi-Protocol, and Modular Capabilities

May 9, 2025 – M5Stack, a leader in modular IoT and embedded development platforms, unveils Tab5, a next-generation 5-inch smart touch terminal powered by the advanced 400MHz ESP32-P4...

Step into the M5Stack world: A recap of M5Stack Open Day 2024

On November 18, 2024, M5Stack opened its doors to individual visitors for the first time. More than 70 visitors from all around the world attended...

2023 in Review: M5Stack's Top 10 Bestselling Products Revealed

Time flies, and 2023 has come to an end. M5Stack's products and services have accompanied users worldwide throughout the year. 2023 was a year of...

Comming soon ...