#esphome run can_pcf8574_bridge.yaml
esphome:
  name: can_pcf8574_bridge

esp32:
  board: nodemcu-32s
  framework:
    type: arduino

logger:
# Reference the secrets file from a directory above
substitutions: !include ../secrets.yaml
mqtt:
  id: mqtt_client #MQTT id
  broker: "${mqtt_broker}"
  port: 1883
  username: "${mqtt_username}"
  password: "${mqtt_password}"
ota:
  platform: esphome
  password: "${ota_password}"

wifi:
  networks:
  - ssid: '${wifi_ssid1}'
    password: '${wifi_password1}'
  - ssid: '${wifi_ssid2}'
    password: '${wifi_password2}'
  - ssid: '${wifi_ssid3}'
    password: '${wifi_password3}'
  reboot_timeout: 60s
  manual_ip:
    # Set this to the IP of the ESP
    static_ip: 192.168.xx.xx
    # Set this to the IP address of the router. Often ends with .1
    gateway: 192.168.xx.1
    # The subnet of the network. 255.255.255.0 works for most home networks.
    subnet: 255.255.255.0
number:
    - platform: template
      name: "pcf_0x20"
      optimistic: true
      min_value: 0
      max_value: 255
      initial_value: 0
      step: 1
      mode: slider
      id: id_pcf_0x20
      icon: "mdi:counter"
    - platform: template
      name: "pcf_0x21"
      optimistic: true
      min_value: 0
      max_value: 31
      initial_value: 0
      step: 1
      mode: slider
      id: id_pcf_0x21
      icon: "mdi:counter"
switch:
    - platform: template
      id: write_mode
      name: "W"
      optimistic: true
spi:
  - id: mcp_spi
    clk_pin: GPIO18
    mosi_pin: GPIO23
    miso_pin: GPIO19

i2c:
  sda: GPIO21
  scl: GPIO22
  scan: true
  id: bus_a

pcf8574:
  - id: pcf8574_0x20
    address: 0x20
    pcf8575: false
  - id: pcf8574_0x21
    address: 0x21
    pcf8575: false

interval:
  - interval: 100ms
    then:
      - lambda: |-
          uint8_t pcf_0x20 = (uint8_t)id(id_pcf_0x20).state;
          uint8_t pcf_0x21 = (uint8_t)id(id_pcf_0x21).state;
          bool    is_write    = id(write_mode).state;
          uint8_t base   = pcf_0x21 & 0x1F;
          uint8_t result = (base & ~0x80) | (is_write ? 0x80 : 0x00);
          id(bus_a).write(0x20, &pcf_0x20, 1);
          ESP_LOGI("i2c pcf_0x20", "Sent: 0x%02X", pcf_0x20);
          id(bus_a).write(0x21, &result, 1);
          ESP_LOGI("i2c pcf_0x21", "Sent: 0x%02X", result);
          char bin[9];
          for (int i = 7; i >= 0; --i) {
              bin[7 - i] = (result & (1 << i)) ? '1' : '0';
          }
          bin[8] = '\0';
          ESP_LOGI("i2c", "Sent: %s", bin);
 

canbus:
  - platform: mcp2515
    spi_id: mcp_spi
    cs_pin: GPIO5
    can_id: 4
    use_extended_id: false
    bit_rate: 500kbps
    id: mcp2515_bus
    on_frame:
      - can_id: 0
        can_id_mask: 0
        use_extended_id: false
        remote_transmission_request: false
        then:
          - lambda: |-
              bool ext = false;
              auto pdo_id = can_id;

              if (pdo_id == 0x150) {
                if (x[0] == 0x01) {
                  // обработка запуска
                }
                if (x[0] == 0x00) {
                  // обработка остановки
                }
              }

              if (pdo_id >= 0x160 && pdo_id <= 0x18F) {
                uint8_t node_id = pdo_id - 0x160 + 1;

                if (x[0] == 0x01) {
                  // индивидуальный запуск
                }
                if (x[0] == 0x00) {
                  // индивидуальная остановка
                }

                uint64_t I = (uint64_t)(x[2] << 8) | x[1];
                uint64_t I_ma = I * 1000 * 0.0146628;
                uint8_t byte1 = (I_ma >> 24) & 0xFF;
                uint8_t byte2 = (I_ma >> 16) & 0xFF;
                uint8_t byte3 = (I_ma >> 8)  & 0xFF;
                uint8_t byte4 =  I_ma        & 0xFF;

                // использование I_ma по твоей логике
              }