Skip to content

Instantly share code, notes, and snippets.

@cerealcable
Last active November 6, 2023 18:05
Show Gist options
  • Save cerealcable/c5f04a5ce09a6d59c4a5dc8827343db6 to your computer and use it in GitHub Desktop.
Save cerealcable/c5f04a5ce09a6d59c4a5dc8827343db6 to your computer and use it in GitHub Desktop.
Home Assistant configuration, dashboard and automation for GenMon via MQTT with notifications
alias: Generator State Notifications
description: ""
trigger:
- platform: state
entity_id:
- sensor.generator_engine_state
condition:
- condition: template
value_template: "{{ trigger.from_state.state != 'unavailable' }}"
action:
- variables:
action_start: "{{ 'START_' ~ context.id }}"
action_stop: "{{ 'STOP_' ~ context.id }}"
action_transfer: "{{ 'TRANSFER_' ~ context.id }}"
action_auto: "{{ 'AUTO_' ~ context.id }}"
- choose:
- conditions:
- condition: state
entity_id: sensor.generator_engine_state
state: Running
sequence:
- service: notify.<mobile_app_something>
data:
message: >
Using {{ states('sensor.generator_transfer_switch_state') }}
Power
title: |
Generator {{ states('sensor.generator_engine_state') }}
data:
notification_icon: mdi:generator-stationary
tag: generator_engine_state
clickAction: /lovelace/generator
actions:
- action: "{{ action_stop }}"
title: Stop
icon: mdi:flash-off
- action: "{{ action_transfer }}"
title: Transfer
icon: mdi:transmission-tower-export
alias: Running
- conditions:
- condition: state
entity_id: sensor.generator_engine_state
state: Cranking
sequence:
- service: notify.notify.<mobile_app_something>
data:
message: >
Using {{ states('sensor.generator_transfer_switch_state') }}
Power
title: |
Generator {{ states('sensor.generator_engine_state') }}
data:
notification_icon: mdi:generator-stationary
tag: generator_engine_state
clickAction: /lovelace/generator
alias: Cranking
- conditions:
- condition: state
entity_id: sensor.generator_engine_state
state: Off - Ready
sequence:
- service: notify.<mobile_app_something>
data:
message: >
Using {{ states('sensor.generator_transfer_switch_state') }}
Power
title: |
Generator {{ states('sensor.generator_engine_state') }}
data:
notification_icon: mdi:generator-stationary
tag: generator_engine_state
clickAction: /lovelace/generator
actions:
- action: "{{ action_start }}"
title: Start
icon: mdi:flash
- action: "{{ action_transfer }}"
title: Transfer
icon: mdi:transmission-tower-export
alias: Off - Ready
- conditions:
- condition: state
entity_id: sensor.generator_engine_state
state: Stopped
sequence:
- service: notify.<mobile_app_something>
data:
message: >
Using {{ states('sensor.generator_transfer_switch_state') }}
Power
title: |
Generator {{ states('sensor.generator_engine_state') }}
data:
notification_icon: mdi:generator-stationary
tag: generator_engine_state
clickAction: /lovelace/generator
actions:
- action: "{{ action_auto }}"
title: Auto
icon: mdi:auto-mode
- action: "{{ action_start }}"
title: Start
icon: mdi:flash
- action: "{{ action_transfer }}"
title: Transfer
icon: mdi:transmission-tower-export
alias: Stopped
default:
- service: notify.<mobile_app_something>
data:
message: |
Using {{ states('sensor.generator_transfer_switch_state') }} Power
title: |
Generator {{ states('sensor.generator_engine_state') }}
data:
notification_icon: mdi:generator-stationary
tag: generator_engine_state
clickAction: /lovelace/generator
- wait_for_trigger:
- platform: event
event_type: mobile_app_notification_action
event_data:
action: "{{ action_start }}"
- platform: event
event_type: mobile_app_notification_action
event_data:
action: "{{ action_stop }}"
- platform: event
event_type: mobile_app_notification_action
event_data:
action: "{{ action_transfer }}"
- platform: event
event_type: mobile_app_notification_action
event_data:
action: "{{ action_auto }}"
alias: Wait for a response
- alias: Perform the action
choose:
- conditions: "{{ wait.trigger.event.data.action == action_start }}"
sequence:
- service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=start
- conditions: "{{ wait.trigger.event.data.action == action_stop }}"
sequence:
- service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=stop
- conditions: "{{ wait.trigger.event.data.action == action_transfer }}"
sequence:
- service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=starttransfer
- conditions: "{{ wait.trigger.event.data.action == action_auto }}"
sequence:
- service: mqtt.publish
target: {}
data:
qos: 0
topic: generator/command
payload: setremote=auto
mode: restart
title: Home
views:
- title: Generator
path: generator
badges: []
cards:
- type: vertical-stack
cards:
- type: vertical-stack
cards:
- type: custom:mushroom-title-card
title: Generator Status
- type: custom:mushroom-template-card
primary: '{{ states(''sensor.generator_engine_state'') }}'
secondary: '{{ states(''sensor.generator_transfer_switch_state'') }}'
icon: >-
{%- set current = states('sensor.generator_engine_state') |
lower -%} {%- if 'off - ready' == current -%}
mdi:power-standby {%- elif 'exercising' in current -%} mdi:run
{%- elif 'cooling down' in current -%} mdi:fan {%- elif
'startup delay' in current -%} mdi:timer-outline {%- elif
'cranking' in current -%} mdi:progress-wrench {%- elif
'running' in current -%} mdi:engine {%- elif 'stopped' in
current -%}
{%- if 'alarm' in current -%}
mdi:alert-octagon
{%- elif 'warning' in current -%}
mdi:alert-octagon-outline
{%- else -%}
mdi:octagon
{%- endif %}
{%- else -%} mdi:help {%- endif %}
layout: vertical
badge_color: >-
{%- set current = states('sensor.generator_engine_state') |
lower -%} {%- if 'alarm' in current -%} red {%- elif 'warning'
in current -%} yellow {%- endif -%}
badge_icon: >-
{%- set current = states('sensor.generator_engine_state') |
lower -%} {%- if 'warning' in current or 'alarm' in current
-%} true {%- endif -%}
fill_container: true
icon_color: >-
{%- set current = states('sensor.generator_engine_state') |
lower -%} {%- if 'off - ready' in current -%} blue {%- elif
'running' in current -%} green {%- elif 'stopped' in current
-%} red {%- else -%} yellow {%- endif -%}
- type: conditional
conditions:
- condition: state
entity: sensor.generator_engine_state
state: Off - Ready
card:
type: custom:mushroom-chips-card
chips:
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=start
icon: mdi:flash
icon_color: green
content: Start
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=starttransfer
icon: mdi:transmission-tower-export
content: Transfer
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=off
icon: mdi:flash-off-outline
icon_color: red
content: 'Off'
- type: conditional
conditions:
- condition: state
entity: sensor.generator_engine_state
state: Stopped
card:
type: custom:mushroom-chips-card
chips:
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=auto
icon: mdi:auto-mode
icon_color: green
content: Auto
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=start
icon: mdi:flash
icon_color: green
content: Start
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=starttransfer
icon: mdi:transmission-tower-export
content: Transfer
- type: conditional
conditions:
- condition: state
entity: sensor.generator_engine_state
state: Running
- condition: state
entity: sensor.generator_transfer_switch_state
state: Utility
card:
type: custom:mushroom-chips-card
chips:
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=stop
icon: mdi:flash-off
content: Stop
icon_color: red
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=off
icon: mdi:flash-off-outline
icon_color: red
content: 'Off'
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=starttransfer
icon: mdi:transmission-tower-export
content: Transfer
- type: conditional
conditions:
- condition: state
entity: sensor.generator_engine_state
state: Running
- condition: state
entity: sensor.generator_transfer_switch_state
state_not: Utility
card:
type: custom:mushroom-chips-card
chips:
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=stop
icon: mdi:flash-off
content: Stop
icon_color: red
- type: template
tap_action:
action: call-service
service: mqtt.publish
target: {}
data:
qos: 0
retain: false
topic: generator/command
payload: setremote=off
icon: mdi:flash-off-outline
icon_color: red
content: 'Off'
- type: vertical-stack
cards:
- type: horizontal-stack
cards:
- type: gauge
entity: sensor.generator_utility_voltage
max: 270
name: Utility Voltage
needle: true
segments:
- from: 0
color: var(--error-color)
- from: 217
color: var(--warning-color)
- from: 228
color: var(--success-color)
- from: 250
color: var(--warning-color)
- from: 260
color: var(--error-color)
- type: gauge
entity: sensor.generator_output_voltage
max: 270
name: Output Voltage
needle: true
segments:
- from: 0
color: var(--error-color)
- from: 217
color: var(--warning-color)
- from: 228
color: var(--success-color)
- from: 250
color: var(--warning-color)
- from: 260
color: var(--error-color)
- type: horizontal-stack
cards:
- type: gauge
entity: sensor.generator_frequency
max: 70
name: Output Frequency
needle: true
segments:
- from: 0
color: var(--error-color)
- from: 57
color: var(--warning-color)
- from: 59
color: var(--success-color)
- from: 61
color: var(--warning-color)
- from: 63
color: var(--error-color)
unit: Hz
- type: gauge
entity: sensor.generator_rpm
max: 2000
min: 1000
needle: true
segments:
- from: 0
color: var(--error-color)
- from: 1700
color: var(--warning-color)
- from: 1750
color: var(--success-color)
- from: 1850
color: var(--warning-color)
- from: 1900
color: var(--error-color)
- type: vertical-stack
cards:
- type: history-graph
entities:
- entity: sensor.generator_engine_state
hours_to_show: 2
title: Engine State
show_names: false
- type: entities
entities:
- entity: sensor.generator_engine_state
- entity: sensor.generator_engine_displacement
- entity: sensor.generator_nominal_rpm
- entity: sensor.generator_transfer_switch_state
icon: mdi:transmission-tower
- entity: sensor.generator_switch_state
- entity: sensor.generator_battery_voltage
name: Generator Battery
- entity: sensor.outside_temperature
- type: vertical-stack
cards:
- type: vertical-stack
cards:
- type: custom:mushroom-entity-card
entity: sensor.generator_monitor_health
- type: custom:mushroom-entity-card
entity: sensor.generator_last_run_log
secondary_info: name
primary_info: state
name: Last Action
icon: mdi:check-decagram-outline
fill_container: false
layout: horizontal
- type: custom:mushroom-entity-card
entity: sensor.generator_last_alarm_log
secondary_info: name
primary_info: state
name: Last Alarm
icon: mdi:alert
- type: custom:mushroom-entity-card
entity: sensor.generator_total_run_time
- type: custom:mushroom-entity-card
entity: sensor.generator_last_service_log
secondary_info: state
primary_info: name
name: Last Service
icon: mdi:wrench
- type: custom:mushroom-entity-card
name: Service A Due Hours
secondary_info: state
primary_info: name
icon: mdi:progress-wrench
entity: sensor.generator_service_a_due_hours
- type: custom:mushroom-entity-card
name: Service A Due Date
secondary_info: state
primary_info: name
icon: ''
entity: sensor.generator_service_a_due_date
- type: custom:mushroom-entity-card
entity: sensor.generator_service_b_due_hours
name: Service B Due Hours
secondary_info: state
primary_info: name
icon: mdi:progress-wrench
- type: custom:mushroom-entity-card
entity: sensor.generator_service_b_due_date
name: Service B Due Date
secondary_info: state
primary_info: name
icon: ''
################################################################
## Package / Generator
################################################################
#
# Version 0.6-cereal
#
# Package for Home Assistant. See https://www.home-assistant.io/docs/configuration/packages/
#
# This interfaces Home Assistant to a Generac generator montiored by
# https://github.com/jgyates/genmon
#
# Based on version 0.5 of the configuration by Louis Mamakos <louie@transsys.com> at
# https://community.home-assistant.io/t/monitor-your-generac-generator-with-home-assistant/62701
#
# Modifications:
# - Minor changes for being ESP32-based
# - Use JSON numerics (to avoid string parsing)
# - Add icons, device_class, etc
# - Corrected unit types
# - Added parsed values for Service A Due and Service B Due into Date and Hours
#
# Required Genmon MQTT settings:
# - Blacklist Filter: Run Time,Monitor Time,Generator Time,Communication Stats,Platform Stats
# - JSON Numerics: ON
# - Root topic: (blank)
#
# Notes:
# - unique_id values in this file are not signficant (or
# even required at all). They exist so that the entities show up
# within the Home Assistant configuration GUI for customization.
# - MQTT topics need to match what is configured in genmon
mqtt:
sensor:
- unique_id: "fd8f8c07-7d6f-4aea-92b5-16b7d8acc66b"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
state_topic: 'generator/Outage/Status'
name: Generator Outage Status
icon: mdi:alarm-light-outline
- unique_id: "f565fed6-8a19-49d4-8066-4015c5ca91b1"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
state_topic: 'generator/Outage/Utility Voltage/value' # if JSON numerics
name: Generator Utility Voltage
#icon: mdi:sine-wave
device_class: voltage
unit_of_measurement: "V"
# status related sensors
- unique_id: "713eb4b9-feec-4425-8c83-84a9f486aae7"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Battery Voltage
icon: mdi:car-battery
device_class: voltage
state_topic: 'generator/Status/Engine/Battery Voltage/value' # if JSON numerics
unit_of_measurement: "V"
- unique_id: "83fd4b02-1b5b-4f0c-8a90-fc7cd102a190"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Switch State
icon: mdi:electric-switch
state_topic: 'generator/Status/Engine/Switch State'
- unique_id: "63f6e276-be1d-44ad-8a8a-fe4af30bcff8"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Engine State
state_topic: 'generator/Status/Engine/Engine State'
- unique_id: "f3a8aedd-206b-4e5f-baa9-677496ee8d3c"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator RPM
icon: mdi:gauge
unit_of_measurement: "RPM"
state_topic: 'generator/Status/Engine/RPM/value' # if JSON numerics
- unique_id: "705eaa66-df97-490f-a10b-5e4967bbf79d"
name: Generator Nominal RPM
icon: mdi:gauge
unit_of_measurement: "RPM"
state_topic: 'generator/Maintenance/Nominal RPM'
- unique_id: "32190b61-6c89-4d41-9574-2aeb1e6f62da"
name: Generator Engine Displacement
icon: mdi:engine
unit_of_measurement: "L"
value_template: '{{ value | default(0) | float }}'
state_topic: 'generator/Maintenance/Engine Displacement/value'
- unique_id: "5b38db3d-23db-4ad6-9bac-6098e26769ac"
expire_after: 300
name: Generator Monitor Health
icon: mdi:medical-bag
state_topic: 'generator/Monitor/Generator Monitor Stats/Monitor Health'
- unique_id: "5d3fd00f-3e3a-4cd3-b030-0faadf114ce7"
expire_after: 300
name: Generator Transfer Switch State
icon: mdi:transmission_tower
state_topic: 'generator/Status/Line/Transfer Switch State'
- unique_id: "cbdc9c28-5748-4aef-91bc-5b5ec95ed545"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Frequency
device_class: frequency
unit_of_measurement: "Hz"
state_topic: 'generator/Status/Engine/Frequency/value' # if JSON numerics
- unique_id: "f5f462db-e16d-4596-9bd3-232b70fa5038"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Output Voltage
device_class: voltage
unit_of_measurement: "V"
state_topic: 'generator/Status/Engine/Output Voltage/value' # if JSON numerics
# current measurement is garbage on 22KW product, apparently
- unique_id: "10e1def6-35fd-4922-932a-90f25abb7f29"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Output Current
device_class: current
unit_of_measurement: "A"
icon: mdi:sine-wave
state_topic: 'generator/Status/Engine/Output Current/value' # if JSON numerics
# current measurement is garbage on 22KW product, apparently, so this value may
# also be suspect on that model
- unique_id: "914a4e97-54a0-41e7-bbeb-a256134e5e35"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Output Power
device_class: power
unit_of_measurement: "W"
state_topic: 'generator/Status/Engine/Output Power (Single Phase)/value' # if JSON numerics
# this is normalized to watts from kilowatts
value_template: '{{ value | float * 1000 | round(0) }}'
- unique_id: "8cb64471-9123-48f6-b9be-15c01595981e"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Last Alarm Log
state_topic: 'generator/Status/Last Log Entries/Logs/Alarm Log'
- unique_id: "bce3182a-a525-47dc-937c-8be4e5afc619"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Last Service Log
state_topic: 'generator/Status/Last Log Entries/Logs/Service Log'
- unique_id: "faa2f487-fc30-4e9c-8733-5b27270b3e17"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Last Run Log
state_topic: 'generator/Status/Last Log Entries/Logs/Run Log'
# maint related sensors
- unique_id: "bf7cbe92-2b1e-48ca-addd-df963697626c"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Capacity
device_class: power
state_topic: 'generator/Maintenance/Rated kW'
# normalize to watts
value_template: '{{ value | regex_replace(" *[Kk]W", "") | float * 1000 | round(0) }}'
unit_of_measurement: 'W'
- unique_id: "825657b6-c67a-427a-bee9-7b6ea2182628"
expire_after: 300 # genmon MQTT flushes out MQTT updated every 60 seconds
name: Generator Exercise Time
icon: mdi:fan-clock
state_topic: 'generator/Maintenance/Exercise/Exercise Time'
# might be nice to maybe somehow normalize this, but not sure into what date/time representation
# value is something like: "Weekly Sunday 17:35 Quiet Mode On"
- unique_id: "41c981db-5979-4ee6-b9fb-d1ca44f83b3f"
expire_after: 300
name: Generator Total Run Time
device_class: duration
unit_of_measurement: h
state_topic: 'generator/Maintenance/Service/Total Run Hours/value' # if JSON numerics
value_template: '{{ value | default(0) | float }}'
- unique_id: "927b24b7-772d-434a-8fa1-4f1c5549c90d"
expire_after: 300
name: Generator Hardware Version
state_topic: 'generator/Maintenance/Service/Hardware Version'
- unique_id: "4cf182de-c37b-48c9-8727-75e1f5053d0d"
expire_after: 300
name: Generator Firmware Version
state_topic: 'generator/Maintenance/Service/Firmware Version'
- unique_id: "8f9caada-2e90-4cb9-9571-597a27b97a9e"
expire_after: 300
name: Generator Service A Due
state_topic: 'generator/Maintenance/Service/Service A Due'
# value is something like "191 hrs or 04/12/2024"
- unique_id: "93ce68bb-b4e4-4e94-bd89-0affdb8dbf6e"
expire_after: 300
name: Generator Service A Due Hours
state_topic: 'generator/Maintenance/Service/Service A Due'
value_template: "{{ value | regex_replace('hrs or \\d{2}/\\d{2}/\\d{4}') | int }}"
device_class: duration
unit_of_measurement: h
- unique_id: "5e06bfa8-acb0-465d-98e8-880650ed557c"
expire_after: 300
name: Generator Service A Due Date
state_topic: 'generator/Maintenance/Service/Service A Due'
value_template: "{{ strptime(value.strip() | regex_replace('\\d+ hrs or '), '%m/%d/%Y').date().isoformat() }}"
device_class: date
- unique_id: "6ec00786-1eaf-4a58-b97a-57052cc0641c"
expire_after: 300
name: Generator Service B Due
state_topic: 'generator/Maintenance/Service/Service B Due'
# value is something like "191 hrs or 04/12/2024"
- unique_id: "b025486b-037f-4e3c-a3b2-c8b7a1f7696c"
expire_after: 300
name: Generator Service B Due Hours
state_topic: 'generator/Maintenance/Service/Service B Due'
value_template: "{{ value | regex_replace('hrs or \\d{2}/\\d{2}/\\d{4}') | int }}"
device_class: duration
unit_of_measurement: h
- unique_id: "18463226-384c-4c80-8cb5-ef18be1cdb2c"
expire_after: 300
name: Generator Service B Due Date
state_topic: 'generator/Maintenance/Service/Service B Due'
value_template: "{{ strptime(value.strip() | regex_replace('\\d+ hrs or '), '%m/%d/%Y').date().isoformat() }}"
device_class: date
- unique_id: "7f37ec3c-e1c5-4e10-ba9d-f8f15d27a019"
expire_after: 300
name: Generator Battery Check Due
state_topic: 'generator/Maintenance/Service/Battery Check Due'
# value is something like "4/12/2024"
# genmon monitor related sensors
- unique_id: "9bc1d83a-34bc-4a1e-a643-3c0eb62501dd"
expire_after: 300
name: Genmon Version
state_topic: 'generator/Monitor/Generator Monitor Stats/Generator Monitor Version'
#
# probably the most useful sensor - are we in a power outage condition or not?
#
binary_sensor:
- unique_id: "468414df-32b1-4127-8636-4202a11b880c"
name: Generator Power Outage
state_topic: 'generator/Outage/System In Outage'
payload_on: 'Yes'
payload_off: 'No'
############################################################################3
#
# Fun facts (For 22kw generac model)
#
# Per specification, fuel consumption for propane is
# 2.56 gal/hr at 50% load (11KW)
# 3.87 gal/hr at 100% load (22KW)
#
# Per genmon code, the 3 term polynomial to compute this is: [0, 2.74, 1.16]
#
# gal/hr = (T0 * pctLoad^2) + (T1 * pctLoad) + T3
# gal/hr = 2.74 * pctLoad + 1.16
#
# This is a pretty good fit to the spec sheet -
# 50% = 2.53 gal/hr (vs 2.56 spec)
# 100% = 3.90 gal/hr (vs 3.87 spec)
#
# Home assistant could compute a gallons/hour rate in a template sensor if this seems useful.
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment