Athom Human Presence Sensor mmwave (share your experiences)

@bryanw Since 2024.5.4 (May 28th release) OTA is fixed for me!

I needed to retry the OTA installation several times, but it then worked.
See release notes ESPHome 2024.5.0 - 15th May 2024 — ESPHome

with the fix “Also reduces fw size.”
[helpers] Move Base64 string to cpp by gabest11 · Pull Request #6819 · esphome/esphome · GitHub


Still, if the latest OTA really doesn’t work for you, then do a 2-step OTA procedure:
First, install a minimal version with OTA.
Second, install the full version with OTA.
Don’t forget to change your friendly_name, name and key.
Note: sometimes i had to retry the update several times until it went through.


Step 1 - Minimal OTA config

substitutions:
  name: athom-presence-sensor-my-id
  friendly_name: My Nice Athom
  
esphome:
  name: ${name}
  name_add_mac_suffix: false
  friendly_name: ${friendly_name}

esp8266:
  board: esp8285
ota:
logger:

api:
  encryption:
    key: XYZXYZXYZXYZXYZXYZXYZXYZXYZXYZXYZXYZ

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

Step 2 - Full OTA config

substitutions:
  name: athom-presence-sensor-my-id
  friendly_name: My Nice Athom

packages:
  Athom_Technology.Presence_Sensor: github://athom-tech/athom-configs/athom-presence-sensor.yaml

esphome:
  name: ${name}
  name_add_mac_suffix: false
  friendly_name: ${friendly_name}

api:
  encryption:
    key: XYZXYZXYZXYZXYZXYZXYZXYZXYZXYZXYZXYZ

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

@Hell255 - Thank you for sharing this information! I noticed my Athom sensors updated fine now. :slight_smile: Glad it was fixed.

1 Like

Thanks for sharing this, but even with the base config and trying it a BUNCH of times including resetting the device - I didn’t have any luck.
I think I’m going to have to factory reset my two units, adopt them, and then update their configs. :frowning:

1 Like

I have 2 of these. One in my living room and one in my basement media area. Main purpose is to turn off the lights/tv when no one is there and they are left on. I am overall very happy with the devices. using blakadder’s config.

I have several different esp based presence sensors (screek, athom, apollo, seeedstudio kit). The best in my opinion on accuracy/true positives/false positives are the screeks. I haven’t played much with the apollo one yet. The athoms are good enough and reliable enough that I put them to use right away with minimal tweaking to get the result I was looking for. I would recommend also looking into the screek products (I am using two 2A’s and one 1U). They don’t however have a PIR if that is something you specifically are wanting.

Thanks for sharing your experience! I was considering the screek devices for a time, then decided to just build the rest of my presence sensors using ESP32 boards and sensors from Ali Express.

The “homemade” presence sensors work well now, but required a LOT more tuning that the Athom sensor. Athom sensors work really well and require minimal setup. Glad to hear the screek are pretty good too. I believe the Apollo is highly rated & you’ll find that works very well too.

I’m thinking a nice upgrade to these sensors would be a temperature sensor. Has anyone else tried doing this? It looks like there’s a few free I/O’s which could possibly make this work with a DS18B20 or something.

I haven’t tried a temperature sensor yet. If anyone has please share your experience.

thanks for this info. I too had had the PS01 working fine for 7 days and then for some reason the presence sensor stopped clearing. After making the adjustments you suggested this now appears to be back to normal again :+1:

Yes. Had it today. Just a cold soldering. Mine was started to be stable after i resoldered with 320 degrees C the dupont pin headers with some extra flux.

I have two of these devices that have their mmWave sensors stuck on “Detected”. Tried different ESPHome configs to no avail.

Does anyone have yaml / bin config that allows static IP input?
tried giving wifi address like this but after flashing the device seems to brick, serial logging wont work… the led just stays solid

substitutions:
  name: athom-presence-34987ad939ad
  friendly_name: athom-presence-34987ad939ad
esphome:
  name: athomps-smokingtengah1 
  name_add_mac_suffix: False
  friendly_name: athomps-smokingtengah1
