Shelly Plus 1PM config with adjustable overcurrent and overload protection

substitutions:
  device_name: "Shelly Plus 1PM"
  current_res: "0.001"
  voltage_div: "1825"

globals:
  - id: max_temp
    type: float
    restore_value: no
    initial_value: '80.0'
  
  - id: max_voltage
    type: float
    restore_value: no
    initial_value: '250.0'

esphome:
  name: shelly_plus_1pm
  friendly_name: ${device_name}
  platformio_options:
    board_build.f_cpu: 160000000L

esp32:
  board: esp32doit-devkit-v1
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_FREERTOS_UNICORE: y
      CONFIG_ESP32_DEFAULT_CPU_FREQ_160: y
      CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ: "160"

logger:
  level: ERROR

api:
  encryption:
    key: !secret api_key

ota:
  password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

time:
  - platform: homeassistant

output:
  - platform: gpio
    id: "relay_output"
    pin: GPIO26

switch:
  - platform: output
    id: "relay"
    output: "relay_output"
    internal: true

  - platform: template
    name: None
    id: output
    lambda: 'return id(relay).state;'
    turn_on_action:
      - if:
          condition:
            and:
              - sensor.in_range:
                  id: temperature
                  below: 80.0
          then:
            - switch.turn_on: relay
    turn_off_action:
          - switch.turn_off: relay

number:
  - platform: template
    name: "Max Power"
    id: max_power
    optimistic: true
    min_value: 1.0
    max_value: 3600.0
    step: 0.1
    restore_value: true
    entity_category: "CONFIG"
  - platform: template
    name: "Max Ampere"
    id: max_amp
    optimistic: true
    min_value: 0.001
    max_value: 16.0
    step: 0.001
    restore_value: true
    entity_category: "CONFIG"

binary_sensor:
  - platform: gpio
    name: "Switch Button"
    pin: GPIO4
    on_press:
      then:
        - switch.turn_on: "output"
    on_release:
      then:
        - switch.turn_off: "output"
    filters:
      - delayed_on_off: 50ms
  
  - platform: template
    name: "Overload"
    icon: mdi:flash-alert
    entity_category: "DIAGNOSTIC"
    device_class: problem
    id: overload
    lambda: 'return id(power).state > id(max_power).state'

  - platform: template
    name: "Overcurrent"
    icon: mdi:flash-alert
    entity_category: "DIAGNOSTIC"
    device_class: problem
    id: overcurrent
    lambda: 'return id(ampere).state > id(max_amp).state'
  
  - platform: template
    name: "Overvoltage"
    icon: mdi:flash-alert
    entity_category: "DIAGNOSTIC"
    device_class: problem
    id: overvoltage
    lambda: 'return id(voltage).state > id(max_voltage)'

  - platform: template
    name: "Overheating"
    icon: mdi:thermometer-alert
    entity_category: "DIAGNOSTIC"
    device_class: problem
    id: overheating
    lambda: 'return id(temperature).state > id(max_temp)'

  

sensor:
  - platform: ntc
    sensor: temp_resistance_reading
    name: "Internal Temperature"
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    icon: "mdi:thermometer"
    entity_category: "DIAGNOSTIC"
    id: temperature
    calibration:
      b_constant: 3350
      reference_resistance: 10kOhm
      reference_temperature: 298.15K
    on_value:
      then:
        - if:
            condition:
              lambda: 'return id(temperature).state >= id(max_temp).state;'
            then:
              - switch.turn_off: "relay"

  - platform: resistance
    id: temp_resistance_reading
    sensor: temp_analog_reading
    configuration: DOWNSTREAM
    resistor: 10kOhm

  - platform: adc
    id: temp_analog_reading
    pin: GPIO32
    attenuation: 11db

  - platform: adc
    name: "Spannung"
    pin: GPIO33
    attenuation: 11db
    filters:
      - multiply: 8

  - platform: hlw8012
    model: BL0937
    sel_pin:
      number: GPIO23
      inverted: true
    cf_pin: GPIO5
    cf1_pin: GPIO18
    current_resistor: ${current_res}
    voltage_divider: ${voltage_div}
    current:
      id: ampere
      unit_of_measurement: A
      accuracy_decimals: 3
      internal: true
    voltage:
      id: voltage
      unit_of_measurement: V
      accuracy_decimals: 1
      internal: true
      on_value_range:
        - above: "250.0"
          then:
            - switch.turn_off: "relay"
    power:
      id: power
      unit_of_measurement: W
      internal: true
      on_value:
        then:
          if:
            condition:
              lambda: 'return id(power).state >= id(max_power).state;'
            then:
              - switch.turn_off: relay
    change_mode_every: 3
    update_interval: 500ms

  - platform: template
    name: "Power"
    id: exposed_power
    unit_of_measurement: W
    accuracy_decimals: 1
    icon: mdi:flash
    lambda: |-
      return id(power).state;
    update_interval: 2s
  
  - platform: template
    name: "Current"
    id: exposed_ampere
    unit_of_measurement: A
    accuracy_decimals: 3
    icon: mdi:current-ac
    lambda: |-
      return id(ampere).state;
    update_interval: 2s

  - platform: template
    name: "Voltage"
    id: exposed_voltage
    unit_of_measurement: V
    accuracy_decimals: 1
    icon: mdi:sine-wave
    lambda: |-
      return id(voltage).state;
    update_interval: 2s
  
  - platform: total_daily_energy
    name: "Daily Energy"
    power_id: power
    filters:
      - multiply: 0.001
    unit_of_measurement: kWh
    accuracy_decimals: 3
    icon: mdi:flash

  - platform: wifi_signal
    name: "WiFi Signal Strength"
    update_interval: 60s

  - platform: uptime
    name: "Uptime"
    update_interval: 60s
    icon: mdi:clock


status_led:
  pin:
    number: GPIO0
    inverted: true