This paste brought to you by paste.linuxiarz.pl. View Raw

  1. esphome:
  2.   name: esp32-sofar
  3.   comment: SofarSolar Logger (Modbus/RS485)
  4.  
  5. esp32:
  6.   board: esp32dev
  7.  
  8. substitutions:
  9.   devicename: sofarsolar-logger
  10.   friendly_name: SofarSolar
  11.   hostname: esp32-${inverter_short_name}
  12.   comment: ${friendly_name} Modbus Interface
  13.   friendly_node_name: ESP-Sofar
  14.   inverter_short_name: sofar
  15.   upper_inverter_short_name: Sofar
  16.   esp_id: esp_${inverter_short_name}
  17.  
  18. external_components:
  19.   - source:
  20.       type: git
  21.       url: https://github.com/zdzichu6969/esphome-components
  22.     components: [ heapmon ]
  23.     refresh: 12h
  24.  
  25. wifi:
  26.   ssid: !secret wifi_ssid
  27.   password: !secret wifi_password
  28.   reboot_timeout: 300s
  29.   power_save_mode: none
  30.  
  31.   ap:
  32.     ssid: Fallback-AP-${hostname}
  33.     password: ""
  34.     ap_timeout: 300s
  35.  
  36. api:
  37.   encryption:
  38.     key: !secret api_encryption_key
  39.   reboot_timeout: 0s
  40.  
  41. ota:
  42.   password: !secret ota_password
  43.   safe_mode: True
  44.  
  45.  
  46. mdns:
  47. captive_portal:
  48. logger:
  49.     level: INFO
  50.     baud_rate: 0
  51.  
  52. uart:
  53.   id: mod_bus
  54.   tx_pin: GPIO17
  55.   rx_pin: GPIO16
  56.   baud_rate: 9600
  57.   stop_bits: 1
  58.   rx_buffer_size: 512
  59.  
  60. modbus:
  61.   id: mod_bus_sofar
  62.   send_wait_time: 500ms
  63.  
  64. modbus_controller:
  65.   - id: sofarsolar
  66.     address: 0x01
  67.     modbus_id: mod_bus_sofar
  68.     update_interval: 5s
  69.     setup_priority: -10
  70.     command_throttle: 750ms
  71.  
  72. text_sensor:
  73.   - platform: template
  74.     name: ${friendly_node_name} Uptime (human readable)
  75.     id: uptime_human
  76.     icon: "mdi:clock-start"
  77.     update_interval: 5s
  78.     entity_category: diagnostic
  79.  
  80.   - platform: version
  81.     name: ${friendly_node_name} ESPHome Version
  82.     id: ${friendly_name}_esphome_version
  83.  
  84.   - platform: wifi_info
  85.     ip_address:
  86.       name: ${friendly_node_name} IP Address
  87.       id: ${friendly_name}_ip_address
  88.       icon: mdi:ip-network
  89.  
  90.   - platform: modbus_controller
  91.     modbus_controller_id: sofarsolar
  92.     name: ${friendly_name} Status
  93.     id: ${esp_id}_status
  94.     register_type: holding
  95.     icon: "mdi:information-outline"
  96.     address: 0x0000
  97.     response_size: 2
  98.     lambda: |-
  99.       auto z = "Unknown";
  100.       char d = data[item->offset+1];
  101.       if (d == 0) z = "Wait";
  102.       else if (d == 1) z = "Check";
  103.       else if (d == 2) z = "Normal";
  104.       else if (d == 3) z = "Fault";
  105.       else if (d == 4) z = "Permanent";
  106.       return {z};
  107.  
  108.   - platform: modbus_controller
  109.     modbus_controller_id: sofarsolar
  110.     name: ${friendly_name} Fault Message
  111.     id: inverter_fault_message
  112.     register_type: holding
  113.     icon: "mdi:alert-outline"
  114.     address: 0x0001
  115.     response_size: 10
  116.     lambda: |-
  117.       std::string z = "";
  118.       int idx = item->offset;
  119.       //byte[0]
  120.       if ((data[idx] & 0x1) != 0) z += "GridOVP,";
  121.       if ((data[idx] & 0x2) != 0) z += "GridUVP,";
  122.       if ((data[idx] & 0x4) != 0) z += "GridOFP,";
  123.       if ((data[idx] & 0x8) != 0) z += "GridUFP,";
  124.       if ((data[idx] & 0x10) != 0) z += "PVUVP,";
  125.       if ((data[idx] & 0x20) != 0) z += "GridLVRT,";
  126.       if ((data[idx] & 0x40) != 0) z += "reserve-ID7,";
  127.       if ((data[idx] & 0x80) != 0) z += "reserve-ID8,";
  128.       //byte[1]
  129.       idx++;
  130.       if ((data[idx] & 0x1) != 0) z += "PVOVP,";
  131.       if ((data[idx] & 0x2) != 0) z += "IpvUnbalance,";
  132.       if ((data[idx] & 0x4) != 0) z += "PvConfigSetWrong,";
  133.       if ((data[idx] & 0x8) != 0) z += "GFCIFault,";
  134.       if ((data[idx] & 0x10) != 0) z += "PhaseSequenceFault,";
  135.       if ((data[idx] & 0x20) != 0) z += "HwBoostOCP,";
  136.       if ((data[idx] & 0x40) != 0) z += "HwAcOCP,";
  137.       if ((data[idx] & 0x80) != 0) z += "AcRmsOCP,";
  138.       //byte[2]
  139.       idx++;
  140.       if ((data[idx] & 0x1) != 0) z += "HwADFaultIGrid,";
  141.       if ((data[idx] & 0x2) != 0) z += "HwADFaultDCI,";
  142.       if ((data[idx] & 0x4) != 0) z += "HwADFaultVGrid,";
  143.       if ((data[idx] & 0x8) != 0) z += "GFCIDeviceFault,";
  144.       if ((data[idx] & 0x10) != 0) z += "MChip_Fault,";
  145.       if ((data[idx] & 0x20) != 0) z += "HwAuxPowerFault,";
  146.       if ((data[idx] & 0x40) != 0) z += "BusVoltZeroFault,";
  147.       if ((data[idx] & 0x80) != 0) z += "IacRmsUnbalance,";
  148.       //byte[3]
  149.       idx++;
  150.       if ((data[idx] & 0x1) != 0) z += "BusUVP,";
  151.       if ((data[idx] & 0x2) != 0) z += "BusOVP,";
  152.       if ((data[idx] & 0x4) != 0) z += "VbusUnbalance,";
  153.       if ((data[idx] & 0x8) != 0) z += "DciOCP,";
  154.       if ((data[idx] & 0x10) != 0) z += "SwOCPInstant,";
  155.       if ((data[idx] & 0x20) != 0) z += "SwBOCPInstant,";
  156.       if ((data[idx] & 0x40) != 0) z += "reserved-ID31,";
  157.       if ((data[idx] & 0x80) != 0) z += "reserved-ID32,";
  158.       //byte[4]
  159.       idx++;
  160.       if (data[idx] != 0) z += "reserved-ID33~40,";
  161.       //byte[5]
  162.       idx++;
  163.       if (data[idx] != 0) z += "reserved-ID41~48,";
  164.       //byte[6]
  165.       idx++;
  166.       if ((data[idx] & 0x1) != 0) z += "ConsistentFault_VGrid,";
  167.       if ((data[idx] & 0x2) != 0) z += "ConsistentFault_FGrid,";
  168.       if ((data[idx] & 0x4) != 0) z += "ConsistentFault_DCI,";
  169.       if ((data[idx] & 0x8) != 0) z += "ConsistentFault_GFCI,";
  170.       if ((data[idx] & 0x10) != 0) z += "SpiCommLose,";
  171.       if ((data[idx] & 0x20) != 0) z += "SciCommLose,";
  172.       if ((data[idx] & 0x40) != 0) z += "RelayTestFail,";
  173.       if ((data[idx] & 0x80) != 0) z += "PvIsoFault,";
  174.       //byte[7]
  175.       idx++;
  176.       if ((data[idx] & 0x1) != 0) z += "OverTempFault_Inv,";
  177.       if ((data[idx] & 0x2) != 0) z += "OverTempFault_Boost,";
  178.       if ((data[idx] & 0x4) != 0) z += "OverTempFault_Env,";
  179.       if ((data[idx] & 0x8) != 0) z += "PEConnectFault,";
  180.       if ((data[idx] & 0x10) != 0) z += "reserved-ID61,";
  181.       if ((data[idx] & 0x20) != 0) z += "reserved-ID62,";
  182.       if ((data[idx] & 0x40) != 0) z += "reserved-ID63,";
  183.       if ((data[idx] & 0x80) != 0) z += "reserved-ID64,";
  184.       //byte[8]
  185.       idx++;
  186.       if ((data[idx] & 0x1) != 0) z += "unrecoverHwAcOCP,";
  187.       if ((data[idx] & 0x2) != 0) z += "unrecoverBusOVP,";
  188.       if ((data[idx] & 0x4) != 0) z += "unrecoverIacRmsUnbalance,";
  189.       if ((data[idx] & 0x8) != 0) z += "unrecoverIpvUnbalance,";
  190.       if ((data[idx] & 0x10) != 0) z += "unrecoverVbusUnbalance,";
  191.       if ((data[idx] & 0x20) != 0) z += "unrecoverOCPInstant,";
  192.       if ((data[idx] & 0x40) != 0) z += "unrecoverPvConfigSetWrong,";
  193.       if ((data[idx] & 0x80) != 0) z += "reserved-ID72,";
  194.       //byte[9]
  195.       idx++;
  196.       if ((data[idx] & 0x1) != 0) z += "reserved-ID73,";
  197.       if ((data[idx] & 0x2) != 0) z += "unrecoverIPVInstant,";
  198.       if ((data[idx] & 0x4) != 0) z += "unrecoverWRITEEEPROM,";
  199.       if ((data[idx] & 0x8) != 0) z += "unrecoverREADEEPROM,";
  200.       if ((data[idx] & 0x10) != 0) z += "unrecoverRelayFail,";
  201.       if ((data[idx] & 0x20) != 0) z += "reserved-ID78,";
  202.       if ((data[idx] & 0x40) != 0) z += "reserved-ID79,";
  203.       if ((data[idx] & 0x80) != 0) z += "reserved-ID80,";
  204.       if(z.length() > 0){
  205.         z.pop_back();
  206.       }
  207.       return {z};
  208.  
  209. sensor:
  210.   - platform: wifi_signal
  211.     id: ${esp_id}_wifi_signal
  212.     name: ${friendly_node_name} WiFi Signal
  213.     update_interval: 30s
  214.     icon: "mdi:wifi"
  215.  
  216.   - platform: uptime
  217.     id: ${esp_id}_uptime
  218.     name: ${friendly_node_name} Uptime
  219.     filters:
  220.       - lambda: return x / 60.0;
  221.     unit_of_measurement: minutes
  222.     icon: "mdi:clock-start"
  223.  
  224.   - platform: heapmon  
  225.     id: heapspace  
  226.     name: ${friendly_node_name} Heapsize
  227.     icon: "mdi:memory"
  228.     update_interval: 5s
  229.     filters:
  230.       - throttle: 30s
  231.     entity_category: diagnostic
  232.  
  233.   - platform: modbus_controller
  234.     modbus_controller_id: sofarsolar
  235.     name: ${friendly_name} DC1 Voltage
  236.     id: ${esp_id}_dc_v1
  237.     register_type: holding
  238.     address: 0x0006
  239.     unit_of_measurement: "V"
  240.     state_class: "measurement"
  241.     device_class: "voltage"
  242.     icon: "mdi:alpha-v-circle-outline"
  243.     value_type: U_WORD
  244.     accuracy_decimals: 1
  245.     filters:
  246.       - multiply: 0.1
  247.  
  248.   - platform: modbus_controller
  249.     modbus_controller_id: sofarsolar
  250.     name: ${friendly_name} DC1 Current
  251.     id: ${esp_id}_dc_c1
  252.     register_type: holding
  253.     address: 0x0007
  254.     unit_of_measurement: "A"
  255.     state_class: "measurement"
  256.     device_class: "current"
  257.     icon: "mdi:alpha-a-circle-outline"
  258.     value_type: U_WORD
  259.     accuracy_decimals: 2
  260.     filters:
  261.       - multiply: 0.01
  262.  
  263.   - platform: modbus_controller
  264.     modbus_controller_id: sofarsolar
  265.     name: ${friendly_name} DC2 Voltage
  266.     id: ${esp_id}_dc_v2
  267.     register_type: holding
  268.     address: 0x0008
  269.     unit_of_measurement: "V"
  270.     state_class: "measurement"
  271.     device_class: "voltage"
  272.     icon: "mdi:alpha-v-circle-outline"
  273.     value_type: U_WORD
  274.     accuracy_decimals: 1
  275.     filters:
  276.       - multiply: 0.1
  277.  
  278.   - platform: modbus_controller
  279.     modbus_controller_id: sofarsolar
  280.     name: ${friendly_name} DC2 Current
  281.     id: ${esp_id}_dc_c2
  282.     register_type: holding
  283.     address: 0x0009
  284.     unit_of_measurement: "A"
  285.     state_class: "measurement"
  286.     device_class: "current"
  287.     icon: "mdi:alpha-a-circle-outline"
  288.     value_type: U_WORD
  289.     accuracy_decimals: 2
  290.     filters:
  291.       - multiply: 0.01
  292.  
  293.   - platform: modbus_controller
  294.     modbus_controller_id: sofarsolar
  295.     name: ${friendly_name} DC1 Power
  296.     id: ${esp_id}_dc_power1
  297.     register_type: holding
  298.     address: 0x000a
  299.     unit_of_measurement: "W"
  300.     state_class: "measurement"
  301.     device_class: "power"
  302.     icon: "mdi:solar-power"
  303.     value_type: U_WORD
  304.     filters:
  305.       - multiply: 10
  306.  
  307.   - platform: modbus_controller
  308.     modbus_controller_id: sofarsolar
  309.     name: ${friendly_name} DC2 Power
  310.     id: ${esp_id}_dc_power2
  311.     register_type: holding
  312.     address: 0x000b
  313.     unit_of_measurement: "W"
  314.     state_class: "measurement"
  315.     device_class: "power"
  316.     icon: "mdi:solar-power"
  317.     value_type: U_WORD
  318.     filters:
  319.       - multiply: 10
  320.  
  321.   - platform: modbus_controller
  322.     modbus_controller_id: sofarsolar
  323.     name: ${friendly_name} AC Power
  324.     id: ${esp_id}_ac_power
  325.     register_type: holding
  326.     address: 0x000c
  327.     unit_of_measurement: "W"
  328.     state_class: "measurement"
  329.     device_class: "power"
  330.     icon: "mdi:solar-power-variant-outline"
  331.     value_type: U_WORD
  332.     filters:
  333.       - multiply: 10
  334.  
  335.   - platform: modbus_controller
  336.     modbus_controller_id: sofarsolar
  337.     name: ${friendly_name} AC Reactive Power
  338.     id: ${esp_id}_ac_reactive_power
  339.     register_type: holding
  340.     address: 0x000d
  341.     unit_of_measurement: "kVar"
  342.     state_class: "measurement"
  343.     icon: "mdi:math-cos"
  344.     value_type: S_WORD
  345.     filters:
  346.       - multiply: 10
  347.  
  348.   - platform: modbus_controller
  349.     modbus_controller_id: sofarsolar
  350.     name: ${friendly_name} L1 Voltage
  351.     id: ${esp_id}_ac_v1
  352.     register_type: holding
  353.     address: 0x000f
  354.     unit_of_measurement: "V"
  355.     state_class: "measurement"
  356.     device_class: "voltage"
  357.     icon: "mdi:alpha-v-circle"
  358.     value_type: U_WORD
  359.     accuracy_decimals: 1
  360.     filters:
  361.       - multiply: 0.1
  362.  
  363.   - platform: modbus_controller
  364.     modbus_controller_id: sofarsolar
  365.     name: ${friendly_name} L2 Voltage
  366.     id: ${esp_id}_ac_v2
  367.     register_type: holding
  368.     address: 0x0011
  369.     unit_of_measurement: "V"
  370.     state_class: "measurement"
  371.     device_class: "voltage"
  372.     icon: "mdi:alpha-v-circle"
  373.     value_type: U_WORD
  374.     accuracy_decimals: 1
  375.     filters:
  376.       - multiply: 0.1
  377.  
  378.   - platform: modbus_controller
  379.     modbus_controller_id: sofarsolar
  380.     name: ${friendly_name} L3 Voltage
  381.     id: ${esp_id}_ac_v3
  382.     register_type: holding
  383.     address: 0x0013
  384.     unit_of_measurement: "V"
  385.     state_class: "measurement"
  386.     device_class: "voltage"
  387.     icon: "mdi:alpha-v-circle"
  388.     value_type: U_WORD
  389.     accuracy_decimals: 1
  390.     filters:
  391.       - multiply: 0.1
  392.  
  393.   - platform: modbus_controller
  394.     modbus_controller_id: sofarsolar
  395.     name: ${friendly_name} L1 Current
  396.     id: ${esp_id}_ac_c1
  397.     register_type: holding
  398.     address: 0x0010
  399.     unit_of_measurement: "A"
  400.     state_class: "measurement"
  401.     device_class: "current"
  402.     icon: "mdi:alpha-a-circle"
  403.     value_type: U_WORD
  404.     accuracy_decimals: 2
  405.     filters:
  406.       - multiply: 0.01
  407.  
  408.   - platform: modbus_controller
  409.     modbus_controller_id: sofarsolar
  410.     name: ${friendly_name} L2 Current
  411.     id: ${esp_id}_ac_c2
  412.     register_type: holding
  413.     address: 0x0012
  414.     unit_of_measurement: "A"
  415.     state_class: "measurement"
  416.     device_class: "current"
  417.     icon: "mdi:alpha-a-circle"
  418.     value_type: U_WORD
  419.     accuracy_decimals: 2
  420.     filters:
  421.       - multiply: 0.01
  422.  
  423.   - platform: modbus_controller
  424.     modbus_controller_id: sofarsolar
  425.     name: ${friendly_name} L3 Current
  426.     id: ${esp_id}_ac_c3
  427.     register_type: holding
  428.     address: 0x0014
  429.     unit_of_measurement: "A"
  430.     state_class: "measurement"
  431.     device_class: "current"
  432.     icon: "mdi:alpha-a-circle"
  433.     value_type: U_WORD
  434.     accuracy_decimals: 2
  435.     filters:
  436.       - multiply: 0.01
  437.  
  438.   - platform: modbus_controller
  439.     modbus_controller_id: sofarsolar
  440.     name: ${friendly_name} AC Freq
  441.     id: ${esp_id}_ac_freq
  442.     register_type: holding
  443.     address: 0x000e
  444.     unit_of_measurement: "Hz"
  445.     state_class: "measurement"
  446.     icon: "mdi:current-ac"
  447.     value_type: U_WORD
  448.     accuracy_decimals: 2
  449.     filters:
  450.       - multiply: 0.01
  451.  
  452.   - platform: modbus_controller
  453.     modbus_controller_id: sofarsolar
  454.     name: ${friendly_name} Energy total
  455.     id: ${esp_id}_energy_total
  456.     register_type: holding
  457.     address: 0x0015
  458.     unit_of_measurement: "kWh"
  459.     accuracy_decimals: 2
  460.     device_class: "energy"
  461.     state_class: "total_increasing"
  462.     icon: "mdi:solar-power-variant-outline"
  463.     value_type: U_DWORD
  464.  
  465.   - platform: modbus_controller
  466.     modbus_controller_id: sofarsolar
  467.     name: ${friendly_name} Energy generation time total
  468.     id: ${esp_id}_energy_generation_time_total
  469.     register_type: holding
  470.     address: 0x0017
  471.     unit_of_measurement: "h"
  472.     icon: "mdi:timeline-clock"
  473.     value_type: U_DWORD
  474.  
  475.   - platform: modbus_controller
  476.     modbus_controller_id: sofarsolar
  477.     name: ${friendly_name} Energy today
  478.     id: ${esp_id}_energy_today
  479.     register_type: holding
  480.     address: 0x0019
  481.     unit_of_measurement: "kWh"
  482.     state_class: "measurement"
  483.     device_class: "energy"
  484.     icon: "mdi:solar-power-variant-outline"
  485.     value_type: U_WORD
  486.     accuracy_decimals: 2
  487.     filters:
  488.       - multiply: 0.01
  489.  
  490.   - platform: modbus_controller
  491.     modbus_controller_id: sofarsolar
  492.     name: ${friendly_name} Energy generation time today
  493.     id: ${esp_id}_energy_generation_time_today
  494.     register_type: holding
  495.     address: 0x001A
  496.     unit_of_measurement: "min"
  497.     icon: "mdi:timeline-clock"
  498.     value_type: U_WORD
  499.  
  500.   - platform: modbus_controller
  501.     modbus_controller_id: sofarsolar
  502.     name: ${friendly_name} Temprature module
  503.     id: ${esp_id}_temp_module
  504.     register_type: holding
  505.     address: 0x001B
  506.     unit_of_measurement: "°C"
  507.     state_class: "measurement"
  508.     device_class: "temperature"
  509.     icon: "mdi:temperature-celsius"
  510.     value_type: U_WORD
  511.     filters:
  512.     - throttle: 10min
  513.  
  514.   - platform: modbus_controller
  515.     modbus_controller_id: sofarsolar
  516.     name: ${friendly_name} Temprature inverter
  517.     id: ${esp_id}_temp_inverter
  518.     register_type: holding
  519.     address: 0x001C
  520.     unit_of_measurement: "°C"
  521.     state_class: "measurement"
  522.     device_class: "temperature"
  523.     icon: "mdi:temperature-celsius"
  524.     value_type: U_WORD
  525.     filters:
  526.     - throttle: 30s
  527.  
  528.   - platform: modbus_controller
  529.     modbus_controller_id: sofarsolar
  530.     name: ${friendly_name} Bus voltage
  531.     id: ${esp_id}_bus_voltage
  532.     register_type: holding
  533.     address: 0x001D
  534.     unit_of_measurement: "V"
  535.     state_class: "measurement"
  536.     device_class: "voltage"
  537.     icon: "mdi:alpha-v-circle-outline"
  538.     value_type: U_WORD
  539.     accuracy_decimals: 1
  540.     filters:
  541.       - multiply: 0.1
  542.  
  543.   - platform: modbus_controller
  544.     modbus_controller_id: sofarsolar
  545.     name: ${friendly_name} PV1+ isolation resistance
  546.     id: ${esp_id}_dc_isolation_resistance1
  547.     register_type: holding
  548.     address: 0x0024
  549.     unit_of_measurement: "Ohm"
  550.     state_class: "measurement"
  551.     icon: "mdi:omega"
  552.     value_type: U_WORD
  553.  
  554.   - platform: modbus_controller
  555.     modbus_controller_id: sofarsolar
  556.     name: ${friendly_name} PV2+ isolation resistance
  557.     id: ${esp_id}_dc_isolation_resistance2
  558.     register_type: holding
  559.     address: 0x0025
  560.     unit_of_measurement: "Ohm"
  561.     state_class: "measurement"
  562.     icon: "mdi:omega"
  563.     value_type: U_WORD
  564.  
  565.   - platform: modbus_controller
  566.     modbus_controller_id: sofarsolar
  567.     name: ${friendly_name} PV- isolation resistance
  568.     id: ${esp_id}_cathode_to_ground_impedance
  569.     register_type: holding
  570.     address: 0x0026
  571.     unit_of_measurement: "Ohm"
  572.     state_class: "measurement"
  573.     icon: "mdi:omega"
  574.     value_type: U_WORD
  575.  
  576.   - platform: template
  577.     name: ${friendly_name} DC Power (total)  
  578.     id: ${esp_id}_dc_power_total
  579.     lambda: |-
  580.       return (id(${esp_id}_dc_power2).state + id(${esp_id}_dc_power1).state);
  581.     unit_of_measurement: W
  582.     state_class: "measurement"
  583.     device_class: "power"
  584.     accuracy_decimals: 0
  585.     icon: "mdi:alpha-a-circle-outline"
  586.     update_interval: 5s
  587.  
  588.   - platform: uptime
  589.     name: ${friendly_name} Uptime
  590.     id: uptime_sensor
  591.     update_interval: 5s
  592.     icon: "mdi:clock-start"
  593.     internal: true
  594.     entity_category: diagnostic
  595.     on_raw_value:
  596.       then:
  597.         - text_sensor.template.publish:
  598.             id: uptime_human
  599.             state: !lambda |-
  600.               int seconds = round(id(uptime_sensor).raw_state);
  601.               seconds = seconds % (24 * 3600);
  602.               int hours = seconds / 3600;
  603.               seconds = seconds % 3600;
  604.               int minutes = seconds /  60;
  605.               seconds = seconds % 60;
  606.               return (
  607.                 (hours ? to_string(hours) + "h " : "") +
  608.                 (minutes ? to_string(minutes) + "m " : "") +
  609.                 (to_string(seconds) + "s")
  610.               ).c_str();
  611.  
  612.   - platform: copy
  613.     source_id: ${esp_id}_wifi_signal
  614.     id: ${esp_id}_wifi_signal_hr
  615.     name: "${friendly_node_name} WiFi %"
  616.     filters:
  617.       - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
  618.     unit_of_measurement: "%"
  619.     icon: "mdi:wifi"
  620.     device_class: "signal_strength"
  621.     entity_category: "diagnostic"
  622.  
  623. switch:
  624.   - platform: restart
  625.     name: ${friendly_node_name} Restart
  626.  
  627. binary_sensor:
  628.   - platform: status
  629.     name: ${friendly_node_name} Status