packages:
  Athom_Technology.Athom_PS01C3_Presence_Sensor: github://athom-tech/esp32-configs/athom-presence-sensor-v3.yaml
#esp8266:
 # board: esp8285

#logger:

# Enable Home Assistant API
api:
  encryption:
    key: "REi5jjC0XhoMiWPme8Hwsf0edtZAi607/UNdVHmq5Pk="

ota:
  - platform: esphome
    password: "dd38ef4b97286d5c0df15f04700302db"

wifi:
  ssid: "cemara_tool"
  password: ""
  manual_ip:
    static_ip: 192.168.88.178
    gateway: 192.168.88.1
    subnet: 255.255.255.0
  # Enable fallback hotspot (captive portal) in case wifi connection fails

This is mine:

wifi:
  ssid: !secret wifi_ssid_not_1
  password: !secret wifi_password_not_1
  manual_ip:
    static_ip: 192.168.30.181
    gateway: 192.168.30.1
    subnet: 255.255.255.0

Works fine.

Could you share the complete yaml? For some reason the web flasher says flash is successful but it bricks the sensor…

Yeah, no problem.

substitutions:
  name: "alfresco-presence-sensor"
  friendly_name: "Alfresco Presence Sensor"
#  room: ""
  device_description: "mmwave radar human presence sensor"
  project_name: "Athom Technology.Presence Sensor"
  project_version: "1.0-blak"
  pir_delay_off: "1s" # set the PIR no occupancy delay here, it also influences delay for Occupancy sensor

esphome:
  name: "${name}"
  friendly_name: "${friendly_name}"
  name_add_mac_suffix: true
  project:
    name: "${project_name}"
    version: "${project_version}"

esp8266:
  board: esp8285
  restore_from_flash: True

logger:

api:

ota:
  platform: esphome
  
mdns:
  disabled: false

web_server:
  port: 80

wifi:
  ssid: !secret wifi_ssid_not_1
  password: !secret wifi_password_not_1
  manual_ip:
    static_ip: 192.168.30.181
    gateway: 192.168.30.1
    subnet: 255.255.255.0

captive_portal:

dashboard_import:
  package_import_url: github://blakadder/esphome-configs/athom_ps01.yaml

light:
  - platform: status_led
    name: "Status LED"
    id: led
    pin: GPIO16
    disabled_by_default: true
    entity_category: config

i2c:
  sda: GPIO4
  scl: GPIO5
  scan: true

uart:
  tx_pin: GPIO15
  rx_pin: GPIO13
  baud_rate: 115200
  # debug:
  #   direction: BOTH
  #   dummy_receiver: true
  #   after:
  #     delimiter: "\n"
  #   sequence:
  #     - lambda: UARTDebug::log_string(direction, bytes);


binary_sensor:
  - platform: status
    name: "Status"

  - platform: gpio
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: true
    name: "Button"
    disabled_by_default: true
    internal: true
    on_multi_click:
      - timing:
          - ON for at least 10s
        then:
          - button.press: factory_reset_device

  - platform: gpio
    pin:
      number: GPIO14
      mode:
        input: true
        pullup: true
    name: "Pir Sensor"
    id: pir
    filters:
#      - delayed_on: 50ms
#      - delayed_off: 500ms
       - delayed_off: ${pir_delay_off}
    device_class: motion
#    on_press:
#      then:
#        - light.turn_on: led

  - platform: gpio
    pin:
      number: GPIO12
      mode:
        input: true
        pullup: true
    name: "mmWave Sensor"
    id: mmwave
#    filters:
#      - delayed_on: 50ms
    device_class: occupancy
    on_press:
      then:
        - light.turn_on: led
    on_release:
      then:
        - light.turn_off: led


  - platform: template
    name: "Occupancy"
    id: occupancy
    device_class: occupancy
    lambda: |-
      if ( id(mmwave).state or id(pir).state) {
        return true;
      } 
      else if (id(mmwave).state == 0 and id(pir).state == 0) {
        return false;
      } 
      else {
        return id(occupancy).state;
      }
  
