# todos: # - move code into packages to make this re-useable # - testing substitutions: ota_password: "" api_enckey: "" wifi_ssid: "" wifi_password: "" vault_role_id: "" vault_secret_id: "" ###### nothing to change below this line ###### esphome: name: mlock-${name_of_board} platform: ESP8266 board: d1_mini on_boot: - priority: 600 then: - light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 100% } - priority: -100 then: - if: condition: switch.is_on: mlock_${name_of_board}_switch then: - light.addressable_set: { id: status_led, red: 0%, green: 100%, blue: 0% } else: - light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% } # Enable logging logger: api: encryption: key: $api_enckey ota: - platform: esphome password: $ota_password wifi: ssid: $wifi_ssid password: $wifi_password # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "$name_of_board Fallback Hotspot" password: "PZe2PJENtBiu" manual_ip: static_ip: $ip_addr gateway: 172.23.23.1 dns1: 172.23.23.1 subnet: 255.255.255.0 captive_portal: spi: clk_pin: GPIO14 mosi_pin: GPIO13 miso_pin: GPIO12 http_request: useragent: esphome timeout: 2s id: http_request_data verify_ssl: false globals: - id: my_token type: std::string restore_value: no - id: my_tag type: std::string restore_value: no - id: may_switch_output type: int restore_value: no rc522_spi: cs_pin: GPIO15 on_tag: then: - light.addressable_set: id: status_led red: 100% green: 100% blue: 0% # store the tag id into global variable - lambda: |- id(my_tag) = x; # login to vault with role_id to fetch short lived token - http_request.post: url: https://vault.ctdo.de/v1/auth/approle/login headers: Content-Type: application/json json: role_id: $vault_role_id secret_id: $vault_secret_id on_response: # fetch token from response, store into my_token then: - lambda: |- json::parse_json(body, [](JsonObject root) -> bool { id(my_token) = (const char*) root["auth"]["client_token"]; return true; }); # use the token to get json of scanned tag from vault - http_request.get: url: !lambda |- return ((std::string) "https://vault.ctdo.de/v1/maschinenlock/" + id(my_tag)); headers: X-Vault-Token: !lambda return id(my_token).c_str(); on_response: then: - if: condition: lambda: 'return response.status_code == 200;' then: # when found, check if machine is allowed, turn on output or blink LED red - lambda: |- json::parse_json(body, [](JsonObject root) -> bool { id(may_switch_output) = root["data"]["mlock-$name_of_board"]; return true; }); - if: condition: lambda: 'return id(may_switch_output);' then: - if: condition: switch.is_on: mlock_${name_of_board}_switch then: - switch.turn_off: mlock_${name_of_board}_switch - homeassistant.event: event: esphome.mlock_locked data: tag: !lambda return id(my_tag); machine: ${name_of_board} else: - switch.turn_on: mlock_${name_of_board}_switch - homeassistant.event: event: esphome.mlock_unlocked data: tag: !lambda return id(my_tag); machine: ${name_of_board} - text.set: id: ${name_of_board}_letzte_entsperrung value: !lambda return id(my_tag); else: - repeat: count: 3 then: - light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% } - delay: 0.1s - light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 0% } - delay: 0.1s else: # vault returns 404 on missing/unknown Tag so blink LED - repeat: count: 3 then: - light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% } - delay: 0.5s - light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 0% } - delay: 0.5s - if: # return LED to switch state before condition: switch.is_on: mlock_${name_of_board}_switch then: - light.addressable_set: { id: status_led, red: 0%, green: 100%, blue: 0% } else: - light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% } # switch component for the output state switch: - platform: gpio pin: D1 name: "Relais Output" id: mlock_${name_of_board}_switch internal: true # hide from Homeassistant, so no one can turn it on without Tag-Scanning binary_sensor: # sensor input for Turning Device off - platform: gpio pin: number: D3 inverted: true mode: INPUT_PULLUP id: ${name_of_board}gpio_input_ausschalter on_press: - switch.turn_off: mlock_${name_of_board}_switch - light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% } # a template sensor for showing the current switch state (read only) - platform: template id: mlock_${name_of_board}_state_output name: "${name_of_board} Status Ausgang" publish_initial_state: true lambda: |- return id(mlock_${name_of_board}_switch).state; # a button element for Homeassistant UI to allow turning off button: - platform: template name: "${name_of_board} Ausschalter" id: ${name_of_board}_btn_ausschalter on_press: - switch.turn_off: mlock_${name_of_board}_switch - light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% } light: - platform: neopixelbus type: GRB variant: WS2812 pin: D4 name: status_led id: status_led num_leds: 1 internal: true text: - platform: template name: "$name_of_board Letzte Entsperung" id: ${name_of_board}_letzte_entsperrung optimistic: true mode: text