Raspberry Pi 的 IoT Home Assistant API






4.90/5 (8投票s)
构建一个改善 Home Assistant 和 Docker 容器之间交互的胚胎 API。
引言
本项目测试了家庭助理(Home Assistant)与 Docker 容器之间的交互。本系列的前几篇文章包括:
- IoT.Starter.Pi.Thing:使用树莓派、Linux、Docker 和 .NET Core 构建家庭智能的雏形。该项目基于树莓派 3B 型号,配备 Raspbian GNU/Linux 9.1 Stretch Lite 和一个由 Swagger Hub 几乎自动生成的 Web 服务。该雏形平台包含独立容器中的 API 和 UI,以加速物联网项目的启动阶段。
- IoT.Home.Thing:家庭物联网(Home of Things)将 Raspberry# IO 添加到平台中。它是一个用于树莓派的 .NET/Mono IO 库,由 Raspberry# 社区发起。Ramon Balaguer 首先将其更新到 .NET Standard 1.6,然后升级到 .NET Core 2.1 并集成到
IoT.Starter.Pi
雏形中。
由于我们正在构建一个物联网入门的雏形,因此到目前为止,一直提供一个空的 MVC 网站作为用户界面(UI)的种子。现在,这个空的用户界面将被 Home Assistant 应用程序取代,从而在项目启动后立即获得更快、更高效的结果。
Home Assistant 是一个运行在 Python 3 上的开源家庭自动化平台。它用于跟踪和控制家中的所有设备,并具有许多实用工具来帮助我们进行自动化控制。您可以通过 Home Assistant 的博客查看社区的活跃程度,该平台不断进行更新和升级。我们希望 Home Assistant 能与 IoT.Starter.Pi
设备中可用的雏形 API 进行交互。
生成磁盘镜像
安装 Home Assistant 有多种方法,因为它支持多种不同的硬件平台。本项目重点介绍 Haspbian,这是一个包含在树莓派上运行 Home Assistant 所需一切的磁盘镜像。
Haspbian 镜像使用与生成树莓派基金会官方 Raspbian 镜像相同的脚本构建。用于创建 raspberrypi.org Raspbian 镜像的相同工具是从 home-assistant/pi-gen
存储库分叉而来。最终阶段被移除,并替换了一个新的 stage-3 以安装 Home Assistant。除了 git,所有依赖项都由构建脚本处理。
对于本项目,这个 pi-gen 工具再次从 home-assistant/pi-gen
分叉到 josemotta/pi-gen
,并添加了一个新的 thing
分支,其中包含一个 stage-4,用于包含 Lirc 安装和 IoT.Starter.Pi
雏形的其他初始设置。请查看下面的 run.sh 脚本,其中显示了添加到磁盘镜像的一些有用依赖项。
#!/bin/bash -e
install -d "${ROOTFS_DIR}/var/run/lirc"
install -m 666 -d "${ROOTFS_DIR}/home/pi/config"
install -m 666 -d "${ROOTFS_DIR}/home/pi/backup"
rm -f "${ROOTFS_DIR}/etc/lirc/lircd.conf.d/devinput.lircd.conf"
install -m 644 files/i2c1-bcm2708.dtbo "${ROOTFS_DIR}/boot/overlays"
install -m 644 files/config.txt "${ROOTFS_DIR}/boot/config.txt"
install -m 644 files/lirc_options.conf "${ROOTFS_DIR}/etc/lirc/lirc_options.conf"
install -m 644 files/ir-remote.conf "${ROOTFS_DIR}/etc/modprobe.d/ir-remote.conf"
install -m 644 files/lirc24.conf "${ROOTFS_DIR}/etc/lirc/lircd.conf.d/lirc24.conf"
install -m 644 files/lirc44.conf "${ROOTFS_DIR}/etc/lirc/lircd.conf.d/lirc44.conf"
install -m 644 files/Samsung_BN59-00678A.conf
"${ROOTFS_DIR}/etc/lirc/lircd.conf.d/Samsung_BN59-00678A.conf"
install -m 644 files/AppConfig.json "${ROOTFS_DIR}/app"
install -m 755 files/setup.sh "${ROOTFS_DIR}/home/pi/setup.sh"
rm -f "${ROOTFS_DIR}/etc/default/keyboard"
install -m 644 files/keyboard "${ROOTFS_DIR}/etc/default/keyboard"
cat << EOF >> ${ROOTFS_DIR}/etc/samba/smb.conf
[config]
path = /home/pi/config
available = yes
valid users = pi
read only = no
browsable = yes
public = yes
writable = yes
[backup]
path = /home/pi/backup
available = yes
valid users = pi
read only = no
browsable = yes
public = yes
writable = yes
EOF
如您所见,stage-4 还安装和配置了 Samba 服务器,以公开几个文件夹
- /home/pi/config:Home Assistant 配置文件夹
- /home/pi/backup:用于备份/恢复雏形设置的文件夹
在我的开发 PC 上创建的虚拟 Debian 机器上运行 pi-gen
半小时后,生成了一个包含所有已安装依赖项的 SD 磁盘镜像。使用 Etcher 烧录镜像,即可获得雏形的核心,准备植入树莓派驱动器。该镜像已在 RPI 2B/3B 上成功测试。请暂时保留 SD 磁盘,因为我们首先要构建项目。
在开发机上构建
根据IoT.Starter.Pi.Thing的策略,构建在 RPI 之外进行,使用配备 Windows 10、Visual Studio、Docker 和 Hyper-V 的快速 x64 微型计算机。在开发机器上,我们应该根据 api.yml 文件使用 docker-compose
命令构建项目。
请参阅下面的文件,其中包括 api、hass、mosquitto 和 portainer 服务。
version: "3"
services:
api:
image: josemottalopes/home-api
build:
context: .
dockerfile: src/IO.Swagger/api.dockerfile
ports:
- "5000:5000"
network_mode: bridge
privileged: true
restart: always
devices:
- /dev/mem:/dev/mem
- /dev/i2c-1:/dev/i2c-1
- /dev/gpiomem:/dev/gpiomem
volumes:
- /var/run/lirc:/var/run/lirc
environment:
- ASPNETCORE_ENVIRONMENT=Release
hass:
image: homeassistant/raspberrypi3-homeassistant:0.80.3
ports:
- "8123:8123"
network_mode: bridge
volumes:
- /home/pi/config:/config
restart: always
devices:
- /dev/i2c-1:/dev/i2c-1
- /dev/gpiomem:/dev/gpiomem
environment:
- TZ=America/Sao_Paulo
depends_on:
- mosquitto
- api
mosquitto:
build:
context: ./Mosquitto
restart: unless-stopped
ports:
- "1883:1883"
network_mode: bridge
volumes:
- ./Mosquitto/auth.conf:/etc/mosquitto/conf.d/auth.conf:ro
- ./Mosquitto/users.passwd:/etc/mosquitto/users.passwd:ro
portainer:
image: portainer/portainer
ports:
- "9000:9000"
command: -H unix:///var/run/docker.sock
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
volumes:
portainer_data:
以下是每个服务的简要描述:
api
:这是由 Swagger Hub 生成的 API,它包含雏形消息。hass
:这是 Home Assistant 应用程序,用作雏形的 UI。mosquitto
:一个供 Home Assistant 逻辑使用的 MQQT 代理。portainer
:这是一个用于 Docker 的简单管理解决方案。
构建解决方案是一个漫长的过程,包括编译由 Swagger Hub 生成的 API 和 Raspberry# IO 库。当前解决方案还包括本系列之前使用的空 UI MVC 网站。下面是构建会话的快捷方式。
jo@CANOAS24 MINGW64 /c/_git/IoT.Home.Pi/home (master)
$ docker-compose -f api.yml build
Building api
Step 1/35 : FROM microsoft/dotnet:2.0.7-runtime-stretch-arm32v7 AS base
---> 87595eb7f1f4
Step 2/35 : ENV DOTNET_CLI_TELEMETRY_OPTOUT 1
---> Using cache
---> 9e6c62851cc6
Step 3/35 : ENV ASPNETCORE_URLS "http://*:5000"
---> Using cache
---> c290db537f12
Step 4/35 : WORKDIR /app
---> Using cache
---> 7dccd40b712f
Step 5/35 : RUN apt-get update && apt-get upgrade -y && apt-get install -ylirc
--no-install-recommends && rm -rf /var/lib/apt/lists/*
---> Using cache
... big build including all projects from solution
IO.Swagger -> /src/src/IO.Swagger/bin/Release/netcoreapp2.0/linux-arm/IO.Swagger.dll
IO.Swagger -> /app/
Removing intermediate container e98edde9e6b1
---> 37f4b8ed2042
Step 32/35 : FROM base AS final
---> 055ee036885d
Step 33/35 : WORKDIR /app
---> Using cache
---> 79c8c71c098b
Step 34/35 : COPY --from=publish /app .
---> f0e36a46b8d2
Step 35/35 : ENTRYPOINT ["dotnet", "IO.Swagger.dll"]
---> Running in 9d100e734c07
Removing intermediate container 9d100e734c07
---> 46b9b656c5e2
Successfully built 46b9b656c5e2
Successfully tagged josemottalopes/home-api:latest
Building mosquitto
Step 1/3 : FROM resin/raspberry-pi-debian:stretch
---> ced6fc5da205
Step 2/3 : RUN apt-get update && apt-get upgrade -y && apt-get install
-ymosquitto mosquitto-clients --no-install-recommends && rm -rf /var/lib/apt/lists/*
---> Using cache
---> 66afe7dadb46
Step 3/3 : CMD [ "/usr/sbin/mosquitto", "-c", "/etc/mosquitto/mosquitto.conf" ]
---> Using cache
---> d20ea9daf328
Successfully built d20ea9daf328
Successfully tagged home_mosquitto:latest
hass uses an image, skipping
portainer uses an image, skipping
最终构建步骤应该再次使用 docker-compose
命令,这次是将 API 镜像推送到 Docker Hub。请看下面的实际操作:
jo@CANOAS24 MINGW64 /c/_git/IoT.Home.Pi/home (master)
$ docker-compose -f api.yml push
Pushing api (josemottalopes/home-api:latest)...
The push refers to repository [docker.io/josemottalopes/home-api]
5b74c38596fb: Pushed
63edb82122c7: Pushed
08c704bc3c1a: Pushed
bf8666defb3a: Pushed
1f48f9c632fb: Pushed
3ae6b6a37d49: Pushed
0bbaa93801e6: Pushed
28d327b91985: Pushed
2917ff0f1d45: Pushed
420a4cbda8df: Layer already exists
53c3793bdb6b: Layer already exists
002111fc932d: Layer already exists
2e9c4696ffa4: Layer already exists
latest: digest: sha256:779b47a4c1f9757c8abf3f137df19261e4e335c3b18cff1d16b94ddd1a92efba
size: 3037
现在,我们可以前往 RPI 部署雏形。
部署到 RPI
将带有胚胎核心的 SD 磁盘插入树莓派驱动器插槽。该板已配备一个Anavi 红外 pHat,这是一个附加板,可将您的树莓派转换为智能遥控器。它还支持温度、湿度、气压和光线传感器模块。请查看下面的 RPI,它连接了三个传感器,左上方是提供强红外信号的双红外 LED。Anavi 红外 pHat 通过 RPI GPIO 连接器连接。树莓派还具有 5V 电源,并通过 RJ-45 网线连接到互联网路由器。
首次运行时,文件系统会初始化。启动后,我们应该首次登录树莓派并更改 pi
用户的初始密码。请注意,它保留了“raspberry”,与 raspberrypi.org Raspbian 镜像相同。由于 SSH 可用,可以使用无头 RPI,从另一台微型计算机打开 bash 终端。否则,只需插入 USB 键盘和 HDMI 连接器即可直接与雏形交互。
克隆仓库
让我们使用 ssh
从开发 PC 启动一个 bash 会话。请看下面 pi@copa
,这是本次演示选择的主机名。
jo@CANOAS24 MINGW64 ~
$ ssh pi@copa
pi@copa's password:
Linux copa 4.14.70-v7+ #1144 SMP Tue Sep 18 17:34:46 BST 2018 armv7l
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Oct 29 13:17:49 2018 from 192.168.20.113
让我们在树莓派本地克隆 Iot.Home.Pi
仓库。多亏了修改后的 pi-gen
,在 pi 默认文件夹中应该已经有一个脚本可以完成此操作。
pi@copa:~ $ cat setup.sh
#!/bin/sh
set -e
# Home Setup
REPO="https://github.com/josemotta/IoT.Home.Pi.git"
HOME="/home/pi/IoT.Home.Pi"
git clone $REPO $HOME
然后,停留在默认的 /home/pi 文件夹中,您只需运行
./setup.sh
请注意,这是在开发机器上构建项目时使用的同一个仓库。不同之处在于我们现在在 RPI 端。我们希望使用 docker-compose 命令两次,始终基于之前构建时使用的同一个 api.yml 文件。
- 首先从 Docker Hub 拉取镜像,然后
- 其次,编排相应的容器
文件夹 ~/IoT.Home.Pi/home 应该包含雏形项目的基本文件。
pi@copa:~ $ cd I*/home
pi@copa:~/IoT.Home.Pi/home $ ls -l
total 60
-rw-r--r-- 1 pi pi 1017 Oct 6 20:10 api.yml
-rw-r--r-- 1 pi pi 257 Oct 6 20:10 _clear.bat
drwxr-xr-x 3 pi pi 4096 Oct 6 20:10 Docker
-rw-r--r-- 1 pi pi 1385 Oct 6 20:10 docker-compose.dcproj
-rw-r--r-- 1 pi pi 458 Oct 6 20:10 docker-compose.yml
drwxr-xr-x 2 pi pi 4096 Oct 6 20:38 Hass
-rw-r--r-- 1 pi pi 1490 Oct 6 20:10 home-api.yml
-rw-r--r-- 1 pi pi 905 Oct 6 20:10 home-compose.yml
-rw-r--r-- 1 pi pi 5870 Oct 6 20:10 Home.sln
drwxr-xr-x 4 pi pi 4096 Oct 6 20:10 Lirc
-rw-r--r-- 1 pi pi 579 Oct 6 20:10 NuGet.Config
drwxr-xr-x 3 pi pi 4096 Oct 6 20:10 Proxy
drwxr-xr-x 2 pi pi 4096 Oct 6 20:10 Raspberry.IO
drwxr-xr-x 11 pi pi 4096 Oct 6 20:10 src
安装 Docker
在 Hass 文件夹中有一个 setup.sh 脚本,用于安装 Docker 和 docker-compose
。正如之前解释的,RPI 的最新版本 docker-compose
是手动构建的,并通过安装脚本安装。此外,应该设置一个密码来保护公开的配置和备份文件夹。
#!/bin/sh
set -e
DOCKER_COMPOSE="$HOME/Docker/docker-compose"
KEY_USER="josemotta@bampli.com"
KEY_FILE="/home/pi/.ssh/id_rsa"
CONFIG_FOLDER=/home/pi/config/
BACKUP_FOLDER=/home/pi/backup/
DEFAULT_CONFIG=*_hassconfig_*
USERNAME=pi
PASSWORD=password
chmod 0777 $BACKUP_FOLDER
chmod 0777 $CONFIG_FOLDER
cp ${HOME}/Hass/${DEFAULT_CONFIG} ${BACKUP_FOLDER}
# Docker
curl -fsSL get.docker.com -o get-docker.sh
sh get-docker.sh
usermod -aG docker pi
# Docker-compose
cp $DOCKER_COMPOSE /usr/local/bin
chown root:root /usr/local/bin/docker-compose
chmod 0755 /usr/local/bin/docker-compose
# Senha inicial do "config"
echo -e "$PASSWORD\n$PASSWORD" | smbpasswd -a -s -c /etc/samba/smb.conf $USERNAME
# SSH
ssh-keygen -t rsa -b 4096 -C $KEY_USER -q -N "" -f $KEY_FILE
更改目录到 Hass 并运行 sudo ./setup.sh
以完成 RPI 设置。然后检查 Docker 是否正常运行。
pi@copa:~ $ docker version
Client:
Version: 18.06.1-ce
API version: 1.38
Go version: go1.10.3
Git commit: e68fc7a
Built: Tue Aug 21 17:30:52 2018
OS/Arch: linux/arm
Experimental: false
Server:
Engine:
Version: 18.06.1-ce
API version: 1.38 (minimum version 1.12)
Go version: go1.10.3
Git commit: e68fc7a
Built: Tue Aug 21 17:26:37 2018
OS/Arch: linux/arm
Experimental: false
pi@copa:~ $ docker-compose version
docker-compose version 1.19.0-rc2, build dfcb02c
docker-py version: 2.7.0
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t 3 May 2016
拉取镜像
docker-compose pull
命令用于从 Docker Hub 下载最新的 josemottalopes/home-api 镜像。
pi@copa:~/IoT.Home.Pi/home $ docker-compose -f api.yml pull
Pulling portainer (portainer/portainer:latest)...
latest: Pulling from portainer/portainer
Digest: sha256:07c0e19e28e18414dd02c313c36b293758acf197d5af45077e3dd69c630e25cc
Status: Image is up to date for portainer/portainer:latest
Pulling api (josemottalopes/home-api:latest)...
latest: Pulling from josemottalopes/home-api
5483105d0916: Already exists
4a08fa0bd267: Already exists
5db6c48919a3: Already exists
4ed51a05c924: Already exists
be01d4da0224: Pull complete
9902b97c6ff4: Pull complete
d45a0684105a: Pull complete
2fd83b49817b: Pull complete
9036c0edc62a: Pull complete
f66a27b68370: Pull complete
5e974242185a: Pull complete
ae3b66331312: Pull complete
4d4cbdc4d968: Pull complete
Digest: sha256:779b47a4c1f9757c8abf3f137df19261e4e335c3b18cff1d16b94ddd1a92efba
Status: Downloaded newer image for josemottalopes/home-api:latest
Pulling hass (homeassistant/raspberrypi3-homeassistant:0.78.3)...
0.78.3: Pulling from homeassistant/raspberrypi3-homeassistant
Digest: sha256:f06dc1d1bea815f50aa8244df31593e13d953d1b650427423375d9fc43443625
Status: Image is up to date for homeassistant/raspberrypi3-homeassistant:0.78.3
全部运行
再次使用另一个 docker-compose
命令,现在使用 docker-compose up -d
来正确编排容器
pi@copa:~/IoT.Home.Pi/home $ docker-compose -f api.yml up -d
Creating network "home_default" with the default driver
Pulling portainer (portainer/portainer:latest)...
latest: Pulling from portainer/portainer
d1e017099d17: Pull complete
a9e4458c8fdc: Pull complete
Digest: sha256:07c0e19e28e18414dd02c313c36b293758acf197d5af45077e3dd69c630e25cc
Status: Downloaded newer image for portainer/portainer:latest
Creating home_portainer_1 ... done
Creating home_api_1 ... done
Creating home_hass_1 ... done
pi@copa:~/IoT.Home.Pi/home $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fdd60b1edf87 portainer/portainer "/portainer -H unix:�" 48 seconds ago Up 34 seconds 0.0.0.0:9000->9000/tcp home_portainer_1
c1163bb370db homeassistant/raspberrypi3-homeassistant:0.78.3 "/bin/entry.sh pytho�" 48 seconds ago Up 36 seconds 0.0.0.0:8123->8123/tcp home_hass_1
71cf17d6af66 josemottalopes/home-api "dotnet IO.Swagger.d�" 48 seconds ago Up 36 seconds 0.0.0.0:5000->5000/tcp home_api_1
pi@copa:~/IoT.Home.Pi/home $
容器正在运行,我们可以检查端口 5000、8123 和 9000,以查看所有服务的相应 UI。
查看胚胎结果
Home Assistant 仪表板显示可用状态,包括可用传感器。
Portainer 管理器屏幕显示有关容器和运行镜像的所有详细信息。
还有由 Swagger Hub 生成的胚胎 API,显示使用 Raspberry# IO 库收集的传感器数据。
远程 API 可以使用 curl 发布红外命令,例如:
jo@CANOAS24 MINGW64 /c/_git/IoT.Home.Pi/home (master)
$ curl -X GET "http://192.168.20.105:5000/motta/home/1.0.3/remotes" -H "accept: text/plain"
Samsung_BN59-00678A
LED_24_KEY
LED_44_KEY
jo@CANOAS24 MINGW64 /c/_git/IoT.Home.Pi/home (master)
$ curl -X GET "http://192.168.20.105:5000/motta/home/1.0.3/remotes/LED_24_KEY"
-H "accept: text/plain"
0000000000000001 BRIGHT_DOWN
0000000000000002 BRIGHT_UP
0000000000000003 OFF
0000000000000004 ON
0000000000000005 RED
0000000000000006 GREEN
0000000000000007 BLUE
0000000000000008 WHITE
0000000000000009 ORANGE
000000000000000a PEA_GREEN
000000000000000b DARK_BLUE
000000000000000c 7_JUMP
000000000000000d DARK_YELLOW
000000000000000e CYAN
000000000000000f BROWN
0000000000000010 ALL_FADE
0000000000000011 YELLOW
0000000000000012 LIGHT_BLUE
0000000000000013 PINK
0000000000000014 7_FADE
0000000000000015 STRAW_YELLOW
0000000000000016 SKY_BLUE
0000000000000017 PURPLE
0000000000000018 3_JUMP
Swagger UI 也可以用于发布红外命令,如下图所示:
结论
IoT.Home.Pi 胚胎
已准备好进行定制,可以使用 Swagger Hub 的自动代码生成器来帮助进行 API 设计。Home Assistant 应正确配置以显示信息并控制可用设备。Portainer 管理器允许检查所有容器及其相关信息。还可以使用 Portainer 和 docker-compose 方法停止和运行容器。
祝您在物联网项目中玩得开心,工作顺利!
喜欢吗?请给我一颗星⭐️!
历史
- 2018 年 10 月 29 日:初始版本,仓库位于 https://github.com/josemotta/IoT.Home.Pi