#:########################################################################################:# # Package: Network Monitoring # File: network_monitoring.yaml # Version: v1.3.0 # Date: 2026-08-28 # # Purpose: # Supplies the calculated Internet, router, MQTT, and Home Assistant health # information for general network monitoring, including the independent # Panda and Beaver MQTT brokers, plus Node-RED Panda. # # Behaviour: # - Tracks daily and seven-day Internet speed-test peaks. # - Calculates rolling 24-hour and seven-day WAN traffic averages and peaks. # - Measures external HTTP latency and tracks the current public IP address. # - Monitors the Panda MQTT broker through Home Assistant's birth topic and # Beaver's MQTT listener through a direct TCP probe. # - Monitors Node-RED Panda through independent HTTP and MQTT signals. # - Retains the latest outage time for each monitored network service. # # Dependencies: # - packages/internet_monitoring.yaml # - packages/edgerouter_snmp.yaml # - MQTT integration with the default homeassistant/status birth topic. # - Existing Zigbee2MQTT connectivity entity. # # Notes: # - WAN traffic source values are kB/s and retain that unit in statistics. # - The 24-hour and seven-day traffic values are rolling windows. # - Home Assistant's own last outage is represented by sensor.uptime because # Home Assistant cannot record an event while Core itself is offline. # - Public IP data is fetched from api.ipify.org every five minutes. # # Version History: # - v1.3.0 (2026-08-28): Renamed package for general network use. # - v1.2.0 (2026-08-28): Consolidated Node-RED Panda monitoring. # - v1.1.0 (2026-08-28): Added Beaver MQTT and HA Core health monitoring. # - v1.0.0 (2026-08-15): Initial monitoring and outage tracking package. #:########################################################################################:# command_line: #:######################################################################################:# # EXTERNAL NETWORK INFORMATION #:######################################################################################:# - sensor: name: "Flounder External IP" unique_id: flounder_external_ip command: >- curl --fail --silent --show-error --max-time 10 https://api.ipify.org command_timeout: 15 scan_interval: 300 - sensor: name: "Flounder Internet Response Time" unique_id: flounder_internet_response_time command: >- curl --fail --silent --show-error --max-time 10 --output /dev/null --write-out "%{time_total}" https://one.one.one.one/cdn-cgi/trace command_timeout: 15 scan_interval: 60 unit_of_measurement: "ms" device_class: duration state_class: measurement value_template: "{{ ((value | float(0)) * 1000) | round(0) }}" - binary_sensor: name: "Flounder Beaver MQTT Broker Connected" unique_id: flounder_beaver_mqtt_broker_connected command: >- timeout 5 bash -c '>/dev/tcp/172.31.6.1/1883' && echo ON || echo OFF command_timeout: 6 scan_interval: 60 device_class: connectivity mqtt: #:######################################################################################:# # MQTT BROKER CONNECTION #:######################################################################################:# binary_sensor: - name: "Flounder MQTT Broker Connected" unique_id: flounder_mqtt_broker_connected state_topic: "homeassistant/status" payload_on: "online" payload_off: "offline" device_class: connectivity - name: "Node-RED Panda Up (MQTT)" unique_id: nodered_panda_up_mqtt state_topic: "nodered/panda/status" payload_on: "online" payload_off: "offline" device_class: connectivity qos: 1 expire_after: 180 binary_sensor: #:######################################################################################:# # NODE-RED PANDA HTTP HEALTH #:######################################################################################:# - platform: rest name: "Node-RED Panda Up (HTTP)" resource: http://192.168.3.200:1880/healthz method: GET device_class: connectivity value_template: "{{ value_json.status == 'ok' }}" timeout: 3 scan_interval: 30 input_number: #:######################################################################################:# # DAILY SPEED-TEST PEAKS #:######################################################################################:# flounder_internet_download_peak_today: name: "Flounder Internet Download Peak Today" min: 0 max: 10000 step: 0.01 mode: box flounder_internet_upload_peak_today: name: "Flounder Internet Upload Peak Today" min: 0 max: 10000 step: 0.01 mode: box input_datetime: #:######################################################################################:# # LAST EXTERNAL IP CHANGE #:######################################################################################:# flounder_external_ip_last_changed: name: "Flounder External IP Last Changed" has_date: true has_time: true input_text: #:######################################################################################:# # LAST OUTAGE TIMES #:######################################################################################:# flounder_internet_last_outage: name: "Flounder Internet Last Outage" max: 40 flounder_edgerouter_last_outage: name: "Flounder EdgeRouter Last Outage" max: 40 flounder_mqtt_broker_last_outage: name: "Flounder MQTT Broker Last Outage" max: 40 flounder_node_red_mqtt_last_outage: name: "Flounder Node-RED MQTT Last Outage" max: 40 flounder_zigbee2mqtt_2_last_outage: name: "Flounder Zigbee2MQTT 2 Last Outage" max: 40 flounder_zigbee2mqtt_3_last_outage: name: "Flounder Zigbee2MQTT 3 Last Outage" max: 40 template: #:######################################################################################:# # POPUP STATUS AND SPEED-TEST VALUES #:######################################################################################:# - binary_sensor: - name: "Flounder EdgeRouter Online" unique_id: flounder_edgerouter_online device_class: connectivity state: "{{ has_value('sensor.edgerouter_uptime') }}" - name: "Flounder HA Core Online" unique_id: flounder_ha_core_online device_class: connectivity state: "{{ has_value('sensor.home_assistant_core_uptime') }}" - name: "Node-RED Panda Up (HTTP/MQTT)" unique_id: nodered_panda_up_combined device_class: connectivity state: >- {{ is_state('binary_sensor.node_red_panda_up_http', 'on') or is_state('binary_sensor.node_red_panda_up_mqtt', 'on') }} availability: >- {{ states('binary_sensor.node_red_panda_up_http') not in ['unknown', 'unavailable'] or states('binary_sensor.node_red_panda_up_mqtt') not in ['unknown', 'unavailable'] }} - sensor: - name: "Flounder Internet Download Peak Today" unique_id: flounder_internet_download_peak_today unit_of_measurement: "Mbit/s" device_class: data_rate state_class: measurement state: >- {{ states('input_number.flounder_internet_download_peak_today') | float(0) }} - name: "Flounder Internet Upload Peak Today" unique_id: flounder_internet_upload_peak_today unit_of_measurement: "Mbit/s" device_class: data_rate state_class: measurement state: >- {{ states('input_number.flounder_internet_upload_peak_today') | float(0) }} sensor: #:######################################################################################:# # INTERNET SPEED-TEST PEAKS #:######################################################################################:# - platform: statistics name: "Flounder Internet Download Peak 7 Days" unique_id: flounder_internet_download_peak_7_days entity_id: sensor.internet_speed_test state_characteristic: value_max max_age: days: 7 precision: 2 - platform: statistics name: "Flounder Internet Upload Peak 7 Days" unique_id: flounder_internet_upload_peak_7_days entity_id: sensor.internet_upload_speed_test state_characteristic: value_max max_age: days: 7 precision: 2 #:######################################################################################:# # WAN DOWNLOAD TRAFFIC STATISTICS #:######################################################################################:# - platform: statistics name: "Flounder WAN Download Average 24 Hours" unique_id: flounder_wan_download_average_24_hours entity_id: sensor.edgerouter_wan_download_rate state_characteristic: average_step max_age: hours: 24 precision: 1 - platform: statistics name: "Flounder WAN Download Peak 24 Hours" unique_id: flounder_wan_download_peak_24_hours entity_id: sensor.edgerouter_wan_download_rate state_characteristic: value_max max_age: hours: 24 precision: 1 - platform: statistics name: "Flounder WAN Download Average 7 Days" unique_id: flounder_wan_download_average_7_days entity_id: sensor.edgerouter_wan_download_rate state_characteristic: average_step max_age: days: 7 precision: 1 - platform: statistics name: "Flounder WAN Download Peak 7 Days" unique_id: flounder_wan_download_peak_7_days entity_id: sensor.edgerouter_wan_download_rate state_characteristic: value_max max_age: days: 7 precision: 1 #:######################################################################################:# # WAN UPLOAD TRAFFIC STATISTICS #:######################################################################################:# - platform: statistics name: "Flounder WAN Upload Average 24 Hours" unique_id: flounder_wan_upload_average_24_hours entity_id: sensor.edgerouter_wan_upload_rate state_characteristic: average_step max_age: hours: 24 precision: 1 - platform: statistics name: "Flounder WAN Upload Peak 24 Hours" unique_id: flounder_wan_upload_peak_24_hours entity_id: sensor.edgerouter_wan_upload_rate state_characteristic: value_max max_age: hours: 24 precision: 1 - platform: statistics name: "Flounder WAN Upload Average 7 Days" unique_id: flounder_wan_upload_average_7_days entity_id: sensor.edgerouter_wan_upload_rate state_characteristic: average_step max_age: days: 7 precision: 1 - platform: statistics name: "Flounder WAN Upload Peak 7 Days" unique_id: flounder_wan_upload_peak_7_days entity_id: sensor.edgerouter_wan_upload_rate state_characteristic: value_max max_age: days: 7 precision: 1 #:######################################################################################:# # EXTERNAL RESPONSE-TIME STATISTICS #:######################################################################################:# - platform: statistics name: "Flounder Internet Response Time Average 24 Hours" unique_id: flounder_internet_response_time_average_24_hours entity_id: sensor.flounder_internet_response_time state_characteristic: average_step max_age: hours: 24 precision: 0 - platform: statistics name: "Flounder Internet Response Time Peak 24 Hours" unique_id: flounder_internet_response_time_peak_24_hours entity_id: sensor.flounder_internet_response_time state_characteristic: value_max max_age: hours: 24 precision: 0 automation: #:######################################################################################:# # SPEED-TEST PEAK TRACKING #:######################################################################################:# - id: flounder_network_record_speed_test_peaks alias: "Flounder Network: Record speed-test peaks" triggers: - trigger: state entity_id: sensor.internet_speed_test conditions: [] actions: - delay: seconds: 1 - condition: template value_template: >- {{ has_value('sensor.internet_speed_test') and has_value('sensor.internet_upload_speed_test') }} - action: input_number.set_value target: entity_id: input_number.flounder_internet_download_peak_today data: value: >- {{ [ states('sensor.internet_speed_test') | float(0), states('input_number.flounder_internet_download_peak_today') | float(0) ] | max }} - action: input_number.set_value target: entity_id: input_number.flounder_internet_upload_peak_today data: value: >- {{ [ states('sensor.internet_upload_speed_test') | float(0), states('input_number.flounder_internet_upload_peak_today') | float(0) ] | max }} mode: queued - id: flounder_network_reset_daily_speed_test_peaks alias: "Flounder Network: Reset daily speed-test peaks" triggers: - trigger: time at: "00:00:00" conditions: [] actions: - action: input_number.set_value target: entity_id: - input_number.flounder_internet_download_peak_today - input_number.flounder_internet_upload_peak_today data: value: 0 mode: single #:######################################################################################:# # PUBLIC IP CHANGE TRACKING #:######################################################################################:# - id: flounder_network_record_external_ip_change alias: "Flounder Network: Record external IP change" triggers: - trigger: state entity_id: sensor.flounder_external_ip conditions: - condition: template value_template: >- {{ trigger.to_state is not none and trigger.to_state.state not in ['unknown', 'unavailable', 'none', ''] and ( trigger.from_state is none or trigger.from_state.state != trigger.to_state.state ) }} actions: - action: input_datetime.set_datetime target: entity_id: input_datetime.flounder_external_ip_last_changed data: timestamp: "{{ now().timestamp() }}" mode: single #:######################################################################################:# # SERVICE OUTAGE TRACKING #:######################################################################################:# - id: flounder_network_record_service_outages alias: "Flounder Network: Record service outages" triggers: - trigger: state entity_id: binary_sensor.internet_connected id: internet - trigger: state entity_id: binary_sensor.flounder_edgerouter_online id: edgerouter - trigger: state entity_id: binary_sensor.flounder_mqtt_broker_connected id: mqtt_broker - trigger: state entity_id: binary_sensor.flounder_beaver_mqtt_broker_connected id: beaver_mqtt_broker - trigger: state entity_id: binary_sensor.node_red_panda_up_2 id: node_red_mqtt - trigger: state entity_id: binary_sensor.zigbee2mqtt_bridge_connection_state_2 id: zigbee2mqtt_2 - trigger: state entity_id: binary_sensor.zigbee2mqtt_bridge_connection_state_3 id: zigbee2mqtt_3 conditions: - condition: template value_template: >- {{ trigger.to_state is not none and trigger.to_state.state in ['off', 'unavailable'] and ( trigger.from_state is none or trigger.from_state.state not in ['off', 'unavailable'] ) }} actions: - choose: - conditions: "{{ trigger.id == 'internet' }}" sequence: - action: input_text.set_value target: entity_id: input_text.flounder_internet_last_outage data: value: "{{ now().isoformat() }}" - conditions: "{{ trigger.id == 'edgerouter' }}" sequence: - action: input_text.set_value target: entity_id: input_text.flounder_edgerouter_last_outage data: value: "{{ now().isoformat() }}" - conditions: "{{ trigger.id == 'mqtt_broker' }}" sequence: - action: input_text.set_value target: entity_id: input_text.flounder_mqtt_broker_last_outage data: value: "{{ now().isoformat() }}" - conditions: "{{ trigger.id == 'beaver_mqtt_broker' }}" sequence: - action: input_text.set_value target: entity_id: input_text.flounder_mqtt_broker_last_outage data: value: "{{ now().isoformat() }}" - conditions: "{{ trigger.id == 'node_red_mqtt' }}" sequence: - action: input_text.set_value target: entity_id: input_text.flounder_node_red_mqtt_last_outage data: value: "{{ now().isoformat() }}" - conditions: "{{ trigger.id == 'zigbee2mqtt_2' }}" sequence: - action: input_text.set_value target: entity_id: input_text.flounder_zigbee2mqtt_2_last_outage data: value: "{{ now().isoformat() }}" - conditions: "{{ trigger.id == 'zigbee2mqtt_3' }}" sequence: - action: input_text.set_value target: entity_id: input_text.flounder_zigbee2mqtt_3_last_outage data: value: "{{ now().isoformat() }}" mode: queued