10029 lines
232 KiB
Markdown
10029 lines
232 KiB
Markdown
---
|
||
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
|
||
|
||
|
||
|
||
<https://community.home-assistant.io/t/how-to-manually-set-state-value-of-sensor/43975/21>
|
||
|
||
\- 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"}
|
||
|
||
- [{#Image51
|
||
align="bottom" width="547" height="113" border="0"}
|
||
]{style="background: #e8f2a1"}
|
||

|
||
|
||
- [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"}
|
||
|
||
- [<http://192.168.178.52:8123/api/hassio_ingress/FJZMGvrT7OnlTzBKdUP9jKiKEe4yp4V4D5VT4zHP5cQ/sources/0/hosts>]{style="background: #e8f2a1"}
|
||
|
||
- [<http://192.168.178.52:8123/hassio/ingress/a0d7b954_influxdb>]{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"}
|
||
|
||
- [<http://192.168.178.52:8123/hassio/ingress/a0d7b954_grafana>]{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
|
||
|
||
\
|
||
|
||
{#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}
|
||
|
||
<https://www.home-assistant.io/integrations/python_script>
|
||
|
||
\
|
||
|
||
## Example 1 {#example-1 .western}
|
||
|
||
<https://community.home-assistant.io/t/how-to-manually-set-state-value-of-sensor/43975/5>
|
||
|
||
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}
|
||
|
||
<https://www.home-assistant.io/integrations/python_script#calling-services>
|
||
|
||
\
|
||
|
||
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"}
|
||
`<config>/python_scripts`{.western}
|
||
- [[[[Create a
|
||
file ]{style="font-weight: normal"}]{style="font-style: normal"}]{style="letter-spacing: normal"}]{style="font-variant: normal"}
|
||
`<config>/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}
|
||
|
||
<https://www.pieterbrinkman.com/2022/01/01/2022-update-flash-esphome-on-esp32-esp2866-nodemcu-board/>
|
||
|
||
\
|
||
|
||
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.
|
||
|
||
{#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}
|
||
|
||
<https://www.pieterbrinkman.com/2021/02/03/build-a-cheap-air-quality-meter-using-esphome-home-assistant-and-a-particulate-matter-sensor/>
|
||
|
||
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.
|
||
|
||
{#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.
|
||
|
||
{#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.
|
||
|
||
{#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}
|
||
|
||
<https://www.berrybase.de/esp32-nodemcu-development-board?sPartner=g_shopping&gclid=Cj0KCQiAnNacBhDvARIsABnDa68SnJ4bQ8qK-zWJiPZKsqYP245LF2rjMlnLhZHn7BHi7THLCbbWnOcaAvoOEALw_wcB>
|
||
|
||
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
|
||
|
||
{#Image5 align="left"
|
||
width="362" height="212" border="0"}\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
{#Image6 align="left"
|
||
width="643" height="151" border="0"}
|
||
{#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}
|
||
|
||
<https://github.com/tschamm/boschshc-hass>
|
||
|
||
\
|
||
|
||
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}
|
||
|
||
<https://smarthomescene.com/guides/top-10-home-assistant-lovelace-themes/>
|
||
|
||
[[[[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
|
||
|
||
<http://nilhcem.com/iot/home-monitoring-with-mqtt-influxdb-grafana>
|
||
|
||
\
|
||
\
|
||
|
||
[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
|
||
|
||
<https://luigi-saetta.medium.com/evolving-my-home-automation-setup-af0323097d51>
|
||
|
||
<https://luigi-saetta.medium.com/evolving-my-home-automation-2-e9b30c2eae54>
|
||
|
||
\
|
||
\
|
||
|
||
Example 4
|
||
|
||
<https://randomnerdtutorials.com/esp32-influxdb/>
|
||
|
||
\
|
||
\
|
||
|
||
<https://randomnerdtutorials.com/esp32-esp8266-sensor-bme280-influxdb/>
|
||
|
||
ssh into rapi via PUTT:
|
||
|
||
<https://randomnerdtutorials.com/esp32-mqtt-publish-subscribe-arduino-ide/>
|
||
|
||
\
|
||
\
|
||
|
||
<https://diyi0t.com/home-assistant-mqtt-tutorial/>
|
||
|
||
<https://community.home-assistant.io/t/publish-mqtt/324939/2>
|
||
|
||
<https://www.home-assistant.io/blog/2015/09/11/different-ways-to-use-mqtt-with-home-assistant/>
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
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}
|
||
|
||
<https://philhawthorne.com/getting-started-with-grafana-influxdb-for-home-assistant/>
|
||
|
||
<https://philhawthorne.com/installing-home-assistant-io-on-a-synology-diskstation-nas/>
|
||
|
||
<https://www.youtube.com/watch?v=rdvyYRBU7CM>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# 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}
|
||
|
||
<https://philhawthorne.com/breaking-down-presence-detection-with-home-assistant/>
|
||
|
||
<https://philhawthorne.com/making-home-assistants-presence-detection-not-so-binary/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Automation of dumb devices {#automation-of-dumb-devices .western}
|
||
|
||
<https://philhawthorne.com/making-dumb-dishwashers-and-washing-machines-smart-alerts-when-the-dishes-and-clothes-are-cleaned/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Using external Data Disk {#using-external-data-disk .western}
|
||
|
||
<https://peyanski.com/home-assistant-external-data-disk/>
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
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.
|
||
|
||
{#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".
|
||
|
||
{#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}
|
||
|
||
<https://community.home-assistant.io/t/save-db-on-usb-stick-drive-hassio/82144/24>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# 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}
|
||
|
||
<https://mary.codes/blog/home_automation/running_home_assistant_from_an_external_hard_drive/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/solved-mount-usb-drive-in-hassio-to-be-used-on-the-media-folder-with-udev-customization/258406/68>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# MQTT with RP2040 {#mqtt-with-rp2040 .western}
|
||
|
||
<https://learn.adafruit.com/quickstart-rp2040-pico-with-wifi-and-circuitpython/internet-connect>
|
||
|
||
<https://www.tomshardware.com/how-to/send-and-receive-data-raspberry-pi-pico-w-mqtt>
|
||
|
||
<https://www.hackster.io/FrankDelporte/sending-sensor-data-from-raspberry-pi-pico-to-mqtt-445c97>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Weather {#weather .western}
|
||
|
||
## accuweather {#accuweather .western}
|
||
|
||
BoraEr
|
||
|
||
ineedweather_90
|
||
|
||
Follow instruction here to create new App:
|
||
<https://www.home-assistant.io/integrations/accuweather>
|
||
|
||
app: ha_weather
|
||
|
||
API key: GV0GKNtlJZNUHYZ5YNW6YGySLVVz0Huq
|
||
|
||
\
|
||
|
||
search location key: <https://www.accuweather.com/en/browse-locations>
|
||
|
||
\
|
||
|
||
Leinfelden: 2604235,
|
||
<https://www.accuweather.com/en/de/leinfelden/70771/weather-forecast/2604235>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
create a sensor from the weather attributes to plot the data:
|
||
|
||
<https://community.home-assistant.io/t/how-to-extract-temperature-from-weather-card/143260/3>
|
||
|
||
\
|
||
\# 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}
|
||
|
||
<https://www.home-assistant.io/integrations/openweathermap/>
|
||
|
||
\
|
||
|
||
BoraEr
|
||
|
||
ineedweather_90
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## animated icons in weather card {#animated-icons-in-weather-card .western}
|
||
|
||
<https://community.home-assistant.io/t/animated-weather-icons/206736>
|
||
|
||
<https://github.com/wowgamr/animated-weather-card>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# read content of DB {#read-content-of-db .western}
|
||
|
||
<https://sqlitebrowser.org/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# InfluxDB: Removing or deleting data {#influxdb-removing-or-deleting-data .western}
|
||
|
||
<https://community.home-assistant.io/t/influxdb-removing-or-deleting-data/292637>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Read external InfluxDB in Home Assistant as a sensor {#read-external-influxdb-in-home-assistant-as-a-sensor .western}
|
||
|
||
<https://itobey.dev/index.php/read-external-influxdb-in-home-assistant-as-sensor/>
|
||
|
||
\
|
||
|
||
# Using both MariaDB and InfluxDB {#using-both-mariadb-and-influxdb .western}
|
||
|
||
<https://smarthomescene.com/guides/optimize-your-home-assistant-database/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# InfluxDB hassio add-on: changing default database location {#influxdb-hassio-add-on-changing-default-database-location .western}
|
||
|
||
<https://community.home-assistant.io/t/influxdb-hassio-add-on-changing-default-database-location/172354/10>
|
||
|
||
<https://community.home-assistant.io/t/where-does-influx-store-db-files-in-hassio/105502>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
location of influxdb database:
|
||
<https://community.home-assistant.io/t/influxdb-location-of-database-on-hass-io/169916/15>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Remote access {#remote-access .western}
|
||
|
||
<https://peyanski.com/home-assistant-remote-access/#What_if_Home_Assistant_Remote_Access_is_not_working_or_you_loose_your_local_access>
|
||
|
||
\
|
||
\
|
||
|
||
<https://siytek.com/home-assistant-remote/>
|
||
|
||
<https://community.home-assistant.io/t/how-to-configure-remote-access-with-lets-encrypt/391432>
|
||
|
||
\
|
||
|
||
## [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}
|
||
|
||
{#Image10 align="bottom"
|
||
width="270" height="286" border="0"}
|
||
|
||
\
|
||
|
||
{#Image13 align="bottom"
|
||
width="285" height="305" border="0"}
|
||
|
||
\
|
||
|
||
{#Image11 align="bottom"
|
||
width="643" height="205" border="0"}
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## Start Let\'s Encrypt addon {#start-lets-encrypt-addon .western}
|
||
|
||
\
|
||
|
||
{#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}
|
||
|
||
<http://192.168.178.32:8123/>
|
||
|
||
→ 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:
|
||
|
||
<https://community.home-assistant.io/t/remote-access-for-home-assistant/206072>
|
||
|
||
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: <https://192.168.178.32:8123/>
|
||
|
||
externall: <https://habora.duckdns.org:8123/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## 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!
|
||
|
||
\
|
||
|
||
<https://www.youtube.com/watch?v=jblBRuW1lu4>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## Fritz Box Aktualisierungsanforderung mit DuckDNS {#fritz-box-aktualisierungsanforderung-mit-duckdns .western}
|
||
|
||
<https://avm.de/service/wissensdatenbank/dok/FRITZ-Box-7590/30_Dynamic-DNS-in-FRITZ-Box-einrichten/>
|
||
|
||
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=\<domain\>&token=\<pass\>&ip=\<ipaddr\>&ipv6=\<ip6addr\>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# GoogleNest TTS issues after setting up ssl {#googlenest-tts-issues-after-setting-up-ssl .western}
|
||
|
||
<https://www.home-assistant.io/integrations/tts>
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/tts-with-ssl-on/207875/3>
|
||
|
||
\
|
||
|
||
DNS-Rebind-Schutz
|
||
|
||
<https://avm.de/service/wissensdatenbank/dok/FRITZ-Box-7390/663_DNS-Auflosung-privater-IP-Adressen-nicht-moglich/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# 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}
|
||
|
||
<https://www.home-assistant.io/examples/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Müllkalender {#müllkalender .western}
|
||
|
||
<https://smarthomeyourself.de/wiki/homeassistant/muellkalender-darstellung-mit-tagen-datum-in-einer-zeile/>
|
||
|
||
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}
|
||
|
||
<https://de.banggood.com/SOLMORE-Smart-APP-WiFi-LED-Strip-Controller-+-24-Keys-Remote-Control-Work-with-Alexa-Google-Assistant-p-1658159.html?cur_warehouse=CN>
|
||
|
||
**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
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://www.home-assistant.io/integrations/tuya>
|
||
|
||
Cloud \> Development \>
|
||
|
||
\
|
||
|
||
<https://iot.tuya.com/>
|
||
|
||
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
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://gadget-freakz.com/tuya-smart-life-integrated-into-home-assistant/#Smart_Life_application_tested>
|
||
|
||
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}
|
||
|
||
<https://github.com/rospogrigio/localtuya>
|
||
|
||
<https://community.home-assistant.io/t/am-i-missing-something-no-color-on-light-in-scene/373591/14>
|
||
|
||
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}
|
||
|
||
<https://community.home-assistant.io/t/get-local-key-tuya-since-june-2022/436399/7>
|
||
|
||
<https://www.youtube.com/watch?v=2kfv0W80NYk&t=481s>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
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
|
||
|
||
<https://github.com/rospogrigio/localtuya/issues/183>
|
||
|
||
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
|
||
|
||
<https://templates.blakadder.com/search.html>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
**Flashing:**
|
||
|
||
<https://siytek.com/esphome-vs-tasmota/#Flashing>
|
||
|
||
<https://siytek.com/flashing-tasmota-methods/#Flashing-Tasmota-Online-using-Chrome-Browser>
|
||
|
||
<https://tasmota.github.io/docs/Tuya-Convert/>
|
||
|
||
\
|
||
|
||
<https://siytek.com/tuya-convert-linux/>
|
||
|
||
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"}**
|
||
|
||
<https://siytek.com/tuya-convert-and-raspberry-pi/>
|
||
|
||
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
|
||
|
||
\
|
||
|
||
→ <http://10.42.42.1/> using tasmota-xxxxx SSID → 192.168.4.1
|
||
|
||
\
|
||
|
||
\
|
||
|
||
**timeout issue with latest Ri OS version!**
|
||
|
||
<https://github.com/ct-Open-Source/tuya-convert/issues/1022>
|
||
|
||
<https://www.drejo.com/blog/neo-tuya-tasmota/>
|
||
|
||
solution: install old version:
|
||
<https://downloads.raspberrypi.org/raspios_arm64/images/raspios_arm64-2020-05-28/2020-05-27-raspios-buster-arm64.zip>
|
||
|
||
\
|
||
|
||
**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
|
||
|
||
<https://support.prepaid-hoster.de/faq/de/virtuelle-server/apt-fehler-this-must-be-accepted-explicitly-before-updates-for-this-repository-can-be-applied.html>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://siytek.com/how-to-set-up-tasmota-mqtt-auto-discovery-for-home-assistant/>
|
||
|
||
<https://templates.blakadder.com/hama_00176547.html>
|
||
|
||
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.**
|
||
|
||
<https://askubuntu.com/questions/180733/how-to-create-a-wi-fi-hotspot-in-access-point-mode/180734#180734>
|
||
|
||
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**
|
||
|
||
<https://askubuntu.com/questions/55868/installing-broadcom-wireless-drivers>
|
||
|
||
<https://www.technolaty.com/how-to-install-wireless-drivers-on-ubuntu/>
|
||
|
||
sudo lshw -C network
|
||
|
||
sudo apt install firmware-b43-installer
|
||
|
||
sudo apt install linux-firmware
|
||
|
||
sudo reboot
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# simulate sunrise {#simulate-sunrise .western}
|
||
|
||
Sunrise:
|
||
|
||
<https://siytek.com/how-to-simulate-a-sunrise-with-home-assistant/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# RP2040 Micropython {#rp2040-micropython .western}
|
||
|
||
## PIR sensor + MQTT {#pir-sensor-mqtt .western}
|
||
|
||
<https://www.tomshardware.com/how-to/send-and-receive-data-raspberry-pi-pico-w-mqtt>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
install MicroPython firmware:
|
||
|
||
<https://www.tomshardware.com/how-to/raspberry-pi-pico-setup>
|
||
|
||
<https://micropython.org/download/rp2-pico-w/>
|
||
|
||
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}
|
||
|
||
<https://microcontrollerslab.com/hc-sr04-ultrasonic-sensor-raspberry-pi-pico-micropython-tutorial/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## Adafruit QT Py RP2040 {#adafruit-qt-py-rp2040 .western}
|
||
|
||
<https://learn.adafruit.com/adafruit-qt-py-2040>
|
||
|
||
\
|
||
|
||
Micopthon formware:
|
||
|
||
<https://micropython.org/download/ADAFRUIT_QTPY_RP2040/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Seeed Xiao ESP32C3 {#seeed-xiao-esp32c3 .western}
|
||
|
||
<https://wiki.seeedstudio.com/XIAO_ESP32C3_Getting_Started/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Force influxdb to update in regular intervals {#force-influxdb-to-update-in-regular-intervals .western}
|
||
|
||
<https://www.reddit.com/r/homeassistant/comments/pa8x5r/write_to_influxdb_at_regular_intervals/>
|
||
|
||
<https://community.home-assistant.io/t/send-metrics-to-influxdb-at-regular-intervals/9096>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# water meter; AI-on-the-edge {#water-meter-ai-on-the-edge .western}
|
||
|
||
<https://www.youtube.com/watch?v=iUgxwbfkIqU>
|
||
|
||
<https://www.arducam.com/esp32-machine-vision-learning-guide/>
|
||
|
||
<https://www.youtube.com/watch?v=mDIJEyElkAU>
|
||
|
||
<https://www.youtube.com/watch?v=zb3AEusPQLQ>
|
||
|
||
<https://www.youtube.com/watch?v=s6qQs4FN9B0>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://www.thingiverse.com/thing:4573481>
|
||
|
||
<https://github.com/jomjol/AI-on-the-edge-device/wiki>
|
||
|
||
<https://github.com/jomjol/water-meter-system-complete>
|
||
|
||
\
|
||
|
||
<https://www.hackster.io/mickeb/esp32-cam-real-time-water-usage-sensor-f9c29d>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://www.youtube.com/watch?v=iUgxwbfkIqU&t=2s>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# water meter with image recognition on PC {#water-meter-with-image-recognition-on-pc .western}
|
||
|
||
\
|
||
|
||
<https://pyimagesearch.com/2017/02/13/recognizing-digits-with-opencv-and-python/>
|
||
|
||
<https://www.geeksforgeeks.org/text-detection-and-extraction-using-opencv-and-ocr/>
|
||
|
||
<https://medium.com/pythoneers/text-detection-and-extraction-from-image-with-python-5c0c75a8ff14>
|
||
|
||
\
|
||
|
||
<https://tesseract-ocr.github.io/tessdoc/Installation.html>
|
||
|
||
<https://tesseract-ocr.github.io/tessdoc/Command-Line-Usage.html#simplest-invocation-to-ocr-an-image>
|
||
|
||
tesseract input.txt output.txt -l eng \--psm 3
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://medium.com/quantrium-tech/installing-and-using-tesseract-4-on-windows-10-4f7930313f82>
|
||
|
||
[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://tesseract-ocr.github.io/tessdoc/ImproveQuality.html#examples>
|
||
|
||
\
|
||
|
||
[[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
|
||
|
||
<https://leangaurav.medium.com/how-to-setup-install-gnu-make-on-windows-324480f1da69>
|
||
|
||
<https://gnuwin32.sourceforge.net/packages/make.htm>
|
||
|
||
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.
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://medium.com/@ahmetxgenc/how-to-use-tesseract-on-windows-fe9d2a9ba5c6>
|
||
|
||
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}
|
||
|
||
<https://nanonets.com/blog/ocr-with-tesseract/#training-tesseract-on-custom-data>
|
||
|
||
\
|
||
|
||
<https://muthu.co/all-tesseract-ocr-options/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Edge Impulse {#edge-impulse .western}
|
||
|
||
<https://studio.edgeimpulse.com/studio/select-project>
|
||
|
||
<https://www.arduino.coach/edge-impulse-demonstration-of-accurate-digits-recognition-with-the-arduino-portenta.html>
|
||
|
||
\
|
||
|
||
<https://github.com/edgeimpulse/example-esp32-cam>
|
||
|
||
\
|
||
|
||
[[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/)
|
||
|
||
\
|
||
|
||
<https://peter-ing.medium.com/beginners-guide-to-object-detection-with-edge-impulse-c8ea95f844a0>
|
||
|
||
\
|
||
|
||
<https://docs.arduino.cc/tutorials/nano-33-ble-sense/edge-impulse>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Tensorflow Lite {#tensorflow-lite .western}
|
||
|
||
<https://wiki.seeedstudio.com/XIAO-BLE-Sense-TFLite-Getting-Started/>
|
||
|
||
\
|
||
|
||
<https://developer.android.com/codelabs/digit-classifier-tflite#0>
|
||
|
||
\
|
||
|
||
<https://www.edgeimpulse.com/blog/get-plugged-in-to-the-future-of-smart-energy-meters>
|
||
|
||
\
|
||
|
||
<https://www.youtube.com/watch?v=pWp3PhYI-OU>
|
||
|
||
\
|
||
|
||
<https://github.com/leriomaggio/deep-learning-keras-tensorflow>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Alarm system {#alarm-system .western}
|
||
|
||
<https://scotthelme.co.uk/creating-a-house-alarm-system-with-home-assistant/>
|
||
|
||
<https://leonardosmarthomemakers.com/how-to-create-a-diy-alarm-system-with-home-assistant/>
|
||
|
||
<https://smarthomescene.com/guides/alarmo-make-your-own-alarm-system-in-home-assistant/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# MICRO PYTHON ON ESP32 (HUZZAH32) {#micro-python-on-esp32-huzzah32 .western}
|
||
|
||
<https://wolfpaulus.com/micro-python-esp32/>
|
||
|
||
<https://learn.adafruit.com/adafruit-esp32-feather-v2/micropython-setup>
|
||
|
||
<http://kentarotanaka.com/huzzah32-esp32-micropython-setup/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# install HACS {#install-hacs .western}
|
||
|
||
<https://peyanski.com/how-to-install-home-assistant-community-store-hacs/>
|
||
|
||
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}
|
||
|
||
<https://docs.m5stack.com/en/quick_start/timer_cam/arduino>
|
||
|
||
<https://randomnerdtutorials.com/esp32-cam-video-streaming-web-server-camera-home-assistant/>
|
||
|
||
<https://community.home-assistant.io/t/m5stack-unit-cam-with-esphome/474378>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://www.fambach.net/esp32-cam-modul/>
|
||
|
||
Kamera Fernsteuern:
|
||
http://\<ip\>/control?var=\<Variablenname\>&val=\<Wert\>
|
||
|
||
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"}
|
||
|
||
\
|
||
|
||
<https://randomnerdtutorials.com/esp32-cam-ov2640-camera-settings/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
entity_id: camera.cam1
|
||
|
||
filename: /config/www/snapshot.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}
|
||
|
||
<https://lemariva.com/blog/2020/06/micropython-m5camera-timelapse-over-mqtt>
|
||
|
||
<https://github.com/lemariva/uPyCam/tree/timelapse-camera>
|
||
|
||
<https://github.com/lemariva/micropython-camera-driver>
|
||
|
||
\
|
||
|
||
due to missing PSRAM, the micropython code does not work\...
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Android controller for ESP32 {#android-controller-for-esp32 .western}
|
||
|
||
<https://www.youtube.com/watch?v=wrtNFFGXi5I&t=363s>
|
||
|
||
<https://drive.google.com/file/d/17kUsL4qcdAIRIxtfcCf5VnePcwTSmhqX/view>
|
||
|
||
<https://play.google.com/store/apps/details?id=com.electro_tex.bluetoothcar>
|
||
|
||
\
|
||
|
||
<https://www.youtube.com/watch?v=Pqs-3GgWW3s>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Python on Win10 {#python-on-win10 .western}
|
||
|
||
Install via Microsoft store
|
||
|
||
\
|
||
\
|
||
|
||
<https://docs.python.org/3/library/venv.html>
|
||
|
||
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}
|
||
|
||
<https://keepassxc.org/download/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
Use Yubico:
|
||
<https://www.yubico.com/de/works-with-yubikey/catalog/keepassxc/>
|
||
|
||
Database \> Database Security \> Add Additional protection... \> Add
|
||
Challenge-Response → choose Yubikey from the drop-down menu
|
||
|
||
\
|
||
|
||
### browser plugin: {#browser-plugin .western}
|
||
|
||
<https://keepassxc.org/docs/KeePassXC_GettingStarted.html#_setup_browser_integration>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## keepass for Android {#keepass-for-android .western}
|
||
|
||
[KeePass2Android]{style="background: #ffff00"} or KeePassDX
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## Syncthing {#syncthing .western}
|
||
|
||
Download: <https://docs.syncthing.net/users/contrib.html#contributions>
|
||
|
||
Getting started:
|
||
<https://docs.syncthing.net/intro/getting-started.html#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:
|
||
<https://docs.syncthing.net/users/autostart.html>
|
||
|
||
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
|
||
|
||
- <https://docs.syncthing.net/users/autostart.html#linux>
|
||
|
||
-
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Soil sensor {#soil-sensor .western}
|
||
|
||
<https://learn.adafruit.com/adafruit-stemma-soil-sensor-i2c-capacitive-moisture-sensor>
|
||
|
||
\
|
||
|
||
3D models for assembling Adafruit soil sensor:
|
||
|
||
<https://learn.adafruit.com/soil-node>
|
||
|
||
<https://learn.adafruit.com/pyportal-pet-planter-with-adafruit-io>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# use wildcard for mqtt topics in automations {#use-wildcard-for-mqtt-topics-in-automations .western}
|
||
|
||
<https://community.home-assistant.io/t/mqtt-topic-wildcard/389382>
|
||
|
||
topic: \"stat/+/RESULT\"
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/automation-based-on-mqtt-message-with-wildcard-and-value-condition/311518/6>
|
||
|
||
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\"
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/try-to-send-the-mqtt-payload-as-a-message-to-notify-mobile-app-in-ios/169197/6>
|
||
|
||
\
|
||
|
||
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}
|
||
|
||
<https://community.home-assistant.io/t/tutorial-to-fix-401-unauthorised-error-with-grafana-for-mobile-devices/242622/9>
|
||
|
||
\
|
||
|
||
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}
|
||
|
||
<https://kb.shelly.cloud/knowledge-base/shelly-plus-1pm-web-interface-guide>
|
||
|
||
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
|
||
|
||
\
|
||
\
|
||
|
||
{#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
|
||
|
||
{#Image49 align="bottom"
|
||
width="332" height="413" border="0"}
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
<https://shelly-api-docs.shelly.cloud/gen2/General/RPCChannels>
|
||
|
||
shellyplus1pm-a8032ab82968/rpc
|
||
|
||
shellyplus1pm-a8032ab82968/events/rpc
|
||
|
||
shellyplusi4-a8032ab1d7d0/events/rpc
|
||
|
||
shellyplusi4-a8032ab1c9e0/events/rpc
|
||
|
||
shellyrgbw2-E0AC83/events/rpc
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://www.home-assistant.io/integrations/shelly/>
|
||
|
||
Generation 2 devices use the values btn_down, btn_up, single_push,
|
||
double_push and long_push as click_type.
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<http://192.168.178.53/rpc/Shelly.GetStatus>
|
||
|
||
\
|
||
|
||
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:
|
||
|
||
<https://community.home-assistant.io/t/shelly-plus-i4-wall-switch-example-automation/401625>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
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}
|
||
|
||
<https://shelly-api-docs.shelly.cloud/gen2/ComponentsAndServices/Mqtt>
|
||
|
||
[\<model\> = shellyplus1pm]{style="background: #ffff00"}
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://shelly-api-docs.shelly.cloud/gen1/#shelly1-1pm-mqtt>
|
||
|
||
Shelly1/1PM: MQTT
|
||
|
||
\
|
||
|
||
Shelly1 and Shelly1PM uses the following topics, where \<model\> is
|
||
either shelly1 or shelly1pm:
|
||
|
||
\
|
||
|
||
shellies/\<model\>-\<deviceid\>/relay/0 to report status: on, off or
|
||
overpower (the latter only for Shelly1PM)
|
||
|
||
shellies/\<model\>-\<deviceid\>/relay/0/command accepts on, off or
|
||
toggle and applies accordingly
|
||
|
||
shellies/\<model\>-\<deviceid\>/input/0 reports the state of the SW
|
||
terminal
|
||
|
||
shellies/\<model\>-\<deviceid\>/longpush/0 reports longpush state as 0
|
||
(shortpush) or 1 (longpush)
|
||
|
||
shellies/\<model\>-\<deviceid\>/input_event/0 reports input event and
|
||
event counter, e.g.: {\"event\":\"S\",\"event_cnt\":2} see /status for
|
||
details
|
||
|
||
\
|
||
|
||
Shelly1PM adds:
|
||
|
||
\
|
||
|
||
shellies/shelly1pm-\<deviceid\>/relay/0/power reports instantaneous
|
||
power in Watts
|
||
|
||
shellies/shelly1pm-\<deviceid\>/relay/0/energy reports an incrementing
|
||
energy counter in Watt-minute
|
||
|
||
shellies/shelly1pm-\<deviceid\>/temperature reports internal device
|
||
temperature in °C
|
||
|
||
shellies/shelly1pm-\<deviceid\>/temperature_f reports internal device
|
||
temperature in °F
|
||
|
||
shellies/shelly1pm-\<deviceid\>/overtemperature reports 1 when device
|
||
has overheated, normally 0
|
||
|
||
shellies/shelly1pm-\<deviceid\>/temperature_status reports Normal, High,
|
||
Very High
|
||
|
||
shellies/shelly1pm-\<deviceid\>/relay/0/overpower_value reports the
|
||
value in Watts, on which an overpower condition is detected
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/shelly-gen-2-plus-and-pro-using-mqtt/347979/19>
|
||
|
||
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
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://community.openhab.org/t/shelly-plus-1pm-via-mqtt/139826>
|
||
|
||
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
|
||
```
|
||
|
||
\
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
<https://sequr.be/blog/2020/10/mqtt-templates-for-shelly-devices/#mqtt-templates>
|
||
|
||
\## /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}
|
||
|
||
<https://usa.shelly.cloud/knowledge-base/shelly-rgbw2/>
|
||
|
||
<https://community.home-assistant.io/t/shelly-rgbw2-automations-mqtt/234564>
|
||
|
||
<https://cyan-automation.medium.com/setting-up-a-white-shelly-rgbw2-using-mqtt-in-home-assistant-d7996db6ce7d>
|
||
|
||
shellies/shellyrgbw2-E0AC83/white/3/status
|
||
|
||
shellies/shellyrgbw2-E0AC83/color/0/status
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Shelly integration via ESPHome {#shelly-integration-via-esphome .western}
|
||
|
||
<https://www.esphome-devices.com/devices/Shelly-Plus-1PM>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Shelly firmware update {#shelly-firmware-update .western}
|
||
|
||
## Via MQTT {#via-mqtt .western}
|
||
|
||
<https://community.home-assistant.io/t/shelly-firmware-updates/123123/2>
|
||
|
||
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}
|
||
|
||
<https://community.home-assistant.io/t/shelly-firmware-updates-using-shelly-integration-not-mqtt/323833>
|
||
|
||
http://\[IP-OF-SHELLY/ota?update=1 does the trick
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Node Red {#node-red .western}
|
||
|
||
<https://smarthome.university/home-assistant/node-red/>
|
||
|
||
\
|
||
|
||
<https://funprojects.blog/2020/03/23/home-assistant-with-node-red/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Deye Wechselrichter {#deye-wechselrichter .western}
|
||
|
||
Solarman?
|
||
|
||
See KeePassXC
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
\
|
||
|
||
# Using Wemos Lolin ESP32 boards {#using-wemos-lolin-esp32-boards .western}
|
||
|
||
## C3 Mini {#c3-mini .western}
|
||
|
||
<https://www.wemos.cc/en/latest/c3/c3_mini.html>
|
||
|
||
\
|
||
|
||
<https://www.fambach.net/d1-mini-esp8266-modul-2-3/>
|
||
|
||
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
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://codeandlife.com/2022/02/25/using-ssd1306-oled-wemos-s2-pico-esp32-s2-board/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://microcontrollerslab.com/oled-display-raspberry-pi-pico-micropython-tutorial/>
|
||
|
||
## []{#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}
|
||
|
||
<https://github.com/slashback100/presence_simulation>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://blog.jonsdocs.org.uk/2022/08/29/simulating-presence-with-home-assistant/>
|
||
|
||
\
|
||
|
||
[[[[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
|
||
```
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://blog.mornati.net/home-assistant-simple-presence-simulation-script>
|
||
|
||
\
|
||
\
|
||
|
||
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}
|
||
|
||
<https://github.com/nielsfaber/scheduler-component>
|
||
|
||
<https://github.com/nielsfaber/scheduler-card>
|
||
|
||
\
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# reduce size of database {#reduce-size-of-database .western}
|
||
|
||
<https://www.home-assistant.io/integrations/recorder>
|
||
|
||
recorder:
|
||
|
||
purge_keep_days: 5
|
||
|
||
db_url: sqlite:////home/user/.homeassistant/test
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/simple-way-to-reduce-your-db-size/234787>
|
||
|
||
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"}
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/how-to-keep-your-recorder-database-size-under-control/295795>
|
||
|
||
homeassistant:
|
||
|
||
allowlist_external_dirs:
|
||
|
||
\- /config
|
||
|
||
sensor:
|
||
|
||
\- platform: filesize
|
||
|
||
file_paths:
|
||
|
||
\- /config/home-assistant_v2.db
|
||
|
||
\
|
||
|
||
\
|
||
|
||
{#Image14 align="left"
|
||
width="643" height="339" border="0"}\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# WIZ light scenes {#wiz-light-scenes .western}
|
||
|
||
<https://github.com/sbidy/pywizlight/blob/a11d2c7744d7110eb42ce8af5eddb3f6f40bd228/pywizlight/scenes.py>
|
||
|
||
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}
|
||
|
||
<https://iotprojectsideas.com/portable-esp32-wifi-repeater/>
|
||
|
||
\
|
||
|
||
download repository and flash tool:
|
||
|
||
<https://github.com/martin-ger/esp32_nat_router>
|
||
|
||
<https://www.espressif.com/en/support/download/other-tools>
|
||
|
||
\
|
||
|
||
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.
|
||
|
||
\
|
||
|
||
{#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
|
||
|
||
\
|
||
|
||
<https://raspberrytips.com/docker-on-raspberry-pi/>
|
||
|
||
[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}
|
||
|
||
<https://www.home-assistant.io/installation/raspberrypi#install-home-assistant-container>
|
||
|
||
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://\<host\>:8123
|
||
|
||
http://192.168.178.52:8123
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
RESTART HOME ASSISTANT
|
||
|
||
docker restart homeassistant
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## configuration {#configuration .western}
|
||
|
||
<https://community.home-assistant.io/t/configurator-file-editor-for-ha-core-in-docker/238472/4>
|
||
|
||
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"}
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/configure-ssl-with-docker/196878>
|
||
|
||
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
|
||
|
||
\
|
||
|
||
**\<html\>**
|
||
|
||
**\<body\>**
|
||
|
||
**\<h1\>Welcome\</h1\>**
|
||
|
||
**It works!**
|
||
|
||
**\</html\>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:** **<boraers@googlemail.com>,
|
||
[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:81/>
|
||
|
||
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
|
||
|
||
- <boraers@googlemail.com>
|
||
|
||
\
|
||
|
||
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}
|
||
|
||
<https://www.addictedtotech.net/nginx-proxy-manager-tutorial-duckdns-configuration-episode-7/>
|
||
|
||
\
|
||
|
||
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.
|
||
|
||
{#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"}
|
||
|
||
{#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
|
||
|
||
{#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"}
|
||
|
||
{#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"}
|
||
|
||
{#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:
|
||
|
||
{#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"}
|
||
|
||
{#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"}
|
||
|
||
{#Image43 align="bottom"
|
||
width="819" height="461" border="0"}
|
||
|
||
Press the Logs button to check all is as expected. It should look like
|
||
this:
|
||
|
||
{#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:
|
||
|
||
{#Image45 align="bottom"
|
||
width="819" height="461" border="0"}
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## Mosquitto (MQTT broker) on Raspberry Pi / Docker {#mosquitto-mqtt-broker-on-raspberry-pi-docker .western}
|
||
|
||
<https://www.schaerens.ch/raspi-setting-up-mosquitto-mqtt-broker-on-raspberry-pi-docker/>
|
||
|
||
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
|
||
|
||
<https://community.openhab.org/t/mosquitto-error-address-already-in-use/121506>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
Now you can install and start Mosquitto:
|
||
|
||
docker-compose up -d
|
||
|
||
\
|
||
|
||
Check if Mosquitto is running:
|
||
|
||
docker ps
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://hub.docker.com/_/eclipse-mosquitto/>
|
||
|
||
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}
|
||
|
||
<https://darkwolfcave.de/raspberry-pi-docker-ohne-probleme-installieren/>
|
||
|
||
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"}
|
||
|
||
{#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.
|
||
|
||
{#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"}
|
||
|
||
{#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"}
|
||
|
||
{#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"}
|
||
|
||
{#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"}
|
||
|
||
{#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/**
|
||
|
||
{#Image46 align="left"
|
||
width="643" height="285" border="0"}\
|
||
|
||
\
|
||
|
||
**https://thenewstack.io/python-mqtt-tutorial-store-iot-metrics-with-influxdb/**
|
||
|
||
{#Image47 align="left"
|
||
width="643" height="301" border="0"}\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## Install Grafana {#install-grafana .western}
|
||
|
||
<https://darkwolfcave.de/raspberry-pi-monitoring-grafana-installieren/>
|
||
|
||
{#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"}
|
||
|
||
{#Image23
|
||
align="bottom" width="623" height="403" border="0"} {#Image24 align="bottom"
|
||
width="819" height="248" border="0"} {#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"}
|
||
|
||
{#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"}
|
||
|
||
{#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"}
|
||
|
||
{#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"}
|
||
|
||
{#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"}
|
||
|
||
{#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"**
|
||
|
||
{#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!
|
||
|
||
{#Image32
|
||
align="bottom" width="819" height="419" border="0"}\
|
||
\
|
||
\
|
||
|
||
\
|
||
|
||
### Grafana with influxdb 2.x {#grafana-with-influxdb-2.x .western}
|
||
|
||
<https://www.youtube.com/watch?v=gEIgg5zHuIU>
|
||
|
||
- the influxdb data explorer, select a quer and cop from the script
|
||
editor
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## Install telegraf {#install-telegraf .western}
|
||
|
||
<https://darkwolfcave.de/raspberry-pi-monitoring-grafana-installieren/>
|
||
|
||
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"}
|
||
|
||
{#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"}
|
||
|
||
{#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"}
|
||
|
||
{#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}
|
||
|
||
<https://docs.influxdata.com/influxdb/v2.6/write-data/no-code/use-telegraf/manual-config/>
|
||
|
||
\
|
||
|
||
- 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}
|
||
|
||
<https://community.home-assistant.io/t/importing-csv-file-into-influxdb/323933>
|
||
|
||
\
|
||
|
||
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
|
||
|
||
\
|
||
|
||
<https://www.timestamp-converter.com/>
|
||
|
||
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
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://stackoverflow.com/questions/58599352/how-to-convert-formatted-date-to-unix-epoch-in-libreoffice-calc>
|
||
|
||
\
|
||
|
||
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}
|
||
|
||
<https://tasmota.github.io/docs/MQTT/#command-flow>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://tasmota.github.io/docs/Home-Assistant/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://www.synology-forum.de/threads/brauche-mal-hilfe-bei-home-assistant-und-tasmota-einbindung.116762/>
|
||
|
||
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
|
||
|
||
\
|
||
|
||
<http://192.168.178.50/>
|
||
|
||
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
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://tasmota.github.io/docs/Peripherals/#update-interval>
|
||
|
||
[TelePeriod 10]{style="background: #ffff00"}
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
how to keep smart plug powered off after unplugging and re-plugging?
|
||
|
||
<https://tasmota.github.io/docs/Commands/#commands-list>
|
||
|
||
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}
|
||
|
||
\
|
||
|
||
<https://www.home-assistant.io/common-tasks/os/#network-storage>
|
||
|
||
\
|
||
|
||
\\\\192.168.178.1\\FRITZ.NAS\\USB-SanDisk3-2Gen1-01
|
||
|
||
http://fritz.box/nas?sid=41098e807aea021b
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://smartebude.de/einrichtung-einer-nas-als-speicherort-fuer-home-assistant-backups-z-b-fritzbox-als-nas/>
|
||
|
||
user: homeassistant
|
||
|
||
password: bhasfonworf34534thb
|
||
|
||
fritz.nas/USB-SanDisk3-2Gen1-01/Data
|
||
|
||
\
|
||
|
||
{#Image53 align="bottom"
|
||
width="567" height="421" border="0"}
|
||
|
||
{#Image54 align="bottom"
|
||
width="562" height="466" border="0"}
|
||
|
||
{#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}
|
||
|
||
<https://smartebude.de/zeitplaene-nutzen-um-mehrere-temperaturen-in-home-assistant-zu-steuern/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# use Raspberry Pi as WiFi repeater {#use-raspberry-pi-as-wifi-repeater .western}
|
||
|
||
<https://pimylifeup.com/raspberry-pi-wifi-extender/>
|
||
|
||
<https://blog.balena.io/turn-a-raspberry-pi-into-a-wi-fi-access-point-or-repeater/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Timercard (Ein-Aus-Zeit) in HomeAssistant {#timercard-ein-aus-zeit-in-homeassistant .western}
|
||
|
||
<https://smarthomeyourself.de/wiki/homeassistant/timercard-ein-aus-zeit-in-homeassistant/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
[[[[Ä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....
|
||
|
||
[ [{#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}
|
||
|
||
<https://edistechlab.com/esp32-cam-2-projekte-mit-micro-sd-karte/?v=3a52f3c22ed6>
|
||
|
||
{#Image59 align="bottom"
|
||
width="643" height="243" border="0"}
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://randomnerdtutorials.com/esp32-cam-pir-motion-detector-photo-capture/>
|
||
|
||
\
|
||
|
||
[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)
|
||
|
||
\
|
||
|
||
{#Image57 align="bottom"
|
||
width="554" height="403" border="0"}
|
||
|
||
{#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 <EEPROM.h> // 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}
|
||
|
||
<https://randomnerdtutorials.com/esp32-cam-video-streaming-web-server-camera-home-assistant/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
``` 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 <WiFi.h>
|
||
#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}
|
||
|
||
<https://cgomesu.com/blog/Esp32cam-tasmota-webcam-server/#required-packages-and-user-permissions>
|
||
|
||
\
|
||
|
||
<https://tasmota.github.io/docs/ESP32/#flashing>
|
||
|
||
<https://ota.tasmota.com/tasmota32/release/>
|
||
|
||
use webinstaller to flash webcam firmware
|
||
|
||
\
|
||
|
||
connect to AP and open 192.168.4.1
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/esp32-cam-with-tasmota-and-rtsp/334281/6>
|
||
|
||
\
|
||
|
||
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
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://github.com/arendst/Tasmota/discussions/13788>
|
||
|
||
http://192.168.178.76:81/stream
|
||
|
||
[http://192.168.178.76:81/cam.mjpeg]{style="background: #ffff00"}
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://ottelo.jimdofree.com/stromz%C3%A4hler-auslesen-tasmota/#4g>
|
||
|
||
**(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)
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://loxwiki.atlassian.net/wiki/spaces/LOX/pages/1594589651/Befehle+f+r+die+Konsole+in+Tasmota>
|
||
|
||
\
|
||
|
||
+-------------+--------+---------------------------------------------+
|
||
| 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
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://tasmota.github.io/docs/Commands/#camera>
|
||
|
||
\
|
||
|
||
+------------------------+--------------------------------------------+
|
||
| []{#wcstream} WcStream | `1`{.western}[ = start webcam stream at |
|
||
| | http://\<device_ip\>:81/stream or |
|
||
| | http://\<device_ip\>: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
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://tasmota.github.io/docs/Commands/#rules>
|
||
|
||
\
|
||
|
||
ON \<trigger\> DO \<command\> \[ENDON \| BREAK\]
|
||
|
||
\
|
||
|
||
<https://tasmota.github.io/docs/Rules/#rule-trigger>
|
||
|
||
\
|
||
|
||
----------------------------- ------------------------------------------------------
|
||
[]{#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}
|
||
|
||
<https://community.home-assistant.io/t/petoneer-smart-dot-add-on/331391>
|
||
|
||
<https://github.com/marcomow/hass-addon-petoneer-smartdot>
|
||
|
||
add repository: https://github.com/marcomow/hass-addons
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
modification for tasmota
|
||
|
||
<https://templates.blakadder.com/petoneer_TY011.html>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# Install Petkit devices {#install-petkit-devices .western}
|
||
|
||
\
|
||
|
||
Account email:
|
||
|
||
account password:
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# perfboard design with fritzing {#perfboard-design-with-fritzing .western}
|
||
|
||
<https://electronics.stackexchange.com/questions/1600/stripboard-veroboard-matrix-board-design-software>
|
||
|
||
\
|
||
|
||
<https://forum.fritzing.org/t/how-shall-i-get-a-perfboard-matrix-board-view/4118>
|
||
|
||
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}
|
||
|
||
<https://www.youtube.com/watch?v=xx9DyCIHK-8>
|
||
|
||
\
|
||
|
||
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: <https://pastebin.com/x974kFUp>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## 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}
|
||
|
||
<https://electronics.stackexchange.com/questions/608515/i-want-to-trigger-buttons-on-a-touch-sensitive-control-panel-not-a-touchscreen>
|
||
|
||
\
|
||
|
||
<https://arduino.stackexchange.com/questions/25662/triggering-capacitive-touch-on-a-touch-device>
|
||
|
||
\
|
||
|
||
<https://electronics.stackexchange.com/questions/60385/how-to-use-a-capacitive-touch-screen-without-a-human-hand>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# 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}
|
||
|
||
<https://smart-live.net/switchbot-esp32-mqtt-die-beste-home-assistant-integration/>
|
||
|
||
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.
|
||
|
||
<https://github.com/devWaves/SwitchBot-MQTT-BLE-ESP32>
|
||
|
||
\
|
||
|
||
[[[[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"}
|
||
|
||
[{#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
|
||
|
||
[{#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"}
|
||
|
||
[{#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}
|
||
|
||
<https://community.home-assistant.io/t/device-tracker-fritz-integration-detect-new-devices/392042>
|
||
|
||
\- 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
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/conbee-setup/67301/19>
|
||
|
||
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"}
|
||
|
||
\
|
||
\
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://phoscon.de/de/conbee3/install#hazha>
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/conbee-iii-conbee-3-from-dresden-elektronik-based-on-silicon-labs-efr32mg21-20dbm-radio-soc-mcu/649835>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://dresden-elektronik.github.io/deconz-rest-doc/endpoints/devices/#pair-with-install-code>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## firmware update {#firmware-update .western}
|
||
|
||
<https://github.com/dresden-elektronik/deconz-rest-plugin/wiki/Update-deCONZ-manually>
|
||
|
||
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.
|
||
|
||
\
|
||
|
||
<https://community.home-assistant.io/t/bosch-thermostat-2/492845>
|
||
|
||
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.
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://www.bosch-smarthome.com/de/de/service/hilfe/hilfe-zum-produkt/hilfe-zum-heizkoerper-thermostat-2/>
|
||
|
||
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.
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://www.home-assistant.io/integrations/zha/#service-zhapermit>
|
||
|
||
[[[[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}
|
||
|
||
<https://dresden-elektronik.github.io/deconz-rest-doc/getting_started/#rest-api-client>
|
||
|
||
\
|
||
|
||
Talend API Tester - Free Edition
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# install proxmox server {#install-proxmox-server .western}
|
||
|
||
\
|
||
|
||
\
|
||
|
||
<https://techbits.io/install-home-assistant-on-proxmox/>
|
||
|
||
<https://tteck.github.io/Proxmox/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
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
|
||
|
||
<https://smarthomescene.com/guides/moving-home-assistants-database-to-mariadb-on-proxmox/>
|
||
|
||
<https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-8/201835>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
mqtt
|
||
|
||
ttek
|
||
|
||
\
|
||
|
||
Mariadb
|
||
|
||
ttek
|
||
|
||
\
|
||
|
||
\
|
||
|
||
influx db
|
||
|
||
ttek
|
||
|
||
<https://smarthomescene.com/guides/how-to-keep-home-assistant-history-infinitely-with-influxdb-on-proxmox/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
grafana
|
||
|
||
ttek
|
||
|
||
\
|
||
|
||
\
|
||
|
||
adguard
|
||
|
||
ttek
|
||
|
||
\
|
||
|
||
\
|
||
|
||
Node-RED
|
||
|
||
ttek
|
||
|
||
\
|
||
|
||
Visual Studio Code
|
||
|
||
tte
|
||
|
||
\
|
||
|
||
\
|
||
|
||
frigate
|
||
|
||
<https://www.homeautomationguy.io/blog/running-frigate-on-proxmox>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
Vaultwarden
|
||
|
||
ttek
|
||
|
||
\
|
||
|
||
Nginx Proxy Manager
|
||
|
||
ttek
|
||
|
||
\
|
||
|
||
Syncthing
|
||
|
||
ttek
|
||
|
||
\
|
||
|
||
\
|
||
|
||
Wiki.js
|
||
|
||
ttek
|
||
|
||
<https://docs.requarks.io/install/windows>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
WireGuard
|
||
|
||
ttek
|
||
|
||
\
|
||
|
||
\
|
||
|
||
deCONZ
|
||
|
||
ttek
|
||
|
||
\
|
||
|
||
grocy
|
||
|
||
ttek
|
||
|
||
<https://leonardosmarthomemakers.com/how-to-track-chores-in-home-assistant-with-grocy-and-nfc-tags/>
|
||
|
||
<https://www.reddit.com/r/homeassistant/comments/kptfbg/track_chores_in_home_assistant_with_grocy_nfc/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
# 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}
|
||
|
||
<https://www.diskpart.com/de/articles/usb-stick-formatieren.html>
|
||
|
||
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"}
|
||
|
||
[[ [{#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}
|
||
|
||
<https://randomnerdtutorials.com/getting-started-thonny-micropython-python-ide-esp32-esp8266/>
|
||
|
||
\
|
||
|
||
<https://thonny.org/>
|
||
|
||
<https://github.com/thonny/thonny/wiki/Linux>
|
||
|
||
sudo apt install python3-tk thonny
|
||
|
||
\
|
||
|
||
\
|
||
|
||
## [VSCode]{style="background: #c9211e"} {#vscode .western}
|
||
|
||
<https://randomnerdtutorials.com/micropython-esp32-esp8266-vs-code-pymakr/>
|
||
|
||
<https://randomnerdtutorials.com/raspberry-pi-pico-vs-code-micropython/>
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
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 \<user\>
|
||
|
||
\>\>sudo usermod -a -G tty \<user\>
|
||
|
||
\
|
||
|
||
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...
|
||
|
||
\
|
||
|
||
<https://askubuntu.com/questions/1219498/could-not-open-port-dev-ttyacm0-error-after-every-restart>
|
||
|
||
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
|
||
|
||
<https://randomnerdtutorials.com/flashing-micropython-firmware-esptool-py-esp32-esp8266/>
|
||
|
||
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!
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|
||
\
|
||
|