Skip to content

Commit 6f43081

Browse files
committed
Update home assistant documentation
Includes: * [hassio support](https://gist.github.com/Paraphraser/55643bd660db46716f6c81266905cae8#hassio-support-optional) material from old gist; and * material originally posted as part of [Issue 312](#312), recommended for inclusion by [lole-elol](https://github.com/lole-elol). Adds how-tos for uninstalling and re-installing Docker as an alternative to rebuilding a Pi if the decision to install hass.io comes after Docker has been installed via IOTstack. Also tidies-up some formatting and typos.
1 parent 360dd7e commit 6f43081

File tree

1 file changed

+220
-23
lines changed

1 file changed

+220
-23
lines changed

docs/Containers/Home-Assistant.md

Lines changed: 220 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,169 @@
11
# Home assistant
2+
23
## References
34
- [Docker](https://hub.docker.com/r/homeassistant/home-assistant/)
45
- [Webpage](https://www.home-assistant.io/)
56

67
Hass.io is a home automation platform running on Python 3. It is able to track and control all devices at home and offer a platform for automating control. Port binding is `8123`.
7-
Hass.io is exposed to your hosts' network in order to discover devices on your LAN. That means that it does not sit inside docker's network.
8+
Hass.io is exposed to your hosts' network in order to discover devices on your LAN. That means that it does not sit inside Docker's network.
89

910
## To avoid confusion
10-
There are 2 versions of Home Assistant: Hass.io and Home Assistant Docker. Hass.io uses its own orchastration with 3 docker images: `hassio_supervisor`, `hassio_dns` and `homeassistant`. Home Assistant Docker runs inside a single docker image, and doesn't support all the features that Hass.io does (such as add-ons). IOTstack allows installing either, but we can only offer limited configuration of Hass.io since it is its own platform. [More info on versions](https://www.home-assistant.io/docs/installation/#recommended)
11+
12+
There are two versions of Home Assistant:
13+
14+
* Hass.io, and
15+
* Home Assistant Docker.
16+
17+
Hass.io uses its own orchestration with 3 docker images:
18+
19+
* `hassio_supervisor`,
20+
* `hassio_dns` and
21+
* `homeassistant`.
22+
23+
Home Assistant Docker runs inside a single Docker image, and doesn't support all the features that Hass.io does (such as add-ons). IOTstack allows installing either, but we can only offer limited configuration of Hass.io since it is its own platform.
24+
25+
> [More info on versions](https://www.home-assistant.io/docs/installation/#recommended).
1126

1227
## Menu installation
28+
1329
Hass.io installation can be found inside the `Native Installs` menu on the main menu. Home Assistant can be found in the `Build Stack` menu.
1430

15-
You will be asked to select you device type during the installation. Hass.io is no longer dependant on the IOTstack, it has its own service for maintaining its uptime.
31+
You will be asked to select your device type during the installation. Hass.io is no longer dependant on the IOTstack, it has its own service for maintaining its uptime.
1632

1733
## Installation
18-
Due to the behaviour of Network Manager, it is strongly recomended to connect the Pi over a wired internet connection, rather than WiFi.
34+
35+
Hass.io creates a conundrum:
36+
37+
* If you are definitely going to install Hass.io then you **must** install its dependencies **before** you install Docker.
38+
* One of Hass.io's dependencies is [Network Manager](https://wiki.archlinux.org/index.php/NetworkManager). Network Manager makes **serious** changes to your operating system, with side-effects you may not expect such as giving your Raspberry Pi's WiFi interface a random MAC address both during the installation and, then, each time you reboot. You are in for a world of pain if you install Network Manager without first understanding what is going to happen and planning accordingly.
39+
* If you don't install Hass.io's dependencies before you install Docker, you will either have to uninstall Docker or rebuild your system. This is because both Docker and Network Manager adjust your Raspberry Pi's networking. Docker is happy to install after Network Manager, but the reverse is not true.
40+
41+
### If Docker is already installed, uninstall it
42+
43+
```
44+
$ sudo apt -y purge docker-ce docker-ce-cli containerd.io
45+
$ sudo apt -y remove docker-compose
46+
$ sudo pip3 uninstall docker-compose
47+
```
48+
49+
Note that this does **not** interfere with your existing `~/IOTstack` folder.
50+
51+
### Ensure your system is fully up-to-date
52+
53+
```
54+
$ sudo apt update
55+
$ sudo apt upgrade -y
56+
```
57+
58+
### Install Hass.io dependencies (stage 1)
59+
60+
```bash
61+
$ sudo apt install -y apparmor apparmor-profiles apparmor-utils
62+
$ sudo apt install -y software-properties-common apt-transport-https ca-certificates dbus
63+
```
64+
65+
The first line is required. A post at [community.home-assistant.io](ttps://community.home-assistant.io/t/installing-home-assistant-supervised-on-raspberry-pi-os/201836) implies the second line may also be required but it is not clear whether those packages are strictly necessary.
66+
67+
### Connect to your Raspberry Pi via Ethernet
68+
69+
You can skip this step if you interact with your Raspberry Pi via a screen connected to its HDMI port, along with a keyboard and mouse.
70+
71+
If, however, you are running "headless" (SSH or VNC), connect your Raspberry Pi to Ethernet.
72+
73+
When the Ethernet interface initialises, work out its IP address:
74+
75+
```bash
76+
$ ifconfig eth0
77+
78+
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
79+
inet 192.168.132.9 netmask 255.255.255.0 broadcast 192.168.132.255
80+
ether ab:cd:ef:12:34:56 txqueuelen 1000 (Ethernet)
81+
RX packets 4166292 bytes 3545370373 (3.3 GiB)
82+
RX errors 0 dropped 0 overruns 0 frame 0
83+
TX packets 2086814 bytes 2024386593 (1.8 GiB)
84+
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
85+
```
86+
87+
In the above, the IP address assigned to the Ethernet interface is 192.168.132.9.
88+
89+
Drop out of your existing session (SSH or VNC) and re-connect to your Raspberry Pi using the IP address assigned to its Ethernet interface:
90+
91+
```bash
92+
93+
```
94+
95+
or:
96+
97+
```
98+
99+
```
100+
101+
The reason for stipulating the IP address, rather than a name like `raspberrypi.local` is so that you are *definitely* connected to the Ethernet interface.
102+
19103
If you ignore the advice about connecting via Ethernet and install Network Manager while your session is connected via WiFi, your connection will freeze part way through the installation (when Network Manager starts running and unconditionally changes your Raspberry Pi's WiFi MAC address).
20104

21-
Ensure your system is up to date with:
105+
> If you want to know more about why the connection freezes, see [why random MACs are such a hassle ](#aboutRandomMACs).
106+
107+
You *may* be able to re-connect after the WiFi interface acquires a new IP address and advertises that via multicast DNS associated with the name of your device (eg `raspberrypi.local`), but you may also find that the only way to regain control is to power-cycle your Raspberry Pi.
108+
109+
The advice about using Ethernet is well-intentioned. You should heed this advice even if means you need to temporarily relocate your Raspberry Pi just so you can attach it via Ethernet for the next few steps. You can go back to WiFi later, once everything is set up. You have been warned!
110+
111+
### Install Hass.io dependencies (stage 2)
112+
113+
Install Network Manager:
114+
115+
```bash
116+
$ sudo apt install -y network-manager
117+
```
118+
119+
### Consider disabling random MAC address allocation
120+
121+
According to [@steveatk on Discord](https://discordapp.com/channels/638610460567928832/638610461109256194/758825690715652116), you can stop Network Manager from allocating random MAC addresses to your WiFi interface by editing:
122+
123+
```bash
124+
$ sudo vi /etc/NetworkManager/NetworkManager.conf
22125
```
23-
sudo apt update
126+
127+
and adding:
128+
129+
```bash
130+
[device]
131+
wifi.scan-rand-mac-address=no
24132
```
25-
If not already installed, install the network manager with:
133+
134+
This needs to be done **twice**:
135+
136+
* after Network Manager is installed; and again
137+
* after Hass.io is installed via the IOTstack menu.
138+
139+
In both cases, `NetworkManager.conf` is replaced with a version that enables random MAC allocation.
140+
141+
### Re-install docker
142+
143+
If you had to uninstall Docker in the earlier step, now is the time to re-install it. You can use the menu or one of the scripts provided with IOTstack but it is probably just as easy to run:
144+
145+
```bash
146+
$ curl -fsSL https://get.docker.com | sh
147+
$ sudo usermod -G docker -a $USER
148+
$ sudo usermod -G bluetooth -a $USER
149+
$ sudo apt install -y python3-pip python3-dev
150+
$ sudo pip3 install -U docker-compose
151+
$ sudo pip3 install -U ruamel.yaml==0.16.12 blessed
152+
$ sudo reboot
26153
```
27-
sudo apt-get install network-manager apparmor-utils
154+
155+
Note that this does **not** interfere with your existing `~/IOTstack` folder.
156+
157+
### Run the Hass.io installation
158+
159+
Start at:
160+
161+
```
162+
$ cd ~/IOTstack
163+
$ ./menu.sh
28164
```
29-
before running the hass.io installation to avoid any potential errors.
165+
166+
and then navigate to the installation option.
30167

31168
The installation of Hass.io takes up to 20 minutes (depending on your internet connection). Refrain from restarting your machine until it has come online and you are able to create a user account.
32169

@@ -35,34 +172,94 @@ The installation of Hass.io takes up to 20 minutes (depending on your internet c
35172
To remove Hass.io you first need to stop the service that controls it. Run the following in the terminal:
36173

37174
```bash
38-
sudo systemctl stop hassio-supervisor.service
39-
sudo systemctl disable hassio-supervisor.service
175+
$ sudo systemctl stop hassio-supervisor.service
176+
$ sudo systemctl disable hassio-supervisor.service
40177
```
41178

42179
This should stop the main service however there are two additional container that still need to be address
43180

44-
This will stop the service and disable it from starting on the next boot
181+
This will stop the service and disable it from starting on the next boot.
45182

46-
Next you need to stop the hassio_dns and hassio_supervisor
183+
Next you need to stop the `hassio_dns` and `hassio_supervisor`:
47184

48185
```bash
49-
docker stop hassio_supervisor
50-
docker stop hassio_dns
51-
docker stop homeassistant
186+
$ docker stop hassio_supervisor
187+
$ docker stop hassio_dns
188+
$ docker stop homeassistant
52189
```
53190

54-
If you want to remove the containers
191+
If you want to remove the containers:
55192

56193
```bash
57-
docker rm hassio_supervisor
58-
docker rm hassio_dns
59-
docker stop homeassistant
194+
$ docker rm hassio_supervisor
195+
$ docker rm hassio_dns
196+
$ docker stop homeassistant
60197
```
61198

62-
After rebooting you should be able to reinstall
199+
After rebooting you should be able to reinstall.
63200

64-
The stored file are located in `/usr/share/hassio` which can be removed if you need to
201+
The stored files are located in `/usr/share/hassio` which can be removed if you need to.
65202

66-
Double check with `docker ps` to see if there are other hassio containers running. They can stopped and removed in the same fashion for the dns and supervisor
203+
Double-check with `docker ps` to see if there are other hassio containers running. They can stopped and removed in the same fashion for the dns and supervisor.
67204

68205
You can use Portainer to view what is running and clean up the unused images.
206+
207+
## <a name="aboutRandomMACs"> Why random MACs are such a hassle </a>
208+
209+
> This material was originally posted as part of [Issue 312](https://github.com/SensorsIot/IOTstack/issues/312). It was moved here following a suggestion by [lole-elol](https://github.com/lole-elol).
210+
211+
When you connect to a Raspberry Pi via SSH, that's a protocol that is riding on top of TCP/IP. SSH (the layer 4 protocol) uses TCP (a connection-oriented protocol) which rides on IP (the layer 3 protocol). So far, so good.
212+
213+
But you also need to know what happens at layers 2 and 1. When your SSH client (eg Mac or PC or another Unix box) opens its SSH connection, at layer 3 the IP stack applies the subnet mask against the IP addresses of both the source device (your Mac, PC, etc) and destination device (Raspberry Pi) to split them into "network portion" (on the left) and "host portion" on the right. It then compares the two network portions and, if they are the same, it says "local network".
214+
215+
> To complete the picture, if they do not compare the same, then IP substitutes the so-called "default gateway" address (ie your router) and repeats the mask-and-compare process which, unless something is seriously mis-configured, will result in those comparing the same and being "local network". This is why data-comms gurus sometimes say, "all networking is local".
216+
217+
What happens next depends on the data communications media but we'll assume Ethernet and WiFi seeing as they are pretty much interchangeable for our purposes.
218+
219+
The source machine (Mac, PC, etc) issues an ARP (address resolution protocol). It is a broadcast frame (we talk about "frames" rather than "packets" at Layer 2) asking the question, "who has this destination IP address?" The Raspberry Pi responds with a unicast packet saying, "that's me" and part of that includes the MAC (media access control) address of the Raspberry Pi. The source machine only does this **once** (and this is a key point). It assumes the relationship between IP address and MAC address will not change and it adds the relationship to its "ARP cache". You can see the cache on any Unix computer with:
220+
221+
```
222+
$ arp -a
223+
```
224+
225+
The Raspberry Pi makes the same assumption: it has learned both the IP and MAC address of the source machine (Mac, PC, etc) from the ARP request and has added that to its own ARP cache.
226+
227+
In addition, every layer two switch (got one of those in your home?) has been snooping on this traffic and has learned, for each of its ports, which MAC address(es) are on those ports.
228+
229+
Not "MAC **and** IP". A switch works at Layer 2. All it sees are frames. It only caches MAC addresses!
230+
231+
When the switch saw the ARP broadcast, it replicated that out of all of its ports but when the "that's me" came back from the Raspberry Pi as a unicast response, it only went out on the switch port where the source machine (Mac, PC, etc) was attached.
232+
233+
After that, it's all caching. The Mac or PC has a packet to send to the Pi. It finds the hit in its ARP cache, wraps the packet in a frame and sends it out its Ethernet or WiFi interface. Any switches receive the frame, consult their own tables, and send the frame out the port on the next hop to the destination device. It doesn't matter whether you have one switch or several in a cascade, they have all learned the "next hop" to each destination MAC address they have seen.
234+
235+
Ditto when the Pi sends back any reply packets. ARP. Switch. Mac/PC. All cached.
236+
237+
The same basic principles apply, irrespective of whether the "switching function" is wired (Ethernet) or WiFi, so it doesn't really matter if your home arrangement is as straightforward as Mac or PC and Pi, both WiFi, via a local WiFi "hub" which is either standalone or part of your router. If something is capable of learning where a MAC is, it does.
238+
239+
Still so far so good.
240+
241+
Now comes the problem. You have established an SSH session connected to the Pi over its WiFi interface. You install Network Manager. As part of its setup, Network Manager discards the **fixed** MAC address which is burned into the Pi's WiFi interface and substitutes a randomly generated MAC address. It doesn't ask for permission to do that. It doesn't warn you it's about to do it. It just does it.
242+
243+
When the WiFi interface comes up, it almost certainly "speaks" straight away via DHCP to ask for an IP address. The DHCP server looks in its own table of MAC-to-IP associations (fixed or dynamic, doesn't matter) and says "never seen **that** MAC before - here's a brand new IP address lease".
244+
245+
The DHCP request is broadcast so all the switches will have learned the new MAC but they'll also still have the old MAC (until it times out). The Mac/PC will receive the DHCP broadcast but, unless it's the DHCP server, will discard it. Either way, it has no means of knowing that this new random MAC belongs to the Pi so it can't do anything sensible with the information.
246+
247+
Meanwhile, SSH is trying to keep the session alive. It still thinks "old IP address" and its ARP cache still thinks old IP belongs to old MAC. Switches know where the frames are meant to go but even if a frame does get somewhere near the Pi, the Pi's NIC (network interface card) ignores it because it's the wrong destination MAC. The upshot is that SSH looks like the session has frozen and it will eventually time-out with a broken pipe.
248+
249+
To summarise: Network Manager has changed the MAC without so much as a by-your-leave and, unless you have assigned static IP addresses **in the Raspberry Pi** it's quite likely that the Pi will have a different IP address as well. But even a static IP can't save you from the machinations of Network Manager!
250+
251+
The Pi is as happy as the proverbial Larry. It goes on, blissfully unaware that it has just confused the heck out of everything else. You can speed-up some of the activities that need to happen before everything gets going again. You can do things like clear the old entry from the ARP cache on the Mac/PC. You can try to force a multicast DNS daemon restart so that the "raspberrypi.local" address gets updated more quickly but mDNS is a distributed database so it can be hit and miss (and can sometimes lead to complaints about two devices trying to use the same name). Usually, the most effective thing you can do is pull power from the Pi, reboot your Mac/PC (easiest way to clear its ARP cache) and then apply power to the Pi so that it announces its mDNS address at the right time for the newly-booted Mac/PC to hear it and update its mDNS records.
252+
253+
That's why the installation advice says words to the effect of:
254+
255+
> whatever else you do, **don't** try to install Network Manager while you're connected over WiFi. If SSH is how you're going to do it, you're in for a world of pain if you don't run an Ethernet cable for at least that part of the process.
256+
257+
And it does get worse, of course. Installing Network Manager turns on random WiFi MAC. You can turn it off and go back to the fixed MAC. But then, when you install Docker, it happens again. It may also be that other packages come along in future and say, "hey, look, Network Manager is installed - let's take advantage of that" and it happens again when you least expect it.
258+
259+
Devices changing their MACs at random is becoming reasonably common. If you have a mobile device running a reasonably current OS, it is probably changing its MAC all the time. The idea is to make it hard for Fred's Corner Store to track you and conclude, "Hey, Jim is back in the shop again."
260+
261+
Random MACs are not a problem for a **client** device like a phone, tablet or laptop. But they are definitely a serious problem for a **server** device.
262+
263+
> In TCP/IP any device can be a client or a server for any protocol. The distinction here is about *typical* use. A mobile device is not usually set up to *offer* services like MQTT or Node-RED. It typically *initiates* connections with servers like Docker containers running on a Raspberry Pi.
264+
265+
It is not just configuration-time SSH sessions that break. If you decide to leave Raspberry Pi random Wifi MAC active **and** you have other clients (eq IoT devices) communicating with the Pi over WiFi, you will wrong-foot those clients each time the Raspberry Pi reboots. Data communications services from those clients will be impacted until those client devices time-out and catch up.

0 commit comments

Comments
 (0)