Jump to content

SENSBLUE ATLAS/Home Assistant: Difference between revisions

No edit summary
No edit summary
 
(29 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 u 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|Atlas-ha-install-v1.zip]]</span>
    </td>
</table>
= Home Assistant integration =
= Home Assistant integration =
'''Installing Home Assistant on the SENSBLUE ATLAS / i.Cee²'''
'''Installing Home Assistant on the SENSBLUE ATLAS / i.Cee²'''
Line 16: Line 26:


=== 1. Prerequisites ===
=== 1. Prerequisites ===
{| class="wikitable"
{| class="wikitable mix-table"
!Item
!Item
!Value / check
!Value / check
Line 50: Line 60:
=== 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 74: Line 84:
done
done
</syntaxhighlight>
</syntaxhighlight>
=== 3. Installing Docker ===
Install Docker Engine and the Docker Compose plugin through Docker's official Debian repository.
Summary of the process:
# Update packages.
# Install dependencies.
# Add the Docker GPG key.
# Add the Docker repository.
# Install Docker Engine and the Docker Compose plugin.
# Test with hello-world.
Check that Docker is operational:<syntaxhighlight lang="bash">
sudo docker run --rm hello-world
</syntaxhighlight>If <code>apt-get update</code> returns a 404 error for the Docker repository, temporarily use the bookworm line for the Docker repository and repeat the update/installation.
Example 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 ===
Create the project folder:<syntaxhighlight lang="bash">
sudo mkdir -p /opt/atlas-ha
cd /opt/atlas-ha
</syntaxhighlight>Create the <code>docker-compose.yml</code> file:<syntaxhighlight lang="bash">
sudo tee docker-compose.yml > /dev/null << 'EOF'
services:
    homeassistant:
      container_name: homeassistant
      image: ghcr.io/home-assistant/home-assistant:stable
      network_mode: host
      volumes:
        - ./ha-config:/config
        - /etc/localtime:/etc/localtime:ro
      environment:
        - TZ=Europe/Lisbon
      restart: unless-stopped
EOF
</syntaxhighlight>'''Important notes:'''
{| class="wikitable mix-table"
!Option
!Reason
|-
|network_mode: host
|Allows direct access to the port and local Mosquitto at 127.0.0.1:1883
|-
|./ha-config:/config
|Stores Home Assistant configuration in /opt/atlas-ha/ha-config
|-
|restart: unless-stopped
|Automatically restarts Home Assistant after reboot or failure
|-
|TZ=Europe/Lisbon
|Sets the correct time zone
|}
=== 5. Start Home Assistant ===
From the <code>/opt/atlas-ha</code> folder:<syntaxhighlight lang="bash">
sudo docker compose up -d
</syntaxhighlight>The first start may take a few minutes as the image is downloaded and Home Assistant initialises the configuration.
'''Check container status:'''<syntaxhighlight lang="bash">
sudo docker ps
</syntaxhighlight>'''Check 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 accessible
|-
|302
|Home Assistant accessible, with redirection
|-
|000 connection refused
|May be normal in the first 1-2 minutes; wait and retry
|}
=== 6. Initial onboarding ===
Open in a browser on a PC on the same network:<syntaxhighlight lang="bash">
http://<atlas-ip>:8123
</syntaxhighlight>Then:
# Create the administrator account.
# Set the location, e.g., Portugal, or skip.
# Complete until you reach the main dashboard.
'''From this point, Home Assistant is installed and operational.'''
=== 7. Configure MQTT integration in Home Assistant ===
Since the container uses <code>network_mode: host</code>, Home Assistant can access the local Mosquitto via:
{| class="wikitable mix-table"
!Field
!Value
|-
|Broker
|127.0.0.1
|-
|Port
|1883
|-
|User/password
|As per Mosquitto configuration; blank if no authentication
|}
In Home Assistant:
'''Settings → Devices & services → Add integration → MQTT'''
Configure the broker as:
'''127.0.0.1:1883'''
After adding the MQTT integration, create the following YAML files to declare the entities used in the current installation.
=== 8. Create configuration.yaml ===
Enter the Home Assistant configuration folder:<syntaxhighlight lang="bash">
cd /opt/atlas-ha/ha-config
</syntaxhighlight>Create or replace the <code>configuration.yaml</code> file:<syntaxhighlight lang="bash">
sudo tee configuration.yaml > /dev/null << 'EOF'
default_config:
frontend:
  themes: !include_dir_merge_named themes
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
mqtt: !include mqtt.yaml
EOF
</syntaxhighlight>Create the included files if they do not already exist:<syntaxhighlight lang="bash">
sudo touch automations.yaml scripts.yaml scenes.yaml
sudo mkdir -p themes
</syntaxhighlight>
=== 9. Create mqtt.yaml ===
Create the file:<syntaxhighlight lang="bash">
cd /opt/atlas-ha/ha-config
sudo tee mqtt.yaml > /dev/null << 'EOF'
sensor:
  - name: "ATLAS AI1"
    unique_id: atlas_ai1
    state_topic: "analogInputs/runtime/out"
    value_template: "{{ value_json.task.taskResult.AI1.result | float(0) }}"
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
  - name: "ATLAS AI2"
    unique_id: atlas_ai2
    state_topic: "analogInputs/runtime/out"
    value_template: "{{ value_json.task.taskResult.AI2.result | float(0) }}"
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
  - name: "ATLAS AI3"
    unique_id: atlas_ai3
    state_topic: "analogInputs/runtime/out"
    value_template: "{{ value_json.task.taskResult.AI3.result | float(0) }}"
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
  - name: "ATLAS AI4"
    unique_id: atlas_ai4
    state_topic: "analogInputs/runtime/out"
    value_template: "{{ value_json.task.taskResult.AI4.result | float(0) }}"
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
binary_sensor:
  - name: "ATLAS DI1"
    unique_id: atlas_di1
    state_topic: "digitalInputs/runtime/out"
    value_template: >-
      {% set di = value_json.task.taskResult.DI1 %}
      {% if di.result is defined %}
        {{ 'ON' if di.result == true else 'OFF' }}
      {% else %}
        {{ 'ON' if di.state == 'high' else 'OFF' }}
      {% endif %}
    payload_on: "ON"
    payload_off: "OFF"
  - name: "ATLAS DI2"
    unique_id: atlas_di2
    state_topic: "digitalInputs/runtime/out"
    value_template: >-
      {% set di = value_json.task.taskResult.DI2 %}
      {% if di.result is defined %}
        {{ 'ON' if di.result == true else 'OFF' }}
      {% else %}
        {{ 'ON' if di.state == 'high' else 'OFF' }}
      {% endif %}
    payload_on: "ON"
    payload_off: "OFF"
  - name: "ATLAS DI3"
    unique_id: atlas_di3
    state_topic: "digitalInputs/runtime/out"
    value_template: >-
      {% set di = value_json.task.taskResult.DI3 %}
      {% if di.result is defined %}
        {{ 'ON' if di.result == true else 'OFF' }}
      {% else %}
        {{ 'ON' if di.state == 'high' else 'OFF' }}
      {% endif %}
    payload_on: "ON"
    payload_off: "OFF"
  - name: "ATLAS DI4"
    unique_id: atlas_di4
    state_topic: "digitalInputs/runtime/out"
    value_template: >-
      {% set di = value_json.task.taskResult.DI4 %}
      {% if di.result is defined %}
        {{ 'ON' if di.result == true else 'OFF' }}
      {% else %}
        {{ 'ON' if di.state == 'high' else 'OFF' }}
      {% endif %}
    payload_on: "ON"
    payload_off: "OFF"
switch:
  - name: "ATLAS DO1"
    unique_id: atlas_do1
    command_topic: "digitalOutputs/runtime/in"
    state_topic: "digitalOutputs/runtime/out"
    payload_on: '{"id":0,"origin":"HA","task":{"action":"SET","taskParams":{"DO1":{"state":"high"}}}}'
    payload_off: '{"id":0,"origin":"HA","task":{"action":"SET","taskParams":{"DO1":{"state":"low"}}}}'
    value_template: "{{ value_json.task.taskResult.DO1.state }}"
    state_on: "high"
    state_off: "low"
    optimistic: false
  - name: "ATLAS DO2"
    unique_id: atlas_do2
    command_topic: "digitalOutputs/runtime/in"
    state_topic: "digitalOutputs/runtime/out"
    payload_on: '{"id":0,"origin":"HA","task":{"action":"SET","taskParams":{"DO2":{"state":"high"}}}}'
    payload_off: '{"id":0,"origin":"HA","task":{"action":"SET","taskParams":{"DO2":{"state":"low"}}}}'
    value_template: "{{ value_json.task.taskResult.DO2.state }}"
    state_on: "high"
    state_off: "low"
    optimistic: false
  - name: "ATLAS DO3"
    unique_id: atlas_do3
    command_topic: "digitalOutputs/runtime/in"
    state_topic: "digitalOutputs/runtime/out"
    payload_on: '{"id":0,"origin":"HA","task":{"action":"SET","taskParams":{"DO3":{"state":"high"}}}}'
    payload_off: '{"id":0,"origin":"HA","task":{"action":"SET","taskParams":{"DO3":{"state":"low"}}}}'
    value_template: "{{ value_json.task.taskResult.DO3.state }}"
    state_on: "high"
    state_off: "low"
    optimistic: false
  - name: "ATLAS DO4"
    unique_id: atlas_do4
    command_topic: "digitalOutputs/runtime/in"
    state_topic: "digitalOutputs/runtime/out"
    payload_on: '{"id":0,"origin":"HA","task":{"action":"SET","taskParams":{"DO4":{"state":"high"}}}}'
    payload_off: '{"id":0,"origin":"HA","task":{"action":"SET","taskParams":{"DO4":{"state":"low"}}}}'
    value_template: "{{ value_json.task.taskResult.DO4.state }}"
    state_on: "high"
    state_off: "low"
    optimistic: false
EOF
</syntaxhighlight>'''Notes about this mqtt.yaml'''
{| class="wikitable mix-table"
!Entity
!MQTT Topic
!Function
|-
|sensor.atlas_ai1 .. ai4
|analogInputs/runtime/out
|Show analogue readings AI..AI4
|-
|binary_sensor.atlas_di1 .. di4
|digitalInputs/runtime/out
|Show digital input states DI..DI4
|-
|switch.atlas_do1 .. do4
|digitalOutputs/runtime/in/out
|Control and confirm digital outputs DO..DO4
|}
Digital inputs accept two response formats:<syntaxhighlight lang="bash">
{
"result": true
}
</syntaxhighlight>or:<syntaxhighlight lang="bash">
{
"state": "high"
}
</syntaxhighlight>This allows compatibility with different versions of the Node-RED flow.
=== 10. Restart and validate configuration ===
'''Restart Home Assistant:'''<syntaxhighlight lang="bash">
cd /opt/atlas-ha
sudo docker compose restart
</syntaxhighlight>'''View logs:'''<syntaxhighlight lang="bash">
sudo docker logs -f homeassistant
</syntaxhighlight>'''Confirm there are no errors related to MQTT or YAML.'''
In Home Assistant, check for entities similar to:
{| class="wikitable mix-table"
!Entity
!Type
|-
|sensor.atlas_ai1
|Analogue sensor
|-
|sensor.atlas_ai2
|Analogue sensor
|-
|sensor.atlas_ai3
|Analogue sensor
|-
|sensor.atlas_ai4
|Analogue sensor
|-
|binary_sensor.atlas_di1
|Digital input
|-
|binary_sensor.atlas_di2
|Digital input
|-
|binary_sensor.atlas_di3
|Digital input
|-
|binary_sensor.atlas_di4
|Digital input
|-
|switch.atlas_do1
|Digital output
|-
|switch.atlas_do2
|Digital output
|-
|switch.atlas_do3
|Digital output
|-
|switch.atlas_do4
|Digital output
|}
=== 11. Simple dashboard in Home Assistant ===
Once the entities exist, you can create a simple card in the Dashboard.
'''Example YAML for a Lovelace view:'''<syntaxhighlight lang="yaml">type: vertical-stack
cards:
  - type: entities
    title: Analog Inputs
    entities:
      - sensor.atlas_ai1
      - sensor.atlas_ai2
      - sensor.atlas_ai3
      - sensor.atlas_ai4
  - type: entities
    title: Digital Inputs
    entities:
      - binary_sensor.atlas_di1
      - binary_sensor.atlas_di2
      - binary_sensor.atlas_di3
      - binary_sensor.atlas_di4
  - type: entities
    title: Digital Outputs
    entities:
      - switch.atlas_do1
      - switch.atlas_do2
      - switch.atlas_do3
      - switch.atlas_do4</syntaxhighlight>
[[File:Home Assistant img 1.png|center|frameless|1037x1037px]]
[[File:Home Assistant img 2.png|center|frameless|1037x1037px]]
=== 12. Test MQTT communication ===
Install MQTT client if necessary:<syntaxhighlight lang="bash">
sudo apt-get install -y mosquitto-clients
</syntaxhighlight>View MQTT messages received by Home Assistant:<syntaxhighlight lang="bash">
mosquitto_sub -h 127.0.0.1 -t 'analogInputs/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
</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 ===
Run these commands inside the folder:<syntaxhighlight lang="bash">
cd /opt/atlas-ha
</syntaxhighlight>
{| class="wikitable mix-table"
!Action
!Command
|-
|View logs
|sudo docker logs -f homeassistant
|-
|View status
|sudo docker ps
|-
|Restart
|sudo docker compose restart
|-
|Stop
|sudo docker compose stop
|-
|Start
|sudo docker compose start
|-
|Update
|sudo docker compose pull && sudo docker compose up -d
|}
=== 14. Configuration backup ===
The <code>ha-config</code> folder contains the Home Assistant state/configuration. Create a backup:<syntaxhighlight lang="bash">
sudo tar czf ~/atlas-ha-backup.tar.gz -C /opt/atlas-ha docker-compose.yml ha-config
</syntaxhighlight>
=== 15. Production notes ===
Before sending a unit to a client, review the following points:
{| class="wikitable mix-table"
!Point
!Note
|-
|MQTT Broker
|Mosquitto may be unauthenticated and listening on 0.0.0.0; secure before exposing the unit
|-
|Grafana
|Change default credentials, e.g., admin/admin
|-
|Access Point
|If ATLAS routes traffic via wlan0, validate FORWARD, DOCKER-USER, nftables rules and persistence
|-
|Initial HA account
|The admin account should not be the same on all units
|-
|Network
|Validate port exposure when the unit has a routable IP via Ethernet/LTE
|}
=== 16. Automatic installation with script ===
The current installation can be performed using the script:<syntaxhighlight lang="bash">
install-atlas-ha.sh
</syntaxhighlight>This script takes a backup <code>.tar.gz</code> file as an argument and installs/restores Home Assistant in:<syntaxhighlight lang="bash">
/opt/atlas-ha
</syntaxhighlight>
==== 16.1 Script used ====
<syntaxhighlight lang="bash">
#!/bin/bash
set -e
BACKUP_FILE="$1"
INSTALL_DIR="/opt/atlas-ha"
if [ -z "$BACKUP_FILE" ]; then
  echo "Usage:"
  echo "sudo ./install-atlas-ha.sh atlas-ha-backup.tar.gz"
  exit 1
fi
echo "Installing dependencies..."
sudo apt update
sudo apt install -y docker.io docker-compose-plugin
echo "Enabling Docker..."
sudo systemctl enable docker
sudo systemctl start docker
echo "Creating installation folder..."
sudo mkdir -p "$INSTALL_DIR"
echo "Extracting backup..."
sudo tar -xzvf "$BACKUP_FILE" -C "$INSTALL_DIR"
echo "Starting Home Assistant..."
cd "$INSTALL_DIR"
sudo docker compose up -d
echo "Installation complete."
echo "Access at: http://DEVICE_IP:8123"
</syntaxhighlight>
==== 16.2 What the script does ====
{| class="wikitable mix-table"
!Step
!Action
|-
|Validate argument
|Confirms a backup file was specified
|-
|Install dependencies
|Runs apt update and installs docker.io + docker-compose-plugin
|-
|Enable Docker
|Runs systemctl enable docker and systemctl start docker
|-
|Create folder
|Ensures /opt/atlas-ha exists
|-
|Extract backup
|Extracts the .tar.gz to /opt/atlas-ha
|-
|Start HA
|Enters /opt/atlas-ha and runs sudo docker compose up -d
|-
|Show URL
|Indicates access via <nowiki>http://DEVICE_IP:8123</nowiki>
|}
==== 16.3 Prepare files ====
Copy to ATLAS:<syntaxhighlight lang="bash">
install-atlas-ha.sh
atlas-ha-backup.tar.gz
</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>
==== 16.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>
==== 16.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.
==== 16.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://&#x3C;atlas-ip&#x3E;:8123
=== 17. 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.
=== 18. 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://&#x3C;ip-do-atlas&#x3E;: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
|}