# Configuration file for ebusd MQTT integration with Home Assistant (https://www.home-assistant.io/). # Use this file with ebusd in MQTT JSON mode to have many seen messages automatically appear on HA. This is achieved by # using the MQTT Discovery feature of Home Assistant (see https://www.home-assistant.io/integrations/mqtt#mqtt-discovery). # The commandline options to ebusd should contain e.g.: # --mqttport=1883 --mqttjson --mqttint=/etc/ebusd/mqtt-hassio.cfg # This file allows flexible construction of MQTT topics and payloads depending on message and field definitions as well # as global status topics. # It is a set of named variables (or constants) with the name on the left of an equal sign and the value on the right, # where only the value is allowed to contain references to other variables. # A reference to a variable is escaped by a leading "%" character in front of the variable name consisting of only # alphabetic characters or the underscore. A double percent character "%%" is replaced by a single "%" in the value. # Curly braces may be used to separate a variable explicitly from the rest, e.g. as "%{version}" instead of "%version". # Every variable without an underscore in the name is automatically made available as well with an uppercase name and a # normalized value composed of only alphanumeric characters or underscore (i.e. suitable for being part of a topic). # When using "?=" instead of only the equal sign in a variable definition, the variable value is set to empty when one # of the variables referred to is empty or missing. # The variable replacements are constructed for each message and/or field (depending on whether the topic is field # specific or not) in the following order: # 1. predefined constants from ebusd, i.e. # %version the ebusd version number. # %prefix the invariable prefix part of the "--mqtttopic" configuration option, defaults to "ebusd/". # %prefixn the same as %prefix but without trailing slashes or underscores. # 2. variables referring to constants only (directly or indirectly). # 3. circuit and message specific variables: # %circuit the circuit name. # %name the message name. # %priority the message poll priority (or 0). # %level the message access level (or empty). # %messagecomment the message comment. # %direction the message direction ("r", "w", "u", or "uw"). # %topic the message update topic built from the mqtttopic configuration option (only if the topic is not field # specific) and/or the %topic variable defined here. # 4. the direction mapped from variables named "direction_map-%direction" with the actual direction in the suffix. # Available as "%direction_map". # 5. the field type mapped from variables named "type_map-%direction-%type" or "type_map-%type" as fallback with the # field type and the optional direction in the suffix. The variable including the direction is evaluated first and # if it is missing or the result is empty, the variable excluding the direction is used instead. # This is also an implicit field type filter as missing or empty mappings are not published at all. # Available as "%type_map". # 6. other field specific variables for each field (only once for each message if the topic is field specific): # %index the numeric field index (excluding ignored fields). # %field the field name and key for JSON objects (equals the field index if no name is defined or the names are not # unique in the message). # %fieldname the field name (and nothing else like in %field, might be empty though!) # %type the field type (one of "number", "list", "string", "date", "time", or "datetime"). # %basetype the base data type ID (e.g. "UCH"). # %comment the field comment (if any). # %unit the field unit (if any). # %min, %max, and %step the minimum/maximum possible value and step value for number fields. # %topic the field (or message) update topic built from the mqtttopic configuration option and/or the %topic variable # defined here. # 7. optional field type switch in "%type_switch" using the value of the variable named "type_switch-by" and matching it # against the value lines of the variable named "type_switch-%type" with the field type in the suffix. # The value of such a variable needs to be a constant list of string pairs with one pair per line. Each pair is # separated by "=" and the left part is the value set to the "type_switch" variable when the wildcard pattern in the # right part matches the value of the "type_switch-by" value. The list is traversed from top to bottom with the # first match stopping the evaluation. Optionally, "type_switch-names" can be used to define a list of variable # names to be set in addition to the "type_switch" variable, in which case a list of variable names (comma # separated) is expected as "type_switch-names" value and the appropriate values to set on the left side of each # match list entry. # Available as "%type_switch" and optionally by the set of fields as defined in "%type_switch-names". # 8. optional field type part mapping in "%type_part" for each field type in variables named "type_part-%type" with the # field type in the suffix (or the value of the "type_part-by" variable). # 9. if the %fields_payload variable is used, then it is set to the concatenation of all fields of the message: # %field_payload is expected to build a single field payload. # %field-separator is the separator placed between consecutive field payloads. # %fields_payload is set to the concatenation of all fields of the message, separated by %field-separator. # 10. %definition-topic, %definition-payload, and %definition-retain to build the message definition topic and payload # and determine the retain value. # Before constructing the variable replacements, the messages and fields can optionally be filtered in order to use # certain message definitions only. All of these criteria are applied, so they are basically combined by "AND". # Filters with a "partial match" mention in the documentation allow using a limited glob/regex inspired case insensitive # matching with the following options: # - "|" allows defining alternatives, e.g. "a|b" matches "but" as well as "all". # - "^" matches the beginning of the input, e.g. "^al" matches "al" but not "hal". # - "$" matches the end of the input, e.g. "al$" matches "hal" but not "all". # - "*" matches a single arbitrary length wildcard part in the middle, e.g. "^a*l$" matches "all" but not "always". # Only a single "*" per line is supported # include only messages having data sent at least once (only checked for passive or read messages, not for active write) # when set to 1. If set to >1, then all messages passing the other filter criteria (including active read messages) will # automatically be set to have a poll priority of at most this value, so these are automatically being polled. # HA integration: filtering only seen messages to avoid unnecessary "pollution" and auto-poll all matched messages #filter-seen = 1 # include only messages having a priority less than or equal to the specified value. #filter-priority = # include only messages having the specified circuit (partial match, alternatives and wildcard supported). #filter-circuit = # exclude messages having the specified circuit (partial match, alternatives and wildcard supported). #filter-non-circuit = # include only messages having the specified name (partial match, alternatives and wildcard supported). # HA integration: filter to some useful names for monitoring the heating circuit #filter-name = status|temp|yield|fuel|count|energy|power|runtime|hours|starts|mode|curve|load|party|cooling|heat|sensor|data|error|pressure|flame|date|time|a|e|i|y|o|u|day # exclude messages having the specified name (partial match, alternatives and wildcard supported). #filter-non-name = # include only messages having the specified level (partial match, alternatives and wildcard supported). # Note: This is a filter on top of the messages already filtered implicitly for the ebusd "mqtt" user (if any). # Note: Since the empty string matches all levels, an explicit check for empty string (with "^$") needs to be used for # including only messages without a level. #filter-level = ^$ # include only messages having the specified direction ("r", "w", "u", or "uw". partial match, alternatives and wildcard supported). # HA integration: writable messages excluded for now #filter-direction = r|u|^w # HA integration: for including writable messages, use this line or overwrite with '--mqttvar=filter-direction=r|u|^w'. #filter-direction = r|u|^w # include only fields having the specified name (partial match, alternatives and wildcard supported). #filter-field = # exclude fields having the specified name (partial match, alternatives and wildcard supported). # HA integration: exclude the useless sensor ok/cutoff info from temperature sensor. #filter-non-field = ^sensor$ # HA integration: home assistant configuration topics prefix haprefix = homeassistant # HA integration: the area of all entities in home assistant area = Heating # HA integration: circuit specific part used as device entity for message definitions below circuit_part = { "identifiers":"%{PREFIX}_%CIRCUIT", "manufacturer":"ebusd.eu", "name":"%circuit", "via_device":"%PREFIXN", "sw_version":"%version", "suggested_area":"%area" } # the field type mapped from variables named "type_map-%direction-%type" or "type_map-%type" as fallback with the # field type and the optional direction in the suffix. The variable including the direction is evaluated first and # if it is missing or the result is empty, the variable excluding the direction is used instead. # This is also an implicit field type filter as missing or empty mappings are not published at all. type_map-number = number type_map-list = string # HA integration: skip string/date/time types completely type_map-string = string type_map-date = date type_map-time = time type_map-datetime = datetime # field type switch designator, see below. # HA integration: this is used to set several variable values depending on the field type, message name, field name, and unit. type_switch-by = %name%field,%unit # field type switch variables names to use in addition to %type_switch in case of multiple keys (separated by comma). # HA integration: var names for topic/class/state/sub values mapped from field type, message name, field name, and unit. type_switch-names = type_topic,type_class,type_state,type_sub # field type switch for each field type and optionally direction (between dash before the field type) available as # %type_switch (as well as the variable names defined in "type_switch-names" if any). # The value needs to be a constant list of string pairs with one pair per line. Each pair is separated by "=" and the # left part is the value set to the type_switch variable (as well as the variable names defined in %type_switch-names) # when the wildcard string in the right part matched the "type_switch-by" value. The list is traversed from top to # bottom stopping at the first match. If direction specific definitions exist, these are traversed first. If no line # matches at all, the variable(s) are set to the empty string. # HA integration: the mapping list for (potentially) writable number entities by field type, name, message, and unit. type_switch-w-number = number,heating curve, = curve*%% number,heating curve, = Curve*%% number,temperature, = temp|,°C$|,K$ number,power_factor, = power*%% number,power, = power|,kW$|,W$ number,voltage, = volt|,V$ number,current, = current,|,A$ number,pressure, = bar$ number,gas, = gas*/min$ number,volume, = m³$ number,volume_flow_rate, = m³/h$ number,humidity, = humid*%%$ number,, = integral|,°min$ number,, = air|,m³/h$ number,, = # HA integration: the mapping list for numeric sensor entities by field type, name, message, and unit. type_switch-number = sensor,heating curve,measurement = curve sensor,heating curve,measurement = Curve sensor,power_factor,measurement = power*%% sensor,temperature,measurement = temp|,°C$|,K$ sensor,power,measurement = power|,kW$|,W$ sensor,voltage,measurement = volt|,V$ sensor,current,measurement = current,|,A$ sensor,energy,total_increasing = energy|,Wh$ sensor,yield,total_increasing = total*,Wh$ sensor,duration,total_increasing = hours|days|,h$ sensor,pressure,measurement = bar$|Pa$ sensor,gas,measurement = gas*/min$ sensor,volume,total_increasing = total*,m³$ sensor,volume,measurement = m³$ sensor,volume_flow_rate,measurement = m³/h$ sensor,carbon_dioxide,measurement = CO2*,ppm$ sensor,humidity,measurement = humid*%%$ sensor,,total_increasing = poweron|count, sensor,,measurement = integral|,°min$ sensor,,total_increasing = starts*,$ sensor,,measurement = air|,m³/h$ sensor,, = # HA integration: the mapping list for (potentially) writable binary switch entities by field type, name, message, and unit. type_switch-w-list = switch,, = onoff switch,,,yesno = yesno select,, = # HA integration: the mapping list for rather binary sensor entities by field type, name, message, and unit. type_switch-list = binary_sensor,,measurement = onoff binary_sensor,,measurement,yesno = yesno binary_sensor,,name = Flame sensor,,,list = # HA integration: the mapping list for (potentially) writable string entities containing a time value by field type, name, message, and unit. type_switch-w-time = text,,,time = from,|to,|time2,|timer text,,,time3 = time, type_switch-time = sensor,,,time = from,|to,|time2,|timer sensor,,,time3 = time, # HA integration: currently unused mapping lists for non-numeric/non-binary entities. type_switch-w-date = text,,,date = date, text,, = date, text,, = type_switch-w-datetime = text,, = btime, text,, = dcfstate, text,, = datetime, text,, = bdate, text,, = type_switch-w-string = text,, = date, text,, = datetime, text,, = dcfstate, text,, = bdate, text,, = btime, text,, = phone, text,, = type_switch-date = sensor,, = date, sensor,, = type_switch-datetime = sensor,, = type_switch-string = sensor,, = # HA integration: optional variable with the entity device class for numbers type_class_number ?= , "device_class":"%type_class" # HA integration: optional variable with the entity device class for sensors type_class_sensor ?= , "device_class":"%type_class" # HA integration: optional variable with the entity state class state_class ?= , "state_class":"%type_state" # HA integration: optional variable with the entity unit unit_of_measurement ?= , "unit_of_measurement":"%unit" # HA integration: optional variable with the minimum numeric value min_number ?= , "min":%min # HA integration: optional variable with the maximum numeric value max_number ?= , "max":%max # HA integration: optional variable with the numeric step value step_number ?= , "step":%step # field type part suffix to use instead of the field type itself, see below. # HA integration: %type_part variable mapped from the mapped %type_topic and optional %type_sub type_part-by = %type_topic%type_sub # field type part mappings for each field type (or the "type_part-by" variable value) in the suffix (available as # %type_part). # HA integration: %type_part variable for number %type_topic type_part-number = , "command_topic":"%topic/set"%min_number%max_number%step_number%unit_of_measurement%state_class%type_class_number # HA integration: %type_part variable for sensor %type_topic type_part-sensor = %unit_of_measurement%state_class%type_class_sensor # HA integration: %type_part variable for switch %type_topic type_part-switch = , "command_topic":"%topic/set", "payload_on":"on", "payload_off":"off"%state_class type_part-switchyesno = , "command_topic":"%topic/set", "payload_on":"yes", "payload_off":"no"%state_class # HA integration: %type_part variable for binary_sensor %type_topic type_part-binary_sensor = , "payload_on":"on", "payload_off":"off"%state_class type_part-binary_sensoryesno = , "payload_on":"yes", "payload_off":"no"%state_class # HA integration: %type_part variable for text %type_topic type_part-texttime = , "command_topic":"%topic/set", "pattern": "^[012][0-9]:[0-5][0-9]$"%state_class type_part-textphone = , "command_topic":"%topic/set", "pattern": "^[0-9]{9}$"%state_class type_part-texttime3 = , "command_topic":"%topic/set", "pattern": "^[012][0-9]:[0-5][0-9]:[0-5][0-9]$"%state_class type_part-textdate = , "command_topic":"%topic/set", "pattern": "^[0-3][0-9].[01][0-9].20[0-3][0-9]$"%state_class type_part-textdatetime = , "command_topic":"%topic/set"%state_class type_part-text = , "command_topic":"%topic/set"%state_class # optional format string for converting a fields value list into %field_values. # "$value" and "$text" are being replaced by the corresponding part. field_values-entry = "$text" # optional separator for concatenating of field value list items. field_values-separator = , # optional prefix for surrounding field value list items. field_values-prefix = [ # optional suffix for surrounding field value list items. field_values-suffix = ] # HA integration: %type_part variable for select %type_topic and sensor with list of known values type_part-select = , "command_topic":"%topic/set", "options":%field_values type_part-sensorlist = , "device_class":"enum", "options":%field_values # the field specific part (evaluated after the message specific part). # HA integration: set to the mapped %type_part from above field_payload = %type_part # the message definition config topic, payload, and retain setting. # HA integration: the config topic for HA's MQTT discovery for the ebusd message definition found. # set to conditionally to avoid incomplete configs. definition-topic ?= %haprefix/%type_topic/%{TOPIC}_%FIELD/config # HA integration: this is the config topic payload for HA's MQTT discovery. definition-payload = { "unique_id":"%{TOPIC}_%FIELD", "name":"%name %fieldname", "device":%circuit_part, "value_template":"{{value_json[\"%field\"].value}}", "state_topic":"%topic"%field_payload } #definition-retain = 1 # the message value topic (if other than the default). If set here, it will be replaced by the "--mqtttopic" # configuration option only if that one contains at least one variable. If the the "--mqtttopic" configuration option # does not contain any variable, it is taken as prefix and can be used here as well. # HA integration: use the prefix from --mqtttopic and non field specific topic for the actual data topic = %prefix/%circuit/%name # HA integration: global part used as device entity for the global config topics global_device = { "identifiers":"%PREFIXN", "manufacturer":"ebusd.eu", "name":"%prefixn", "sw_version":"%version", "suggested_area":"%area" } # HA integration: common prefix for global parts global_prefix = { "unique_id":"%TOPIC", "device":%global_device, "state_topic":"%topic", "name":"%name" # HA integration: boolean suffix for global parts global_boolean_suffix = , "payload_on":"true", "payload_off":"false" } # the common global config topic, payload, and retain setting (used by running, version, signal, uptime, updatecheck, # and scan if not otherwise defined explicitly). # HA integration: the config topic for HA's MQTT discovery for the ebusd global parts. def_global-topic = %haprefix/sensor/%TOPIC/config def_global-payload = %global_prefix } def_global-retain = 1 # individual global running, version, signal, uptime, updatecheck, and scan config topic, payload, and retain setting. def_global_running-topic = %haprefix/binary_sensor/%TOPIC/config def_global_running-payload = %global_prefix, "device_class":"running"%global_boolean_suffix def_global_version-topic = def_global_uptime-payload = %global_prefix, "device_class":"duration", "state_class":"total_increasing", "unit_of_measurement":"s" } def_global_signal-topic = %haprefix/binary_sensor/%TOPIC/config def_global_signal-payload = %global_prefix, "device_class":"connectivity"%global_boolean_suffix def_global_updatecheck-topic = %haprefix/update/%TOPIC/config def_global_updatecheck-payload = %global_prefix, "value_template":"{%% set my_new = value_json|truncate(255)|regex_replace(find=',.*| available|revision v|version v|OK',replace='') %%}{%% if my_new == '' %%}{%% set my_new = '%version' %%}{%% endif %%}{{ {'installed_version':'%version','latest_version':my_new,'entity_picture':'https://ebusd.eu/logo-32x32.png','release_url':'https://github.com/john30/ebusd/releases/latest'} | tojson }}" } # optional secondary update check for the enhanced eBUS device (consuming the same topic though!) def_global_updatecheck_device-topic = %haprefix/update/%{TOPIC}_device/config def_global_updatecheck_device-payload = { "unique_id":"%{TOPIC}_device", "device":{ "identifiers":"%{PREFIXN}_device", "manufacturer":"ebusd.eu", "name":"%prefixn eBUS device", "via_device":"%PREFIXN", "suggested_area":"%area" }, "state_topic":"%topic", "name":"%prefixn %name", "value_template":"{%% set my_new = value_json|truncate(255)|regex_replace(find='^[^,]*|, device firmware |,.*| available',replace='') %%}{%% set my_cur = 'old' %%}{%% if my_new == '' %%}{%% set my_new = 'current' %%}{%% set my_cur = 'current' %%}{%% endif %%}{{ {'installed_version':my_cur,'latest_version':my_new,'entity_picture':'https://adapter.ebusd.eu/favicon.ico','release_url':'https://adapter.ebusd.eu/firmware/ChangeLog'} | tojson }}" } # the topic and payload to listen to in order to republish all config messages. # HA integration: force republish of all configs when HA goes down and comes up again. config_restart-topic = %haprefix/status config_restart-payload = online