substitutions: name: boneio-32-sw-07-f43278 friendly_name: 'BoneIO ESP 32x10 Switches' serial_prefix: 'esp' #Don't change it. esphome: name: '${name}' friendly_name: '${friendly_name}' name_add_mac_suffix: false project: name: boneio.32x10-lights version: '0.7' on_boot: - priority: 1001 then: - lambda: |- gpio_reset_pin((gpio_num_t)14); gpio_reset_pin((gpio_num_t)15); - priority: 0 then: - display.page.show: first_page - component.update: ip_address - component.update: oled_display - script.execute: screensaver_script esp32: board: nodemcu-32s framework: type: esp-idf ethernet: id: eth type: LAN8720 mdc_pin: GPIO23 mdio_pin: GPIO18 clk: pin: GPIO0 mode: CLK_EXT_IN phy_addr: 1 power_pin: GPIO16 logger: api: reboot_timeout: 0s ota: - platform: esphome - platform: web_server web_server: port: 80 local: true time: - platform: homeassistant timezone: Europe/Warsaw id: homeassistant_time # ─── External components ────────────────────────────────────────────────────── external_components: - source: github://boneIO-eu/esphome-LM75@main components: [lm75] # ─── I2C ───────────────────────────────────────────────────────────────────── i2c: - id: i2c_bus sda: GPIO17 scl: GPIO33 scan: True frequency: 400kHz # ─── GPIO Expanders ─────────────────────────────────────────────────────────── pcf8574: - id: 'pcf_inputs_1to14' i2c_id: i2c_bus address: 0x20 pcf8575: true - id: 'pcf_inputs_15to28' i2c_id: i2c_bus address: 0x21 pcf8575: true - id: 'pcf_inputs_28to35_menu' i2c_id: i2c_bus address: 0x22 pcf8575: false - id: 'pcf_left' address: 0x23 pcf8575: true i2c_id: i2c_bus - id: 'pcf_right' address: 0x24 pcf8575: true i2c_id: i2c_bus # ─── 1-Wire ─────────────────────────────────────────────────────────────────── one_wire: - platform: gpio pin: GPIO32 # ─── Wiegand ────────────────────────────────────────────────────────────────── wiegand: - id: wiegand_reader_1 d0: GPIO4 d1: GPIO35 on_tag: - text_sensor.template.publish: id: wiegand_1_tag state: !lambda 'return x;' - homeassistant.tag_scanned: !lambda 'return x;' - lambda: |- std::string tag = id(wiegand_1_tag).state; std::string expected = id(ha_card_apartament_1).state; if (tag == expected) { ESP_LOGI("wiegand1", "Karta poprawna: %s - zwalniam zamek", tag.c_str()); id(unlock_apartament_1).execute(); } else { ESP_LOGI("wiegand1", "Karta nieznana: %s (oczekiwano: %s)", tag.c_str(), expected.c_str()); } on_key: - lambda: |- ESP_LOGI("wiegand1", "Klawisz: %d", x); on_raw: - lambda: |- ESP_LOGI("wiegand1", "Raw: %d bitow, wartosc %llx", bits, value); - id: wiegand_reader_2 d0: GPIO36 d1: GPIO39 on_tag: - text_sensor.template.publish: id: wiegand_2_tag state: !lambda 'return x;' - homeassistant.tag_scanned: !lambda 'return x;' - lambda: |- std::string tag = id(wiegand_2_tag).state; std::string expected = id(ha_card_apartament_2).state; if (tag == expected) { ESP_LOGI("wiegand2", "Karta poprawna: %s - zwalniam zamek", tag.c_str()); id(unlock_apartament_2).execute(); } else { ESP_LOGI("wiegand2", "Karta nieznana: %s (oczekiwano: %s)", tag.c_str(), expected.c_str()); } on_key: - lambda: |- ESP_LOGI("wiegand2", "Klawisz: %d", x); on_raw: - lambda: |- ESP_LOGI("wiegand2", "Raw: %d bitow, wartosc %llx", bits, value); key_collector: - id: pincode_reader_1 source_id: wiegand_reader_1 min_length: 2 max_length: 8 end_keys: "#" end_key_required: true back_keys: "*" allowed_keys: "0123456789" timeout: 5s on_progress: - lambda: |- ESP_LOGI("pin1", "PIN w trakcie: '%s'", x.c_str()); on_result: - text_sensor.template.publish: id: wiegand_1_pin state: !lambda 'return x;' - lambda: |- char expected[16]; snprintf(expected, sizeof(expected), "%.0f", id(ha_pin_apartament_1).state); if (x == expected) { ESP_LOGI("pin1", "PIN poprawny: '%s' - zwalniam zamek", x.c_str()); id(unlock_apartament_1).execute(); } else { ESP_LOGI("pin1", "PIN niepoprawny: '%s' (oczekiwano: '%s')", x.c_str(), expected); } on_timeout: - lambda: |- ESP_LOGI("pin1", "PIN timeout: '%s'", x.c_str()); - id: pincode_reader_2 source_id: wiegand_reader_2 min_length: 2 max_length: 8 end_keys: "#" end_key_required: true back_keys: "*" allowed_keys: "0123456789" timeout: 5s on_progress: - lambda: |- ESP_LOGI("pin2", "PIN w trakcie: '%s'", x.c_str()); on_result: - text_sensor.template.publish: id: wiegand_2_pin state: !lambda 'return x;' - lambda: |- char expected[16]; snprintf(expected, sizeof(expected), "%.0f", id(ha_pin_apartament_2).state); if (x == expected) { ESP_LOGI("pin2", "PIN poprawny: '%s' - zwalniam zamek", x.c_str()); id(unlock_apartament_2).execute(); } else { ESP_LOGI("pin2", "PIN niepoprawny: '%s' (oczekiwano: '%s')", x.c_str(), expected); } on_timeout: - lambda: |- ESP_LOGI("pin2", "PIN timeout: '%s'", x.c_str()); # ─── Sensors ────────────────────────────────────────────────────────────────── sensor: - platform: homeassistant id: ha_pin_apartament_1 entity_id: input_number.apartament_1 internal: true - platform: homeassistant id: ha_pin_apartament_2 entity_id: input_number.apartament_2 internal: true - platform: uptime id: wt32_uptime_seconds update_interval: 60s entity_category: diagnostic on_raw_value: then: - text_sensor.template.publish: id: wt32_uptime state: !lambda |- int seconds = round(id(wt32_uptime_seconds).raw_state); int days = seconds / (24 * 3600); seconds = seconds % (24 * 3600); int hours = seconds / 3600; seconds = seconds % 3600; int minutes = seconds / 60; return ( (days ? to_string(days) + "d " : "") + (hours ? to_string(hours) + "h " : "") + (to_string(minutes) + "m") ).c_str(); - platform: ina219 address: 0x40 shunt_resistance: 0.1 ohm current: id: ina_current name: 'INA219 Current' power: id: ina_power name: 'INA219 Power' bus_voltage: id: ina_bus_voltage name: 'INA219 Bus Voltage' shunt_voltage: id: ina_shunt_voltage name: 'INA219 Shunt Voltage' max_voltage: 32.0V max_current: 3.2A update_interval: 30s - platform: lm75 id: boneIO_temp name: 'LM75B Temperature' update_interval: 30s # ─── Text Sensors ───────────────────────────────────────────────────────────── text_sensor: - platform: homeassistant id: ha_card_apartament_1 entity_id: input_text.apartament_karta_1 internal: true - platform: homeassistant id: ha_card_apartament_2 entity_id: input_text.apartament_karta_2 internal: true - platform: template name: Uptime id: wt32_uptime entity_category: diagnostic icon: mdi:clock-start - platform: template name: 'IP Address' id: ip_address entity_category: diagnostic icon: 'mdi:ip-network' lambda: |- return id(eth).get_ip_addresses().empty() ? "Unset" : id(eth).get_ip_addresses()[0].str(); update_interval: 60s - platform: template name: 'Serial No.' id: serial_no lambda: |- std::string mac = get_mac_address(); return std::string("${serial_prefix}") + mac.substr(mac.length()/2); icon: mdi:expansion-card-variant entity_category: diagnostic update_interval: 60min - platform: template name: 'Wiegand 1 Tag' id: wiegand_1_tag icon: mdi:card-account-details - platform: template name: 'Wiegand 2 Tag' id: wiegand_2_tag icon: mdi:card-account-details - platform: template name: 'Wiegand 1 PIN' id: wiegand_1_pin icon: mdi:numeric - platform: template name: 'Wiegand 2 PIN' id: wiegand_2_pin icon: mdi:numeric # ─── Buzzer ─────────────────────────────────────────────────────────────────── switch: - platform: gpio id: buzzer name: 'Buzzer' pin: number: GPIO2 mode: output: true inverted: false # ─── Output ─────────────────────────────────────────────────────────────────── - platform: output name: 'Elektrozamek apartament 1' output: out_01 id: switch_01 restore_mode: ALWAYS_ON - platform: output name: 'Elektrozamek apartament 2' output: out_02 id: switch_02 restore_mode: ALWAYS_ON - platform: output name: 'Switch 03' output: out_03 id: switch_03 - platform: output name: 'Switch 04' output: out_04 id: switch_04 - platform: output name: 'Switch 05' output: out_05 id: switch_05 - platform: output name: 'Switch 06' output: out_06 id: switch_06 - platform: output name: 'Switch 07' output: out_07 id: switch_07 - platform: output name: 'Switch 08' output: out_08 id: switch_08 - platform: output name: 'Switch 09' output: out_09 id: switch_09 - platform: output name: 'Switch 10' output: out_10 id: switch_10 - platform: output name: 'Switch 11' output: out_11 id: switch_11 - platform: output name: 'Switch 12' output: out_12 id: switch_12 - platform: output name: 'Switch 13' output: out_13 id: switch_13 - platform: output name: 'Switch 14' output: out_14 id: switch_14 - platform: output name: 'Switch 15' output: out_15 id: switch_15 - platform: output name: 'Switch 16' output: out_16 id: switch_16 - platform: output name: 'Switch 17' output: out_17 id: switch_17 - platform: output name: 'Switch 18' output: out_18 id: switch_18 - platform: output name: 'Switch 19' output: out_19 id: switch_19 - platform: output name: 'Switch 20' output: out_20 id: switch_20 - platform: output name: 'Switch 21' output: out_21 id: switch_21 - platform: output name: 'Switch 22' output: out_22 id: switch_22 - platform: output name: 'Switch 23' output: out_23 id: switch_23 - platform: output name: 'Switch 24' output: out_24 id: switch_24 - platform: output name: 'Switch 25' output: out_25 id: switch_25 - platform: output name: 'Switch 26' output: out_26 id: switch_26 - platform: output name: 'Switch 27' output: out_27 id: switch_27 - platform: output name: 'Switch 28' output: out_28 id: switch_28 - platform: output name: 'Switch 29' output: out_29 id: switch_29 - platform: output name: 'Switch 30' output: out_30 id: switch_30 - platform: output name: 'Switch 31' output: out_31 id: switch_31 - platform: output name: 'Switch 32' output: out_32 id: switch_32 # ─── GPIO Outputs (PCF expanders) ───────────────────────────────────────────── output: - platform: gpio id: out_01 pin: pcf8574: pcf_left number: 15 mode: output: true inverted: true - platform: gpio id: out_02 pin: pcf8574: pcf_left number: 14 mode: output: true inverted: true - platform: gpio id: out_03 pin: pcf8574: pcf_left number: 13 mode: output: true inverted: true - platform: gpio id: out_04 pin: pcf8574: pcf_left number: 12 mode: output: true inverted: true - platform: gpio id: out_05 pin: pcf8574: pcf_left number: 11 mode: output: true inverted: true - platform: gpio id: out_06 pin: pcf8574: pcf_left number: 10 mode: output: true inverted: true - platform: gpio id: out_07 pin: pcf8574: pcf_left number: 9 mode: output: true inverted: true - platform: gpio id: out_08 pin: pcf8574: pcf_left number: 8 mode: output: true inverted: true - platform: gpio id: out_09 pin: pcf8574: pcf_right number: 15 mode: output: true inverted: true - platform: gpio id: out_10 pin: pcf8574: pcf_right number: 14 mode: output: true inverted: true - platform: gpio id: out_11 pin: pcf8574: pcf_right number: 13 mode: output: true inverted: true - platform: gpio id: out_12 pin: pcf8574: pcf_right number: 12 mode: output: true inverted: true - platform: gpio id: out_13 pin: pcf8574: pcf_right number: 11 mode: output: true inverted: true - platform: gpio id: out_14 pin: pcf8574: pcf_right number: 10 mode: output: true inverted: true - platform: gpio id: out_15 pin: pcf8574: pcf_right number: 9 mode: output: true inverted: true - platform: gpio id: out_16 pin: pcf8574: pcf_right number: 8 mode: output: true inverted: true - platform: gpio id: out_17 pin: pcf8574: pcf_left number: 0 mode: output: true inverted: true - platform: gpio id: out_18 pin: pcf8574: pcf_left number: 1 mode: output: true inverted: true - platform: gpio id: out_19 pin: pcf8574: pcf_left number: 2 mode: output: true inverted: true - platform: gpio id: out_20 pin: pcf8574: pcf_left number: 3 mode: output: true inverted: true - platform: gpio id: out_21 pin: pcf8574: pcf_left number: 4 mode: output: true inverted: true - platform: gpio id: out_22 pin: pcf8574: pcf_left number: 5 mode: output: true inverted: true - platform: gpio id: out_23 pin: pcf8574: pcf_left number: 6 mode: output: true inverted: true - platform: gpio id: out_24 pin: pcf8574: pcf_left number: 7 mode: output: true inverted: true - platform: gpio id: out_25 pin: pcf8574: pcf_right number: 0 mode: output: true inverted: true - platform: gpio id: out_26 pin: pcf8574: pcf_right number: 1 mode: output: true inverted: true - platform: gpio id: out_27 pin: pcf8574: pcf_right number: 2 mode: output: true inverted: true - platform: gpio id: out_28 pin: pcf8574: pcf_right number: 3 mode: output: true inverted: true - platform: gpio id: out_29 pin: pcf8574: pcf_right number: 4 mode: output: true inverted: true - platform: gpio id: out_30 pin: pcf8574: pcf_right number: 5 mode: output: true inverted: true - platform: gpio id: out_31 pin: pcf8574: pcf_right number: 6 mode: output: true inverted: true - platform: gpio id: out_32 pin: pcf8574: pcf_right number: 7 mode: output: true inverted: true # ─── Binary Sensors (Inputs) ────────────────────────────────────────────────── binary_sensor: - platform: gpio entity_category: config id: boneIO_button pin: pcf8574: pcf_inputs_28to35_menu number: 7 mode: input: true inverted: true on_press: then: - if: condition: display.is_displaying_page: last_page then: - display.page.show: first_page - component.update: oled_display else: - if: condition: display.is_displaying_page: screensaver then: - display.page.show: first_page - component.update: oled_display else: - display.page.show_next: oled_display - component.update: oled_display - script.execute: screensaver_script - platform: gpio name: 'IN_01' id: in_01 pin: pcf8574: pcf_inputs_1to14 number: 0 mode: input: true inverted: true on_press: then: - switch.toggle: switch_01 - platform: gpio name: 'IN_02' id: in_02 pin: pcf8574: pcf_inputs_1to14 number: 1 mode: input: true inverted: true on_press: then: - switch.toggle: switch_02 - platform: gpio name: 'IN_03' id: in_03 pin: pcf8574: pcf_inputs_1to14 number: 2 mode: input: true inverted: true on_press: then: - switch.toggle: switch_03 - platform: gpio name: 'IN_04' id: in_04 pin: pcf8574: pcf_inputs_1to14 number: 3 mode: input: true inverted: true on_press: then: - switch.toggle: switch_04 - platform: gpio name: 'IN_05' id: in_05 pin: pcf8574: pcf_inputs_1to14 number: 4 mode: input: true inverted: true on_press: then: - switch.toggle: switch_05 - platform: gpio name: 'IN_06' id: in_06 pin: pcf8574: pcf_inputs_1to14 number: 5 mode: input: true inverted: true on_press: then: - switch.toggle: switch_06 - platform: gpio name: 'IN_07' id: in_07 pin: pcf8574: pcf_inputs_1to14 number: 6 mode: input: true inverted: true on_press: then: - switch.toggle: switch_07 - platform: gpio name: 'IN_08' id: in_08 pin: pcf8574: pcf_inputs_1to14 number: 8 mode: input: true inverted: true on_press: then: - switch.toggle: switch_08 - platform: gpio name: 'IN_09' id: in_09 pin: pcf8574: pcf_inputs_1to14 number: 9 mode: input: true inverted: true on_press: then: - switch.toggle: switch_09 - platform: gpio name: 'IN_10' id: in_10 pin: pcf8574: pcf_inputs_1to14 number: 10 mode: input: true inverted: true on_press: then: - switch.toggle: switch_10 - platform: gpio name: 'IN_11' id: in_11 pin: pcf8574: pcf_inputs_1to14 number: 11 mode: input: true inverted: true on_press: then: - switch.toggle: switch_11 - platform: gpio name: 'IN_12' id: in_12 pin: pcf8574: pcf_inputs_1to14 number: 12 mode: input: true inverted: true on_press: then: - switch.toggle: switch_12 - platform: gpio name: 'IN_13' id: in_13 pin: pcf8574: pcf_inputs_1to14 number: 13 mode: input: true inverted: true on_press: then: - switch.toggle: switch_13 - platform: gpio name: 'IN_14' id: in_14 pin: pcf8574: pcf_inputs_1to14 number: 14 mode: input: true inverted: true on_press: then: - switch.toggle: switch_14 - platform: gpio name: 'IN_15' id: in_15 pin: pcf8574: pcf_inputs_15to28 number: 6 mode: input: true inverted: true on_press: then: - switch.toggle: switch_15 - platform: gpio name: 'IN_16' id: in_16 pin: pcf8574: pcf_inputs_15to28 number: 5 mode: input: true inverted: true on_press: then: - switch.toggle: switch_16 - platform: gpio name: 'IN_17' id: in_17 pin: pcf8574: pcf_inputs_15to28 number: 4 mode: input: true inverted: true on_press: then: - switch.toggle: switch_17 - platform: gpio name: 'IN_18' id: in_18 pin: pcf8574: pcf_inputs_15to28 number: 3 mode: input: true inverted: true on_press: then: - switch.toggle: switch_18 - platform: gpio name: 'IN_19' id: in_19 pin: pcf8574: pcf_inputs_15to28 number: 2 mode: input: true inverted: true on_press: then: - switch.toggle: switch_19 - platform: gpio name: 'IN_20' id: in_20 pin: pcf8574: pcf_inputs_15to28 number: 1 mode: input: true inverted: true on_press: then: - switch.toggle: switch_20 - platform: gpio name: 'IN_21' id: in_21 pin: pcf8574: pcf_inputs_15to28 number: 0 mode: input: true inverted: true on_press: then: - switch.toggle: switch_21 - platform: gpio name: 'IN_22' id: in_22 pin: pcf8574: pcf_inputs_15to28 number: 8 mode: input: true inverted: true on_press: then: - switch.toggle: switch_22 - platform: gpio name: 'IN_23' id: in_23 pin: pcf8574: pcf_inputs_15to28 number: 9 mode: input: true inverted: true on_press: then: - switch.toggle: switch_23 - platform: gpio name: 'IN_24' id: in_24 pin: pcf8574: pcf_inputs_15to28 number: 10 mode: input: true inverted: true on_press: then: - switch.toggle: switch_24 - platform: gpio name: 'IN_25' id: in_25 pin: pcf8574: pcf_inputs_15to28 number: 11 mode: input: true inverted: true on_press: then: - switch.toggle: switch_25 - platform: gpio name: 'IN_26' id: in_26 pin: pcf8574: pcf_inputs_15to28 number: 12 mode: input: true inverted: true on_press: then: - switch.toggle: switch_26 - platform: gpio name: 'IN_27' id: in_27 pin: pcf8574: pcf_inputs_15to28 number: 13 mode: input: true inverted: true on_press: then: - switch.toggle: switch_27 - platform: gpio name: 'IN_28' id: in_28 pin: pcf8574: pcf_inputs_15to28 number: 14 mode: input: true inverted: true on_press: then: - switch.toggle: switch_28 - platform: gpio name: 'IN_29' id: in_29 pin: pcf8574: pcf_inputs_28to35_menu number: 0 mode: input: true inverted: true on_press: then: - switch.toggle: switch_29 - platform: gpio name: 'IN_30' id: in_30 pin: pcf8574: pcf_inputs_28to35_menu number: 1 mode: input: true inverted: true on_press: then: - switch.toggle: switch_30 - platform: gpio name: 'IN_31' id: in_31 pin: pcf8574: pcf_inputs_28to35_menu number: 2 mode: input: true inverted: true on_press: then: - switch.toggle: switch_31 - platform: gpio name: 'IN_32' id: in_32 pin: pcf8574: pcf_inputs_28to35_menu number: 3 mode: input: true inverted: true on_press: then: - switch.toggle: switch_32 - platform: gpio name: 'IN_33' pin: pcf8574: pcf_inputs_28to35_menu number: 4 mode: input: true inverted: true - platform: gpio name: 'IN_34' pin: pcf8574: pcf_inputs_28to35_menu number: 5 mode: input: true inverted: true - platform: gpio name: 'IN_35' pin: pcf8574: pcf_inputs_28to35_menu number: 6 mode: input: true inverted: true # ─── Display ────────────────────────────────────────────────────────────────── font: - file: 'gfonts://Ubuntu' id: size_10 size: 10 script: - id: unlock_apartament_1 mode: single then: - switch.turn_off: switch_01 - delay: 5s - switch.turn_on: switch_01 - id: unlock_apartament_2 mode: single then: - switch.turn_off: switch_02 - delay: 5s - switch.turn_on: switch_02 - id: screensaver_script mode: restart then: - delay: 30s - display.page.show: screensaver - component.update: oled_display display: - platform: ssd1306_i2c id: oled_display model: 'SH1106 128x64' address: 0x3C contrast: 0.5 pages: - id: first_page lambda: |- it.rectangle(0, 0, 126, 15); it.printf(64,11, id(size_10), TextAlign::BASELINE_CENTER, "Peak Control"); it.printf(4, 37, id(size_10), TextAlign::BASELINE_LEFT ,"IP addr:"); it.printf(124, 37, id(size_10), TextAlign::BASELINE_RIGHT ,"%s", id(ip_address).state.c_str()); it.printf(4, 49, id(size_10), TextAlign::BASELINE_LEFT ,"Uptime:"); it.printf(124, 49, id(size_10), TextAlign::BASELINE_RIGHT ,"%s", id(wt32_uptime).state.c_str()); it.printf(4, 61, id(size_10), TextAlign::BASELINE_LEFT ,"Temperature:"); it.printf(124, 61, id(size_10), TextAlign::BASELINE_RIGHT ,"%.2f°C", id(boneIO_temp).state); - id: last_page lambda: |- it.rectangle(0, 0, 126, 15); it.printf(64,11, id(size_10), TextAlign::BASELINE_CENTER, "Peak Control"); it.printf(4, 25, id(size_10), TextAlign::BASELINE_LEFT ,"Current:"); it.printf(124, 25, id(size_10), TextAlign::BASELINE_RIGHT ,"%.3fA", id(ina_current).state); it.printf(4, 37, id(size_10), TextAlign::BASELINE_LEFT ,"Power:"); it.printf(124, 37, id(size_10), TextAlign::BASELINE_RIGHT ,"%.2fW", id(ina_power).state); it.printf(4, 49, id(size_10), TextAlign::BASELINE_LEFT ,"Bus Volt:"); it.printf(124, 49, id(size_10), TextAlign::BASELINE_RIGHT ,"%.2fV", id(ina_bus_voltage).state); it.printf(4, 61, id(size_10), TextAlign::BASELINE_LEFT ,"Shunt Volt:"); it.printf(124, 61, id(size_10), TextAlign::BASELINE_RIGHT ,"%.2fV", id(ina_shunt_voltage).state); - id: screensaver lambda: |- it.fill(COLOR_OFF); ###################### ### MODBUS SECTION ### ###################### # UNCOMMENT BELOW TO USE MODBUS # uart: # id: uart_pin14_15 # rx_pin: # number: GPIO14 # mode: # input: true # pullup: true # tx_pin: GPIO15 # baud_rate: 9600 # stop_bits: 1 # modbus: # send_wait_time: 200ms # uart_id: uart_pin14_15 # id: boneio_modbus # modbus_controller: # - id: YOURDEVICE ID # address: 0x09 # modbus_id: mod_bus # setup_priority: -10 # update_interval: 60s