sensor:
  - platform: uptime
    name: "Uptime Sensor"

  - platform: wifi_signal
    name: "WiFi Signal Sensor"
    update_interval: 60s

  - platform: bh1750
    name: "Light Sensor"
    address: 0x23
    update_interval: 5s

switch:
  - platform: template
    name: "mmWave Status"
    id: "mmwave_sensor"
    internal: true
    entity_category: config
    optimistic: true
    restore_mode: DISABLED
    turn_on_action:
      - uart.write: "sensorStart\r\n"
    turn_off_action:
      - uart.write: "sensorStop\r\n"

number:
  - platform: template
    name: Farthest Detection          #Value range: 1.9 ~ 12m  Default: 6 
    id: Farthest_Detection
    entity_category: config
    min_value: 1.9
    max_value: 12
    initial_value: 6
    optimistic: true
    step: 0.1
    restore_value: true
    unit_of_measurement: m
    mode: box
    set_action:
      - switch.turn_off: mmwave_sensor
      - delay: 500ms
      - uart.write: !lambda 
          std::string ranges = "setRange 1.8 " + str_sprintf("%.1f",id(Farthest_Detection).state) + "\r\n";
          return std::vector<uint8_t>(ranges.begin(), ranges.end());
      - delay: 500ms
      - uart.write: "saveConfig\r\n"
      - delay: 500ms
      - switch.turn_on: mmwave_sensor

  - platform: template
    name: Maintain Sensitivity          #Value range: 0 ~ 9   Default Maintain sensitivity: 7 
    id: Maintain_Sensitivity
    entity_category: config
    min_value: 0
    max_value: 9
    initial_value: 7
    optimistic: true
    step: 1
    restore_value: true
    mode: slider
    set_action:
      - switch.turn_off: mmwave_sensor
      - delay: 500ms
      - uart.write: !lambda 
          std::string sensitivitys = "setSensitivity " + str_sprintf("%.0f",id(Maintain_Sensitivity).state) + " " + str_sprintf("%.0f",id(Trigger_Sensitivity).state) + "\r\n";
          return std::vector<uint8_t>(sensitivitys.begin(), sensitivitys.end());
      - delay: 500ms
      - uart.write: "saveConfig\r\n"
      - delay: 500ms
      - switch.turn_on: mmwave_sensor

  - platform: template
    name: Trigger Sensitivity           #Value range: 0 ~ 9   Default Trigger sensitivity: 5
    id: Trigger_Sensitivity
    entity_category: config
    min_value: 0
    max_value: 9
    initial_value: 5
    optimistic: true
    step: 1
    restore_value: true
    mode: slider
    set_action:
      - switch.turn_off: mmwave_sensor
      - delay: 500ms
      - uart.write: !lambda 
          std::string sensitivityss = "setSensitivity " + str_sprintf("%.0f",id(Maintain_Sensitivity).state) + " " + str_sprintf("%.0f",id(Trigger_Sensitivity).state) + "\r\n";
          return std::vector<uint8_t>(sensitivityss.begin(), sensitivityss.end());
      - delay: 500ms
      - uart.write: "saveConfig\r\n"
      - delay: 500ms
      - switch.turn_on: mmwave_sensor

  - platform: template
    name: Detection Delay      #Confirmation delay      Value range: 0 ~ 100  default 0.050 seconds.
    id: Detection_Delay
    entity_category: config
    min_value: 0.05
    max_value: 60
    initial_value: 0.05
    optimistic: true
    step: 0.05
    mode: box
    restore_value: true
    unit_of_measurement: seconds
    set_action:
      - switch.turn_off: mmwave_sensor
      - delay: 500ms
      - uart.write: !lambda |-
          std::string detections = "setLatency " + str_sprintf("%.1f",id(Detection_Delay).state) + " " + str_sprintf("%.0f",id(Fading_Time).state) + "\r\n";
          return std::vector<uint8_t>(detections.begin(),detections.end());
      - delay: 500ms
      - uart.write: "saveConfig\r\n"
      - delay: 500ms
      - switch.turn_on: mmwave_sensor

  - platform: template
    name: Fading Time           #Fade-out delay        Value range: 0.5 ~ 1500, default 15 seconds.
    id: Fading_Time
    entity_category: config
    min_value: 0.5
    max_value: 300
    initial_value: 15
    optimistic: true
    step: 0.5
    restore_value: true
    unit_of_measurement: seconds
    mode: auto
    set_action:
      - switch.turn_off: mmwave_sensor
      - delay: 500ms
      - uart.write: !lambda |-
          std::string fadings = "setLatency " + str_sprintf("%.1f",id(Detection_Delay).state) + " " + str_sprintf("%.0f",id(Fading_Time).state) + "\r\n";
          return std::vector<uint8_t>(fadings.begin(), fadings.end());
      - delay: 500ms
      - uart.write: "saveConfig\r\n"
      - delay: 500ms
      - switch.turn_on: mmwave_sensor

  - platform: template  
    name: Blockade Time                  #Configure block time        Value range: 1 ~ 255, default 1 seconds.
    id: Blockade_Time
    entity_category: config
    min_value: 1
    max_value: 255
    initial_value: 1
    optimistic: true
    step: 1
    restore_value: true
    unit_of_measurement: seconds
    mode: box
    set_action:
      - switch.turn_off: mmwave_sensor
      - delay: 500ms
      - uart.write: !lambda 
          std::string blockades = "setInhibit " + str_sprintf("%.0f",x) + "\r\n";
          return std::vector<uint8_t>(blockades.begin(), blockades.end());
      - delay: 500ms
      - uart.write: "saveConfig\r\n"
      - delay: 500ms
      - switch.turn_on: mmwave_sensor

