SENSBLUE ATLAS/Home Assistant: Difference between revisions
Appearance
No edit summary |
No edit summary |
||
| (57 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
{{DISPLAYTITLE:Home Assistant}}[[File:Home Assistant Logo.png|frameless|150x150px]] | |||
== Fast installation script == | |||
(If you are feeling lazy) | |||
<table style="border: none; background: transparent; margin: 15px 0; border-collapse: collapse;"> | |||
<td style="padding: 0 0 0 10px; border: none; background: transparent;"> | |||
<span class="atlas-btn">[[Media:Atlas-ha-install-v1.zip|Download Script]]</span> | |||
</td> | |||
</table>This script takes a backup file as an argument and contains: <code>.tar.gz</code> <syntaxhighlight lang="bash"> | |||
atlas-ha-installer/ | |||
├── docker-compose.yml | |||
├── install.sh | |||
├── README.md | |||
├── provision_areas.py | |||
└── ha-config/ | |||
├── configuration.yaml | |||
├── mqtt.yaml | |||
├── automations.yaml | |||
├── scripts.yaml | |||
└── scenes.yaml | |||
</syntaxhighlight> | |||
=== 1. What the script does === | |||
{| class="wikitable mix-table" | |||
!Stage | |||
!Action | |||
|- | |||
|Validates argument | |||
|Confirms that a backup file was specified | |||
|- | |||
|Installs dependencies | |||
|Run <code>apt update</code> and install <code>docker.io</code> and <code>docker-compose-plugin</code> | |||
|- | |||
|Enables Docker | |||
|Executes <code>systemctl enable docker</code> and <code>systemctl start docker</code> | |||
|- | |||
|Breed pasta | |||
|Ensure <code>/opt/atlas-ha</code> exists | |||
|- | |||
|Extract backup | |||
|Extract the <code>.tar.gz</code> file to <code>/opt/atlas-ha</code> | |||
|- | |||
|HA starts up | |||
|Navigates to <code>/opt/atlas-ha</code> and runs <code>sudo docker compose up -d</code> | |||
|- | |||
|Show URL | |||
|Indicate access via <code><nowiki>http://DEVICE_IP:8123</nowiki></code> | |||
|} | |||
=== 2. Prepare Device === | |||
Transfer the package to ATLAS, for example using WinSCP: | |||
# Open the connection to ATLAS using WinSCP. | |||
# Copy <code>atlas-ha-installer.zip</code> or <code>atlas-ha-installer.tar.gz</code> to <code>/home/pi</code>. | |||
# Drag the folder extracted from the .zip file to the /home/pi directory on ATLAS. | |||
'''Note:''' If you need help installing WinSCP, '''''<u>[[SENSBLUE ATLAS/Putty & WinSCP#Install WinSCP|click here]]</u>'''''. | |||
On ATLAS, after transferring the necessary files, establish an SSH connection | |||
If the package is <code>.zip</code>:<syntaxhighlight lang="bash"> | |||
cd /home/pi | |||
unzip atlas-ha-installer.zip | |||
cd atlas-ha-installer | |||
</syntaxhighlight>If the package is:<code>.tar.gz</code><syntaxhighlight lang="bash">cd /home/pi tar | |||
-xzf atlas-ha-installer.tar.gz | |||
cd atlas-ha-installer</syntaxhighlight>Grant execution permission<syntaxhighlight lang="bash"> | |||
chmod +x install.sh | |||
</syntaxhighlight> | |||
=== 3. Execute installation === | |||
The script will install the required dependencies, install/configure Docker, copy the files to <code>/opt/atlas-ha</code>, and start Home Assistant.<syntaxhighlight lang="bash"> | |||
sudo ./install.sh | |||
</syntaxhighlight>After installation, the following should exist:<syntaxhighlight> | |||
/opt/atlas-ha/ | |||
├── docker-compose.yml | |||
└── ha-config/ | |||
├── configuration.yaml | |||
├── mqtt.yaml | |||
├── automations.yaml | |||
├── scripts.yaml | |||
└── scenes.yaml | |||
</syntaxhighlight> | |||
=== 4. Post-script validation === | |||
Verify that the container is active:<syntaxhighlight lang="bash"> | |||
sudo docker ps | |||
</syntaxhighlight>Check logs:<syntaxhighlight lang="bash"> | |||
sudo docker logs -f homeassistant | |||
</syntaxhighlight>Verify HTTP response:<syntaxhighlight lang="bash"> | |||
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8123 | |||
</syntaxhighlight>Expected result: | |||
{| class="wikitable mix-table" | |||
!Code | |||
!Meaning | |||
|- | |||
|200 | |||
|Home Assistant access | |||
|- | |||
|302 | |||
|Home Assistant accessible, with redirection | |||
|- | |||
|000 or connection refused | |||
|It can be normal for the first 1–2 minutes; wait and repeat. | |||
|}Access in browser<syntaxhighlight> | |||
http://<ip-do-atlas>:8123 | |||
</syntaxhighlight> | |||
= Home Assistant integration = | = Home Assistant integration = | ||
'''Installing Home Assistant on the SENSBLUE ATLAS | '''Installing Home Assistant on the SENSBLUE ATLAS''' | ||
'''Objective''' | '''Objective''' | ||
| Line 16: | Line 124: | ||
=== 1. Prerequisites === | === 1. Prerequisites === | ||
{| class="wikitable" | {| class="wikitable mix-table" | ||
!Item | !Item | ||
!Value / check | !Value / check | ||
|- | |- | ||
|Device | |Device | ||
|SENSBLUE ATLAS | |SENSBLUE ATLAS | ||
|- | |- | ||
|Platform | |Platform | ||
| Line 44: | Line 152: | ||
|Local Mosquitto on 127.0.0.1:1883 | |Local Mosquitto on 127.0.0.1:1883 | ||
|} | |} | ||
To locate the IP address of the ATLAS device, '''toggle the joystick to the right''' to navigate to the '''<nowiki/>'Network'''' screen, where the '''eth1''' address is displayed. | |||
[[File:Front Screen.svg|center|frameless|566x566px]] | |||
Once your preferred terminal application (e.g., PuTTY) is installed, initiate an SSH session using the ATLAS IP address and execute the following command to verify the system: | |||
'''Note:''' If you need help installing PuTTY, [[SENSBLUE ATLAS/Putty & WinSCP#Install PuTTY|'''''<u>click here</u>''''']]. | |||
[[File:Image.png|center|frameless|448x448px]] | |||
'''Note:''' SSH access to the ATLAS device requires authentication. | |||
* '''Username:''' pi | |||
* '''Password:''' atlas2026 | |||
<syntaxhighlight lang="bash">cat /etc/os-release | grep PRETTY_NAME | |||
uname -m | uname -m | ||
df -h /</syntaxhighlight> | df -h /</syntaxhighlight>'''Expected output:'''<syntaxhighlight lang="bash"> | ||
PRETTY_NAME="Debian GNU/Linux 13 (trixie)" | |||
aarch64 | |||
Filesystem Size Used Avail Use% Mounted on | |||
/dev/mmcblk0p2 29G 5.5G 23G 20% / | |||
</syntaxhighlight> | |||
=== 2. Ports used on ATLAS === | === 2. Ports used on ATLAS === | ||
Before and after installation, confirm that the existing stack continues to respond. | Before and after installation, confirm that the existing stack continues to respond. | ||
{| class="wikitable" | {| class="wikitable mix-table" | ||
!Service | !Service | ||
!Port | !Port | ||
| Line 69: | Line 198: | ||
|8123 | |8123 | ||
|} | |} | ||
Check the stack's ports:<syntaxhighlight lang="bash"> | '''Check the stack's ports:'''<syntaxhighlight lang="bash"> | ||
for p in 1880 1883 3000 8086; do | for p in 1880 1883 3000 8086; do | ||
ss -tlnp | grep ":$p " && echo "port $p OK" | ss -tlnp | grep ":$p " && echo "port $p OK" | ||
done | done | ||
</syntaxhighlight>'''Expected output:'''<syntaxhighlight lang="bash"> | |||
LISTEN 0 511 0.0.0.0:1880 0.0.0.0:* users:(("node-red",pid=614,fd=19)) | |||
porta 1880 OK | |||
LISTEN 0 100 0.0.0.0:1883 0.0.0.0:* | |||
LISTEN 0 100 [::]:1883 [::]:* | |||
porta 1883 OK | |||
LISTEN 0 4096 *:3000 *:* | |||
porta 3000 OK | |||
LISTEN 0 4096 *:8086 *:* | |||
porta 8086 OK | |||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 87: | Line 226: | ||
# Test with hello-world. | # Test with hello-world. | ||
==== 3.1 Update packages ==== | |||
<syntaxhighlight lang="bash"> | |||
sudo apt-get update | |||
</syntaxhighlight> | |||
==== 3.2 Install dependencies ==== | |||
<syntaxhighlight lang="bash"> | |||
sudo apt-get install -y ca-certificate curl | |||
sudo install -m 0755 -d /etc/apt/keyrings | |||
</syntaxhighlight> | |||
==== 3.3 Add Docker GPG key ==== | |||
<syntaxhighlight lang="bash"> | |||
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc | |||
sudo chmod a+r /etc/apt/keyrings/docker.asc | |||
</syntaxhighlight> | |||
==== 3.4 Add Docker repository ==== | |||
<syntaxhighlight lang="bash"> | |||
echo \ | |||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \ https://download.docker.com/linux/debian \ | |||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ | |||
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null | |||
</syntaxhighlight> | |||
==== 3.5 Install Docker Engine and Docker Compose plugin ==== | |||
<syntaxhighlight lang="bash"> | |||
sudo apt-get update | |||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin | |||
</syntaxhighlight> | |||
==== 3.6 Verify if Docker is operational ==== | |||
<syntaxhighlight lang="bash"> | |||
sudo docker run --rm hello-world | sudo docker run --rm hello-world | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Example alternative line:<syntaxhighlight lang="bash"> | ==== '''Note on Debian 13 (Trixie)''' ==== | ||
deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable | If <code>apt-get update</code> returns a <code>404</code> error for the Docker repository on <code>trixie</code>, temporarily use <code>bookworm</code> in the Docker repository line and re-run the update/installation. | ||
</syntaxhighlight> | |||
Example of the alternative line:<syntaxhighlight lang="bash">deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable</syntaxhighlight> | |||
=== 4. Create the Home Assistant project === | === 4. Create the Home Assistant project === | ||
| Line 115: | Line 286: | ||
EOF | EOF | ||
</syntaxhighlight>'''Important notes:''' | </syntaxhighlight>'''Important notes:''' | ||
{| class="wikitable" | {| class="wikitable mix-table" | ||
!Option | !Option | ||
!Reason | !Reason | ||
| Line 142: | Line 313: | ||
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8123 | curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8123 | ||
</syntaxhighlight>'''Expected result:''' | </syntaxhighlight>'''Expected result:''' | ||
{| class="wikitable" | {| class="wikitable mix-table" | ||
!Code | !Code | ||
!Meaning | !Meaning | ||
| Line 169: | Line 340: | ||
=== 7. Configure MQTT integration in Home Assistant === | === 7. Configure MQTT integration in Home Assistant === | ||
Since the container uses <code>network_mode: host</code>, Home Assistant can access the local Mosquitto via: | Since the container uses <code>network_mode: host</code>, Home Assistant can access the local Mosquitto via: | ||
{| class="wikitable" | {| class="wikitable mix-table" | ||
!Field | !Field | ||
!Value | !Value | ||
| Line 188: | Line 359: | ||
Configure the broker as: | Configure the broker as: | ||
'''127.0.0.1 | '''127.0.0.1''' | ||
After adding the MQTT integration, create the following YAML files to declare the entities used in the current installation. | After adding the MQTT integration, create the following YAML files to declare the entities used in the current installation. | ||
| Line 215: | Line 386: | ||
sudo tee mqtt.yaml > /dev/null << 'EOF' | sudo tee mqtt.yaml > /dev/null << 'EOF' | ||
sensor: | sensor: | ||
- name: "ATLAS AI1" | - name: "ATLAS AI1" | ||
unique_id: atlas_ai1 | unique_id: atlas_ai1 | ||
state_topic: "analogInputs/runtime/out" | state_topic: "analogInputs/runtime/out" | ||
value_template: "{{ value_json.task.taskResult.AI1.result | value_template: "{{ value_json.task.taskResult.AI1.result }}" | ||
unit_of_measurement: "V" | unit_of_measurement: "V" | ||
device_class: voltage | device_class: voltage | ||
| Line 227: | Line 399: | ||
unique_id: atlas_ai2 | unique_id: atlas_ai2 | ||
state_topic: "analogInputs/runtime/out" | state_topic: "analogInputs/runtime/out" | ||
value_template: "{{ value_json.task.taskResult.AI2.result | value_template: "{{ value_json.task.taskResult.AI2.result }}" | ||
unit_of_measurement: "V" | unit_of_measurement: "V" | ||
device_class: voltage | device_class: voltage | ||
| Line 235: | Line 407: | ||
unique_id: atlas_ai3 | unique_id: atlas_ai3 | ||
state_topic: "analogInputs/runtime/out" | state_topic: "analogInputs/runtime/out" | ||
value_template: "{{ value_json.task.taskResult.AI3.result | value_template: "{{ value_json.task.taskResult.AI3.result }}" | ||
unit_of_measurement: "V" | unit_of_measurement: "V" | ||
device_class: voltage | device_class: voltage | ||
| Line 243: | Line 415: | ||
unique_id: atlas_ai4 | unique_id: atlas_ai4 | ||
state_topic: "analogInputs/runtime/out" | state_topic: "analogInputs/runtime/out" | ||
value_template: "{{ value_json.task.taskResult.AI4.result | value_template: "{{ value_json.task.taskResult.AI4.result }}" | ||
unit_of_measurement: "V" | unit_of_measurement: "V" | ||
device_class: voltage | device_class: voltage | ||
state_class: measurement | state_class: measurement | ||
- name: "ATLAS CPU Usage" | |||
unique_id: atlas_cpu_usage | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.cpu_percent }}" | |||
unit_of_measurement: "%" | |||
device_class: power_factor | |||
state_class: measurement | |||
- name: "ATLAS CPU Temperature" | |||
unique_id: atlas_cpu_temperature | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.cpu_tempC }}" | |||
unit_of_measurement: "°C" | |||
device_class: temperature | |||
state_class: measurement | |||
- name: "ATLAS CPU0 Frequency" | |||
unique_id: atlas_cpu0_frequency | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.cpu_freqs.cpu0.frequency_mhz }}" | |||
unit_of_measurement: "MHz" | |||
state_class: measurement | |||
- name: "ATLAS CPU1 Frequency" | |||
unique_id: atlas_cpu1_frequency | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.cpu_freqs.cpu1.frequency_mhz }}" | |||
unit_of_measurement: "MHz" | |||
state_class: measurement | |||
- name: "ATLAS CPU2 Frequency" | |||
unique_id: atlas_cpu2_frequency | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.cpu_freqs.cpu2.frequency_mhz }}" | |||
unit_of_measurement: "MHz" | |||
state_class: measurement | |||
- name: "ATLAS CPU3 Frequency" | |||
unique_id: atlas_cpu3_frequency | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.cpu_freqs.cpu3.frequency_mhz }}" | |||
unit_of_measurement: "MHz" | |||
state_class: measurement | |||
- name: "ATLAS CPU Throttle" | |||
unique_id: atlas_cpu_throttle | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: > | |||
{% if value_json.task.taskResult.cpu_throttle == "0x0" %} | |||
No | |||
{% else %} | |||
Yes | |||
{% endif %} | |||
- name: "ATLAS RAM Usage" | |||
unique_id: atlas_ram_usage | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.ram_percent }}" | |||
unit_of_measurement: "%" | |||
state_class: measurement | |||
- name: "ATLAS RAM Total" | |||
unique_id: atlas_ram_total | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.ram_total_mb }}" | |||
unit_of_measurement: "GB" | |||
state_class: measurement | |||
- name: "ATLAS RAM Used" | |||
unique_id: atlas_ram_used | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.ram_used_mb }}" | |||
unit_of_measurement: "GB" | |||
state_class: measurement | |||
- name: "ATLAS RAM Available" | |||
unique_id: atlas_ram_available | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.ram_available_mb }}" | |||
unit_of_measurement: "GB" | |||
state_class: measurement | |||
- name: "ATLAS Disk Usage" | |||
unique_id: atlas_disk_usage | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.disk_percent }}" | |||
unit_of_measurement: "%" | |||
state_class: measurement | |||
- name: "ATLAS Disk Total" | |||
unique_id: atlas_disk_total | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.disk_total_gb }}" | |||
unit_of_measurement: "GB" | |||
device_class: data_size | |||
state_class: measurement | |||
- name: "ATLAS Disk Used" | |||
unique_id: atlas_disk_used | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.disk_used_gb }}" | |||
unit_of_measurement: "GB" | |||
device_class: data_size | |||
state_class: measurement | |||
- name: "ATLAS Disk Free" | |||
unique_id: atlas_disk_free | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.disk_free_gb }}" | |||
unit_of_measurement: "GB" | |||
device_class: data_size | |||
state_class: measurement | |||
- name: "ATLAS eMMC RUL State" | |||
unique_id: atlas_emmc_rul_state | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.emmc_rul.state }}" | |||
- name: "ATLAS eMMC RUL Reason" | |||
unique_id: atlas_emmc_rul_reason | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.emmc_rul.reason }}" | |||
- name: "ATLAS Uptime" | |||
unique_id: atlas_uptime_seconds | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: "{{ value_json.task.taskResult.uptime_sec }}" | |||
unit_of_measurement: "s" | |||
device_class: duration | |||
state_class: measurement | |||
binary_sensor: | binary_sensor: | ||
| Line 252: | Line 557: | ||
unique_id: atlas_di1 | unique_id: atlas_di1 | ||
state_topic: "digitalInputs/runtime/out" | state_topic: "digitalInputs/runtime/out" | ||
value_template: > | value_template: > | ||
{% | {% if value_json.task.taskResult.DI1.result == true %} | ||
ON | |||
{% else %} | {% else %} | ||
OFF | |||
{% endif %} | {% endif %} | ||
payload_on: "ON" | payload_on: "ON" | ||
| Line 265: | Line 569: | ||
unique_id: atlas_di2 | unique_id: atlas_di2 | ||
state_topic: "digitalInputs/runtime/out" | state_topic: "digitalInputs/runtime/out" | ||
value_template: > | value_template: > | ||
{% | {% if value_json.task.taskResult.DI2.result == true %} | ||
ON | |||
{% else %} | {% else %} | ||
OFF | |||
{% endif %} | {% endif %} | ||
payload_on: "ON" | payload_on: "ON" | ||
| Line 278: | Line 581: | ||
unique_id: atlas_di3 | unique_id: atlas_di3 | ||
state_topic: "digitalInputs/runtime/out" | state_topic: "digitalInputs/runtime/out" | ||
value_template: > | value_template: > | ||
{% | {% if value_json.task.taskResult.DI3.result == true %} | ||
ON | |||
{% else %} | {% else %} | ||
OFF | |||
{% endif %} | {% endif %} | ||
payload_on: "ON" | payload_on: "ON" | ||
| Line 291: | Line 593: | ||
unique_id: atlas_di4 | unique_id: atlas_di4 | ||
state_topic: "digitalInputs/runtime/out" | state_topic: "digitalInputs/runtime/out" | ||
value_template: > | value_template: > | ||
{% | {% if value_json.task.taskResult.DI4.result == true %} | ||
ON | |||
{% else %} | {% else %} | ||
OFF | |||
{% endif %} | {% endif %} | ||
payload_on: "ON" | payload_on: "ON" | ||
payload_off: "OFF" | payload_off: "OFF" | ||
- name: "ATLAS eMMC RUL OK" | |||
unique_id: atlas_emmc_rul_ok | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: > | |||
{% if value_json.task.taskResult.emmc_rul.ok == true %} | |||
ON | |||
{% else %} | |||
OFF | |||
{% endif %} | |||
payload_on: "ON" | |||
payload_off: "OFF" | |||
device_class: problem | |||
- name: "ATLAS eMMC RUL Problem" | |||
unique_id: atlas_emmc_rul_problem | |||
state_topic: "systemHealth/runtime/out" | |||
value_template: > | |||
{% if value_json.task.taskResult.emmc_rul.ok == false %} | |||
ON | |||
{% else %} | |||
OFF | |||
{% endif %} | |||
payload_on: "ON" | |||
payload_off: "OFF" | |||
device_class: problem | |||
switch: | switch: | ||
- name: "ATLAS DO1" | - name: "ATLAS DO1" | ||
unique_id: atlas_do1 | unique_id: atlas_do1 | ||
state_topic: "digitalOutputs/runtime/out" | |||
command_topic: "digitalOutputs/runtime/in" | command_topic: "digitalOutputs/runtime/in" | ||
value_template: > | |||
payload_on: '{ | {% if value_json.task.taskResult.DO1.result == true %} | ||
payload_off: '{ | ON | ||
{% else %} | |||
state_on: " | OFF | ||
state_off: " | {% endif %} | ||
payload_on: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO1":true}}}' | |||
payload_off: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO1":false}}}' | |||
state_on: "ON" | |||
state_off: "OFF" | |||
- name: "ATLAS DO2" | - name: "ATLAS DO2" | ||
unique_id: atlas_do2 | unique_id: atlas_do2 | ||
state_topic: "digitalOutputs/runtime/out" | |||
command_topic: "digitalOutputs/runtime/in" | command_topic: "digitalOutputs/runtime/in" | ||
value_template: > | |||
payload_on: '{ | {% if value_json.task.taskResult.DO2.result == true %} | ||
payload_off: '{ | ON | ||
{% else %} | |||
state_on: " | OFF | ||
state_off: " | {% endif %} | ||
payload_on: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO2":true}}}' | |||
payload_off: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO2":false}}}' | |||
state_on: "ON" | |||
state_off: "OFF" | |||
- name: "ATLAS DO3" | - name: "ATLAS DO3" | ||
unique_id: atlas_do3 | unique_id: atlas_do3 | ||
state_topic: "digitalOutputs/runtime/out" | |||
command_topic: "digitalOutputs/runtime/in" | command_topic: "digitalOutputs/runtime/in" | ||
value_template: > | |||
payload_on: '{ | {% if value_json.task.taskResult.DO3.result == true %} | ||
payload_off: '{ | ON | ||
{% else %} | |||
state_on: " | OFF | ||
state_off: " | {% endif %} | ||
payload_on: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO3":true}}}' | |||
payload_off: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO3":false}}}' | |||
state_on: "ON" | |||
state_off: "OFF" | |||
- name: "ATLAS DO4" | - name: "ATLAS DO4" | ||
unique_id: atlas_do4 | unique_id: atlas_do4 | ||
state_topic: "digitalOutputs/runtime/out" | |||
command_topic: "digitalOutputs/runtime/in" | |||
value_template: > | |||
{% if value_json.task.taskResult.DO4.result == true %} | |||
ON | |||
{% else %} | |||
OFF | |||
{% endif %} | |||
payload_on: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO4":true}}}' | |||
payload_off: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO4":false}}}' | |||
state_on: "ON" | |||
state_off: "OFF" | |||
- name: "ATLAS DO5" | |||
unique_id: atlas_do5 | |||
state_topic: "digitalOutputs/runtime/out" | |||
command_topic: "digitalOutputs/runtime/in" | |||
value_template: > | |||
{% if value_json.task.taskResult.DO5.result == true %} | |||
ON | |||
{% else %} | |||
OFF | |||
{% endif %} | |||
payload_on: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO5":true}}}' | |||
payload_off: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO5":false}}}' | |||
state_on: "ON" | |||
state_off: "OFF" | |||
- name: "ATLAS DO6" | |||
unique_id: atlas_do6 | |||
state_topic: "digitalOutputs/runtime/out" | |||
command_topic: "digitalOutputs/runtime/in" | command_topic: "digitalOutputs/runtime/in" | ||
value_template: > | |||
{% if value_json.task.taskResult.DO6.result == true %} | |||
ON | |||
{% else %} | |||
OFF | |||
{% endif %} | |||
payload_on: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO6":true}}}' | |||
payload_off: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO6":false}}}' | |||
state_on: "ON" | |||
state_off: "OFF" | |||
- name: "ATLAS DO7" | |||
unique_id: atlas_do7 | |||
state_topic: "digitalOutputs/runtime/out" | state_topic: "digitalOutputs/runtime/out" | ||
payload_on: '{" | command_topic: "digitalOutputs/runtime/in" | ||
value_template: > | |||
value_template: "{{ value_json.task.taskResult. | {% if value_json.task.taskResult.DO7.result == true %} | ||
ON | |||
{% else %} | |||
OFF | |||
{% endif %} | |||
payload_on: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO7":true}}}' | |||
payload_off: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO7":false}}}' | |||
state_on: "ON" | |||
state_off: "OFF" | |||
- name: "ATLAS DO8" | |||
unique_id: atlas_do8 | |||
state_topic: "digitalOutputs/runtime/out" | |||
command_topic: "digitalOutputs/runtime/in" | |||
value_template: > | |||
{% if value_json.task.taskResult.DO8.result == true %} | |||
ON | |||
{% else %} | |||
OFF | |||
{% endif %} | |||
payload_on: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO8":true}}}' | |||
payload_off: '{"origin":"HA","task":{"alias":"SET_DO","taskParams":{"DO8":false}}}' | |||
state_on: "ON" | |||
state_off: "OFF" | |||
number: | |||
- name: "ATLAS AO1" | |||
unique_id: atlas_ao1 | |||
state_topic: "analogOutputs/runtime/out" | |||
command_topic: "analogOutputs/runtime/in" | |||
value_template: "{{ value_json.task.taskResult.AO1.result }}" | |||
command_template: > | |||
{"origin":"HA","task":{"alias":"SET_AO","taskParams":{"AO1":{{ value | float }}}}} | |||
min: 4 | |||
max: 20 | |||
step: 0.1 | |||
unit_of_measurement: "mA" | |||
mode: slider | |||
- name: "ATLAS AO2" | |||
unique_id: atlas_ao2 | |||
state_topic: "analogOutputs/runtime/out" | |||
command_topic: "analogOutputs/runtime/in" | |||
value_template: "{{ value_json.task.taskResult.AO2.result }}" | |||
command_template: > | |||
{"origin":"HA","task":{"alias":"SET_AO","taskParams":{"AO2":{{ value | float }}}}} | |||
min: 4 | |||
max: 20 | |||
step: 0.1 | |||
unit_of_measurement: "mA" | |||
mode: slider | |||
EOF | EOF | ||
</syntaxhighlight>'''Notes about this mqtt.yaml''' | </syntaxhighlight>'''Notes about this mqtt.yaml''' | ||
{| class="wikitable" | {| class="wikitable mix-table" | ||
!Entity | !Entity | ||
!MQTT Topic | !MQTT Topic | ||
| Line 383: | Line 813: | ||
In Home Assistant, check for entities similar to: | In Home Assistant, check for entities similar to: | ||
{| class="wikitable" | {| class="wikitable mix-table" | ||
!Entity | !Entity | ||
!Type | !Type | ||
| Line 462: | Line 892: | ||
mosquitto_sub -h 127.0.0.1 -t 'digitalInputs/runtime/out' -v | mosquitto_sub -h 127.0.0.1 -t 'digitalInputs/runtime/out' -v | ||
mosquitto_sub -h 127.0.0.1 -t 'digitalOutputs/runtime/out' -v | mosquitto_sub -h 127.0.0.1 -t 'digitalOutputs/runtime/out' -v | ||
</syntaxhighlight>Send a test to a digital output: | </syntaxhighlight>Send a test to a digital output:<syntaxhighlight lang="bash"> | ||
mosquitto_pub -h 127.0.0.1 -t 'digitalOutputs/runtime/in' -m '{"id":0,"origin":"TEST","task":{"action":"SET","taskParams":{"DO1":{"state":"high"}}}}' | |||
</syntaxhighlight> | |||
=== 13. Daily operation === | === 13. Daily operation === | ||
| Line 470: | Line 900: | ||
cd /opt/atlas-ha | cd /opt/atlas-ha | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{| class="wikitable" | {| class="wikitable mix-table" | ||
!Action | !Action | ||
!Command | !Command | ||
| Line 498: | Line 928: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== 15 | === 15. Automatic installation with script === | ||
The current installation can be performed using the script:<syntaxhighlight lang="bash"> | The current installation can be performed using the script:<syntaxhighlight lang="bash"> | ||
install-atlas-ha.sh | install-atlas-ha.sh | ||
| Line 527: | Line 935: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== 15.1 Script used ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
| Line 563: | Line 971: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== 15.2 What the script does ==== | ||
{| class="wikitable" | {| class="wikitable mix-table" | ||
!Step | !Step | ||
!Action | !Action | ||
| Line 590: | Line 998: | ||
|} | |} | ||
==== | ==== 15.3 Prepare files ==== | ||
Copy to ATLAS:<syntaxhighlight lang="bash"> | Copy to ATLAS:<syntaxhighlight lang="bash"> | ||
install-atlas-ha.sh | install-atlas-ha.sh | ||
atlas-ha-backup.tar.gz | atlas-ha-backup.tar.gz | ||
</syntaxhighlight>Example with '''scp''' from PC: | </syntaxhighlight>Example with '''scp''' from PC:<syntaxhighlight lang="bash"> | ||
scp install-atlas-ha.sh atlas-ha-backup.tar.gz pi@<atlas-ip>:/home/pi/ | |||
</syntaxhighlight>On ATLAS:<syntaxhighlight lang="bash"> | |||
cd /home/pi | |||
chmod +x install-atlas-ha.sh | |||
</syntaxhighlight> | |||
==== 15.4 Run installation ==== | |||
<syntaxhighlight lang="bash"> | |||
sudo ./install-atlas-ha.sh atlas-ha-backup.tar.gz | |||
</syntaxhighlight>If the backup has a different name, replace in the command:<syntaxhighlight lang="bash"> | |||
sudo ./install-atlas-ha.sh <backup-name>.tar.gz | |||
</syntaxhighlight> | |||
==== 15.5 Expected backup structure ==== | |||
The backup should contain the necessary structure so that, after extraction in <code>/opt/atlas-ha</code>, at least the following exists: | |||
/opt/atlas-ha/ | |||
├── docker-compose.yml | |||
└── ha-config/ | |||
├── configuration.yaml | |||
├── mqtt.yaml | |||
├── automations.yaml | |||
├── scripts.yaml | |||
└── scenes.yaml | |||
If the backup does not contain <code>docker-compose.yml</code>, the command <code>sudo docker compose up -d</code> will not be able to start Home Assistant. | |||
==== 15.6 Validation after the script ==== | |||
Check if the container is active:<syntaxhighlight lang="bash"> | |||
sudo docker ps | |||
</syntaxhighlight>View logs:<syntaxhighlight lang="bash"> | |||
sudo docker logs -f homeassistant | |||
</syntaxhighlight>Check HTTP response:<syntaxhighlight lang="bash"> | |||
curl -s -o /dev/null -w "%{http_code} | |||
" http://localhost:8123 | |||
</syntaxhighlight>'''Expected result:''' | |||
{| class="wikitable mix-table" | |||
!Code | |||
!Meaning | |||
|- | |||
|200 | |||
|Home Assistant accessible | |||
|- | |||
|302 | |||
|Home Assistant accessible, with redirection | |||
|- | |||
|000 connection refused | |||
|May be normal in the first 1-2 minutes; wait and retry | |||
|} | |||
Access in browser: | |||
http://<atlas-ip>:8123 | |||
=== 16. Uninstall / revert === | |||
Stop and remove the container:<syntaxhighlight lang="bash"> | |||
cd /opt/atlas-ha | |||
sudo docker compose down | |||
</syntaxhighlight>Remove the image:<syntaxhighlight lang="bash"> | |||
sudo docker image rm ghcr.io/home-assistant/home-assistant:stable | |||
</syntaxhighlight>Optionally, also remove the configuration:<syntaxhighlight lang="bash"> | |||
sudo rm -rf /opt/atlas-ha | |||
</syntaxhighlight>The native ATLAS stack, including Node-RED, Grafana, InfluxDB, and Mosquitto, is not removed by these steps. | |||
=== 17. Summary === | |||
{| class="wikitable mix-table" | |||
!Step | |||
!Command / Action | |||
|- | |||
|Create folder | |||
|sudo mkdir -p /opt/atlas-ha | |||
|- | |||
|Create compose | |||
|docker-compose.yml with network_mode: host | |||
|- | |||
|Start | |||
|sudo docker compose up -d | |||
|- | |||
|Access | |||
|[http://<ip-do-atlas>:8123 '''<u>http://<atlas-ip>:8123</u>'''] | |||
|- | |||
|Configure MQTT | |||
|Broker 127.0.0.1:1883 | |||
|- | |||
|Create entities | |||
|configuration.yaml + mqtt.yaml | |||
|- | |||
|Restart | |||
|sudo docker compose restart | |||
|- | |||
|Logs | |||
|sudo docker logs -f homeassistant | |||
|- | |||
|Backup | |||
|'''tar''' from the '''ha-config''' folder | |||
|- | |||
|Revert | |||
|sudo docker compose down | |||
|} | |||