--- title: Homeassistant description: published: 1 date: 2024-02-03T20:43:39.935Z tags: editor: markdown dateCreated: 2024-02-03T20:23:54.798Z --- Need to access time sensor alternatively, use now template: - trigger: - platform: time_pattern seconds: "/1" sensor: - name: time state: "{{ now().strftime('%H:%M:%S') }}" {{ now().strftime("%I:%M %p") }} {{ as_timestamp(state_attr("device_tracker.android_9050f88e39898022", "last_time_reachable")) | timestamp_local }} {##{{ state_attr("device_tracker.android_9050f88e39898022", "last_time_reachable").strftime('%H:%M:%S') }}##} - condition: template value_template: '"{{ now().timestamp()+300 < (as_timestamp(state_attr("device_tracker.android_9050f88e39898022", "last_time_reachable")) | float) }}"' Change attribute value via automation \- id: automation 3 trigger: platform: time_pattern minutes: '/1' action: service: python_script.set_state data_template: entity_id: sensor.cold_water_rate state: 42 # new HA OS on RaPi4 {#new-ha-os-on-rapi4 .western} http://192.168.178.52:8123/ - [create user]{style="background: #e8f2a1"} - [user: bora, pass: bora]{style="background: #e8f2a1"} - [select location]{style="background: #e8f2a1"} - activate advanced mode under profile settings - install add ons - [Samba share]{style="background: #e8f2a1"} - [username: homeassistant, password: bora, workgroup: WORKGROUP]{style="background: #e8f2a1"} - [add a new network location: \\\\192.168.178.52\\config]{style="background: #e8f2a1"} - [file editor]{style="background: #e8f2a1"} - [duckdns]{style="background: #e8f2a1"} - [domains: \- habora.duckdns.org token: 799093a4-0b34-454f-99cb-25a4637bf404 aliases: [] lets_encrypt: accept_terms: true algo: secp384r1 certfile: fullchain.pem keyfile: privkey.pem seconds: 300]{style="background: #e8f2a1"} - [MariaDB]{style="background: #e8f2a1"} - [databases: \- homeassistant logins: \- username: homeassistant password: password1234 \- username: read_only_user password: password1234 rights: \- username: homeassistant database: homeassistant \- username: read_only_user database: homeassistant privileges: \- SELECT]{style="background: #e8f2a1"} - [recorder: db_url: mysql://homeassistant:password@core-mariadb/homeassistant?charset=utf8mb4]{style="background: #e8f2a1"} - [Nginx Proxy Manager]{style="background: #e8f2a1"} - [Open WebUI → admin@example.com / changeme]{style="background: #e8f2a1"} - [Hosts -- Proxy Hosts → Add Proxy Host]{style="background: #e8f2a1"} - [Domain Names: habora.duckdns.org]{style="background: #e8f2a1"} - [Als Scheme wählt Ihr http, unter „Forward Hostname / IP" tragt Ihr die IP eures Home Assistant ein. → 192.168.178.52]{style="background: #e8f2a1"} - [Bei Forward Port gebt Ihr den Port ein, unter dem euer Home Assistant erreichbar ist. (Standardmäßig ist das der Port 8123)]{style="background: #e8f2a1"} - [Aktiviert abschließend noch den Punkt „Websockets Support„.]{style="background: #e8f2a1"} - [Anschließend wechselt Ihr auf den Reiter SSL.]{style="background: #e8f2a1"} - [Hier wählt ihr unter „SSL Certificate" den Eintrag „Request a new SSL Certificate" um ein neues Zertifikat zu erstellen aus.]{style="background: #e8f2a1"} - [Aktiviert nun den Punkt „Force SSL„, tragt eine gültige Email-Adresse für eure Zertifikat ein und akzeptiert die Let's Encrypt Bedingungen durch aktivieren der Option am unteren Rand der Dialog.]{style="background: #e8f2a1"} - [Bestätigt nun die Eingaben durch einen Klick auf „Save" und wartet, bis der Vorgang abgeschlossen ist.]{style="background: #e8f2a1"} - [Dann werden im Hintergrund die Zertifikate von Let's Encrypt generiert. Das kann einen Augenblick in Anspruch nehmen.]{style="background: #e8f2a1"} - [Das registrieren des Zertifikates funktioniert nur, wenn die eingetragene Domain auch auf eure externe IP zeigt, und die Ports 80 und 443 auf die Home Assistant IP weitergeleitet sind.]{style="background: #e8f2a1"} - [![](Home_assistant_html_eeaf4fb9a08969e4.png){#Image51 align="bottom" width="547" height="113" border="0"} ]{style="background: #e8f2a1"} ![home_assistant_html_eeaf4fb9a08969e4.png](/pictures/home_assistant_html_eeaf4fb9a08969e4.png) - [configuration.yaml]{style="background: #e8f2a1"} - [http:]{style="background: #e8f2a1"} - [ use_x_forwarded_for: true]{style="background: #e8f2a1"} - [ trusted_proxies:]{style="background: #e8f2a1"} - [ - 127.0.0.1]{style="background: #e8f2a1"} - [ - 172.30.33.0/24]{style="background: #e8f2a1"} - [ - ::1]{style="background: #e8f2a1"} - [Let\'s Encrypt]{style="background: transparent"} - [domains:\ - habora.duckdns.org\ email: boraers@googlemail.com\ keyfile: privkey.pem\ certfile: fullchain.pem\ challenge: http\ dns: {}]{style="background: transparent"} - [add to configuration.aml\ http:\ ssl_certificate: /ssl/fullchain.pem\ ssl_key: /ssl/privkey.pem]{style="background: transparent"} - [influxdb]{style="background: #e8f2a1"} - [no adaptation of configuration was needed]{style="background: #e8f2a1"} - []{style="background: #e8f2a1"} - []{style="background: #e8f2a1"} - [create database: home_assistant]{style="background: #e8f2a1"} - [create user: homeassistant, pass: homeassistant, permissions: ALL]{style="background: #e8f2a1"} - [mosquitto]{style="background: #e8f2a1"} - [Logins:\ - username: note4\ password: note4]{style="background: #e8f2a1"} - [MQTT integration configuration:\ 127.0.0.1 ← not core-mosquitto\ 1883\ note4\ note4\ MQTT protocol: 5]{style="background: #e8f2a1"} - [Grafana]{style="background: #e8f2a1"} - [env_vars:\ - name: GF_SECURITY_ALLOW_EMBEDDING\ value: \"true\"\ - name: GF_AUTH_ANONYMOUS_ORG_NAME\ value: Main Org.\ - name: GF_AUTH_ANONYMOUS_ENABLED\ value: \"true\"\ - name: GF_AUTH_DISABLE_LOGIN_FORM\ value: \"false\"]{style="background: #e8f2a1"} - [SSL: false or true, depending on having ssl set up]{style="background: #e8f2a1"} - [Network:\ 3000]{style="background: #e8f2a1"} - []{style="background: #e8f2a1"} - [in web panel]{style="background: #e8f2a1"} - [add data source: InfluxDB]{style="background: #e8f2a1"} - [URL: [http://](http://a0d7b954-influxdb:8086/)[a0d7b954](http://192.168.178.52:8123/hassio/ingress/a0d7b954_influxdb)[-influxdb:8086](http://a0d7b954-influxdb:8086/)]{style="background: #e8f2a1"} - [database, user, pass]{style="background: #e8f2a1"} - - [Terminal and SSH]{style="background: #e8f2a1"} - integrations - HACS - github credentials required - OpenWeatherMap - API Ke: - solarman - re-use old config files - automations - blueprints - bosch_shc - custom_components - group - images - python_scripts - www - alarm_control_panel.yaml - automations.yaml - climate.yaml - configuration.yaml - influxdb.yaml - mqtt.yaml - scenes.yaml - scripts.yaml - secrets.yaml - sensor.yaml - move to external SSD - che \ ![](Home_assistant_html_8c01be9bb611f888.png){#Image48 align="left" width="561" height="677" border="0"}\ \ \ \ \ \ \ \ \ # Home-Assistant script template {#home-assistant-script-template .western} \ {## Imitate available variables: ##}\ {% set my_test_json = {\ \"temperature\": 25,\ \"unit\": \"°C\"\ } %}\ \ The temperature is {{ my_test_json.temperature }} {{ my_test_json.unit }}.\ \ {% if is_state(\"sun.sun\", \"above_horizon\") -%}\ The sun rose {{ relative_time(states.sun.sun.last_changed) }} ago.\ {%- else -%}\ The sun will rise at {{ as_timestamp(state_attr(\"sun.sun\", \"next_rising\")) \| timestamp_local }}.\ {%- endif %}\ \ For loop example getting entity values in the weather domain:\ \ {% for state in states.weather -%}\ {%- if loop.first %}The {% elif loop.last %} and the {% else %}, the {% endif -%}\ {{ state.name \| lower }} is {{state.state_with_unit}}\ {%- endfor %}.\ \ {% set tado_temp = states(\'sensor.tado_wohnzimmer_temperature\')\|float(20) %}\ {% set room_temp = states(\'sensor.meter_plus_90b4_temperature\')\|float(20) %}\ {% set current_offset = state_attr(\'climate.tado_wohnzimmer\',\ \'offset_celsius\') %}\ {{ tado_temp\|round(1) }}\ {{ room_temp\|round(1) }}\ {{ current_offset\|round(1) }}\ {{ (-(tado_temp - room_temp) + current_offset)\|round(1) }}\ {{ (tado_temp - current_offset)\|round(1) }}\ \ \ {% set average_temp = 0 %}\ {% set active_rooms = 0 %}\ {% set temp_bedroom = states(\'sensor.radiator_thermostat_bedroom_temperature\')\|float(15) %}\ {% set climate_bedroom = states(\'climate.room_climate_bedroom\') %}\ {% set temp_top = states(\'sensor.radiator_thermostat_child_top_temperature\')\|float(15) %}\ {% set climate_top = states(\'climate.room_climate_child_s_room_1_top\') %}\ {% set temp_bottom = states(\'sensor.radiator_thermostat_bottom_temperature\')\|float(15) %}\ {% set climate_bottom = states(\'climate.room_climate_child_s_room_2_botto\') %}\ \ {% if climate_bedroom not in (\"unavailable\", \"unknown\", \"off\") %}\ {% set active_rooms = active_rooms + 1 %}\ {% set average_temp = average_temp + temp_bedroom %}\ {% endif %}\ \ {{ average_temp/active_rooms\|round(1) if active_rooms\>0 else 77 }}\ \ \ \ \ \ \ \ \ \ \ \ # Python Scripts {#python-scripts .western} \ ## Example 1 {#example-1 .western} Scripts are placed in a python_scripts folder under the configuration directory, in my case it is /home/homeassistant/.homeassistant/python_scripts. You then need to either restart Home Assistant or click RELOAD SCRIPTS under Configuration, General, Configuration Reloading. \ For what it's worth, I have been hunting for a solution to this problem and I finally decided to make a small script: \# python_scripts/set_state.py \ #================================================================================================== \# python_scripts/set_state.py #================================================================================================== \ #\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- \# Set the state or other attributes for the entity specified in the Automation Action #\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- \ inputEntity = data.get(\'entity_id\') if inputEntity is None: logger.warning(\"===== entity_id is required if you want to set something.\") else: inputStateObject = hass.states.get(inputEntity) inputState = inputStateObject.state inputAttributesObject = inputStateObject.attributes.copy() \ for item in data: newAttribute = data.get(item) logger.debug(\"===== item = {0}; value = {1}\".format(item,newAttribute)) if item == \'entity_id\': continue \# already handled elif item == \'state\': inputState = newAttribute else: inputAttributesObject\[item\] = newAttribute hass.states.set(inputEntity, inputState, inputAttributesObject) \ \ \ With this script in place, the action could be: \ action: service: python_script.set_state data_template: entity_id: Binary_sensor.sensor1 state: ON \ \ \ ## Example 2 {#example-2 .western} \ Start by enabling the Python script and create the first script. - [[[[Add to ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `configuration.yaml`{.western}[[[[: ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `python_script:`{.western} - [[[[Create folder ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `/python_scripts`{.western} - [[[[Create a file ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `/python_scripts/hello_world.py`{.western}[[[[ in the folder and give it this content:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ``` {.western style="line-height: 150%; text-align: left; orphans: 2; widows: 2; border: 1px solid #cccccc; padding: 0.02in; background: #ffffff"} # `data` is available as builtin and is a dictionary with the input data. name = data.get("name", "world") # `logger` and `time` are available as builtin without the need of explicit import. logger.info("Hello {} at {}".format(name, time.time())) ``` \ - Start Home Assistant to reload the script configuration. - [[[[Call your new ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `python_script.hello_world`{.western}[[[[ service (with parameters) from the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[Services]{style="font-weight: normal"}]{.underline}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}](https://my.home-assistant.io/redirect/developer_services){target="_blank"}[[[[, using the YAML mode.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ``` {.western style="line-height: 150%; text-align: left; orphans: 2; widows: 2; border: 1px solid #cccccc; padding: 0.02in; background: #ffffff"} service: python_script.hello_world data: name: "Input-Text" ``` [[[[Running this script show absolutely no output on the screen, but it logs with level ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `info`{.western}[[[[. You must have the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[Logger]{style="font-weight: normal"}]{.underline}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}](https://www.home-assistant.io/integrations/logger/)[[[[ enabled at least for level ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `info`{.western}[[[[.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[[[Your ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `confiuration.yaml`{.western}[[[[ should include something like this.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ``` {.western style="line-height: 150%; text-align: left; orphans: 2; widows: 2; border: 1px solid #cccccc; padding: 0.02in; background: #ffffff"} logger: default: info ``` \ \ \ \ \ # Flash ESPhome on ESP32 ESP2866 NodeMCU board {#flash-esphome-on-esp32-esp2866-nodemcu-board .western} \ Install using esphome-flasher: 1. download compiled firmware: In the Install menu click Manual Download. The compilation will now start and the .bin file will download when ready. 2. [[[[Go to the esphome-flasher GitHub page and download the flasher for the OS you're using. There is a esp home flash tool for macOS, Ubuntu and Windows :\ ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[**[https://github.com/esphome/esphome-flasher/releases]{style="background: transparent"}**]{.underline}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}](https://github.com/esphome/esphome-flasher/releases) 3. Connect your ESP board with USB to your laptop. 4. Open the flasher tool - **[[[**Serial port**]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}**[[[[: select COM port where the board is connected (there is probably only one option 😊).]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} - **[[[**Firmware**]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}**[[[[: Browse to the location where you downloaded your compiled firmware and select your firmware.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} - [[[[Click]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}**[[[[ ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[**Flash ESP **]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}**[[[[and wait]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 5. The ESP will be flashed now, you can follow the progress in the console window. When finished writing the firmware the ESP will restart and connect to your WiFi. ![](Home_assistant_html_c35888ec30af40ce.png){#Image1 align="bottom" width="302" height="190" border="0"} The ESP will be ready after it states that it's **ready for Over-The-Air Updates** and **that he API server is ready**. \ \ # Measuring DHT22 {#measuring-dht22 .western} 1. ***[***Note: ***]{style="letter-spacing: normal"}**[*[Step 1 and 2 have been changed with new UI and features in both Home Assistant and ESPHome. Read the ]{style="font-weight: normal"}*]{style="letter-spacing: normal"}[[*[**[updated article to flash ESPhome on your ESP32 / ESP2866 NodeMCU board]{style="background: transparent"}**]{.underline}*]{style="letter-spacing: normal"}](https://www.pieterbrinkman.com/2022/01/01/2022-update-flash-esphome-on-esp32-esp2866-nodemcu-board/)*[[ ]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[and skip step 1 and 2 below.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 3\. Wire the PMS5003 Particular Matter sensor and DHT22 to the ESP board - Wiring the DHT sensor is straight forward. - Connect the GND to any free GND pin on the ESP - Connect the VSS to any free 3V3 pin on the ESP - Connect the DATA to D4 on the ESP **[[[**4.** ]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[Configure ESPHome to read the measurements and supply them to Home Assistant]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}** Now it's time to expose the measurement values to Home Assistant. Open ESPHome and click EDIT on your node. The ESPHome configuration editor will now show. Add the following configuration at the bottom of the configuration. ``` {.western style="line-height: 160%; orphans: 2; widows: 2; border: none; padding: 0in; background: #f9f9f9"} uart: tx_pin: D6 rx_pin: D7 baud_rate: 9600 sensor: - platform: pmsx003 type: PMSX003 pm_1_0: name: "Particulate Matter <1.0µm Concentration" pm_2_5: name: "Particulate Matter <2.5µm Concentration" pm_10_0: name: "Particulate Matter <10.0µm Concentration" - platform: dht pin: D4 temperature: name: "Air quality meter Temperature" humidity: name: "Air quality meter Humidity" update_interval: 20s ``` When ready, press the Upload button and ESPHome will flash the new firmware OTA. Wait till ready and you should be good to go. [===\> this can be done wirelessl now]{style="background: #ffff00"} You can verify the new switch and interval by going to Home Assistant and open the device. You will see that it will have a Start Measuring switch. Enable the switch and notice that the measurements value start changing.   Wait a two minutes and notice that the switch will be turned on for 20 seconds and then turned off again. ![](Home_assistant_html_6645eb4607246ee.png){#Image2 align="bottom" width="276" height="39" border="0"} Now add the some graph to your dashboard. **6. Add air quality measurements to Home Assistant** [[[[For viewing the measurements in my lovelace dashboard I used a custom card called ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[**[mini-graph-card]{style="background: transparent"}**]{.underline}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}](https://github.com/kalkih/mini-graph-card){target="_blank"}[[[[, this card can be easily installed using HACS. I used the following Lovelace configuration.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ``` {.western style="font-variant: normal; letter-spacing: normal; font-style: normal; font-weight: normal; line-height: 160%; orphans: 2; widows: 2; background: #f9f9f9"} type: 'custom:mini-graph-card' name: Air quality inside icon: 'mdi:server' line_width: 2 animate: true hours_to_show: 24 points_per_hour: 1.5 entities: - entity: sensor.particulate_matter_1_0um_concentration name: 1 µm > - entity: sensor.particulate_matter_2_5um_concentration name: 2.5 µm > - entity: sensor.particulate_matter_10_0um_concentration name: 10 µm > ``` ### Adding measurements of outside air {#adding-measurements-of-outside-air .western style="font-variant: normal; letter-spacing: normal; font-style: normal; font-weight: normal; line-height: 140%; orphans: 2; widows: 2; margin-top: 0in; margin-bottom: 0in; border: none; padding: 0in"} [[[[To create additional context I also use]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[[ ]{style="background: transparent"}]{style="font-weight: normal"}]{.underline}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}](https://www.home-assistant.io/integrations/luftdaten/){target="_blank"}[[[[[**[Luftdaten integration]{style="background: transparent"}**]{.underline}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}](https://www.home-assistant.io/integrations/luftdaten/){target="_blank"}[[[[ to get outside air quality measurements nearby. This way you could automate opening windows or triggering ventilation to get better quality air from outside.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} Luftdaten is making the world a better place through community driven, open environmental data. The coverage within northern Europe is impressive. ![](Home_assistant_html_b7a34d7754cb750c.png){#Image3 align="bottom" width="819" height="367" border="0"} Exposing both inside and outside air quality with a vertical stack card will provide a nice comparison view. ![](Home_assistant_html_99d77d30d22d0a29.png){#Image4 align="bottom" width="322" height="369" border="0"} That's it. Now it's time to start measuring and learn more about the air quality in your house. Let me know if you have any questions and if you managed to make it work! \ \ # Working DHT11 on Berrbase NodeMCU ESP32 {#working-dht11-on-berrbase-nodemcu-esp32 .western} ESP32 NodeMCU Development Board Artikel-Nr.: NMCU-ESP32 \| EAN: 4251266700609 \ \ ## Connection {#connection .western} DHT on breakout board with SMD resistors and LED was used → might need 10 kOhm resistor for bare DHT11 \ 12 = GPIO12 VCC = 3.3V GND = Gnd \ \ ## test-esp32nmcu.yaml → test-esp32nmcu\_\_\_working_20221211.bin {#test-esp32nmcu.yaml-test-esp32nmcu___working_20221211.bin .western} [esphome:]{style="background: #fffffe"} [  [name]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[test-esp32nmcu]{style="font-weight: normal"}]{style="background: #fffffe"} \ [esp32:]{style="background: #fffffe"} [  [board]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[esp32dev]{style="font-weight: normal"}]{style="background: #fffffe"} [  [framework]{style="font-weight: normal"}[:]{style="font-weight: normal"}]{style="background: #fffffe"} [    [type]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[arduino]{style="font-weight: normal"}]{style="background: #fffffe"} \ [\# Enable logging]{style="background: #fffffe"} [logger:]{style="background: #fffffe"} \ [\# Enable Home Assistant API]{style="background: #fffffe"} [api:]{style="background: #fffffe"} [  [encryption]{style="font-weight: normal"}[:]{style="font-weight: normal"}]{style="background: #fffffe"} [    [key]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[\"MI1DnjQWboPRECsx7PlLQS4BiR7SQQSpYczCuzpupS4=\"]{style="font-weight: normal"}]{style="background: #fffffe"} \ [ota:]{style="background: #fffffe"} [  [password]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[\"bb47b47929f02cd349e51eddd8602edb\"]{style="font-weight: normal"}]{style="background: #fffffe"} \ [wifi:]{style="background: #fffffe"} [  [#ssid: !secret wifi_ssid]{style="font-weight: normal"}]{style="background: #fffffe"} [  [#password: !secret wifi_password]{style="font-weight: normal"}]{style="background: #fffffe"} [  [#ssid: \"FRITZ!Box Gastzugang\"]{style="font-weight: normal"}]{style="background: #fffffe"} [  [#password: \"zakihasalittlewiener\"]{style="font-weight: normal"}]{style="background: #fffffe"} [  [ssid]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[\"FRITZ!Box 7530 GD\"]{style="font-weight: normal"}]{style="background: #fffffe"} [  [password]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[\"78302839617779115068\"]{style="font-weight: normal"}]{style="background: #fffffe"} \ [  [\# Optional manual IP]{style="font-weight: normal"}]{style="background: #fffffe"} [  [manual_ip]{style="font-weight: normal"}[:]{style="font-weight: normal"}]{style="background: #fffffe"} [    [static_ip]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[192.168.178.42]{style="font-weight: normal"}]{style="background: #fffffe"} [    [gateway]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[192.168.178.1]{style="font-weight: normal"}]{style="background: #fffffe"} [    [subnet]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[255.255.255.0]{style="font-weight: normal"}]{style="background: #fffffe"} \ [  [\# Enable fallback hotspot (captive portal) in case wifi connection fails]{style="font-weight: normal"}]{style="background: #fffffe"} [  [ap]{style="font-weight: normal"}[:]{style="font-weight: normal"}]{style="background: #fffffe"} [    [ssid]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[\"Test-Esp32Nmcu Fallback Hotspot\"]{style="font-weight: normal"}]{style="background: #fffffe"} [    [password]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[\"pJDTx6ABN80C\"]{style="font-weight: normal"}]{style="background: #fffffe"} \ [captive_portal:]{style="background: #fffffe"} \ [sensor:]{style="background: #fffffe"} [  [- ]{style="font-weight: normal"}[platform]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[dht]{style="font-weight: normal"}]{style="background: #fffffe"} [    [pin]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[12]{style="font-weight: normal"}]{style="background: #fffffe"} [    [temperature]{style="font-weight: normal"}[:]{style="font-weight: normal"}]{style="background: #fffffe"} [      [name]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[\"Air quality meter Temperature\"]{style="font-weight: normal"}]{style="background: #fffffe"} [    [humidity]{style="font-weight: normal"}[:]{style="font-weight: normal"}]{style="background: #fffffe"} [      [name]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[\"Air quality meter Humidity\"]{style="font-weight: normal"}]{style="background: #fffffe"} [    [update_interval]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[10s]{style="font-weight: normal"}]{style="background: #fffffe"} [    [model]{style="font-weight: normal"}[: ]{style="font-weight: normal"}[DHT11]{style="font-weight: normal"}]{style="background: #fffffe"} \ \ \ ## flashing using ESPHome-Flasher-1.4.0-Windows-x64 {#flashing-using-esphome-flasher-1.4.0-windows-x64 .western} \ see above \ \ \ ## activate the sensor in HA {#activate-the-sensor-in-ha .western} after some minutes, the ESP32 should appear under Integrations with the initiall assigned name ![](Home_assistant_html_3f1f9bd2d382bd8b.png){#Image5 align="left" width="362" height="212" border="0"}\ \ \ \ \ \ \ \ \ \ \ ![](Home_assistant_html_3736a24f705ebf1f.png){#Image6 align="left" width="643" height="151" border="0"} ![](Home_assistant_html_da20b167c94ec7a9.png){#Image7 align="left" width="643" height="422" border="0"}\ \ \ \ # How to integrate full functionality of Bosch smart home components {#how-to-integrate-full-functionality-of-bosch-smart-home-components .western} \ shc11d14d 192.168.178.34 \ \ ## Connect via Samba share {#connect-via-samba-share .western} \ add a Network Location in Windows Explorer \ LAN: [\\\\192.168.178.32\\config](smb://192.168.178.32/config) WLAN: [\\\\192.168.17](smb://192.168.179.43/config)[9](smb://192.168.179.43/config)[.](smb://192.168.179.43/config)[4](smb://192.168.179.43/config)[3\\config](smb://192.168.179.43/config) → not working?? \ user: homeassistant pass: bora \ \ ## cop following folders into the config folder on RaPi: {#cop-following-folders-into-the-config-folder-on-rapi .western} - custom_components - images - tests \ ## after restarting HA all components and functions should be available {#after-restarting-ha-all-components-and-functions-should-be-available .western} \ \ \ \ \ # Dashboard individualization {#dashboard-individualization .western} [[[[If you have not enabled custom themes already, add this to your ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}**[[[**configuration.yaml**]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}**[[[[ file and reboot Home Assistant:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ``` {.western style="orphans: 2; widows: 2; border: none; padding: 0in; background: #eeeeee"} frontend: themes: !include_dir_merge_named themes ``` \ \ \ \ \ \ # Guest access {#guest-access .western} create a dedicated account for gests: user: Guest pass: guest [[[[open http://]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[192.168.178.32]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}](smb://192.168.178.32/config)[[[[:8123]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} \ \ \ \ [[[[[https://community.home-assistant.io/t/configuring-a-real-guest-user-an-alternative-approach/455910]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}](https://community.home-assistant.io/t/configuring-a-real-guest-user-an-alternative-approach/455910) Hi, I'd like to share the way I approached the configuration of a guest user in my HA and how I worked around some well-known limitations, especially those related to the lack of a global sidebar / default dashboard configuration. My requirements: 1. Guest user allowed to login only from the internal network 2. Only specific views available to the guest user 3. **[[[**No need for the guest user to switch to a different dashboard once logged in**]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}** 4. **[[[**No unnecessary items to show up in the sidebar for the guest user (including logbook, media, history, etc)**]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}** [[[[Basically a sort of kiosk mode without using frontend hacks (]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[[https://github.com/maykar/kiosk-mode ]{style="background: transparent"}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="text-decoration: none"}]{style="font-variant: normal"}](https://github.com/maykar/kiosk-mode) [2](https://github.com/maykar/kiosk-mode)[[[[ is now deprecated, ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[[https://github.com/Villhellm/custom-sidebar]{style="background: transparent"}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="text-decoration: none"}]{style="font-variant: normal"}](https://github.com/Villhellm/custom-sidebar)[[[[ is no more working in latest HA versions, ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[[https://github.com/galloween/custom-sidebar-v2]{style="background: transparent"}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="text-decoration: none"}]{style="font-variant: normal"}](https://github.com/galloween/custom-sidebar-v2)[[[[ works only for admin users).]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[[[Requirement #1 is the simplest: just create a guest user with a simple password and toggle the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Can only log in from the local network`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ option.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[[[Requirement #2 is also stright-forward: create a dashboard, add a View for the guest user, under ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Visibility`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ allow the guest user only to access that view, disable the guest user to access any other view of the dashboard.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[[[Requirement #3 is tricky. As we know there is no global default dashboard configuration, it is ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}*[[[[per-user]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}*[[[[ / ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}*[[[[per-device]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}*[[[[.\ This means the guest user, upon the first login, lands in the over-complicated ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Overview`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ dashboard and should go in his profile to change the default dashboard. Not something I want them to do neither I want to do it on their behalf.\ After reading tons of posts here, the simplest approach I found is to take control of the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Overview`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ dashboard (if I need the same content I can always create a brand new admin-only dashboard) and put all my views there (both for regular and guest users).\ True, the name of the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Overview`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ dashboard cannot be change as well as the icon but at least in this way every user (guests or not), when logging in, will land to a dashboard populated with the contents I want.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[[[Requirement #4 was also a challenge. As we know also the order in which the items show up in the sidebar and which one is hidden or not is ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}*[[[[per-user]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}*[[[[ / ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}*[[[[per-device]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}*[[[[. The way I approched it was the following:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} - [[[[I migrated all my dashbaords into views in order to have a single dashboard only (the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Overview`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ one). This is not mandatory of course, just an implementation choice, to avoid taking care of the order in which dashbaords are listed in the sidebar]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} - [[[[I disabled in my configuration ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Energy`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[, ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Map`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ and ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Media`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ since not using them at all (Ref. ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[[How can I hide the Energy/Media/Map tabs from the sidebar? - #9 by petro ]{style="background: transparent"}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="text-decoration: none"}]{style="font-variant: normal"}](https://community.home-assistant.io/t/how-can-i-hide-the-energy-media-map-tabs-from-the-sidebar/433297/9) [5](https://community.home-assistant.io/t/how-can-i-hide-the-energy-media-map-tabs-from-the-sidebar/433297/9)[[[[) resulting in the entries to disappear from the sidebar. This required switching from ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`default_config`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ to a long list taken from ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[[Default Config - Home Assistant ]{style="background: transparent"}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="text-decoration: none"}]{style="font-variant: normal"}](https://www.home-assistant.io/integrations/default_config/) [1](https://www.home-assistant.io/integrations/default_config/)[[[[ and commeting out those not needed]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} - [[[[For ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Logbook`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ and ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`History`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[, which are something I need as an admin but don't want the other users to access and see, I made them available for admin users only, opting for the approach described in ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[[Admin only access for Logbook and History menus - #44 by dan_mc ]{style="background: transparent"}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="text-decoration: none"}]{style="font-variant: normal"}](https://community.home-assistant.io/t/admin-only-access-for-logbook-and-history-menus/187722/44) [8](https://community.home-assistant.io/t/admin-only-access-for-logbook-and-history-menus/187722/44)[[[[. This required to copy the code of the two components from ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`/usr/src/homeassistant/homeassistant/components`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ or ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[core/homeassistant/components at master · home-assistant/core · GitHub ](https://github.com/home-assistant/core/tree/master/homeassistant/components) [3](https://github.com/home-assistant/core/tree/master/homeassistant/components)[[[[ into ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`config/custom_components`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[, add ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`version`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ to the manifest file and making the views admin-only in ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`async_register_built_in_panel()`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[ as described in the other post. Of course maintenance of this could be time-consuming since theoretically the code should be updated upon each upgrade]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} In this way not only guest user but also any user on any deice, has no need to touch the sidebar, hide unnecessary entries or set a default dashboard\ Hope can be helpful Thanks \ \ \ \ \ \ \ \ # Influx DB storing of Arduino data {#influx-db-storing-of-arduino-data .western} Example 1 \ \ [Example 2]{style="background: #ffff00"} [[http://www.iotsharing.com/2021/01/building-smart-home-system-with-home.html]{style="background: #ffff00"}](http://www.iotsharing.com/2021/01/building-smart-home-system-with-home.html) \ \ Example 3 \ \ Example 4 \ \ ssh into rapi via PUTT: \ \ \ \ \ \ https://www.youtube.com/watch?v=U8f5FcnKdyw \ [Example 5]{style="background: transparent"} [[https://www.dummylabs.com/post/2019-01-13-influxdb-part1/]{style="background: transparent"}](https://www.dummylabs.com/post/2019-01-13-influxdb-part1/) \ \ \ \ \ \ # Home Assistant with InfluxDB on Synology {#home-assistant-with-influxdb-on-synology .western} \ \ \ # Home Assistant on Linux VM with Docker, reverse proxy, MQTT and Node Red {#home-assistant-on-linux-vm-with-docker-reverse-proxy-mqtt-and-node-red .western} [[https://selmi.medium.com/home-assistant-in-docker-the-ultimate-setup-16d4669dcb7]{style="background: #ffff00"}](https://selmi.medium.com/home-assistant-in-docker-the-ultimate-setup-16d4669dcb7) \ \ \ \ # Presence detection options {#presence-detection-options .western} \ \ # Automation of dumb devices {#automation-of-dumb-devices .western} \ \ \ \ # Using external Data Disk {#using-external-data-disk .western} \ \ \ \ Home Assistant Operating System supports storing most data on an external storage medium (e.g. USB attached SSD or HDD). This data disk contains not only user data but also most of the Home Assistant software as well (Core, Supervisor etc.). This means a fast data disk will make the system overall much faster. ![Graphics showing the architecture of the data disk feature](Home_assistant_html_eb38d3613d558289.png){#Image8 align="bottom" width="762" height="353" border="2"} [[[[The data disk feature can be used on an existing installation without losing data: The system will move existing data to the external data disk automatically. However, it is recommended to create and download a full ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[Backup]{style="font-weight: normal"}]{.underline}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}](https://www.home-assistant.io/common-tasks/os/#backups)[[[[ before proceeding!]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[All data on the target disk will be overwritten!]{style="background: #f7f9e1"}]{style="display: inline-block; border: none; padding: 0in"} [[The storage capacity of the external data disk must be larger than the storage capacity of the existing (boot) disk.]{style="background: #e7f2fa"}]{style="display: inline-block; border: none; padding: 0in"} [[[[[If you have been using a data disk previously with Home Assistant Operating System, you need to use your host computer to delete all partitions ]{style="font-variant: normal"}]{style="background: #e7f2fa"}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"} [*before*[[[[[ using it as a data disk again.]{style="font-variant: normal"}]{style="background: #e7f2fa"}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="background: #e7f2fa"} ### USING UI TO MOVE THE DATA PARTITION {#using-ui-to-move-the-data-partition .western align="left" style="font-variant: normal; font-style: normal; font-weight: normal; line-height: 100%; orphans: 2; widows: 2; border: none; padding: 0in"} 1. Connect the data disk to your system. 2. [[[[Go to ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}**[[[[[**Settings \> System \> Storage**]{.underline}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}](https://my.home-assistant.io/redirect/storage){target="_blank"}**[[[[ in the UI.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 3. Press the three dots on the top right and choose "Move datadisk" 4. Select the data disk from the list of available devices. 5. Press "Move". ![Screenshot of the "Move datadisk" feature](Home_assistant_html_bb6004c436b08021.png){#Image9 width="481" height="248" border="2"} ### USING CLI TO MOVE THE DATA PARTITION {#using-cli-to-move-the-data-partition .western align="left" style="font-variant: normal; font-style: normal; font-weight: normal; line-height: 100%; orphans: 2; widows: 2; border: none; padding: 0in"} To see the current data disk use: ``` {.western style="line-height: 150%; text-align: left; orphans: 2; widows: 2; border: 1px solid #cccccc; padding: 0.02in; background: #ffffff"} $ ha os info ... data_disk: /dev/mmcblk1p4 ... ``` [Sh]{style="display: inline-block; border: none; padding: 0in"} Copy [[[[To get a list of potential targets which can be used by ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `datadisk`{.western}[[[[:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ``` {.western style="line-height: 150%; text-align: left; orphans: 2; widows: 2; margin-bottom: 0.2in; border: 1px solid #cccccc; padding: 0.02in; background: #ffffff"} ha os datadisk list ``` [Sh]{style="display: inline-block; border: none; padding: 0in"} Copy [[[[To initiate the move to the new data disk use the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `move`{.western}[[[[ command:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ``` {.western style="line-height: 150%; text-align: left; orphans: 2; widows: 2; margin-bottom: 0.2in; border: 1px solid #cccccc; padding: 0.02in; background: #ffffff"} ha os datadisk move /dev/sdx ``` [Sh]{style="display: inline-block; border: none; padding: 0in"} Copy The system will prepare the data disk and immediately reboot. The reboot will take 10 minutes or more depending on the speed of the new data disk; please be patient! [[Using an USB attached SSD can draw quite some power. For instance on Raspberry Pi 3 the official Raspberry Pi power supply (PSU) only provides 2.5A which can be too tight. Use a more powerful power supply if you experience issues. Alternatively use a powered USB hub. Connect the Hub to one of the USB slots of your Raspberry Pi, and connect the SSD to the Hub. In this setup the power supply of the Hub will power the attached device(s).]{style="background: #e7f2fa"}]{style="display: inline-block; border: none; padding: 0in"} \ \ \ \ \ # Save DB on USB stick/drive (Hassio) {#save-db-on-usb-stickdrive-hassio .western} \ \ \ # Running Home Assistant on a Raspberry Pi 3 from an external hard drive {#running-home-assistant-on-a-raspberry-pi-3-from-an-external-hard-drive .western} \ \ \ \ \ \ # MQTT with RP2040 {#mqtt-with-rp2040 .western} \ \ \ \ \ \ # Weather {#weather .western} ## accuweather {#accuweather .western} BoraEr ineedweather_90 Follow instruction here to create new App: app: ha_weather API key: GV0GKNtlJZNUHYZ5YNW6YGySLVVz0Huq \ search location key: \ Leinfelden: 2604235, \ \ create a sensor from the weather attributes to plot the data: \ \# Temperatur-Attribut als Extra-Wert sensor\ - platform: template\ sensors:\ norwegian_temperature:\ friendly_name: \"met.no Temperatur Vorhersage\"\ unit_of_measurement: \'°C\'\ value_template: \"{{ state_attr(\'weather.home_musberg\', \'temperature\') }}\" \ ## openweathermap {#openweathermap .western} \ BoraEr ineedweather_90 \ \ \ ## animated icons in weather card {#animated-icons-in-weather-card .western} \ \ \ \ # read content of DB {#read-content-of-db .western} \ \ \ \ \ # InfluxDB: Removing or deleting data {#influxdb-removing-or-deleting-data .western} \ \ # Read external InfluxDB in Home Assistant as a sensor {#read-external-influxdb-in-home-assistant-as-a-sensor .western} \ # Using both MariaDB and InfluxDB {#using-both-mariadb-and-influxdb .western} \ \ # InfluxDB hassio add-on: changing default database location {#influxdb-hassio-add-on-changing-default-database-location .western} \ \ location of influxdb database: \ \ \ \ # Remote access {#remote-access .western} \ \ \ ## [create ]{style="font-weight: normal"}[DuckDNS ]{style="font-weight: normal"}[subdomain]{style="font-weight: normal"}[:]{style="font-weight: normal"} {#create-duckdns-subdomain .western} Duckdns.org account boraers@googlemail.com type free token 799093a4-0b34-454f-99cb-25a4637bf404 Domain: https://habora.duckdns.org \ [attention: if router is restartet, configuration of duckdns has to be updated!]{style="background: #ffff00"} \ to be accessed via the HA app: [https://habora.duckdns.org:](https://habora.duckdns.org:8123/)[8123/](https://habora.duckdns.org:8123/) \ https://192.168.178.32:8123/ \ https://habora.duckdns.org habora.duckdns.org duckdns.org ## edit configuration of DuckDNS addon: {#edit-configuration-of-duckdns-addon .western} domains:\ - https://habora.duckdns.org\ token: 799093a4-0b34-454f-99cb-25a4637bf404\ aliases: \[\]\ lets_encrypt:\ accept_terms: true\ algo: secp384r1\ certfile: fullchain.pem\ keyfile: privkey.pem\ seconds: 300 \ \ ## install Let\'s Encrypt addon {#install-lets-encrypt-addon .western} \ \ domains:\ - habora.duckdns.org\ email: boraers@googlemail.com\ keyfile: privkey.pem\ certfile: fullchain.pem\ challenge: http\ dns: {} \ ## port forwarding in fritz.box {#port-forwarding-in-fritz.box .western} ![](Home_assistant_html_382f235fa92119d6.png){#Image10 align="bottom" width="270" height="286" border="0"} \ ![](Home_assistant_html_b6f47a768db3e3a0.png){#Image13 align="bottom" width="285" height="305" border="0"} \ ![](Home_assistant_html_aa3e230b366baeb8.png){#Image11 align="bottom" width="643" height="205" border="0"} \ \ ## Start Let\'s Encrypt addon {#start-lets-encrypt-addon .western} \ ![](Home_assistant_html_b50f5b35e0e18814.png){#Image12 align="bottom" width="643" height="460" border="0"} \ \ ## check access via calling the subomain (no https yet) {#check-access-via-calling-the-subomain-no-https-yet .western} → this can be done already from the internet → the login screen of HA should appear \ \ ## Enable HTTPS on your HA Install {#enable-https-on-your-ha-install .western} \ edit configuration.yaml: http: ssl_certificate: /ssl/fullchain.pem ssl_key: /ssl/privkey.pem \ \ attention: different HA installation need other paths: Home Assistant OS or Supervised: → Let\'s Encrypt addon must be installed! http: ssl_certificate: /ssl/fullchain.pem ssl_key: /ssl/privkey.pem \ Home Assistant Container: You'll need to mount the location with your SSL keys and certificates to /ssl/ in the container. http: ssl_certificate: /ssl/fullchain.pem ssl_key: /ssl/privkey.pem \ Home Assistant Core: http: ssl_certificate: /etc/letsencrypt/live/hass.example.com/fullchain.pem ssl_key: /etc/letsencrypt/live/hass.example.com/privkey.pem \ \ ## restart HA {#restart-ha .western} after restart, HA should only be available via https: internall: externall: \ \ \ ## Harden the Home Assistant Remote Access Security more {#harden-the-home-assistant-remote-access-security-more .western} Harden the Home Assistant remote access even more by enabling MFA \ Activating ip_ban_option and Multi-factor Authentication Modules is a must if you enable your Home Assistant Remote Access in the way that i'm showing with the port forwarding and SSL. So don't skip this! \ \ \ \ \ ## Fritz Box Aktualisierungsanforderung mit DuckDNS {#fritz-box-aktualisierungsanforderung-mit-duckdns .western} 1. Klicken Sie in der Benutzeroberfläche der FRITZ!Box auf \"Internet\". 2. Klicken Sie im Menü \"Internet\" auf \"Freigaben\". 3. Klicken Sie auf die Registerkarte \"DynDNS\". 4. Aktivieren Sie die Option \"DynDNS benutzen\". 5. Tragen Sie im Feld \"Update-URL\" die Update-URL für Ihren Anbieter ein. Falls die Aktualisierungsanforderung sowohl für IPv4 als auch für IPv6 durchgeführt werden soll und Ihr Anbieter für IPv4 und IPv6 verschiedene Update-URLs erwartet, tragen Sie beide Update-URLs mit einem Leerzeichen getrennt ein. 1. Hinweis:Beispiele für Update-URLs verschiedener Anbieter finden Sie unten in dieser Anleitung. Falls Ihr Anbieter da nicht genannt wird, können Sie die Update-URL wie im Abschnitt \"Update-URL selbst erstellen\" beschrieben selbst erstellen. 6. Tragen Sie im Feld \"Domainnamen\" den Domainnamen ein, den Sie bei Ihrem Anbieter festgelegt haben. 7. Tragen Sie im Feld \"Benutzername\" den Benutzernamen Ihres Benutzerkontos beim Anbieter ein. 8. Tragen Sie im Feld \"Kennwort\" das Kennwort Ihres Benutzerkontos beim Anbieter ein. 9. Klicken Sie zum Speichern der Einstellungen auf \"Übernehmen\". 10. Jetzt übermittelt die FRITZ!Box nach dem Herstellen jeder Internetverbindung ihre jeweils aktuellen IP-Adressen an den Anbieter und ist somit immer unter ihrem individuellen Dynamic-DNS-Domainnamen erreichbar. \ \ DuckDNS.org Die Update-URL für die IPv4- und die IPv6-Adresse: https://www.duckdns.org/update?domains=\&token=\&ip=\&ipv6=\ \ \ \ \ # GoogleNest TTS issues after setting up ssl {#googlenest-tts-issues-after-setting-up-ssl .western} \ \ DNS-Rebind-Schutz \ \ \ \ \ # formatting of dates {#formatting-of-dates .western} \ filename: /Data/cams/{{ now().strftime(\"%Y-%m-%d %H.%M.%S\") }} {{ entity_id.name }}.jpg filename: '/tmp/armcrest_camera\_{{ now().strftime(\"%Y%m%d-%H%M%S\") }}.jpg' filename: \'/home/homeassistant/.homeassistant/www/armcrest_camera\_{{ now().strftime(\"%Y%m%d-%H%M%S\") }}.jpg\' \ filename: \>-\ /config/www/rtsp_esp32\_{{ \"%04d\"\|format(now().year) }}\_{{\ \"%02d\"\|format(now().month) }}\_{{ \"%02d\"\|format(now().day)\ }}\_{{ \"%02d\"\|format(now().hour) }}\_{{ \"%02d\"\|format(now().minute) }}\_{{ \"%02d\"\|format(now().second) }}.jpeg \ \ \ # HA Examples {#ha-examples .western} \ \ \ \ \ \ # Müllkalender {#müllkalender .western} Der folgende Eintrag muss in die configuration.yaml waste_collection_schedule: sources: \- name: ics args: file: \"www/abfall.ics\" customize: \- type: Restabfall alias: Restabfall icon: mdi:trash-can \- type: Papiertonne alias: Papiertonne icon: mdi:trash-can \- type: Bioabfall alias: Bioabfall icon: mdi:trash-can fetch_time: \"04:00\" day_switch_time: \"10:00\" \ sensor: \- platform: waste_collection_schedule name: Papierabfall_date value_template: \'{{value.date.strftime(\"%d.%m.%Y\")}}\' types: \- Papiertonne \- platform: waste_collection_schedule name: Papierabfall_collection value_template: \"{{value.daysTo}}\" types: \- Papiertonne \- platform: waste_collection_schedule name: Restmuelltonne_date value_template: \'{{value.date.strftime(\"%d.%m.%Y\")}}\' types: \- Restabfall \- platform: waste_collection_schedule name: Restmuelltonne_collection value_template: \"{{value.daysTo}}\" types: \- Restabfall \- platform: waste_collection_schedule name: Biotonne_date value_template: \'{{value.date.strftime(\"%d.%m.%Y\")}}\' types: \- Bioabfall \- platform: waste_collection_schedule name: Biotonne_collection value_template: \"{{value.daysTo}}\" types: \- Bioabfall \- platform: waste_collection_schedule name: next_waste_collection_daysto details_format: upcoming value_template: \'{{value.types\|join(\", \")}} in {{value.daysTo}} Tagen\' #button-card# \- platform: waste_collection_schedule name: MyButtonCardSensor value_template: \'{{value.types\|join(\", \")}}\|{{value.daysTo}}\|{{value.date.strftime(\"%d.%m.%Y\")}}\|{{value.date.strftime(\"%a\")}}\' \ \ Folgende Integrationen aus dem HACS Store sind dafür notwendig: custom-cards/button-card custom:multiple-entity-row \ type: entities entities: \- entity: sensor.restmuelltonne_date style: \| :host { color: grey; } icon: \'mdi:delete-empty\' show_state: false type: \'custom:multiple-entity-row\' name: Schwarze Tonne secondary_info: last-changed entities: \- entity: sensor.restmuelltonne_collection name: Abholung in unit: Tage(n) \- entity: sensor.restmuelltonne_date name: Datum \- entity: sensor.biotonne_date style: \| :host { color: brown; } icon: \'mdi:bio\' show_state: false type: \'custom:multiple-entity-row\' name: Braune Tonne secondary_info: last-changed entities: \- entity: sensor.biotonne_collection name: Abholung in unit: Tage(n) \- entity: sensor.biotonne_date name: Datum \- entity: sensor.papierabfall_date style: \| :host { color: blue } icon: \'mdi:tree\' show_state: false type: \'custom:multiple-entity-row\' name: Blaue Tonne secondary_info: last-changed entities: \- entity: sensor.papierabfall_collection name: Abholung in unit: Tage(n) \- entity: sensor.papierabfall_date name: Datum \- entity: sensor.mybuttoncardsensor type: \'custom:button-card\' layout: icon_name_state2nd show_label: true label: \| \[\[\[ var days_to = entity.state.split(\"\|\")\[1\] if (days_to == 0) { return \"Heute\" } else if (days_to == 1) { return \"Morgen\" } else { return \"in \" + days_to + \" Tagen\" } \]\]\] show_name: true name: \| \[\[\[ return entity.state.split(\"\|\")\[0\] \]\]\] state: \- color: red operator: template value: \'\[\[\[ return entity.state.split(\"\|\")\[1\] == 0 \]\]\]\' \- color: orange operator: template value: \'\[\[\[ return entity.state.split(\"\|\")\[1\] == 1 \]\]\]\' \- value: default \ \ \ \ \ \ # connect LED strip {#connect-led-strip .western} **Connection step:** The app name is \"Smart Life\", please search for and install the app on Google Play or Apple Store. Step 1: Scan code download APP Step 2: Make sure your phone is connected to wifi Step 3: Press \"+\" to add the button and select \"Lighting\" Step 4: Long press the controller to make the light flash Step 5: Press the Confirm Flash button on your phone Step 6: Enter the WiFi password and confirm Step 7: Wait for the connection to succeed Step 8: Start using \ boraers@gmail.com tuyaforsmarthome_90 \ \ Cloud \> Development \> \ boraers@googlemail.com tuyaforsmarthome_90 \ UserID: boraers@gmail.com \ Access ID/Client ID: 9wk4ecspwhveyycxev3r Access Secret/Client Secret: 2c0ee61b3377443a88a94a611e1563e1 Project Code: p1671915179957wxkk7v \ \ → tuya integration in HA should recognize device → enter credentials \ \ \ Add smart life to Home Assistant You probably know us, we don't want to use more apps. we want to control everything from one central home automation platform: Home Assistant in our case. As told before: Make sure to can devices added in Smart Life before you can add them into Home Assistant. \ For all the parameters and settings: https://www.home-assistant.io/components/tuya/ \ A sample configuration from me. 31 is the country code of The Netherlands. You can find your country codes in the second column of this site. The entry smart_life is the Tuya platform where I am registered. Add this into your own configuration.yaml and restart your Home Assistant instance. After starting it collects the compatible devices from Tuya. In my case only the Blitzwolf light. \ tuya: username: xxx password: xxx country_code: 49 platform: smart_life After changing your configuration, restart and check out Unused devices. In my case I have 2 products in Smart Life and only one is supported for now in Home Assistant: the Blitzwolf Led Light strip. \ \ \ \ \ # Use local Tuya {#use-local-tuya .western} Add your bulbs as new devices with the following settings: ID: 20 Brightness: 22 Color Temperature: 23 Brightness Lower Value: 0 Brightness Upper Value: 1000 Color Mode: 21 Color: 24 Minimum Color Temperature: 2701 Maximum Color Temperature: 6499 Scene: 25 \ \ ## Get local key tuya since June 2022: {#get-local-key-tuya-since-june-2022 .western} \ \ 45625580bcddc2a2bf27: \"local_key\": \"4b1e7572e8b54ca3\", Hama_LED bf3d5d9718ef1b2a8c5asm: \"local_key\": \"67426b621cacaf5f\", Treppe \ \ \ Issue: Connection to device succeeded but no datapoints found, please try again. Create a new issue and include debug logs if problem persists Adding in config manual works. ``` {.western style="line-height: 145%; orphans: 2; widows: 2; border: none; padding: 0in"} localtuya: - host: 192.168.1.215 device_id: xxx local_key: xxx friendly_name: Tuya Device protocol_version: "3.3" entities: - platform: sensor friendly_name: Plug Voltage id: 20 scaling: 0.1 # Optional device_class: voltage # Optional unit_of_measurement: "V" # Optional ``` \ \ \ \ \ \ # Flash Tasmota on Hama LED {#flash-tasmota-on-hama-led .western} \ Check compatibilit \ \ \ \ **Flashing:** \ sudo apt-get update sudo apt-get upgrade sudo apt-get install git cd \~ git clone https://github.com/ct-Open-Source/tuya-convert cd tuya-convert sudo ./install_prereq.sh sudo ./start_flash.sh \ **[How To Use Tuya Convert On Raspberry Pi (Step-by-step Guide)]{style="background: #ffff00"}** sudo apt-get update sudo apt-get upgrade sudo raspi-config → network options → select WiFi and enter your location and credentials → finish rfkill unblock wifi sudo apt-get install git cd \~ git clone https://github.com/ct-Open-Source/tuya-convert cd tuya-convert && sudo su sudo ./install_prereq.sh sudo ./start_flash.sh \ → using tasmota-xxxxx SSID → 192.168.4.1 \ \ **timeout issue with latest Ri OS version!** solution: install old version: \ **issue**: N: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details. **solution**: apt-get \--allow-releaseinfo-change update \ \ \ \ \ \ Hama 10W 806lm RGBW Bulb (00176547) {\"NAME\":\"Hama Smart WiF\",\"GPIO\":\[0,0,0,0,37,40,0,0,38,0,39,0,0\],\"FLAG\":0,\"BASE\":18} \ In order to turn on discovery mode so that Home Assistant can auto discover our device, we must turn on SetOption 19. Simply enter the following command in the Tasmota console. **SetOption19 onws** \ \ \ \ **Whether your wireless card support Access Point mode.** sudo apt-get update sudo apt-get -y install aptitude sudo aptitude install iw iw list → Look for supported interface section, where it should be a entry called AP like below \ **updateBroadcom wifi driver** sudo lshw -C network sudo apt install firmware-b43-installer sudo apt install linux-firmware sudo reboot \ \ # simulate sunrise {#simulate-sunrise .western} Sunrise: \ \ \ \ \ \ \ \ # RP2040 Micropython {#rp2040-micropython .western} ## PIR sensor + MQTT {#pir-sensor-mqtt .western} \ \ install MicroPython firmware: 1\. Download the MicroPython UF2 file for your model of Raspberry Pi Pico. \ 2\. Push and hold the BOOTSEL button on the Pico, then connect to your computer using a micro USB cable. Release BOOTSEL once the drive RPI-RP2 appears on your computer. \ 3\. Drag and drop the UF2 file on to the RPI-RP2 drive. The Raspberry Pi Pico will reboot and will now run MicroPython. \ \ \ ## Ultrasonic sensor {#ultrasonic-sensor .western} \ \ \ \ \ ## Adafruit QT Py RP2040 {#adafruit-qt-py-rp2040 .western} \ Micopthon formware: \ \ \ \ # Seeed Xiao ESP32C3 {#seeed-xiao-esp32c3 .western} \ \ \ \ \ # Force influxdb to update in regular intervals {#force-influxdb-to-update-in-regular-intervals .western} \ \ \ # water meter; AI-on-the-edge {#water-meter-ai-on-the-edge .western} \ \ \ \ \ \ \ \ # water meter with image recognition on PC {#water-meter-with-image-recognition-on-pc .western} \ \ tesseract input.txt output.txt -l eng \--psm 3 \ \ [need to add esseract to sstempath!!!]{style="background: #ffff00"} cd C:\\Users\\Bora_2\\Downloads tesseract ziffer4.jpg stdout -l eng tesseract ziffer4.jpg output.txt tesseract input.txt output.txt -l eng \ \ \ [[https://github.com/tesseract-ocr/tesstrain]{style="background: #ffff00"}](https://github.com/tesseract-ocr/tesstrain) make training MODEL_NAME=test-model DATA_DIR=/data GROUND_TRUTH_DIR=/data/foo-ground-truth \ \ install GNU make on Win10 1. install software 2. add to PATH 1. C:\\Program Files (x86)\\GnuWin32\\bin 2. Copy the path and jump to edit environment variables from windows search 3. Click Environment Variables. 4. Under user variables, find Path and click Edit. 5. Hit New, paste the copied path and hit Ok. 6. Hit OK on all other windows also. 3. Now open a fresh CMD/Terminal and type make and and hit Enter. 4. \ \ pip install pytesseract pip install numpy pip install opencv-python \ \ \$ tesseract --help-psm Page segmentation modes: 0 Orientation and script detection (OSD) only. 1 Automatic page segmentation with OSD. 2 Automatic page segmentation, but no OSD, or OCR. (not implemented) 3 Fully automatic page segmentation, but no OSD. (Default) 4 Assume a single column of text of variable sizes. 5 Assume a single uniform block of vertically aligned text. 6 Assume a single uniform block of text. 7 Treat the image as a single text line. 8 Treat the image as a single word. 9 Treat the image as a single word in a circle. 10 Treat the image as a single character. 11 Sparse text. Find as much text as possible in no particular order. 12 Sparse text with OSD. 13 Raw line. Treat the image as a single text line, bypassing hacks that are Tesseract-specific. \ \$ tesseract \--help-oem OCR Engine modes: 0 Legacy engine only. 1 Neural nets LSTM engine only. 2 Legacy + LSTM engines. 3 Default, based on what is available. \ \ \ ## Training Tesseract on custom data {#training-tesseract-on-custom-data .western} \ \ \ \ \ # Edge Impulse {#edge-impulse .western} \ \ [[https://www.survivingwithandroid.com/tinyml-esp32-cam-edge-image-classification-with-edge-impulse/]{style="background: #ffff00"}](https://www.survivingwithandroid.com/tinyml-esp32-cam-edge-image-classification-with-edge-impulse/) \ \ \ \ \ \ # Tensorflow Lite {#tensorflow-lite .western} \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ # Alarm system {#alarm-system .western} \ \ \ \ \ \ # MICRO PYTHON ON ESP32 (HUZZAH32) {#micro-python-on-esp32-huzzah32 .western} \ \ \ \ \ \ # install HACS {#install-hacs .western} 1. install addon Terminal & SSH 2. enter follwing code into WEB UI: wget -q -O - https://install.hacs.xyz \| bash - 3. Restart Server 4. search for integration hacs 1. select all 4 check boxes 2. enter github credentials 5. You can further enable AppDaemon and NetDaemon apps discovery & tracking. In simple words these are more option to customize your Home Assistant. 6. \ \ \ \ # Camera {#camera .western} ## M5Stack Timer Camera X {#m5stack-timer-camera-x .western} ### Arduino {#arduino .western} \ \ \ \ Kamera Fernsteuern: http://\/control?var=\&val=\ http://192.168.178.42/control?var=framesize&val=3 http://192.168.178.42:81/stream [commands work with web_cam example! → web_cam_M5Stack_Timer-CAM_working]{style="background: #ffff00"} \ \ \ \ \ entity_id: camera.cam1 filename: /config/www/snapshot.jpg \ \ ![](Home_assistant_html_b0a3a1c1e3c3da03.jpg){#Image52 align="bottom" width="261" height="727" border="0"} \ alias: take periodic pictures\ description: \"\"\ trigger:\ - platform: time_pattern\ minutes: /1\ condition: \[\]\ action:\ - service: camera.snapshot\ data:\ filename: \>-\ /config/Timelapse/Plants\_{{ \"%04d\"\|format(now().year) }}\_{{\ \"%02d\"\|format(now().month) }}\_{{ \"%02d\"\|format(now().day)\ }}\_{{ \"%02d\"\|format(now().hour) }}\_{{ \"%02d\"\|format(now().minute) }}\_{{ \"%02d\"\|format(now().second) }}.jpeg\ target:\ entity_id: camera.esp32cam_1\ mode: single \ \ ### Micropython {#micropython .western} \ due to missing PSRAM, the micropython code does not work\... \ \ \ \ \ \ # Android controller for ESP32 {#android-controller-for-esp32 .western} \ \ \ \ \ \ \ \ # Python on Win10 {#python-on-win10 .western} Install via Microsoft store \ \ create new venv: - python -m venv "D:\\Home Assistant\\Micropython\\myenv" \ activate in command prompt to install packages: - D:\\"Home Assistant"\\Python\\myenv\\Scripts\\activate.bat - pip install \... - deactivate \ to see the new venv in VSCode: 1. Python: Select Interpreter → D:\\Home Assistant\\Micropython\\myenv\\Scripts\\python.exe 2. then, restart VSCode \ \ \ \ \ \ # using password manager {#using-password-manager .western} ## KepassXC {#kepassxc .western} \ \ \ Use Yubico: Database \> Database Security \> Add Additional protection... \> Add Challenge-Response → choose Yubikey from the drop-down menu \ ### browser plugin: {#browser-plugin .western} \ \ \ ## keepass for Android {#keepass-for-android .western} [KeePass2Android]{style="background: #ffff00"} or KeePassDX \ \ \ \ ## Syncthing {#syncthing .western} Download: Getting started: Default Folder: C:\\Users\\Bora_2\\Sync \ Device Identification -- BoraNB: 3YHOKRG-D57OAYW-QW7Z23T-MQPGWLJ-ZGR4UCV-DUB-LX1: KOVYWX3-M6CXGFE-M4UQSQQ VOHODHG-KXFA7RQ-5NQ6LM3-3HLMSXC-6XMN4BH-XCIA7GC-LBZGX2G-N4APPQJ \ Starting Syncthing Automatically: Windows: - create shortcut in following folder - folder: %APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup - Alternatively, in newer versions of Windows, open shell:startup from the Run command (Win+R). - path: \"D:\\Home Assistant\\syncthing-windows-amd64-v1.22.2\\syncthing.exe\" \--no-console \--no-browser - open: [http://localhost:8384](http://localhost:8384/) Linux - - \ \ \ \ \ # Soil sensor {#soil-sensor .western} \ 3D models for assembling Adafruit soil sensor: \ \ \ \ \ \ # use wildcard for mqtt topics in automations {#use-wildcard-for-mqtt-topics-in-automations .western} topic: \"stat/+/RESULT\" \ As you have already discovered, this is not an acceptable way to use a wildcard (#) in an MQTT topic: \ topic: \"#/batt\" The \# wildcard can appear at the end of a topic, like this: \ topic: \"home/sensors/#\" or alone: \ topic: \"#\" You didn't mention the format of the battery topic but maybe the + wildcard can be useful. It is designed to allow for any sub-topic like this: \ topic: \"home/OpenMQTTGateway/BttoMQTT/+/batt\" \ \ \ \ data_template: message: "{{ trigger.payload }}" title: From mqtt_notifier service: persistent_notification.create \ \ \ # Tutorial to fix 401: Unauthorised Error with Grafana for mobile devices {#tutorial-to-fix-401-unauthorised-error-with-grafana-for-mobile-devices .western} \ it works! port forward router:\ 443 to 8123 tcp\ and\ 80 to 3000 tcp\ and grafana setings: ``` {.western style="orphans: 2; widows: 2"} plugins: [] env_vars: - name: GF_AUTH_ANONYMOUS_ORG_NAME value: Main Org. - name: GF_AUTH_ANONYMOUS_ENABLED value: 'true' - name: GF_AUTH_DISABLE_LOGIN_FORM value: 'false' ssl: false certfile: fullchain.pem keyfile: privkey.pem ``` \ \ \ \ # Shelly configuration via web interface {#shelly-configuration-via-web-interface .western} 192.168.33.1 Id: A8032AB82968 bedroom: shellyplus1pm-a8032ab82968 → 192.168.178.53 top child room: shellyplus1pm-a8032abba0b0 → 192.168.178.54 living room: shellyplusi4-a8032ab1d7d0 → 192.168.178.55 bed room: shellyplusi4-a8032ab1c9e0 → 192.168.178.56 shellyrgbw2-E0AC83 → 192.168.178.76 \ \ ![](Home_assistant_html_64332a2908217e72.png){#Image50 align="bottom" width="508" height="284" border="0"} \ \ \ \ FRITZ!Box 7530 GD 78302839617779115068 \ \ MQTT credentials: 192.168.178.32:1883 → 192.168.178.52:1883 note4 note4 ![](Home_assistant_html_c2e67b530b770151.png){#Image49 align="bottom" width="332" height="413" border="0"} \ \ \ \ \ \ \ \ shellyplus1pm-a8032ab82968/rpc shellyplus1pm-a8032ab82968/events/rpc shellyplusi4-a8032ab1d7d0/events/rpc shellyplusi4-a8032ab1c9e0/events/rpc shellyrgbw2-E0AC83/events/rpc \ \ Generation 2 devices use the values btn_down, btn_up, single_push, double_push and long_push as click_type. \ \ \ \ power consumption LED (green channel stuck at 100%; red LEDs not connected on one strip; in total ca. 250 LEDs): green 100%: 7.7 W green+blue 100%: 16.3 W green+red 100%: 18.7 W white = green+blue+red 100%: 26.4 W green 100%+blue 50%+red 50%: 17.8 W green 100%+blue 1%+red 1%: 9.7 W \ \ \ nice automations: \ \ \ \ \ example to send command to shell: service: mqtt.publish data: topic: homeassistant/shellyplus1pm-fgfloodlights/rpc payload: \>- {{ {'id': 1, 'src':'homeassistant/shellyplus1pm-fgfloodlights/status', 'method':'Shelly.GetStatus'} \| to_json }} \ \ \ # Shelly integration via MQTT {#shelly-integration-via-mqtt .western} [\ = shellyplus1pm]{style="background: #ffff00"} \ \ Shelly1/1PM: MQTT \ Shelly1 and Shelly1PM uses the following topics, where \ is either shelly1 or shelly1pm: \ shellies/\-\/relay/0 to report status: on, off or overpower (the latter only for Shelly1PM) shellies/\-\/relay/0/command accepts on, off or toggle and applies accordingly shellies/\-\/input/0 reports the state of the SW terminal shellies/\-\/longpush/0 reports longpush state as 0 (shortpush) or 1 (longpush) shellies/\-\/input_event/0 reports input event and event counter, e.g.: {\"event\":\"S\",\"event_cnt\":2} see /status for details \ Shelly1PM adds: \ shellies/shelly1pm-\/relay/0/power reports instantaneous power in Watts shellies/shelly1pm-\/relay/0/energy reports an incrementing energy counter in Watt-minute shellies/shelly1pm-\/temperature reports internal device temperature in °C shellies/shelly1pm-\/temperature_f reports internal device temperature in °F shellies/shelly1pm-\/overtemperature reports 1 when device has overheated, normally 0 shellies/shelly1pm-\/temperature_status reports Normal, High, Very High shellies/shelly1pm-\/relay/0/overpower_value reports the value in Watts, on which an overpower condition is detected \ \ \ \ \ \ \ mqtt: switch: \- name: \"Garage: Heat pump switch\" state_topic: \"garage-heat-pump-switch-pm/status/switch:0\" value_template: \"{{ value_json.output }}\" state_on: true state_off: false command_topic: \"garage-heat-pump-switch-pm/rpc\" payload_on: \'{\"id\":1, \"src\": \"homeassistant\", \"method\": \"Switch.Set\", \"params\":{\"id\":0,\"on\":true}}\' payload_off: \'{\"id\":1, \"src\": \"homeassistant\", \"method\": \"Switch.Set\", \"params\":{\"id\":0,\"on\":false}}\' optimistic: false qos: 1 retain: false sensor: \- name: \"Garage: Heat pump switch temperature\" unique_id: 4ca71dd5-645d-48e5-a387-a655cc7dd42e state_topic: \"garage-heat-pump-switch-pm/status/switch:0\" value_template: \"{{ value_json.temperature.tC }}\" unit_of_measurement: \"°C\" device_class: temperature \- name: \"Garage: Heat pump switch current power\" unique_id: 44f6d6de-be45-4697-8ff9-882fae91c6a2 state_topic: \"garage-heat-pump-switch-pm/status/switch:0\" value_template: \"{{ value_json.apower }}\" unit_of_measurement: \"W\" device_class: power \- name: \"Garage: Heat pump switch total power\" unique_id: 44f6d6de-be45-4697-8ff9-882fae91c6a1 state_topic: \"garage-heat-pump-switch-pm/status/switch:0\" value_template: \"{{ value_json.aenergy.total }}\" unit_of_measurement: \"W\" device_class: power \ \ \ \ Hi folkes,\ I am a bit inpatient and cannot waiting for the Shelly binding to cover the new devices and I read that due to the new ESP32 and new API, Shelly devices can now run cloud and MQTT in parallel. So if you start controlling your new devices (e.g. the Shelly Plus 1PM) via MQTT, you are not missing out on anything else. So here is my thing code for the Shelly Plus 1PM: ``` {.western style="orphans: 2; widows: 2"} UID: mqtt:topic:5d0f79cab1:b0df524d88 label: MQTT Shelly Plus 1PM thingTypeUID: mqtt:topic configuration: payloadNotAvailable: off payloadAvailable: on bridgeUID: mqtt:broker:5d0f79cab1 location: MQTT channels: - id: id channelTypeUID: mqtt:number label: ID description: "" configuration: stateTopic: shellyplus1pm-44179393f8d0/status/switch:0 transformationPattern: JSONPATH:$.id - id: source channelTypeUID: mqtt:string label: Quelle description: "" configuration: stateTopic: shellyplus1pm-44179393f8d0/status/switch:0 transformationPattern: JSONPATH:$.source - id: output channelTypeUID: mqtt:string label: Ausgang description: "" configuration: stateTopic: shellyplus1pm-44179393f8d0/status/switch:0 transformationPattern: JSONPATH:$.output - id: apower channelTypeUID: mqtt:number label: Leistung description: "" configuration: unit: W formatBeforePublish: "%.2f" stateTopic: shellyplus1pm-44179393f8d0/status/switch:0 transformationPattern: JSONPATH:$.apower - id: voltage channelTypeUID: mqtt:number label: Spannung description: null configuration: unit: V formatBeforePublish: "%.2f" stateTopic: shellyplus1pm-44179393f8d0/status/switch:0 transformationPattern: JSONPATH:$.voltage - id: current channelTypeUID: mqtt:number label: Strom description: null configuration: unit: A formatBeforePublish: "%.2f" stateTopic: shellyplus1pm-44179393f8d0/status/switch:0 transformationPattern: JSONPATH:$.current - id: aenergy channelTypeUID: mqtt:number label: Energie description: null configuration: unit: Wh formatBeforePublish: "%.2f" stateTopic: shellyplus1pm-44179393f8d0/status/switch:0 transformationPattern: JSONPATH:$.aenergy.total - id: temperature channelTypeUID: mqtt:number label: Temperatur description: null configuration: unit: °C formatBeforePublish: "%.2f" stateTopic: shellyplus1pm-44179393f8d0/status/switch:0 transformationPattern: JSONPATH:$.temperature.tC - id: input channelTypeUID: mqtt:switch label: Input description: "" configuration: stateTopic: shellyplus1pm-44179393f8d0/status/input:0 transformationPattern: JSONPATH:$.state off: "false" on: "true" - id: control channelTypeUID: mqtt:switch label: Schalter description: null configuration: commandTopic: shellyplus1pm-44179393f8d0/rpc formatBeforePublish: '{"src":"openhab", "method":"Switch.Set", "params":{"id":0,"on":%s}}' stateTopic: shellyplus1pm-44179393f8d0/status/switch:0 transformationPattern: JSONPATH:$.output off: "false" on: "true" - id: online channelTypeUID: mqtt:switch label: Verbunden description: "" configuration: stateTopic: shellyplus1pm-44179393f8d0/online off: "false" on: "true" - id: cloud channelTypeUID: mqtt:switch label: Cloud description: "" configuration: stateTopic: shellyplus1pm-44179393f8d0/status/cloud transformationPattern: JSONPATH:$.connected off: flase on: "true" - id: mqtt channelTypeUID: mqtt:switch label: MQTT description: "" configuration: stateTopic: shellyplus1pm-44179393f8d0/status/cloud transformationPattern: JSONPATH:$.connected off: "false" on: "true" - id: kvs1 channelTypeUID: mqtt:string label: KVS1 description: null configuration: commandTopic: shellyplus1pm-44179393f8d0/rpc postCommand: true formatBeforePublish: '{"src":"openhab","method":"KVS.Get","params":{"id":1,"key":"admin"}}' stateTopic: shellyplus1pm-44179393f8d0/openhab/rpc transformationPattern: JSONPATH:$.params.value ``` \ \ \ \ \ \ \ \## /sensors/room_x/lamp.yaml \ \ \# Input type \- platform: mqtt name: Room X - lamp - input expire_after: 86400 qos: 1 state_topic: shellies/shelly1pm-\[SHELLY ID\]/input_event/0 \# Device temperature °C \- platform: mqtt name: Room X - lamp - temperature expire_after: 86400 qos: 1 device_class: temperature unit_of_measurement: \'°C\' icon: mdi:temperature-celcius state_topic: shellies/shelly1pm-\[SHELLY ID\]/temperature \# Device temperature °F \- platform: mqtt name: Room X - lamp - temperature F expire_after: 86400 qos: 1 device_class: temperature unit_of_measurement: \'°F\' icon: mdi:temperature-fahrenheit state_topic: shellies/shelly1pm-\[SHELLY ID\]/temperature_f \# Power consumption (live) \- platform: mqtt name: Room X - lamp - power expire_after: 86400 qos: 1 device_class: power unit_of_measurement: \'W\' icon: mdi:lightning-bolt-outline state_topic: shellies/shelly1pm-\[SHELLY ID\]/relay/0/power \# Power consumption (since reboot) \- platform: mqtt name: Room X - lamp - energy expire_after: 86400 qos: 1 device_class: energy state_class: total_increasing unit_of_measurement: \'Wh\' value_template: \"{{ value \| float / 60 }}\" icon: mdi:lightning-bolt state_topic: shellies/shelly1pm-\[SHELLY ID\]/relay/0/energy \# Overpower \- platform: mqtt name: Room X - lamp - overpower expire_after: 86400 qos: 1 device_class: power unit_of_measurement: \'W\' icon: mdi:flash-alert state_topic: shellies/shelly1pm-\[SHELLY ID\]/overpower_value \ \ \ \ \ \ ## rgbw2 via mqtt {#rgbw2-via-mqtt .western} shellies/shellyrgbw2-E0AC83/white/3/status shellies/shellyrgbw2-E0AC83/color/0/status \ \ \ \ \ \ \ \ \ \ \ \ # Shelly integration via ESPHome {#shelly-integration-via-esphome .western} \ \ \ \ # Shelly firmware update {#shelly-firmware-update .western} ## Via MQTT {#via-mqtt .western} in configuration.yaml, add the rest integration and configure like so: \ rest_command: update_shelly: url: \'http://{{ shelly_ip }}/ota?update=true\' \ \ create a new automation, eg. shellyupdate.yaml that looks like this: \ \- alias: \"Shelly New Firmware Notification\" id: \'snfn\' trigger: platform: mqtt topic: shellies/announce condition: condition: template value_template: \"{{ trigger.payload_json\[\'new_fw\'\] == true }}\" action: \- service: persistent_notification.create data_template: title: \"New Shelly Firmware Update Released. Update will be attempted.\" message: Update will be attempted\" notification_id: \"{{ trigger.payload_json\[\'id\'\] }}\" \- service: rest_command.update_shelly data: shelly_ip: \"{{ trigger.payload_json\[\'ip\'\] }}\" \- alias: \"Shelly New Firmware Notification Removal\" id: \'snfnr\' trigger: platform: mqtt topic: shellies/announce condition: condition: template value_template: \"{{ trigger.payload_json\[\'new_fw\'\] == false }}\" action: service: persistent_notification.dismiss data_template: notification_id: \"{{ trigger.payload_json\[\'id\'\] }}\" \ \ \ ## Via REST API {#via-rest-api .western} http://\[IP-OF-SHELLY/ota?update=1 does the trick \ \ \ \ \ \ \ \ \ \ # Node Red {#node-red .western} \ \ \ \ \ \ \ # Deye Wechselrichter {#deye-wechselrichter .western} Solarman? See KeePassXC \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ # Using Wemos Lolin ESP32 boards {#using-wemos-lolin-esp32-boards .western} ## C3 Mini {#c3-mini .western} \ static const uint8_t LED_BUILTIN = 7; #define BUILTIN_LED LED_BUILTIN // backward compatibility static const uint8_t TX = 21; static const uint8_t RX = 20; static const uint8_t SDA = 8; static const uint8_t SCL = 10; static const uint8_t SS = 5; static const uint8_t MOSI = 4; static const uint8_t MISO = 3; static const uint8_t SCK = 2; static const uint8_t A0 = 0; static const uint8_t A1 = 1; static const uint8_t A2 = 2; static const uint8_t A3 = 3; static const uint8_t A4 = 4; static const uint8_t A5 = 5; \ Wifi funktioniert nicht → Wifi TX auf 8,5 dBm setzen: WiFi.setTxPower(WIFI_POWER_8_5dBm); \ ### Arduino: {#arduino-1 .western} - Configure Board - Use lastest esp32 arduino package - Choose board LOLIN C3 MINI - Upload Code - Make C3 boards into Device Firmware Upgrade (DFU) mode. - Hold on Button 9 - Press Button Reset - Release Button 9 When you hear the prompt tone on usb reconnection \ \ \ \ ## Wemos S2 Pico {#wemos-s2-pico .western} - D:\\"Home Assistant"\\Python\\myenv\\Scripts\\activate.bat - pip install esptool \ - Make S2 boards into Device Firmware Upgrade (DFU) mode. - - Hold on Button 0 - Press Button Reset - Release Button 0 When you hear the prompt tone on usb reconnection - Flash using esptool.py - esptool.py \--port PORT_NAME erase_flash - esptool.py \--port COM20 erase_flash - esptool.py \--port PORT_NAME \--baud 1000000 write_flash -z 0x1000 FIRMWARE.bin - esptool.py \--port PORT_NAME \--baud 1000000 write_flash -z 0x1000 FIRMWARE.bin \ \ \ \ ## []{#h-ssd1306-oled-micropython-library} SSD1306 OLED MicroPython Library {#ssd1306-oled-micropython-library .western style="font-variant: normal; letter-spacing: normal; font-style: normal; font-weight: normal"} **We will have to install the SSD1306 OLED library for MicroPython to continue with our project.** - [[[**To successfully do that, open your Thonny IDE with your Raspberry Pi Pico plugged in your system. Go to **]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Tools \> Manage Packages**[[[**. This will open up the Thonny Package Manager.**]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} \ \ - **Search for "ssd1306" in the search bar by typing its name and clicking the button 'Search on PyPI.'** \ \ - **From the following search results click on the one highlighted below: micropython-ssd1306** \ \ **Install this library.** \ \ \ \ \ \ \ # Home Assistant presence simulation {#home-assistant-presence-simulation .western} \ \ \ \ \ [[[[I created an toggle helper called ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `input_boolean.holidaymode`{.western}[[[[:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 1. [[[[Go to ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Settings*[[[[ then ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Devices & Services* 2. [[[[Click on the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Helpers *[[[[tab (in the web interace this will be at the top, on the Android app it\'s an icon at the bottom]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 3. [[[[Click ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *create helper* 4. [[[[Choose ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Toggle* 5. [[[[Type a name (e.g., ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `HolidayMode`{.western}[[[[) and choose an icon (e.g., ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `mdi:beach`{.western}[[[[) and click ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Create* 6. [[[[The list of helpers will now include ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `input_boolean.holidaymode`{.western} [[[[As the automation stores the light it is going to change (switch on or off) in the \"]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *light to switch*[[[[\" variable, we need to create that.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 1. [[[[Go to ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Settings*[[[[ then ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Devices & Services* 2. [[[[Click on the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Helpers *[[[[tab (in the web interace this will be at the top, on the Android app it\'s an icon at the bottom]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 3. [[[[Click ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *create helper* 4. [[[[Choose ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Text* 5. [[[[For name, type ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `light_to_switch`{.western}[[[[ and leave the other options as their defaults]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 6. [[[[Click ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Create* 7. [[[[The list of helpers will now include ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `input_text.light_to_switch`{.western} Once we\'ve created the light group we\'ll be referencing it by name in the automation. 1. [[[[Go to ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Settings*[[[[ then ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Devices & Services* 2. [[[[Click on the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Helpers *[[[[tab (in the web interace this will be at the top, on the Android app it\'s an icon at the bottom]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 3. [[[[Click ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *create helper* 4. [[[[Choose ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Group*[[[[ (a circle with three dots in it)]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 5. [[[[When asked what type of group this is, choose ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Light group* 6. Give your group a name (e.g., \"Presence simulation lights\") and choose the members to include in the group 7. [[[[Click ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Submit* 8. [[[[In the helpers list you\'ll see a group called ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `light.presence_simulation_lights`{.western}[[[[ - copy this name exactly as we\'ll need it in the automation]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} Create automation - random lights on ``` western alias: "Holiday mode: Presence simulation" trigger: - platform: time_pattern minutes: /30 condition: - condition: state entity_id: input_boolean.holidaymode state: "on" - condition: sun after: sunset after_offset: "-00:30:00" - condition: time before: "22:00:00" action: - delay: 00:{{ '{:02}'.format(range(0,30) | random | int) }}:00 - service: input_text.set_value data_template: entity_id: input_text.light_to_switch value: "{{ state_attr('light.presence_simulation_lights','entity_id') | random }}" - service: homeassistant.toggle data_template: entity_id: "{{states('input_text.light_to_switch')}}" initial_state: true hide_entity: false ``` \ Create automation - lights off at random bedtime ``` western alias: "Holiday mode: Turning off all toggled lights" description: "" trigger: - platform: time at: "23:00:00" condition: - condition: state entity_id: input_boolean.holidaymode state: "on" action: - delay: 00:{{ range(15,59) | random | int }}:00 - service: homeassistant.turn_off data: {} target: entity_id: light.presence_simulation_lights initial_state: true hide_entity: false mode: single ``` \ \ \ \ \ \ \ \ Add the following script in your scripts configuration file (ie  `scripts.yaml`{.western}) [COPY]{style="display: inline-block; border: none; padding: 0in"} ``` {.western style="border: none; padding: 0in"} light_duration: mode: parallel description: "Turns on a light for a while, and then turns it off" fields: light: description: "A specific light" example: "light.bedroom" duration: description: "How long the light should be on in minutes" example: "25" sequence: - service: homeassistant.turn_on data: entity_id: "{{ light }}" - delay: "{{ duration }}" - service: homeassistant.turn_off data: entity_id: "{{ light }}" ``` \ The automation will then start the script providing the correct parameters. [COPY]{style="display: inline-block; border: none; padding: 0in"} ``` {.western style="border: none; padding: 0in"} - id: random_away_lights alias: "Random Away Lights" mode: parallel trigger: - platform: time_pattern minutes: "/30" condition: - condition: state entity_id: input_boolean.away state: "on" - condition: sun after: sunset after_offset: "-00:30:00" - condition: time before: "23:59:00" action: service: script.light_duration data: light: "{{states.group.simulation_lights.attributes.entity_id | random}}" duration: "00:{{ '{:02}'.format(range(5,30) | random | int) }}:00" ``` \ I created a group with a list of lights I want to use to simulate the presence. I put only the lights within the rooms visible from the outside. [COPY]{style="display: inline-block; border: none; padding: 0in"} ``` {.western style="border: none; padding: 0in"} simulation_lights: name: Lights Presence Simulation entities: - light.salle_manger - light.cuisine_table - light.bureau_marco - light.salon_corner ``` \ \ \ ## scheduler-component {#scheduler-component .western} \ \ \ \ \ \ # reduce size of database {#reduce-size-of-database .western} recorder: purge_keep_days: 5 db_url: sqlite:////home/user/.homeassistant/test \ \ \ 1. [[[[open up a terminal (SSH or via web, I use this extension for this purpose ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[[https://github.com/hassio-addons/addon-ssh ]{style="background: transparent"}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="text-decoration: none"}]{style="font-variant: normal"}](https://github.com/hassio-addons/addon-ssh) [130](https://github.com/hassio-addons/addon-ssh)[[[[)]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 2. [[[[change directory to config ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`cd ~/config`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 3. [[[[open sqlite shell ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`sqlite3 home-assistant_v2.db`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 4. [[[[enter the following commands in the shell:\ ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`.header on`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[\ ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`.mode column`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[\ ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`.width 50, 10,`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[\ ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`SELECT entity_id, COUNT(*) as count FROM states GROUP BY entity_id ORDER BY count DESC LIMIT 20;`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} \ \ homeassistant: allowlist_external_dirs: \- /config sensor: \- platform: filesize file_paths: \- /config/home-assistant_v2.db \ \ ![](Home_assistant_html_1a71f91fe23da888.png){#Image14 align="left" width="643" height="339" border="0"}\ \ \ \ \ \ # WIZ light scenes {#wiz-light-scenes .western} SCENES = { 1: \"Ocean\", 2: \"Romance\", 3: \"Sunset\", 4: \"Party\", 5: \"Fireplace\", 6: \"Cozy\", 7: \"Forest\", 8: \"Pastel Colors\", 9: \"Wake up\", 10: \"Bedtime\", 11: \"Warm White\", 12: \"Daylight\", 13: \"Cool white\", 14: \"Night light\", 15: \"Focus\", 16: \"Relax\", 17: \"True colors\", 18: \"TV time\", 19: \"Plantgrowth\", 20: \"Spring\", 21: \"Summer\", 22: \"Fall\", 23: \"Deepdive\", 24: \"Jungle\", 25: \"Mojito\", 26: \"Club\", 27: \"Christmas\", 28: \"Halloween\", 29: \"Candlelight\", 30: \"Golden white\", 31: \"Pulse\", 32: \"Steampunk\", 1000: \"Rhythm\", } \ \ \ # ESP32 Wifi repeater {#esp32-wifi-repeater .western} \ download repository and flash tool: \ run the tool and select the three files in the folder D:\\Home Assistant\\ESP32_wifi_repeater\\esp32_nat_router-master\\build\\esp32: bootloader.bin, firmware.bin, partitions.bin \ Now, we also need to specify the hex code indicating where the files are. For the bootloader type 0x1000, for esp32 nat router file type 0x10000, and for partition file type 0x8000. \ Press and hold the boot button on your ESP32 board and click on the start button to start flashing firmware. \ ![](Home_assistant_html_a271954676b4d389.png){#Image15 align="bottom" width="422" height="670" border="0"} \ \ After the first boot, it provides an open WiFi SSID "ESP32_NAT_Router". Connect to this WiFi network and perform basic configuration via a simple web interface. \ The web interface allows for the configuration of all the parameters required for basic forwarding functionality. Open your web browser and enter the following address: "**http://192.168.4.1**". Now you should see the following page. \ Firstly, in the "STA Settings" enter the correct WiFi credentials of your main WiFi network that you want to extend. Leave the password field for open networks. Click on "Connect". The ESP32 reboots and will connect to your WiFi router. You should see the status LED ON after a few seconds. \ You can now reload the page and change the "AP Settings". Enter New SSID and Password and click "Set" and again the ESP reboots. Now it is ready for forwarding traffic over the newly configured Access Point. \ **SSID: ESP32_NAT_Router** **pass: mysupersecurepassword** \ \ \ \ \ \ \ \ # install home assistant in docker {#install-home-assistant-in-docker .western} \ \ \ ## install Docker {#install-docker .western} 192.168.178.52 pi raspberry \ [sudo apt update]{style="background: #ffff00"} [sudo apt upgrade -y]{style="background: #ffff00"} [sudo reboot]{style="background: #ffff00"} [curl -sSL https://get.docker.com \| sh]{style="background: #ffff00"} Allow Docker to be used without being a root → So, here is the command to add the current user to the docker group: sudo usermod -aG docker \$USER → [sudo usermod -aG docker ]{style="background: #ffff00"}[pi]{style="background: #ffff00"} Exit your SSH session, or restart the Raspberry Pi, and you should then be able to run any docker command without sudo. → docker ps → If it works, you are ready to move forward. Test your Docker setup: [docker run hello-world]{style="background: #ffff00"} \ ### Docker commands you need to know {#docker-commands-you-need-to-know .western} - Monitor the running containers: - docker ps - Display the current version of Docker: - docker version - Download a new image: - docker pull \[IMAGE\] - Run an image (and download it if not existing on your local system): - docker run \[IMAGE\] - Search for an image in the Docker repository: - docker search \[X\] - Show the usage statistics: - docker stats - Display the list of all the Docker commands: - docker help \ \ \ \ ## install HA on docker {#install-ha-on-docker .western} docker run -d \\ \--name homeassistant \\ \--privileged \\ \--restart=unless-stopped \\ -e TZ=[Europe/Berlin]{style="background: #ffff00"} \\ -v /PATH_TO_YOUR_CONFIG:[/config]{style="background: #ffff00"} \\ \--network=host \\ ghcr.io/home-assistant/home-assistant:stable \ Once the Home Assistant Container is running Home Assistant should be accessible using http://\:8123 http://192.168.178.52:8123 \ \ \ RESTART HOME ASSISTANT docker restart homeassistant \ \ \ \ \ \ ## configuration {#configuration .western} cd \~/docker mkdir configurator cd configurator sudo nano docker-compose.yaml \ **version: \"3.5\"** **services:** **configurator:** **container_name: configurator** **image: causticlab/hass-configurator-docker:latest** **restart: always** **network_mode: host** **labels:** **- \"com.centurylinklabs.watchtower.enable=true\" \# for Watchtower automatic updates** **ports:** **- \"3218:3218/tcp\"** **volumes:** **- \${HASSIODIR}/:/config \# map this volume to your hassio config directory** **environment:** **- HC_BASEPATH=/config** **- HC_HASS_API_PASSWORD=\${CONFIGURATORPSWD} #Create a Long-Lived Access Token** **- HC_IGNORE_SSL=True** **- PUID=\${PUID}** **- PGID=\${PGID}** **- TZ=\${TZ}\'** \ docker-compose up -d \ [http://192.168.178.52:3218]{style="background: #ffff00"} \ \ edit configuration.yaml: **http:** **base_url: https://myhomeassistant.com:8123** **ssl_certificate: /config/fullchain.pem** **ssl_key: /config/privkey.pem** \ create certifactes: cd /PATH_TO_YOUR_CONFIG sudo openssl req -sha256 -addext \"subjectAltName = IP:192.168.178.52\" -newkey rsa:4096 -nodes -keyout privkey.pem -x509 -days 730 -out fullchain.pem \ \ \ ## install Nginx on docker {#install-nginx-on-docker .western} Home Assistant in Docker with Nginx and Let\'s Encrypt on Raspberry Pi \ cd \~/docker mkdir proxy cd proxy sudo nano docker-compose.yaml \ **version: \'3\'** **services:** **nginx:** **image: arm64v8/nginx** **ports:** **- \"80:80\"** **volumes:** **- ./data/nginx:/etc/nginx/conf.d:ro** **- ./data/wwwroot:/var/www/root:ro** \ mkdir data cd data mkdir nginx cd nginx sudo nano app.conf \ **server {** **listen 80;** **server_name [habora]{style="background: #ffff00"}.duckdns.org; #replace this** **location / {** **root /var/www/root;** **}** **}** \ cd .. mkdir wwwroot cd wwwroot sudo nano index.html \ **\** **\** **\Welcome\** **It works!** **\T** \ cd \~/docker/proxy docker-compose up -d \ http://192.168.178.52:80/ \ cd \~/docker/proxy sudo nano docker-compose.yaml \ **version: \'3\'** **services:** **nginx:** **image: arm64v8/nginx** **ports:** **- \"80:80\"** **- \"443:443\" \# added** **volumes:** **- ./data/nginx:/etc/nginx/conf.d:ro** **- ./data/wwwroot:/var/www/root:ro** **- ./data/certbot/conf:/etc/letsencrypt:ro \# added** **- ./data/certbot/www:/var/www/certbot:ro \# added** \ **certbot: \# added** **image: certbot/certbot:arm64v8-latest \# added** **volumes: \# added** **- ./data/certbot/conf:/etc/letsencrypt \# added** **- ./data/certbot/www:/var/www/certbot \# added** \ \ cd \~/docker/proxy/data/nginx sudo nano app.conf \ **server {** **listen 80;** **server_name [habora]{style="background: #ffff00"}.duckdns.org; \# replace this** **location /.well-known/acme-challenge/ { \# added** **root /var/www/certbot; \# added** **} \# added** **location / {** **root /var/www/root;** **}** **}** **server {** **listen 443 ssl;** **server_name [habora]{style="background: #ffff00"}.duckdns.org;** \ **location / {** **root /var/www/root;** **}** \ **ssl_certificate /etc/letsencrypt/live/[habora.duckdns.org]{style="background: #ffff00"}/fullchain.pem;** **ssl_certificate_key /etc/letsencrypt/live/[habora.duckdns.org]{style="background: #ffff00"}/privkey.pem;** **#Optional: Only works with Philipp\'s script (see below)** **include /etc/letsencrypt/options-ssl-nginx.conf;** **ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;** **}** \ cd \~/docker/proxy curl -L https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh \> init-letsencrypt.sh \ sudo nano init-letsencrypt.sh **Edit the script to add in your domain(s) and your email address. If you've changed the directories of the shared Docker volumes, make sure you also adjust the data_path variable as well.** **Email:** **, [https://habora.duckdns.org](https://habora.duckdns.org/)** \ chmod +x init-letsencrypt.sh sudo ./init-letsencrypt.sh \ docker-compose up -d http://habora.duckdns.org:80/ \ rm docker-compose.yaml sudo nano docker-compose.yaml \ **version: \'3\'** **services:** **nginx:** **image: arm64v8/nginx** **ports:** **- \"80:80\"** **- \"443:443\"** **volumes:** **- ./data/nginx:/etc/nginx/conf.d:ro** **- ./data/wwwroot:/var/www/root:ro** **- ./data/certbot/conf:/etc/letsencrypt:ro** **- ./data/certbot/www:/var/www/certbot:ro** **command: \"/bin/sh -c \'while :; do sleep 6h & wait \$\${!}; nginx -s reload; done & nginx -g \\\"daemon off;\\\"\'\"** **certbot:** **image: certbot/certbot:arm64v8-latest** **volumes:** **- ./data/certbot/conf:/etc/letsencrypt** **- ./data/certbot/www:/var/www/certbot** **entrypoint: \"/bin/sh -c \'trap exit TERM; while :; do certbot renew; sleep 12h & wait \$\${!}; done;\'\"** \ \ \ \ \ \ http://192.168.178.52:9000/ \ \ \ ### working procedure: {#working-procedure .western} [[https://nginxproxymanager.com/guide/#quick-setup]{style="background: #ffff00"}](https://nginxproxymanager.com/guide/#quick-setup) cd \~/docker/proxy sudo rm \* -R sudo nano docker-compose.yml \ **version: \'3\'** **services:** **app:** **image: \'jc21/nginx-proxy-manager:latest\'** **restart: unless-stopped** **ports:** **- \'80:80\'** **- \'81:81\'** **- \'443:443\'** **volumes:** **- ./data:/data** **- ./letsencrypt:/etc/letsencrypt** \ docker-compose up -d \ [[https://theprivatesmarthome.com/how-to/set-up-nginx-proxy-manager-in-home-assistant/]{style="background: #ffff00"}](https://theprivatesmarthome.com/how-to/set-up-nginx-proxy-manager-in-home-assistant/) open the admin page: http://127.0.0.1:81 http://192.168.178.52:81 Email: admin@example.com Password: changeme \ add prox host: - domain names: habora.duckdns.org - scheme: http - forward hostname / ip: 192.168.178.52:8123 - forward port: 8123 - ache asset: false - block common explots: true - websockets support: true - access list: publicl accessible - SSL - "request a new ssl certificate" - force SSL: true - \ edit configuration.yaml **http:** **use_x_forwarded_for: true** **trusted_proxies:** **- 172.16.0.0/12** \ \ these options work now ==\> http://192.168.178.52:8123/lovelace/0 https://habora.duckdns.org/lovelace/0 \ \ \ ## install duckdns containers {#install-duckdns-containers .western} \ STEP 1: SET UP A DUCKDNS ACCOUNT. The First thing to do will be to set up a DuckDNS account which is easy. Just navigate to their homepage and log in using one of the many sign in options they offer. In our example we use Google. ![](Home_assistant_html_91538cd5f68befa0.png){#Image36 align="bottom" width="819" height="461" border="0"} []{#Frame1 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ []{#Frame2 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ []{#Frame3 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ https://www.duckdns.org []{#Step_2_Enter_a_Duckdns_subdomain} STEP 2: ENTER A DUCKDNS SUBDOMAIN. Once logged in we are going to create a subdomain by entering into the white box a name you would like to use for your service. *Note: You will need to create a new subdomain for each docker container service you host.* [[[[In our example, we just put in "]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **a2t**[[[[". Then click on the green "add domain" button.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![](Home_assistant_html_389f1c0b6fc30dbf.png){#Image37 align="bottom" width="819" height="461" border="0"} [[[[This now gives us a domain name to use. In our case it is ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **a2t.duckdns.org**[[[[.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} The DuckDNS service will automatically take the public IP address you are currently on and add this to the IP field. If you are using a VPN, proxy or are using any other network that is different from the one you want to host your service on you will need to update this IP manually to start with to ensure the correct IP address is used. (This will be auto-updated later by our DuckDNS container either way). []{#Step_3_Create_and_deploy_the_Duckdns_container_using_a_stack} STEP 3: CREATE AND DEPLOY THE DUCKDNS CONTAINER USING A STACK. [[[[Now we have our subdomain we are going to]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ** "** **log in"**[[[[ to our "]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Portainer" **[[[[dashboard on our Raspberry Pi and navigate to the "]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Stacks" **[[[[page:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} []{#Frame4 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ []{#Frame5 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ []{#Frame6 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ http://192.168.2.5:9000/#!/1/docker/stacks ![](Home_assistant_html_e860aebf32582055.png){#Image38 align="bottom" width="819" height="461" border="0"} [[[[From there we are going click on the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **"** **Add stack"**[[[[ button.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[[[This will open up a new Stack creation window. We will then name our stack "]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **duckdns**[[[["]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![](Home_assistant_html_369856bc9da6e51a.png){#Image39 align="bottom" width="819" height="461" border="0"} [[[[Then in the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Web editor**[[[[ we will paste the following Docker compose data into the empty field.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} []{#Docker_Compose_Stack} DOCKER COMPOSE STACK: []{#Frame7 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ []{#Frame8 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ []{#Frame9 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ \-\-- [version: \"2.1\"]{style="display: inline-block; border: none; padding: 0in"} [services:]{style="display: inline-block; border: none; padding: 0in"} [duckdns:]{style="display: inline-block; border: none; padding: 0in"} [image: ghcr.io/linuxserver/duckdns]{style="display: inline-block; border: none; padding: 0in"} [container_name: duckdns]{style="display: inline-block; border: none; padding: 0in"} [environment:]{style="display: inline-block; border: none; padding: 0in"} [- PUID=1000 #optional]{style="display: inline-block; border: none; padding: 0in"} [- PGID=1000 #optional]{style="display: inline-block; border: none; padding: 0in"} [- TZ=Europe/London]{style="display: inline-block; border: none; padding: 0in"} [- SUBDOMAINS=subdomain1,subdomain2]{style="display: inline-block; border: none; padding: 0in"} [- TOKEN=token]{style="display: inline-block; border: none; padding: 0in"} [- LOG_FILE=**false** #optional]{style="display: inline-block; border: none; padding: 0in"} [volumes:]{style="display: inline-block; border: none; padding: 0in"} [- /path/to/appdata/config:/config #optional]{style="display: inline-block; border: none; padding: 0in"} [restart: unless-stopped]{style="display: inline-block; border: none; padding: 0in"} **\-\--** **version: \"2.1\"** **services:** **duckdns:** **image: ghcr.io/linuxserver/duckdns** **container_name: duckdns** **environment:** **#- PUID=1000 #optional** **#- PGID=1000 #optional** **- TZ= [Europe/Berlin]{style="background: #ffff00"}** **- SUBDOMAINS=habora #subdomain1,subdomain2** **- TOKEN=799093a4-0b34-454f-99cb-25a4637bf404** **- LOG_FILE=false #optional** **volumes:** **- /path/to/appdata/config:/config #optional** **restart: unless-stopped** \ \ [[[[You will then need to change the fields to match your installation. If you would like to use a specific user account then you will need to find the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **PUID **[[[[and ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **GUID **[[[[of that user account. We have shown how to do this in our Youtube Video so please watch that. If you would like to go with the defaults just remove both these fields as they are optional.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[[[Set your timezone "]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **TZ**[[[[" to your current location.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[[[Add your subdomain name to the "]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **SUBDOMAIN**[[[[" field. If you have more than one you will need to add an entry for each subdomain you wish to use and separate them with a comma.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Note you do not need to add the full domain name only the subdomain part. In our example, we would only put "* *a2t* *" into the "* *SUBDOMAIN* *" field. not a2t.duckdns.org.* [[[[Add your Token to the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **TOKEN **[[[[field, which can be found on the Duckdns subdomain creation page at the top right. This is unique to every user and only needs to be put in once regardless of how many subdomains you use.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![](Home_assistant_html_f30863f684b0ca6f.png){#Image40 align="bottom" width="819" height="461" border="0"} [[[[If you would like to use logs then you can change the field to "]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **true**[[[[" this is optional.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} Under Volumes add the location of where you install all your Docker data. Now you have set them fields your Docker compose Stack should look something like this: ![](Home_assistant_html_ee45f619877bd165.png){#Image41 align="bottom" width="819" height="461" border="0"} [[[[Now you have confirmed all is set up correctly you can press the "]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Deploy the stack**[[[[" button.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![](Home_assistant_html_c47f69cff7760f16.png){#Image42 align="bottom" width="819" height="461" border="0"} [[[[You can now check the Portainer containers page to confirm the "]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **duckdns**[[[[" container has been created correctly.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![](Home_assistant_html_464c08548a198f9f.png){#Image43 align="bottom" width="819" height="461" border="0"} Press the Logs button to check all is as expected. It should look like this: ![](Home_assistant_html_67e1fbd7fa00d5ad.png){#Image44 align="bottom" width="819" height="461" border="0"} To confirm your domain is working correctly you can open a browser window and enter your domain name into the address field. []{#Frame10 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ []{#Frame11 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ []{#Frame12 dir="ltr" style="position: absolute; width: 1.17in; border: none; padding: 0in; background: #ffffff"} \ \ http://a2t.duckdns.org You should now see this: ![](Home_assistant_html_6cab1c59d3acac74.png){#Image45 align="bottom" width="819" height="461" border="0"} \ \ \ \ \ ## Mosquitto (MQTT broker) on Raspberry Pi / Docker {#mosquitto-mqtt-broker-on-raspberry-pi-docker .western} Install Docker on Raspberry Pi curl -sSL https://get.docker.com \| sh \ Add user pi to group docker: sudo usermod -aG docker pi \ Install Docker Compose (first install Python and Pip) sudo apt-get install libffi-dev libssl-dev python3-dev python3 python3-pip -y sudo pip3 install docker-compose \ sudo reboot \ \ Create the following directory tree sudo mkdir /docker sudo mkdir /docker/mosquitto sudo mkdir /docker/mosquitto/config \ Create the config file for Mosquitto with the following content: sudo nano /docker/mosquitto/config/mosquitto.conf **\# Config file for mosquito** **listener 1883** **#protocol websockets** **persistence true** **persistence_location /mosquitto/data/** **log_dest file /mosquitto/log/mosquitto.log** **allow_anonymous false** \ \ Create the config file for docker-compose with the following content (pay attention to the indentation of the lines in the YAML file, use 4 spaces per indentation, no tabs): cd /docker sudo nano docker-compose.yaml \ **version: \'3\'** \ **services:** **mosquitto:** **container_name: mosquitto** **restart: always** **image: eclipse-mosquitto** **ports:** **- \"1883:1883\"** **- \"9001:9001\"** **volumes:** **- ./mosquitto/config/mosquitto.conf:/mosquitto/config/mosquitto.conf** **- ./mosquitto/data:/mosquitto/data** **- ./mosquitto/log:/mosquitto/log** **networks:** **- default** \ **networks:** **default:** \ \ **version: \"3\"** \ **services:** **mosquitto:** **image: eclipse-mosquitto** **network_mode: host** **volumes:** **- ./conf:/mosquitto/conf** **- ./data:/mosquitto/data** **- ./log:/mosquitto/log** \ \ \ \ sudo nano /docker/mosquitto/config/mosquitto.conf \ **\## Config file for mosquito** **listener 1883** **#protocol websockets** **persistence true** **persistence_location /mosquitto/data/** **log_dest file /mosquitto/log/mosquitto.log** **#allow_anonymous false** **password_file /mosquitto/config/mosquitto.conf** \ \ \ \ docker-compose exec mosquitto mosquitto_passwd -c /mosquitto/config/mosquitto.passwd mosquitto \ \ \ [sudo apt install docker-compose]{style="background: #ffff00"} [pip3 install \--upgrade requests]{style="background: #ffff00"} \ \ docker run -d -p 8080:80 \--name webserver nginx docker rm mosquitto sudo docker run -d -it \--name mosquitto -p 127.0.0.1:1883:1883 eclipse-mosquitto sudo docker run -d -it \--name mosquitto -p 8001:8001 myserver_new \ \ Now you can install and start Mosquitto: docker-compose up -d \ Check if Mosquitto is running: docker ps \ \ \ \ docker pull eclipse-mosquitto \ \ ### working approach {#working-approach .western} [[https://medium.com/himinds/mqtt-broker-with-secure-tls-and-docker-compose-708a6f483c92]{style="background: #ffff00"}](https://medium.com/himinds/mqtt-broker-with-secure-tls-and-docker-compose-708a6f483c92) [[https://www.diyhobi.com/install-mqtt-and-openhab-3-in-docker-raspberry-pi-4/]{style="background: #ffff00"}](https://www.diyhobi.com/install-mqtt-and-openhab-3-in-docker-raspberry-pi-4/) curl -sSL https://get.docker.com \| sh sudo usermod -aG docker pi sudo apt-get install libffi-dev libssl-dev python3-dev python3 python3-pip -y sudo pip3 install docker-compose sudo reboot cd mkdir docker cd docker mkdir smarthome mkdir smarthome/mqtt mkdir smarthome/mqtt/config \ sudo nano smarthome/mqtt/config/mosquitto.conf **\# Config file for mosquitto** \ **listener 1883** \ **persistence true** \ **persistence_location /mosquitto/data/** \ **log_dest file /mosquitto/log/mosquitto.log** \ **allow_anonymous false** \ \ cd smarthome nano docker-compose.yaml \ **version: \'[3.]{style="background: #ffff00"}[5]{style="background: #ffff00"}\'** \ **services:** **#mqtt** **mosquitto:** **container_name: mqtt** **#hostname: mosquitto** **restart: always** **image: eclipse-mosquitto** **ports:** **- \"[8883:8883]{style="background: #ffff00"}\"** **- \"9001:9001\"** **volumes:** **- ./mqtt/config/mosquitto.conf:/mosquitto/config/mosquitto.conf** **- ./mqtt/data:/mosquitto/data** **- ./mqtt/log:/mosquitto/log** **networks:** **- default** \ \ **networks:** **default:** \ \ \ docker-compose up -d \ docker ps cd \~/docker/smarthome sudo rm \* -R \ cd mqtt cd config ls sudo rm mosquitto.conf -R \ sudo nano mosquitto.conf \ **\# Config file for mosquitto** \ **listener 1883** \ **persistence true** \ **persistence_location /mosquitto/data/** \ **log_dest file /mosquitto/log/mosquitto.log** \ **allow_anonymous false** \ \ cd \~/docker/smarthome \ docker-compose up -d \ \ \ \ docker exec -it mqtt sh mosquitto_passwd -c /mosquitto/data/pwfile mymqtt [Username: mymqtt, Password: mypassword]{style="background: #ffff00"} \ exit \ sudo nano \~/docker/smarthome/mqtt/config/mosquitto.conf Paste this at the bottom: **password_file /mosquitto/data/pwfile** \ docker start mqtt docker ps \ \ \ [192.168.178.52:1883]{style="background: #ffff00"} \ \ \ ## Installation of portainer {#installation-of-portainer .western} docker volume create portainer_data docker run -d -p 8000:8000 -p 9443:9443 \--name portainer \--restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest docker ps \ [https://IP-DEINES-RASPBERRYS:9443](https://IP-DEINES-RASPBERRYS:9443/) → [https://192.168.178.52:9443]{style="background: #ffff00"} user: admin, pass: password1234 \ \ \ \ ## install influxdb {#install-influxdb .western} sudo mkdir /opt/influxdb sudo mkdir /opt/grafana sudo chmod 775 /opt/influxdb/ /opt/grafana/ \ influxdb:1.8 8086 /var/lib/influxdb \ grafana/grafana 3000 /var/lib/grafana (was leider nur auf der Grafana Seite direkt steht und nicht hier) \ \ \ \ [[[[Starte, am besten in einem neuen Tab, deine Portainer-Umgebung (]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **https://IP-DES_RASPBERRY:9443**[[[[) und logge dich ein.\ In der linken Menüseite wähle den Punkt „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Containers**[[[[" und dann klicke auf den Button " ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **+ Add container**[[[[„:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![Raspberry Pi Monitoring - Portainer - Container](Home_assistant_html_66e29c76134aef0a.png){#Image16 align="bottom" width="819" height="196" border="0"} Lass dich von den Einstellungen nicht erschlagen. Nicht alle benötigen wir, und alle anderen werden nach und nach klarer. ![Raspberry Pi Monitoring - Portainer Einstellungen](Home_assistant_html_3cd0de6670758b76.png){#Image17 align="bottom" width="819" height="497" border="0"} - [[[[Als Erstes geben wir unserem Container einen ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Namen(1)*[[[[: ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **influxDB** - [[[[Dann suchen wir das entsprechende ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Image (2) *[[[[bei „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **DockerHub**[[[[" : ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **influxdb:1.8** - [[[[Jetzt klickst du auf den ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Button * **publish a new network port**[[[[(3) und trägst bei ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Host(4) *[[[[und ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} *Container(5)*[[[[ jeweils den Port ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **8086 **[[[[ein]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![image 42](Home_assistant_html_3352870c1d946201.png){#Image18 align="bottom" width="648" height="414" border="0"} [[[[Unter dem Punk ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **„** **Command & logging"**[[[[ solltest du für die ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Console**[[[[ ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **„** **Interactive & TTY"**[[[[ auswählen.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![image 16](Home_assistant_html_eec6b1679e52d3b.png){#Image19 align="bottom" width="819" height="366" border="0"} [[[[Etwas weiter unten klickst du jetzt auf „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Volumes(1)**[[[[„, dann auf „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **map additional volume(2)**[[[[" sowie auf den Button „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Bind(3)**[[[[„.\ Du erinnerst dich noch an den Pfad, den wir auf der hub.docker Seite unter influxDB in der Beschreibung gesehen haben?\ Denn diesen müssen wir jetzt bei „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **container(4)**[[[[" eintragen: ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **/var/lib/influxdb**[[[[.\ Bei „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Host(5)**[[[[" kommt jetzt das Gegenstück dazu rein, nämlich der Ordner, den wir für die persistenten Daten auf unserem Raspberry angelegt haben: ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **/opt/influxdb** [[[[Im Reiter „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Restart policy"**[[[[ geben wir noch an, wie sich unser Container verhalten soll, falls der Raspberry mal neu startet oder der Container selbst sich mit einem Fehler beendet hat. Hier wählen wir „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Always**[[[[" -- er soll also immer wieder selbst neu starten.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![image 38](Home_assistant_html_62c4cec3debb56a8.png){#Image20 align="bottom" width="819" height="123" border="0"} [[[[\ Nun haben wir soweit alles angegeben was wir benötigen und können, wieder etwas weiter oben, auf den Button „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Deploy the container**[[[[" klicken.\ Das Ganze dauert dann ein wenig, da zu erst das Image heruntergeladen, entpackt und der Container entsprechend angelegt werden muss. Beim nächsten Deploy des Containers würde es deutlich schneller gehen:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![image 18](Home_assistant_html_cfe66c1744a9018f.png){#Image21 align="bottom" width="819" height="470" border="0"} Hiermit hast du jetzt influxDB erfolgreich als Container gestartet. Prüfen kannst du das natürlich auch. Im Menüpunkt Containers wirst du in der Übersicht einen neuen influxDB Container im Status running sehen. Schaue auch ruhig einmal in die Logs. \ \ \ \ [[http://192.168.178.52:8086/]{style="background: #ffff00"}](http://192.168.178.52:8086/) [user:bora, pass:password1234, orga:home, bucket:influxdb_rapi4]{style="background: #ffff00"} token_01: **GK_kb2fTPaEknWQ7c9c5VRU5c5GeRXv8is3_e0qhn9qXLOdbxHkdAfqYZNrfn1jexfQ-RVKYtX7Co9HvKgIJqg==** \ \ \ ### **subscribe to MQTT broker** {#subscribe-to-mqtt-broker .western} **https://diyi0t.com/visualize-mqtt-data-with-influxdb-and-grafana/** ![](Home_assistant_html_4202aa273ecf0532.png){#Image46 align="left" width="643" height="285" border="0"}\ \ **https://thenewstack.io/python-mqtt-tutorial-store-iot-metrics-with-influxdb/** ![](Home_assistant_html_faa23644238e228c.png){#Image47 align="left" width="643" height="301" border="0"}\ \ \ \ \ \ \ \ \ \ \ ## Install Grafana {#install-grafana .western} ![Raspberry Pi Monitoring - Portainer - Container deploy](Home_assistant_html_571f817e4c9a0b99.png){#Image22 align="bottom" width="819" height="753" border="0"} \(1\) -- Name des Containers: „Grafana„ \(2\) -- Name des Image: „grafana/grafana„ \(3\) -- Anklicken um neue Ports eingeben/binden zu können \(4\) -- Port des Hosts(Raspberry): 3000 \(5\) -- Port des Containers: 3000 \(6\) -- Button „Volumes" anklicken \(7\) -- Den Button bei Volume mapping klicken damit wir die Pfade eingeben können \(8\) -- Button „Bind" anklicken \(9\) -- Pfad des Containers: /var/lib/grafana \(10\) -- Pfad auf dem Host(Raspberry) dazu: /opt/grafana Im Reiter „Restart policy" geben wir jetzt noch an, wie sich unser Container verhalten soll, falls der Raspberry mal neu startet oder der Container selbst sich mit einem Fehler beendet hat. Hier wählen wir „Always" -- er soll also immer wieder selbst neu starten. Unter dem Punk „Command & logging" solltest du für die Console „Interactive & TTY" auswählen. \(11\) -- Button „Deploy the container" klicken \ [http://IP-DEINES-RASPBERRY:3000](http://IP-DEINES-RASPBERRY:3000/) → [http://192.168.178.52:3000]{style="background: #ffff00"} \ Mit dem Default User und Passwort (admin/admin) kannst du dich einloggen und direkt das Passwort ändern. \ \ \ ## InfluxDB mit Grafana verbinden {#influxdb-mit-grafana-verbinden .western} [[[[Wir loggen uns jetzt wieder in der Grafana WebGui auf dem Raspberry ein ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **(IP-DEINES_RASPBERRYS:3000)**[[[[.\ Hier wählen wir auf der linken Seite das Zahnrad und „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Data sources**[[[[" aus, dann klicken wir auf den Button „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Add data source**[[[[" und sagen zum Schluss wir wollen eine ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **InfluxDB **[[[[hinzufügen:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![image 31](Home_assistant_html_88f4515c8b37e4e0.png){#Image23 align="bottom" width="623" height="403" border="0"} ![image 32](Home_assistant_html_c6fcf1a7b5e5300d.png){#Image24 align="bottom" width="819" height="248" border="0"} ![image 33](Home_assistant_html_cbbc33380bd08951.png){#Image25 align="bottom" width="819" height="331" border="0"} Jetzt müssen wir nur noch ein paar Angaben zu der Datenbank machen. Damit es einfacher zu handhaben ist, verzichte ich hier vollkommen auf Username / Passwörter. Bedeutet die Datenbank ist frei zugänglich. Da dies alles nur in unserem Netzwerk läuft, ist das kein Problem. Bedenke aber das man unter anderen Umständen immer User und Passwörter vergeben sollte. [[[[Zurück zu unseren Einstellungen.\ Unter ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Name **[[[[kannst du einen Namen vergeben der dann später als Quelle in deinem Dashboard auswählbar ist.\ Im Bereich ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **HTTP**[[[[ und ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **URL **[[[[gibst du die ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **IP deines Raspberrys**[[[[ ein auf dem die Datenbank läuft, gefolgt von dem ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Port 8086**[[[[\ Die restlichen Einstellungen können so bleiben.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![image 34](Home_assistant_html_994478788c5d893a.png){#Image26 align="bottom" width="819" height="546" border="0"} [[[[Etwas weiter unten musst du noch den ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Datenbank Namen **[[[[angeben aus dem die Daten gelesen werden sollen. Du erinnerst dich? Wir haben diesen weiter oben in die telegraf.conf eingetragen. In meinem Fall als „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **raspberry_live**[[[[„.\ Über den Button „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Save & test**[[[[" prüfen wir die Verbindung. Ein grüner Haken und ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **„** **Data source is working**[[[[„, zeigt uns an, das alles funktioniert hat:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![image 35](Home_assistant_html_73e5e602e1634f7e.png){#Image27 align="bottom" width="819" height="594" border="0"} ### []{#Dashboard_fur_Grafana_besorgen}Dashboard für Grafana besorgen {#dashboard-für-grafana-besorgen .western} [[[[Was wäre ein Raspberry Pi Monitoring ohne ein Dashboard?\ Damit wir bei Grafana ein solches sehen können, müssten wir uns selbst eins erstellen oder -- was ich hier bevorzuge -- ein fertiges Dashboard importieren.\ Du kannst dir auf der ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [Grafana Labs Seite](https://grafana.com/grafana/){target="_blank"}[[[[ alle verfügbaren Dashboards ansehen und entsprechend suchen. Wir wollen ja ein speziell für einen Raspberry Pi erstelltes nutzen, daher suchen wir auch nach „Raspberry".\ Ich denke du wirst dann bei deiner Suche direkt auf dieses hier treffen: ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [Raspberry Pi Monitoring](https://grafana.com/grafana/dashboards/10578){target="_blank"} ![Raspberry Pi Monitoring - Grafana Dashboard](Home_assistant_html_674b29325fbfed7e.png){#Image28 align="bottom" width="819" height="513" border="0"} [[[[Dieses nehmen wir auch direkt. Wie?! Ganz einfach: Kopiere dir die ID oben Rechts „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **10578**[[[[„.\ Dann öffnest du bei dir deine Grafana Umgebung (IP-DEINES_RASPBERRYS:3000) und gehst über den Menüpunkt „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Dashboards**[[[[" auf „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **+ Import**[[[[„:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![image 28](Home_assistant_html_602ea3a9161f69e7.png){#Image29 align="bottom" width="447" height="481" border="0"} [[[[Hier trägst du die gerade kopierte oder gemerkte ID des Dashboards ein (]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **10578**[[[[) und betätigst den „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Load**[[[[" Button.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![image 29](Home_assistant_html_cef0de278724e1e6.png){#Image30 align="bottom" width="819" height="622" border="0"} [[[[Jetzt könntest du den Namen des Dashboards ändern und musst auf jeden Fall die Verbindung zu den Daten -- also zu der influxDB -- angeben.\ Diese hatten wir ja gerade eingerichtet und du solltest sie in dem Drop-Down-Feld auswählen können. In meinem Fall „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Raspberry Pi Monitoring"** ![image 36](Home_assistant_html_efaf97c53f6a42c7.png){#Image31 align="bottom" width="819" height="710" border="0"} [[[[Ist alles eingestellt, klicken wir auf den „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Import"**[[[[ Button und sehen einige Sekunden später bereits unser Dashboard mit Daten.\ Ab jetzt kannst du dich einfach mal in Ruhe durch alle Punkte klicken und dir das Dashboard anschauen. Je länger dein Raspberry läuft, je mehr Daten erscheinen. Oben Rechts kannst du die Aktualisierungsrate einstellen. Default ist 1 Minute.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} Herzlichen Glückwunsch, dein Raspberry Pi Monitoring ist somit fertig und funktionsfähig. Viel Spaß damit! ![image 37](Home_assistant_html_81b8624523f575e7.png){#Image32 align="bottom" width="819" height="419" border="0"}\ \ \ \ ### Grafana with influxdb 2.x {#grafana-with-influxdb-2.x .western} - the influxdb data explorer, select a quer and cop from the script editor \ \ \ \ \ \ ## Install telegraf {#install-telegraf .western} Willkommen zurück! Na?! Kopf wieder etwas abgekühlt und aufnahmefähig? 🙂\ Dann lass uns direkt weitermachen und die letzten paar Dinge erledigen. Was jetzt kommt, wird wieder direkt auf dem Raspberry installiert. Also nicht als Container.\ Dazu wie immer per SSH mit deinem pi verbinden. Damit wir Zugriff auf die Quelle von influxDB haben, um uns Pakete herunterladen zu können, besorgen wir uns einen Key und speichern ihn auf dem Raspberry: [[wget -q https://repos.influxdata.com/influxdata-archive_compat.key]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[cat influxdata-archive_compat.key **\|** gpg \--dearmor **\|** sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg **\>** /dev/**null**]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[echo \'deb \[signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg\] https://repos.influxdata.com/debian stable main\' **\|** sudo tee /etc/apt/sources.list.d/influxdata.list]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[sudo rm -f /etc/apt/trusted.gpg.d/influxdb.gpg]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} Dann aktualisieren wir unsere Quellen und installieren apt-transport-https, was wir für den weiteren Schritt benötigen. [[sudo apt-get update **&&** sudo apt-get install apt-transport-https]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} Um später auch Updates erhalten zu können, fügen wir noch einen Eintrag in unserer Paketquelle hinzu: [[sudo echo \'deb \[signed-by=/etc/apt/trusted.gpg.d/influxdb.gpg\] https://repos.influxdata.com/debian stable main\' **\|** sudo tee /etc/apt/sources.list.d/influxdata.list]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} Final installieren wir endlich Telegraf: [[sudo apt-get update **&&** sudo apt-get install telegraf]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} ![Raspberry Pi Monitoring - Telegraf installieren](Home_assistant_html_fd6e56b57f85084.png){#Image33 align="bottom" width="819" height="377" border="0"} [[[[Es sollte jetzt von repos.influxdata.com das Paket für telegraf heruntergeladen und installiert werden.\ Für mehr Informationen, und weiterführende Konfigurationen, schaue dir die ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [Installationsanleitung von Telegraf](https://docs.influxdata.com/telegraf/v1.23/install/){target="_blank"}[[[[ an.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} \ ### []{#telegraf_konfigurieren} [telegraf konfigurieren]{style="display: inline-block; border: none; padding: 0in"} {#telegraf-konfigurieren .western style="font-variant: normal; letter-spacing: normal; font-style: normal; font-weight: normal; orphans: 2; widows: 2; margin-top: 0in; margin-bottom: 0in; border: none; padding: 0in"} Uns fehlen noch ein paar Konfigurationen, damit wir für unser Raspberry Pi Monitoring auch alle benötigten Informationen bekommen, und in unserer Datenbank speichern können.\ Dafür öffnen wir eine config Datei von telegraf: [[sudo nano /etc/telegraf/telegraf.conf]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} Viel Spaß beim scrollen.... ja diese Datei ist WIRKLICH gefühlt unendlich lang. Aber keine Sorge, wir machen da nicht sehr viel mit und müssen es auch für unsere Anforderungen nicht. [[[[Suche mal nach „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **OUTPUT PLUGINS**[[[[" und dann nach ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **\[\[output.influxdb\]\]**[[[[. Unter diesem Punkt geben wir jetzt an, wo sich unsere influxdb-Datenbank befindet.\ Bei dem letzten auskommentierten (#) urls Eintrag entfernen wir einfach die Raute(#) und können es im Prinzip so lassen. Die 127er IP ist der localhost. Da die influxdb ja direkt auf dem Raspberry läuft, kann diese so erreicht werden.\ Falls du noch einen zweiten Raspberry hast, würdest du bei diesem hier die IP des Hosts eingeben, auf dem die influxdb-Datenbank läuft.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[[[Ein wenig unter diesem Eintrag entfernen wir auch die Raute(#) vor dem „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **database = **[[[[" und geben unserer Datenbank einen Namen.\ Diese wird dann später automatisch angelegt und wir brauchen uns da nicht selbst drum kümmern.\ Ich habe meine hier „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **raspberry_live**[[[[" genannt, damit ich später weiß von welchem meiner raspberrys die Daten sind. Bei einem weiteren pi würde ich zum Beispiel „raspberry_test" oder sowas nehmen.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} ![Raspberry Pi Monitoring - Telegraf config](Home_assistant_html_929274bda173b557.png){#Image34 align="bottom" width="778" height="434" border="0"} [[[[Ich greife jetzt einen Schritt vor, denn ich nutze für mein Raspberry Pi Monitoring bei Grafana ein fertiges Dashboard. Und der Entwickler gibt noch ein paar Parameter an, die man in die telegraf.conf eintragen sollte. Daher scrollen wir jetzt sehr weit nach unten bis du „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **INPUT PLUGINS**[[[[" sehen kannst. Direkt da drunter fügst du dann folgendes ein:]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[#In order to monitor both Network interfaces, eth0 and wlan0, uncomment, or add the next:]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[**\[\[**inputs.net**\]\]**]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[**\[\[**inputs.netstat**\]\]**]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[**\[\[**inputs.file**\]\]**]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[files = **\[**\"/sys/class/thermal/thermal_zone0/temp\"**\]**]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[name_override = \"cpu_temperature\"]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[data_format = \"value\"]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[data_type = \"integer\"]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[**\[\[**inputs.exec**\]\]**]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[commands = **\[**\"/opt/vc/bin/vcgencmd measure_temp\"**\]**]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[name_override = \"gpu_temperature\"]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[data_format = \"grok\"]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} [[grok_patterns = **\[**\"%{NUMBER:value:float}\"**\]**]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} ![image 30](Home_assistant_html_794dd4d02d310efd.png){#Image35 align="bottom" width="819" height="767" border="0"} Jetzt speichere die Datei und verlasse sie. Denn hier sind wir erstmal mit fertig.\ Damit wir auf dem Raspberry auch auf die Werte von GPU usw. zugreifen dürfen, müssen wir den telegraf User noch in eine Gruppe hinzufügen: [[sudo usermod -G video telegraf]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} Noch haben unsere Änderungen keine Wirkung, daher starten wir den Service telegraf einmal neu: [[sudo service telegraf restart]{style="background: #282a36"}]{style="display: inline-block; border: none; padding: 0in"} Ab jetzt sollten Daten gesammelt und in die Datenbank geschrieben werden.\ Was weiterhin fehlt ist das Dashboard, damit wir auch etwas sehen, und die Konfiguration zur Datenbank, damit Grafana auch weiß woher die Daten kommen sollen! \ \ \ ### Telegraf with influxdb 2.x {#telegraf-with-influxdb-2.x .western} \ - create database/bucket in influxdb - then, edit telegraf.conf as described in section above but use bucket, token, etc. - need a section \[\[output.influxdb_v2\]\] - \ \ \ \ # add csv data to influxdb / grafana {#add-csv-data-to-influxdb-grafana .western} \ manual entry: Nutrition,measurement=Water,unit=grams value=2000 1645750800000000000 Consumption,measurement=Gas,unit=kWh value=2000 1645750800000000000 Consumption,measurement=Electricity,unit=kWh value=2000 1645750800000000000 Consumption,measurement=Electricity,unit=kWh value=3000 1687377128078000000 \ Timestamp 1687377128 Timestamp in milliseconds 1687377128078 + 000000 ISO 8601 2023-06-21T19:52:08.078Z Date Time (UTC) 21. Juni 2023, 19:52:08 Date Time (your time zone) 21. Juni 2023, 21:52:08 \ \ \ \ \ Operations performed on date data should be automatic provided that the cells are formatted as as a user defined DD.MM.YYYY HH:MM:SS in the \'Format\' \> \'Cells\' \> \'Numbers\' tab. \ If you\'re using the standard settings, LibreOffice Calc uses 12/30/1899 as it\'s default date. So the first step is getting the number of days between 12/30/1899 and 1/1/1970: \ =(DATE(1970,1,1) - DATE(1899,12,30)) = 25569 Number of seconds in a day: \ =(60 \* 60 \* 24) = 86400 If, for example, in cell A2 you have the date 03.12.2013 14:01:49. I subtract the difference between Calc\'s default date and the Unix Epoch we just calculated, and multiply it by the number of seconds in a day: \ [=(A2 - 25569) \* 86400]{style="background: #ffff00"} The result is a value of 1363096909 which is the Epoch time in seconds. If you need it in milliseconds, multiply the equation by 1000. \ \ \ \ \ \ # NOUS A1T with homeassistant {#nous-a1t-with-homeassistant .western} \ \ \ \ integrate via MQTT → Zum Schluss über die Tasmota Console noch folgenden Befehl senden: SetOption19 1 [integrate via Tasmota Integration → SetOption19 0]{style="background: #ffff00"} \ \ [http://192.168.4.1/](http://192.168.4.1/#p) FRITZ!Box 7530 GD 78302839617779115068 \ tasmota-832BEA-3050 with IP address 192.168.178.50 tasmota-836841-2113 with IP address 192.168.178.49 tasmota-8386C8-1736 with IP address 192.168.178.47 tasmota-C68576-1398 with IP address 192.168.178.48 tasmota-833CA2-7330 with IP address 192.168.178.61 tasmota-836841-7745 with IP address 192.168.178.60 tasmota-83310D-4365 with IP address 192.168.178.62 tasmota-837743-5955 with IP address 192.168.178.63 \ [voltageset 220]{style="background: #ffff00"} \ 192.168.178.52 User: note4 Password: note4 \ stat/tasmota_832BEA/RESULT tele/tasmota_832BEA/STATE tele/tasmota_832BEA/SENSOR \ \ [TelePeriod 10]{style="background: #ffff00"} \ \ \ how to keep smart plug powered off after unplugging and re-plugging? 0 / OFF = keep power(s) OFF after power up → [PowerOnState ]{style="background: #ffff00"}[0]{style="background: #ffff00"} 1 / ON = turn power(s) ON after power up \ disable use of button SetOption73 Detach buttons from relays and send multi-press and hold MQTT messages instead 0 = disable (default) 1 = enable → [SetOption73 1]{style="background: #ffff00"} \ \ \ \ \ \ \ \ \ \ # configure network storage (fritz.nas) in home assistant: {#configure-network-storage-fritz.nas-in-home-assistant .western} \ \ \\\\192.168.178.1\\FRITZ.NAS\\USB-SanDisk3-2Gen1-01 http://fritz.box/nas?sid=41098e807aea021b \ \ \ \ \ \ user: homeassistant password: bhasfonworf34534thb fritz.nas/USB-SanDisk3-2Gen1-01/Data \ ![](Home_assistant_html_2dcb84b3a68c1c0c.png){#Image53 align="bottom" width="567" height="421" border="0"} ![](Home_assistant_html_5aabcbff64f7c4de.png){#Image54 align="bottom" width="562" height="466" border="0"} ![](Home_assistant_html_389f84a162b43d24.png){#Image55 align="bottom" width="643" height="90" border="0"} \ \ \ \ \ \ # Zeitpläne nutzen, um mehrere Temperaturen in Home Assistant zu steuern {#zeitpläne-nutzen-um-mehrere-temperaturen-in-home-assistant-zu-steuern .western} \ \ \ \ \ \ \ \ # use Raspberry Pi as WiFi repeater {#use-raspberry-pi-as-wifi-repeater .western} \ \ \ \ \ \ # Timercard (Ein-Aus-Zeit) in HomeAssistant {#timercard-ein-aus-zeit-in-homeassistant .western} \ \ [[[[Ähnlich wie beim ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[[[[Lichtwecker zum Aufstehen ]{style="background: transparent"}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="text-decoration: none"}]{style="font-variant: normal"}](https://smarthomeyourself.de/wiki/homeassistant/lichtwecker-in-homeassistant-erstellen/)[[[[erstellen wir eine Timercard mit On-Off-Time (ideal für die Gartenbewässerung oder ähnliches)]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} []{#more-7101} Als erstes benötigen wir wieder einige Helfer: ``` {.western style="line-height: 150%; text-align: left; orphans: 2; widows: 2; border-top: none; border-bottom: none; border-left: 6.00pt solid #358ccb; border-right: none; padding-top: 0in; padding-bottom: 0in; padding-left: 0.02in; padding-right: 0in; background: transparent"} #- # _ _ _ _ # (_)_ __ _ __ _ _| |_ | |__ ___ ___ | | ___ __ _ _ __ ___ # | | '_ \| '_ \| | | | __| | '_ \ / _ \ / _ \| |/ _ \/ _` | '_ \/ __| # | | | | | |_) | |_| | |_ | |_) | (_) | (_) | | __/ (_| | | | \__ \ # |_|_| |_| .__/ \__,_|\__|___|_.__/ \___/ \___/|_|\___|\__,_|_| |_|___/ # |_| |_____| # #- ## DAYS / WEEKENDS ############################################################## timer_1_mon: name: Montag #initial: off icon: mdi:calendar timer_1_tue: name: Dienstag #initial: off icon: mdi:calendar timer_1_wed: name: Mittwoch #initial: off icon: mdi:calendar timer_1_thu: name: Donnerstag #initial: off icon: mdi:calendar timer_1_fri: name: Freitag #initial: off icon: mdi:calendar timer_1_sat: name: Samstag #initial: off icon: mdi:calendar timer_1_sun: name: Sonntag #initial: off #- # _ _ _ # (_)_ __ _ __ _ _| |_ _ __ _ _ _ __ ___ | |__ ___ _ __ ___ # | | '_ \| '_ \| | | | __| | '_ \| | | | '_ ` _ \| '_ \ / _ \ '__/ __| # | | | | | |_) | |_| | |_ | | | | |_| | | | | | | |_) | __/ | \__ \ # |_|_| |_| .__/ \__,_|\__|___|_| |_|\__,_|_| |_| |_|_.__/ \___|_| |___/ # |_| |_____| # #- ## START TIME ################################################################### timer_1_start_hour: name: Stunden icon: mdi:timer #initial: 6 min: 0 max: 23 step: 1 timer_1_start_minutes: name: Minuten icon: mdi:timer #initial: 30 min: 0 max: 59 ## FINISH TIME ################################################################# timer_1_finish_hour: name: Stunden icon: mdi:timer #initial: 6 min: 0 max: 23 step: 1 timer_1_finish_minutes: name: Minuten icon: mdi:timer #initial: 30 min: 0 max: 59 step: 1 ``` ------------------------------------------------------------------------ Im Gegensatz zum Lichtwecker benötigen wir hier nun 2 Sensoren -- einen für die Startzeit und einen wo Beendet werden soll ``` {.western style="line-height: 150%; text-align: left; orphans: 2; widows: 2; border-top: none; border-bottom: none; border-left: 6.00pt solid #358ccb; border-right: none; padding-top: 0in; padding-bottom: 0in; padding-left: 0.02in; padding-right: 0in; background: transparent"} ####################################################### # # # SCRSENSOR # # # # # ####################################################### ## START TIME ################################################################### - platform: template sensors: timer_1_start_time: friendly_name: 'Start Time' value_template: >- {{ "%0.02d:%0.02d" | format(states("input_number.timer_1_start_hour") | int, states("input_number.timer_1_start_minutes") | int) }} ## FINISH TIME ################################################################# - platform: template sensors: timer_1_finish_time: friendly_name: 'Finish Time' value_template: >- {{ "%0.02d:%0.02d" | format(states("input_number.timer_1_finish_hour") | int, states("input_number.timer_1_finish_minutes") | int) }} ``` ------------------------------------------------------------------------ Und zum Schluss wieder ein Paar Automatisierung, damit alles funktioniert. ``` {.western style="line-height: 150%; text-align: left; orphans: 2; widows: 2; border-top: none; border-bottom: none; border-left: 6.00pt solid #358ccb; border-right: none; padding-top: 0in; padding-bottom: 0in; padding-left: 0.02in; padding-right: 0in; background: transparent"} alias: Timer 1 Starttime description: '' trigger: - platform: time at: '00:01:00' condition: - condition: template value_template: >- {{ is_state('input_boolean.timer_1_' ~ ['mon','tue','wed','thu','fri','sat','sun'][now().weekday()], 'on') }} - condition: template value_template: '{{ now().strftime("%H:%M") == states.sensor.timer_1_start_time.state }}' action: - service: switch.turn_on data: entity_id: - switch.tp_link_01 hide_entity: true mode: single alias: Timer 1 Finishtime description: '' trigger: - platform: time at: '00:01:00' condition: - condition: template value_template: >- {{ is_state('input_boolean.timer_1_' ~ ['mon','tue','wed','thu','fri','sat','sun'][now().weekday()], 'on') }} - condition: template value_template: '{{ now().strftime("%H:%M") == states.sensor.timer_1_finish_time.state }}' action: - service: switch.turn_off data: entity_id: - switch.tp_link_01 hide_entity: true mode: single ``` ------------------------------------------------------------------------ Zum Schluss alles ins Dashboard.... [ [![](Home_assistant_html_acb0022453d57fa7.png){#Image56 align="bottom" width="630" height="509" border="0"}](https://smarthomeyourself.de/wp-content/uploads/2022/05/Bildschirmfoto-2022-05-01-um-11.41.37.png) ]{style="background: transparent"} ``` {.western style="line-height: 150%; text-align: left; orphans: 2; widows: 2; border-top: none; border-bottom: none; border-left: 6.00pt solid #358ccb; border-right: none; padding-top: 0in; padding-bottom: 0in; padding-left: 0.02in; padding-right: 0in; background: transparent"} type: vertical-stack cards: - type: entities show_header_toggle: false entities: - entity: switch.tp_link_01 - entity: sensor.timer_1_start_time icon: mdi:clock-start name: Starten um... - type: custom:fold-entity-row padding: 0 group_config: toggle: false type: custom:slider-entity-row head: label: Uhrzeit type: section items: - entity: input_number.timer_1_start_hour - entity: input_number.timer_1_start_minutes - entity: sensor.timer_1_finish_time name: Beenden um.... icon: mdi:clock-end - type: custom:fold-entity-row padding: 0 group_config: toggle: false type: custom:slider-entity-row head: label: Uhrzeit type: section items: - entity: input_number.timer_1_finish_hour - entity: input_number.timer_1_finish_minutes - type: horizontal-stack cards: - type: custom:button-card name: Mo entity: input_boolean.timer_1_mon icon: mdi:checkbox-blank-circle color: rgb(25, 155, 20) state: - value: 'off' icon: mdi:checkbox-blank-circle-outline color: rgb(61,61,61) - type: custom:button-card name: Di entity: input_boolean.timer_1_tue icon: mdi:checkbox-blank-circle color: rgb(25, 155, 20) state: - value: 'off' icon: mdi:checkbox-blank-circle-outline color: rgb(61,61,61) - type: custom:button-card name: Mi entity: input_boolean.timer_1_wed icon: mdi:checkbox-blank-circle color: rgb(25, 155, 20) state: - value: 'off' icon: mdi:checkbox-blank-circle-outline color: rgb(61,61,61) - type: custom:button-card name: Do entity: input_boolean.timer_1_thu icon: mdi:checkbox-blank-circle color: rgb(25, 155, 20) state: - value: 'off' icon: mdi:checkbox-blank-circle-outline color: rgb(61,61,61) - type: custom:button-card name: Fr entity: input_boolean.timer_1_fri icon: mdi:checkbox-blank-circle color: rgb(25, 155, 20) state: - value: 'off' icon: mdi:checkbox-blank-circle-outline color: rgb(61,61,61) - type: custom:button-card name: Sa entity: input_boolean.timer_1_sat icon: mdi:checkbox-blank-circle color: rgb(25, 155, 20) state: - value: 'off' icon: mdi:checkbox-blank-circle-outline color: rgb(61,61,61) - type: custom:button-card name: So entity: input_boolean.timer_1_sun icon: mdi:checkbox-blank-circle color: rgb(25, 155, 20) state: - value: 'off' icon: mdi:checkbox-blank-circle-outline color: rgb(61,61,61) ``` \# https://smarthomeyourself.de/wiki/homeassistant/naechsten-ausfuehrungszeitpunkt-von-aktiven-zeitplaenen-der-scheduler-card-mit-einem-template-sensor-ermitteln/ \- platform: template sensors: next_scheduler: friendly_name: \"Nächster Scheduler\" state: \> {%- set x = states.switch \| selectattr(\'entity_id\', \'in\', state_attr(\'group.schedulers\', \'entity_id\'))\| selectattr(\'state\',\'eq\',\'on\')\|list -%} {% if x \| count \> 0 %} {{ x\[0\].name }} {% else %} Kein Eintrag in der Liste {%- endif -%} attributes: next_run: \> {%- set x = states.switch \| selectattr(\'entity_id\', \'in\', state_attr(\'group.schedulers\', \'entity_id\'))\| selectattr(\'state\',\'eq\',\'on\')\|list -%} {% if x \| count \> 0 %} {{ as_timestamp( x\[0\].attributes.next_trigger ) \| timestamp_custom(\"%d.%m.%Y, %H:%M Uhr\") }} {% else %} Kein Eintrag in der Liste {%- endif -%} \ \ \ \ \ # ESP32-CAM PIR Motion Detector with Photo Capture {#esp32-cam-pir-motion-detector-with-photo-capture .western} ![](Home_assistant_html_f9a46a8b6be4893.png){#Image59 align="bottom" width="643" height="243" border="0"} \ \ \ \ [PIR is connected via a transistor!!]{style="background: #ffff00"} \ For this project, you'll need the following parts: \ ESP32-CAM with OV2640 -- read Best ESP32-CAM Dev Boards MicroSD card PIR motion sensor 2N3904 transistor FTDI programmer Female-to-female jumper wires 5V power supply for ESP32-CAM or power bank (optional) \ ![](Home_assistant_html_69b921e4cd60a802.png){#Image57 align="bottom" width="554" height="403" border="0"} ![](Home_assistant_html_569811fbb614e552.png){#Image58 align="bottom" width="643" height="306" border="0"} \ \ ``` western /********* Rui Santos Complete project details at https://RandomNerdTutorials.com/esp32-cam-pir-motion-detector-photo-capture/ IMPORTANT!!! - Select Board "AI Thinker ESP32-CAM" - GPIO 0 must be connected to GND to upload a sketch - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. *********/ #include "esp_camera.h" #include "Arduino.h" #include "FS.h" // SD Card ESP32 #include "SD_MMC.h" // SD Card ESP32 #include "soc/soc.h" // Disable brownour problems #include "soc/rtc_cntl_reg.h" // Disable brownour problems #include "driver/rtc_io.h" #include // read and write from flash memory // define the number of bytes you want to access #define EEPROM_SIZE 1 RTC_DATA_ATTR int bootCount = 0; // Pin definition for CAMERA_MODEL_AI_THINKER #define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 int pictureNumber = 0; void setup() { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector Serial.begin(115200); Serial.setDebugOutput(true); camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; pinMode(4, INPUT); digitalWrite(4, LOW); rtc_gpio_hold_dis(GPIO_NUM_4); if(psramFound()){ config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 12; config.fb_count = 1; } // Init Camera esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } Serial.println("Starting SD Card"); delay(500); if(!SD_MMC.begin()){ Serial.println("SD Card Mount Failed"); //return; } uint8_t cardType = SD_MMC.cardType(); if(cardType == CARD_NONE){ Serial.println("No SD Card attached"); return; } camera_fb_t * fb = NULL; // Take Picture with Camera fb = esp_camera_fb_get(); if(!fb) { Serial.println("Camera capture failed"); return; } // initialize EEPROM with predefined size EEPROM.begin(EEPROM_SIZE); pictureNumber = EEPROM.read(0) + 1; // Path where new picture will be saved in SD Card String path = "/picture" + String(pictureNumber) +".jpg"; fs::FS &fs = SD_MMC; Serial.printf("Picture file name: %s\n", path.c_str()); File file = fs.open(path.c_str(), FILE_WRITE); if(!file){ Serial.println("Failed to open file in writing mode"); } else { file.write(fb->buf, fb->len); // payload (image), payload length Serial.printf("Saved file to path: %s\n", path.c_str()); EEPROM.write(0, pictureNumber); EEPROM.commit(); } file.close(); esp_camera_fb_return(fb); delay(1000); // Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4 pinMode(4, OUTPUT); digitalWrite(4, LOW); rtc_gpio_hold_en(GPIO_NUM_4); esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0); Serial.println("Going to sleep now"); delay(1000); esp_deep_sleep_start(); Serial.println("This will never be printed"); } void loop() { } ``` \ \ \ \ \ \ \ # ESP32-CAM Video Streaming Web Server (works with Home Assistant) {#esp32-cam-video-streaming-web-server-works-with-home-assistant .western} \ \ ``` western /********* Rui Santos Complete project details at https://RandomNerdTutorials.com/esp32-cam-video-streaming-web-server-camera-home-assistant/ IMPORTANT!!! - Select Board "AI Thinker ESP32-CAM" - GPIO 0 must be connected to GND to upload a sketch - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. *********/ #include "esp_camera.h" #include #include "esp_timer.h" #include "img_converters.h" #include "Arduino.h" #include "fb_gfx.h" #include "soc/soc.h" //disable brownout problems #include "soc/rtc_cntl_reg.h" //disable brownout problems #include "esp_http_server.h" //Replace with your network credentials const char* ssid = "REPLACE_WITH_YOUR_SSID"; const char* password = "REPLACE_WITH_YOUR_PASSWORD"; #define PART_BOUNDARY "123456789000000000000987654321" // This project was tested with the AI Thinker Model, M5STACK PSRAM Model and M5STACK WITHOUT PSRAM #define CAMERA_MODEL_AI_THINKER //#define CAMERA_MODEL_M5STACK_PSRAM //#define CAMERA_MODEL_M5STACK_WITHOUT_PSRAM // Not tested with this model //#define CAMERA_MODEL_WROVER_KIT #if defined(CAMERA_MODEL_WROVER_KIT) #define PWDN_GPIO_NUM -1 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 21 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 19 #define Y4_GPIO_NUM 18 #define Y3_GPIO_NUM 5 #define Y2_GPIO_NUM 4 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 #elif defined(CAMERA_MODEL_M5STACK_PSRAM) #define PWDN_GPIO_NUM -1 #define RESET_GPIO_NUM 15 #define XCLK_GPIO_NUM 27 #define SIOD_GPIO_NUM 25 #define SIOC_GPIO_NUM 23 #define Y9_GPIO_NUM 19 #define Y8_GPIO_NUM 36 #define Y7_GPIO_NUM 18 #define Y6_GPIO_NUM 39 #define Y5_GPIO_NUM 5 #define Y4_GPIO_NUM 34 #define Y3_GPIO_NUM 35 #define Y2_GPIO_NUM 32 #define VSYNC_GPIO_NUM 22 #define HREF_GPIO_NUM 26 #define PCLK_GPIO_NUM 21 #elif defined(CAMERA_MODEL_M5STACK_WITHOUT_PSRAM) #define PWDN_GPIO_NUM -1 #define RESET_GPIO_NUM 15 #define XCLK_GPIO_NUM 27 #define SIOD_GPIO_NUM 25 #define SIOC_GPIO_NUM 23 #define Y9_GPIO_NUM 19 #define Y8_GPIO_NUM 36 #define Y7_GPIO_NUM 18 #define Y6_GPIO_NUM 39 #define Y5_GPIO_NUM 5 #define Y4_GPIO_NUM 34 #define Y3_GPIO_NUM 35 #define Y2_GPIO_NUM 17 #define VSYNC_GPIO_NUM 22 #define HREF_GPIO_NUM 26 #define PCLK_GPIO_NUM 21 #elif defined(CAMERA_MODEL_AI_THINKER) #define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 #else #error "Camera model not selected" #endif static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; httpd_handle_t stream_httpd = NULL; static esp_err_t stream_handler(httpd_req_t *req){ camera_fb_t * fb = NULL; esp_err_t res = ESP_OK; size_t _jpg_buf_len = 0; uint8_t * _jpg_buf = NULL; char * part_buf[64]; res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE); if(res != ESP_OK){ return res; } while(true){ fb = esp_camera_fb_get(); if (!fb) { Serial.println("Camera capture failed"); res = ESP_FAIL; } else { if(fb->width > 400){ if(fb->format != PIXFORMAT_JPEG){ bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len); esp_camera_fb_return(fb); fb = NULL; if(!jpeg_converted){ Serial.println("JPEG compression failed"); res = ESP_FAIL; } } else { _jpg_buf_len = fb->len; _jpg_buf = fb->buf; } } } if(res == ESP_OK){ size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len); res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); } if(res == ESP_OK){ res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); } if(res == ESP_OK){ res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); } if(fb){ esp_camera_fb_return(fb); fb = NULL; _jpg_buf = NULL; } else if(_jpg_buf){ free(_jpg_buf); _jpg_buf = NULL; } if(res != ESP_OK){ break; } //Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len)); } return res; } void startCameraServer(){ httpd_config_t config = HTTPD_DEFAULT_CONFIG(); config.server_port = 80; httpd_uri_t index_uri = { .uri = "/", .method = HTTP_GET, .handler = stream_handler, .user_ctx = NULL }; //Serial.printf("Starting web server on port: '%d'\n", config.server_port); if (httpd_start(&stream_httpd, &config) == ESP_OK) { httpd_register_uri_handler(stream_httpd, &index_uri); } } void setup() { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector Serial.begin(115200); Serial.setDebugOutput(false); camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; if(psramFound()){ config.frame_size = FRAMESIZE_UXGA; config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 12; config.fb_count = 1; } // Camera init esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } // Wi-Fi connection WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.print("Camera Stream Ready! Go to: http://"); Serial.print(WiFi.localIP()); // Start streaming web server startCameraServer(); } void loop() { delay(1); } ``` \ \ \ \ \ \ \ \ \ \ \ \ \ # ESP32-CAM with Tasmota {#esp32-cam-with-tasmota .western} \ use webinstaller to flash webcam firmware \ connect to AP and open 192.168.4.1 \ \ \ \ how can i activte the rtsp stream? Enter on console: wcrtsp 1 [wcrtsp 0]{style="background: #ffff00"} \ wcstream 0 stops the HTTP stream \ \ ==\> rtsp://IP_der_Kamera:8554/mjpeg/1 rtsp://192.168.178.76:8554/mjpeg/1 \ \ http://192.168.178.76:81/stream [http://192.168.178.76:81/cam.mjpeg]{style="background: #ffff00"} \ \ \ **(4g) Tasmota Einstellungen - Sende- und Abrufintervall, Zeitzone und Home Assistant** 1\. Configure other (Configuration -\> Configure Other):  - MQTT = enabled - Device Name = MT175 (oder wählt einen anderen Namen) 2\. Sende/Abruf Intervall einstellen (Configuration -\> Configure Logging) - Telemetry period\ (Wie oft soll der Wert an HA geschickt werden z.B. 60s) 4\. Main Menu -\> Console: - [[[[Wenn ihr die ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}**[[[[[**Tasmota Home Assistant Integration**]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="text-decoration: none"}]{style="font-variant: normal"}](https://www.home-assistant.io/integrations/tasmota/){target="_blank"}**[[[[ nutzen wollt müsst nicht nichts ändern, da SetOption19 bereits auf 0 eingestellt ist]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} - Wenn ihr verhindern wollt, dass Tasmota rebootet wenn euer WLAN Router mal nicht verfügbar ist dann folgendes eintippen: WifiConfig 5\ (wait until selected AP is available again without rebooting) - Falls ihr Probleme mit der Uhrzeit/Zeitumstellung habt, folgendes eingeben: - Backlog0 Timezone 99; TimeStd 0,0,10,1,3,60; TimeDst 0,0,3,1,2,120 - Skript bezogene Einstellungen findet ihr direkt im Skript ganz oben erklärt (englisch) \ \ \ +-------------+--------+---------------------------------------------+ | SetOption19 | 1 / on | [aktiviert die automatische Erkennung von | | | | Home-Assistant Komponenten (auch: Domoticz | | | | MQTT Discovery).\ | | | | ]{style="font-weight: normal"}* | | | | *[Achtung]{style="font-weight: normal"}**[: | | | | Setoption19 1 ändert die Reihenfolge der | | | | MQTT-Topics | | | | auf %topi | | | | c%/%prefix%/ (Standard: %prefix%/%topic%/). | | | | Dies lässt sich auch nicht durch einen | | | | entsprechenden Konsolenbefehl fulltopic | | | | %prefix%/%topic | | | | %/ erzwingen.]{style="font-weight: normal"} | +-------------+--------+---------------------------------------------+ \ \ SetOption19 0 \ \ \ \ +------------------------+--------------------------------------------+ | []{#wcstream} WcStream | `1`{.western}[ = start webcam stream at | | | http://\:81/stream or | | | http://\:81/cam.mjpeg\ | | | ]{style="font-weight: normal"} | | | | | | `0`{.western}[ = stop | | | stream]{style="font-weight: normal"} | +------------------------+--------------------------------------------+ \ []{#wcstream1}[WcStream 1]{style="background: #ffff00"} \ +--------------------------------+------------------------------------+ | []{#wcresolution} WcResolution | [Set camera resolution.\ | | | ]{style="font-weight: normal"} | | | | | | `0`{.western}[ = 96x96 (96x96)\ | | | ]{style="font-weight: normal"} | | | | | | `1`{.western}[ = QQVGA2 (128x160)\ | | | ]{style="font-weight: normal"} | | | | | | `2`{.western}[ = QCIF (176x144)\ | | | ]{style="font-weight: normal"} | | | | | | `3`{.western}[ = HQVGA (240x176)\ | | | ]{style="font-weight: normal"} | | | | | | `4`{.western}[ = QVGA (320x240)\ | | | ]{style="font-weight: normal"} | | | | | | `5`{.western}[ = CIF (400x296)\ | | | ]{style="font-weight: normal"} | | | | | | `6`{.western}[ = VGA (640x480)\ | | | ]{style="font-weight: normal"} | | | | | | `7`{.western}[ = SVGA (800x600)\ | | | ]{style="font-weight: normal"} | | | | | | `8`{.western}[ = XGA (1024x768)\ | | | ]{style="font-weight: normal"} | | | | | | `9`{.western}[ = SXGA (1280x1024)\ | | | ]{style="font-weight: normal"} | | | | | | `10`{.western}[ = UXGA | | | (1600x1 | | | 200)]{style="font-weight: normal"} | +--------------------------------+------------------------------------+ \ []{#wcresolution1}[WcResolution 10 → XGA (1024x768)]{style="background: transparent"} []{#wcresolution11}[WcResolution 12 → UXGA (1600x1200)]{style="background: #ffff00"} \ WcClock 200 \ \ \ \ ON \ DO \ \[ENDON \| BREAK\] \ \ ----------------------------- ------------------------------------------------------ []{#TimeMinute} Time#Minute every minute Time#Minute\|5 every five minutes Time#Minute=241 every day once at 04:01 (241 minutes after midnight) ----------------------------- ------------------------------------------------------ \ **Restart at specific time each da of the week:** [Timer1 {\"Enable\":1,\"Mode\":0,\"Time\":\"04:0\",\"Window\":0,\"Days\":\"1111111\",\"Repeat\":1,\"Action\":3}]{style="background: #ffff00"} [Rule1 ON clock#Timer=1 DO Restart 1 ENDON]{style="background: #ffff00"} [Rule1 1]{style="background: #ffff00"} \ **[Restart every 5 min:]{style="background: transparent"}** [Rule1 ON [Time#Minute\|5]{style="font-weight: normal"} DO Restart 5 ENDON]{style="background: transparent"} [Rule1 1]{style="background: transparent"} \ \ \ \ \ \ # Petoneer Smart Dot Add-on {#petoneer-smart-dot-add-on .western} add repository: https://github.com/marcomow/hass-addons \ \ \ modification for tasmota \ \ \ \ \ # Install Petkit devices {#install-petkit-devices .western} \ Account email: account password: \ \ \ \ # perfboard design with fritzing {#perfboard-design-with-fritzing .western} \ Select breadboard view (probably delete the breadboard to reduce clutter) then in the parts window on the right select core and move down to the category breadboard view near the bottom. There select the type of perfboard you want and drag it to the breadboard window. Once it is in the window the inspector window on the bottom right will let you change various things about it such as size and prefboard / stripboard. \ \ \ \ \ \ # Frigate {#frigate .western} \ attention to frame size configuration and ffmpeg declaration! \ \ LINKS: \ \ Frigate repository: https://github.com/blakeblackshear/fr\... \ Go2RTC repository: https://github.com/AlexxIT/hassio-addons \ \ Frigate configuration: https://docs.frigate.video/configurat\... \ Go2RTC: https://github.com/AlexxIT/go2rtc \ \ Go2RTC.yaml: https://pastebin.com/Fagfm1sC \ Frigate.yml: \ \ \ \ \ \ \ \ ## stream Tapo C220 with Frigate {#stream-tapo-c220-with-frigate .western} tapo: ffmpeg: inputs: \# Für 1080P (1920\*1080) stream: rtsp://username:password@IP Address:554/stream1 \# Für 360P (640\*360) stream: rtsp://username:password@IP Address:554/stream2 \- path: rtsp://tapocam:watchmyhome90@192.168.178.21:554/stream2?video&audio=all roles: \- detect detect: width: 640 height: 360 \ \ \ \ \ \ \ \ \ # operating touch button with Arduino {#operating-touch-button-with-arduino .western} \ \ \ \ \ \ \ # control Duux Whisper Flex Ultimate {#control-duux-whisper-flex-ultimate .western} Add Duux to Tuya Smart Life app add Tuya integration to homeassistant, which should automatically identif device create scene in app and reload integration \ \ \ \ # use ESP32 as BLE hub or repeater {#use-esp32-as-ble-hub-or-repeater .western} Hier fügst du folgende URL hinzu: https://dl.espressif.com/dl/package_esp32_index.json \ Als nächstes müssen zusätzliche Bibliotheken installiert werden. Hier die Übersicht, welche das sind: \ NimBLEDevice EspMQTTClient ArduinoJson CRC32 library (by Christopher Baker) ArduinoQueue \ Sind Arduino Vorbereitungen erledigt kannst du den Projektcode vom Github herunter laden. \ [[[[Die Zip Datei wird entpackt und die Datei ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **SwitchBot-BLE2MQTT-ESP32.ino**[[[[ in Arduino geöffnet. Im Bereich ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **„** **Configurations to change"**[[[[ müssen nun noch ein paar Einstellungen vorgenommen werden.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 1. Zunächst werden im ersten Abschnitt deine WLAN Daten eingetragen 2. Danach folgen die Angaben zu deinem MQTT Broker 3. [[[[Als nächsten werden die BLE Adressen der ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [Switchbot](https://amzn.to/39MJeTa){target="_blank"}[[[[ Geräte hinterlegt und die Bereiche entsprechend einkommentiert.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [![Arduino Projektcode anpassen](Home_assistant_html_b50bb11cf20b1254.png){#Image60 align="bottom" width="806" height="330" border="0"} [[Arduino Projektcode]{style="font-weight: normal"}]{style="font-style: normal"}]{style="display: inline-block; border: none; padding: 0in"} Zum Schluss noch definieren ob dein Board eine LED hat oder nicht. Im Falle des von mir verwendeten ESP32 ist das folgende Einstellung [![ESP32 LED on Board oder nicht.](Home_assistant_html_f5f44e841889b68c.png){#Image61 align="bottom" width="806" height="158" border="0"} [[ESP32 LED]{style="font-weight: normal"}]{style="font-style: normal"}]{style="display: inline-block; border: none; padding: 0in"} [[[[Nun kann der Sketch kompiliert und auf den ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [ESP32](https://amzn.to/3NiZ3i6){target="_blank"}[[[[ geflasht werden.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [![ESP32 Switchbot Sketch kompilieren](Home_assistant_html_1386d908c9ebed2b.png){#Image62 align="bottom" width="757" height="227" border="0"} [[ESP32 Sketch kompilieren]{style="font-weight: normal"}]{style="font-style: normal"}]{style="display: inline-block; border: none; padding: 0in"} **Switchbot Geräte per MQTT in Home Assistant** [[[[Nach einem Neustart des ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [ESP32](https://amzn.to/3NiZ3i6){target="_blank"}[[[[ sollten alle erreichbaren Switchbot Geräte per Auto-Discovery in der MQTT Karte in Home Assistant zu sehen sein.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} \ \ \ \ \ \ # Best thermostat to control tado {#best-thermostat-to-control-tado .western} \ RU4251787008: wall thermostat IB1670717952: internet bridge; connected to router \ \ \ Definition of entity_id: climate.tado_wohnzimmer: tado integration \ correct tado temperature: /config/sensor/templates.yaml \ calculate average temperature of thermostates: /config/sensor/temp_indoors_average.yaml \ adjust temperature of tado with another sensor.sensor1: /config/automations/automations.yaml alias: Trigger if the state of either thermostat changes standard is 0.5 °C delta \ adjust dynamics of temperature controller \ \ turn off central heater or single thermostat based on presence: /config/automations/home-away.yaml \ \ \ \ \ \ # Fritz box: detect new devices in homeassistant {#fritz-box-detect-new-devices-in-homeassistant .western} \- platform: event id: \"state\" event_type: entity_registry_updated event_data: action: create \ trigger.event.data.entity_id \ \- \"{{trigger.event.data.entity_id.startswith(\'device_tracker\')}}\" \ \ \ \ \ # install Conbee III {#install-conbee-iii .western} \ /dev/serial/by-id/usb-dresden_elektronik_ConBee_III_DE03188934-if00-port0 \ ls /dev/serial/by-id \ \ \ \ List your devices... ``` {.western style="orphans: 2; widows: 2; margin-bottom: 0.2in"} ls /dev > ~/devices.txt ``` \ [[[[NOW plug in ConBee II to USB Port (via USB extension cable)]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} - Reboot. Find the ConBee II device ``` {.western style="orphans: 2; widows: 2"} ls /dev > ~/devices2.txt diff ~/devices.txt ~/devices2.txt ``` [[[[This will show the new device.\ In my case it was ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`/dev/ttyACM0`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} \ \ \ \ \ \ \ \ \ \ \ ## firmware update {#firmware-update .western} GCFFlasher -l GCFFlasher -d COM29 -t 60 -f deCONZ_ConBeeIII_0x264f0900.bin.GCF \ in case of powershell: .\\GCFFlasher -l .\\GCFFlasher -d COM29 -t 60 -f deCONZ_ConBeeIII_0x264f0900.bin.GCF \ \ ## Connect Philips Hue bulb to Conbee {#connect-philips-hue-bulb-to-conbee .western} 1. It seems as if activation of both ZHA and deConz leads to interferences → ZHA alone seems to work 2. Delete bulb in the app 3. if lamp is not immediately recognized, searching for devices with ZHA or deConz will find device automatically \ \ ## Connect Philips Motion Sensor {#connect-philips-motion-sensor .western} 1. delete the sensor from the app 2. push the reset button for 10 s 3. once the orange LED blinks, the device is read for pairing 4. \ \ ## Connect Bosch Smart radiatorThermostate to Conbee {#connect-bosch-smart-radiatorthermostate-to-conbee .western} Thermostate 1: 18FC2600000615BD FC32-9603-E07B 5182-1390-11E8 209B-5433-A9D3 service: zha.permit\ data:\ duration: 60\ ieee: 00:21:2e:ff:ff:0e:1d:f6\ source_ieee: 18:fc:26:00:00:06:15:bd\ install_code: FC32-9603-E07B-5182-1390-11E8-209B-5433-A9D3 \ Via HACS install ZHA toolkit 1. In configuration.yaml add a line zha_toolkit: 2. On the battery cap or on the radiator behind the batteries note the ZigBee EUI-64 code ('Source IEEE') and the Install Code. 3. Go to Developer tools, services, service: Zigbee Home Automation: Permit 4. Enter the Source IEEE code and the install code in the UI. INSTALL 5. YAML looks like this: 6. service: zha.permit 7. data: 8. install_code: 379E-1234-ABCD-E529-1234-E6FE-ABCD-A70F-1234 9. source_ieee: 18:fc:26:00:00:dc:ba:ab 10. After INSTALL, go to Settings, Intergrations, Zigbee Home Automation. Your device should be listed now 11. Done. \ Via HACS install ZHA toolkit 1. [[[[In configuration.yaml add a line ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`zha_toolkit:`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 2. On the battery cap or on the radiator behind the batteries note the ZigBee EUI-64 code ('Source IEEE') and the Install Code. 3. [[[[Go to Developer tools, services, service: ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`Zigbee Home Automation: Permit`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 4. Enter the Source IEEE code and the install code in the UI. INSTALL 5. [[[[YAML looks like this:\ service: zha.permit\ data:\ install_code: ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[`379E-1234-ABCD-E529-1234-E6FE-ABCD-A70F-1234`{.western}]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}[[[[\ source_ieee: 18:fc:26:00:00:dc:ba:ab]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} 6. After INSTALL, go to Settings, Intergrations, Zigbee Home Automation. Your device should be listed now 7. Done. \ \ \ \ \ \ Wie setze ich das Bosch Smart Home Heizkörper-Thermostat II auf die Werkseinstellungen zurück (Zurücksetzen)? Um das Bosch Smart Home Heizkörper-Thermostat II auf die Werkseinstellungen zurückzusetzen gehen Sie wie folgt vor: \ Entfernen Sie eine Batterie. Während Sie die Bedientaste (\"o\") gedrückt halten, setzen Sie die Batterie wieder ein. Halten Sie die Taste solange gedrückt bis die Status-LED orange blinkt und auf dem Display \"RES\" steht. Lassen Sie die Taste nun kurz los und drücken Sie die Taste erneut solange bis die Status-LED grün aufleuchtet. Das Bosch Smart Home Heizkörper-Thermostat II wird nun auf die Werkseinstellungen zurückgesetzt. Bitte beachten Sie, dass hierbei nur die Daten auf dem Bosch Smart Home Heizkörper-Thermostat II selbst, aber nicht auf dem Bosch Smart Home Controller gelöscht werden. Um die Daten auf dem Bosch Smart Home Controller zu löschen, öffnen Sie die Geräteeinstellungen in der Bosch Smart Home App und löschen dort das entsprechende Gerät. \ Bitte beachten Sie hierzu auch unser Reset-Video in diesem Artikel. Sollte es Probleme bei der Darstellung des Videos geben, dann finden Sie unsere Installations- und Reset-Videos auch auf unserem Bosch Smart Home Youtube Channel unter folgendem Link. \ \ \ [[[[To add new devices to the network, call the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `permit`{.western}[[[[ service on the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `zha`{.western}[[[[ domain. Do this by clicking the Service icon in Developer tools and typing ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} `zha.permit`{.western}[[[[ in the ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}**[[[**Service**]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}**[[[[ dropdown box. Next, follow the device instructions for adding, scanning or factory reset.]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}\ \ \ \ \ \ \ ## Use REST client {#use-rest-client .western} \ Talend API Tester - Free Edition \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ # install proxmox server {#install-proxmox-server .western} \ \ \ \ \ \ Proxmox [https://www.cyberithub.com/how-to-install-proxmox-ve-step-by-step-guide/](https://www.cyberithub.com/how-to-install-proxmox-ve-step-by-step-guide/#Step_4_Install_Proxmox_VE)[#Step_4_Install_Proxmox_VE](https://www.cyberithub.com/how-to-install-proxmox-ve-step-by-step-guide/#Step_4_Install_Proxmox_VE) \ \ Nextcloud ttek \ \ Homeassistant ttek \ \ mqtt ttek \ Mariadb ttek \ \ influx db ttek \ \ grafana ttek \ \ adguard ttek \ \ Node-RED ttek \ Visual Studio Code tte \ \ frigate \ \ Vaultwarden ttek \ Nginx Proxy Manager ttek \ Syncthing ttek \ \ Wiki.js ttek \ \ WireGuard ttek \ \ deCONZ ttek \ grocy ttek \ \ \ \ \ \ # Win tips {#win-tips .western} ## open disk manager as admin {#open-disk-manager-as-admin .western} Open Run from the Start menu or Apps screen. Type diskmgmt.msc and press Enter. \ \ ## Formatting disk via command prompt → dangerous!!! {#formatting-disk-via-command-prompt-dangerous .western} Die Windows-Eingabeaufforderung hat ähnliche Funktionen wie die Datenträgerverwaltung, erfordert jedoch hervorragende Fähigkeiten, insbesondere in den Befehlszeilen. Es kann einige USB-Probleme lösen, indem es mit verschiedenen Befehlen formatiert wird. Befolgen Sie die Schritte, um zu sehen, wie Sie dieses Tool zum Formatieren von USB-Sticks verwenden. [[[[Schritt 1. Geben Sie „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **cmd**[[[[" in die Suchleiste ein, klicken Sie mit der rechten Maustaste auf die ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Eingabeaufforderung **[[[[und wählen Sie „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Als Administrator ausführen**[[[[".]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[[[Schritt 2. Geben Sie nacheinander die folgenden Befehlszeilen ein und drücken Sie jedes Mal „]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} **Enter**[[[[":]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} - **diskpart** - **list disk** - **select disk n**[[[[ (n ist die Nummer des USB-Sticks)]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} - **clean** - **create partition primary** - **format fs=fat32 quick**[[[[ (Sie können fat32 durch ntfs oder exfat ersetzen.)]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"} [[ [![USB-Stick formatieren mit Eingabeaufforderung](Home_assistant_html_9b588e9199f4f42.png){#Image63 align="bottom" width="406" height="375" border="1"}](https://www.diskpart.com/screenshot/de/windows-tools/cmd/format-hard-drive-from-command-prompt-in-windows.png){target="_blank"} ]{style="background: transparent"}]{style="display: inline-block; border: none; padding: 0in"} \ \ \ \ \ \ \ # Mycropython IDEs {#mycropython-ides .western} ## [Thonny]{style="background: #81d41a"} {#thonny .western} \ sudo apt install python3-tk thonny \ \ ## [VSCode]{style="background: #c9211e"} {#vscode .western} \ \ \ https://www.bordergate.co.uk/configuring-an-esp32-in-ubuntu-22-04/ First plug the device in, and check it's recognised by the operating system using the lsusb command. You should see an entry similar to the following: \>\>lsusb Bus 001 Device 006: ID 303a:4001 Espressif Systems Espressif Device \ Using the dmesg command, you should be able to see the device being allocated a TTY: \>\> sudo dmesg cdc_acm 1-4:1.0: ttyACM0: USB ACM device \ \>\>screen /dev/ttyACM0 115200 \ You may need to add the user to the "dialout" and "tty" groups to access the TTY device: \>\>sudo usermod -a -G dialout \ \>\>sudo usermod -a -G tty \ \ Log out after making the usermod change. Next attempt to connect to the device using screen: \>\>screen /dev/ttyACM0 115200 \ If the device is working, you should get a blank screen. If you receive an error about screen terminating, something has went wrong... \ ls -l /dev/ttyACM0 \ sudo usermod -aG dialout \$USER sudo usermod -aG tty \$USER \ sudo adduser \$USER dialout sudo chmod a+rw /dev/ttyACM0 \ **==\> need to reboot for effects to take place!!** \ \ ## Flashing Mycropython firmware {#flashing-mycropython-firmware .western} See also esptool.txt document pip install esptool pip install setuptools python -m esptool \ **e.g., T-Display-S3:** cd \"/home/bora/Documents/Home Assistant/Micropython\" python -u -m esptool \--chip esp32s3 \--port /dev/ttyACM0 erase_flash python -u -m esptool \--chip esp32s3 \--port /dev/ttyACM0 write_flash -z 0x0 firmware_t-display-s3_st7789s3_esp_lcd_v1.20.1.bin ==\> several trials with pushing the BOOT button might be required! \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \