Mastering Technology, Systems, Automation and Beyond

Ping server via Home Assistant

Monitoring Website Status in Home Assistant

This post documents how I set up a simple and reliable system in Home Assistant OS (HAOS) to monitor the status of websites, display the result in the UI, and keep a timestamp of the last check. It uses native command_line and template sensors and is designed to be easy to maintain and extend.

Websites Monitoring with Home Assistant

Goal

  • Monitor one or more websites (e.g. soulatech.com, example.com)
  • Use command_line sensors to check status
  • Use template binary_sensor to evaluate status
  • Record and display the timestamp of the last check
  • Send mobile notifications when websites go down or come back up
  • Keep it clean and native (no HACS or external integrations)

Where to Add This Configuration

In your main configuration.yaml, include external files for a clean setup:

# Websites Monitoring
command_line: !include websites_commandline.yaml
template: !include websites_template.yaml

Then create two new files:

websites_commandline.yaml

- sensor:
    name: Web Example Check
    unique_id: web_example_check
    command: >
      echo "$(if curl --max-time 10 -s -o /dev/null -w \"%{http_code}\" https://example.com | grep -q \"200\"; then echo online; else echo offline; fi) @ $(date -Iseconds)"
    scan_interval: 61

- sensor:
    name: Web SAT Check
    unique_id: web_sat_check
    command: >
      echo "$(if curl --max-time 10 -s -o /dev/null -w \"%{http_code}\" https://www.soulatech.com | grep -q \"200\"; then echo online; else echo offline; fi) @ $(date -Iseconds)"
    scan_interval: 62

websites_template.yaml

- binary_sensor:
    - name: "Web Example Status"
      unique_id: web_example_status
      state: "{{ states('sensor.web_example_check').split(' @ ')[0] == 'online' }}"
      device_class: running
      attributes:
        last_check: "{{ states('sensor.web_example_check').split(' @ ')[1] }}"

    - name: "Web SAT Status"
      unique_id: web_sat_status
      state: "{{ states('sensor.web_sat_check').split(' @ ')[0] == 'online' }}"
      device_class: running
      attributes:
        last_check: "{{ states('sensor.web_sat_check').split(' @ ')[1] }}"

Dashboard Example

To display these sensors on a dashboard:

type: entities
entities:
  - entity: binary_sensor.web_example_status
    secondary_info: last-updated
    name: example.com
    icon: mdi:web-check

  - entity: binary_sensor.web_sat_status
    secondary_info: last-updated
    name: soulatech.com
    icon: mdi:web-check

state_color: true
show_header_toggle: true
grid_options:
  columns: full

This card shows the site name, current status, last update time, and a color-coded icon.


Notifications

To receive push notifications on your phone when a website goes down or comes back up, add the following two automations:

Website Down Notification

alias: Website Down
trigger:
  - platform: state
    entity_id:
      - binary_sensor.web_sat_status
      - binary_sensor.web_example_status
    from: "on"
    to: "off"
action:
  - service: notify.mobile_app_phone_bazar
    data:
      message: >
        Website Down ({{ {
          'binary_sensor.web_sat_status': 'SAT',
          'binary_sensor.web_example_status': 'Example'
        }[trigger.entity_id] }}) @ {{ now().strftime('%H:%M') }}
      data:
        channel: Critical
        vibrationPattern: 50, 500, 50, 500, 50, 500, 50
        ledColor: red
        persistent: true
        tag: website
        importance: high
        color: red
mode: single

Website Up Notification

alias: Website Up
trigger:
  - platform: state
    entity_id:
      - binary_sensor.web_sat_status
      - binary_sensor.web_example_status
    to: "on"
action:
  - service: notify.mobile_app_phone_bazar
    data:
      message: >
        Website Up ({{ {
          'binary_sensor.web_sat_status': 'SAT',
          'binary_sensor.web_example_status': 'Example'
        }[trigger.entity_id] }}) @ {{ now().strftime('%H:%M') }}
      data:
        channel: Critical
        vibrationPattern: 50, 500, 50, 500, 50, 500, 50
        ledColor: green
        persistent: true
        tag: website
        importance: high
        color: green
mode: single

Important Considerations

  • The scan_interval values are staggered (e.g., 61s, 62s) to avoid all checks running at the same time. Over time, the interval gaps naturally shift, preventing network congestion.
  • The reason we inject the timestamp directly into the output (online @ timestamp) is to force a change in state output, even if the status (online) remains the same. Without this, Home Assistant would not update the sensor state or last_updated in the UI unless the status changes.
  • By having a timestamp embedded, we can show exactly when the last check occurred, not just when the status last changed — which is far more reliable for monitoring.
  • While this does generate frequent state entries in the Home Assistant logbook and database, HAOS retains only 7–10 days by default and handles it well. The impact is minimal, and the visibility gained is worth it.


Discover more from Soul of All Tech

Subscribe to get the latest posts sent to your email.


Tags


Comments


Leave a Reply

Your email address will not be published. Required fields are marked *

Navigation