button:
  - platform: factory_reset
    name: Restart with Factory Default Settings
    id: Reset
    entity_category: config 
    internal: true
  - platform: template
    name: "Reset device"
    id: "factory_reset_device"
    entity_category: config
    internal: true
    on_press:
      - switch.turn_off: mmwave_sensor
      - delay: 500ms
      - uart.write: "resetCfg\r\n"
      - delay: 1s
      - switch.turn_on: mmwave_sensor
      - button.press: Reset
  - platform: restart
    name: Restart_esp
    id: restart_esp
    entity_category: config 
    internal: true
  - platform: template
    name: "Restart_mmWave"
    id: "restart_mmwave"
    entity_category: config
    internal: true
    on_press:
      - uart.write: "resetSystem\r\n"

  - platform: template
    name: Restart device
    entity_category: config
    on_press:
      - button.press: restart_mmwave
      - delay: 1s
      - button.press: restart_esp

text_sensor:
  - platform: wifi_info
    ip_address:
      name: "IP Address"
    ssid:
      name: "Connected SSID"
      disabled_by_default: true
    mac_address:
      name: "Mac Address"
      disabled_by_default: true
#  - platform: version
#    name: ${name} ESPHome Version
     
time:
  - platform: sntp
    id: my_time
1 Like

Awesome it works! Why didn’t I think of using blakadder’s yaml before…
But would there be any difference performance/accuracy wise compared to the original code? Or is it the same thing?

I’ve been using his code for a long time now and the 2 devices I have are working well. From memory it mainly improved the settings adjustability.

1 Like

I figured out my problem, apparently there are 2 types of chip, C3 and 8285, you can look at the back of the sensor, C3 has PS01C3 and 8285 should only have PS01, no wonder it bricked cause i used wrong yaml.

This is the ESP8285

This is the ESP32C3

2 Likes

Good spotting @cemara. Was having the same issues as you and this as sorted it. I see @blakadder has not updated his config for the new C3/PS01C3 model, so I did some mucking around here to update his old athom_ps01.yaml config.

Note I have very little knowledge on how to contribute to a GitHub project, so I muddled my way thru this process :slight_smile:

1 Like

Hi guys.

I have several ESP32-C3 versions and noticed that the lux meassurement differs to my old hue motion sensors.

The difference is about:

  • ~20 lux diff in the lows < 100
  • ~60 lux diff in higher values >= 200

Anyone of you noticed that?
Do you just adopt your automations on switching from other sensors like hue compensate it with an modification of the yaml like this:

or an helper sensor in HA?