智能家居的进一步入门。
前言


在如上文所写购入迷你主机后,Unraid系统已经稳定运行了近6天,期间运行了11个Docker容器以及一个OP虚拟机,这这篇主要讲一讲AIO服务器的另外两个职能——媒体服务器与智能家居中枢。
HomeAssistant
Homeassistant(以下简称HA)是一个基于 Python 3 开发的开源家庭自动化平台,可以跟踪和控制家庭中的所有设备,并实现自动化控制。作为开源平台的最大优势自然是自托管,隐私不受监控,以及“可接入万物”的强大兼容性。
虽然博主也是先知道米家,进一步深入后才知道HA,不可否认米家让大众对智能家居有了基础的认知,可谓是年轻人的第一个“全屋智能”。米家配件便宜,上手简单,也因此击败Homekit,在国内占据大量市场。对我个人而言,目前屋内几乎所有设备都来自米家。
但长期使用后,也逐渐感受到各种弊端,作为IOS用户,无法在不打开米家APP的情况下控制设备,如果连简单地开个灯也需要等待APP启动,何不如直接起身按个按钮?其次是平台的局限性,为了自动化和一体性,当自己购入了大量米家设备后,如果意图添置新的设备,就必须从米家生态中挑选,但事实上米家也不是在各个方面都能做的很好。最后还是回到隐私性,即便国内的个人隐私近乎透明,但博主仍然愿意在力所能及的范围内,保护自身的隐私。
安装方式
按官方的介绍,HomeAssistant分别为、HomeAssistant OS(HAOS)、HomeAssistant Container、HomeAssistant Core、HomeAssistant Supervised四种,严格来说它们都是HA,只是内部包含的“组件”不同。

上图很好地说明了四种版本的区别,而如果是像博主一样的小白,更推荐HAOS和Container,无论是虚拟机还是Docker,在部署过程中都不会遇到太多障碍。如果仍然选择困难,那么就选择HAOS吧,在四种方式中它的组件是最全的,container少了Supervisor与加载项(加载项毕竟本身是Docker😂),会导致后续的折腾遇到不少麻烦。

只需前往官网下载对应虚拟机的镜像,即可部署HAOS。值得注意的是,官方给出的虚拟机推荐配置是最低2核CPU、2GRAM以及32G磁盘空间,比Container版高出不少,低配机请自行斟酌~
博主最先尝试的也是HAOS,无奈无论如何都安装不成功,总是显示Git clone错误以及找不到Supervisor镜像,猜测是网络原因,最终仍然选择了Container。
docker run -d \
--name homeassistant \
--privileged \
--restart=unless-stopped \
-e TZ=MY_TIME_ZONE \
-v /PATH_TO_YOUR_CONFIG:/config \ #unraid路径一般是/mnt/user/appdata
--network=host \
ghcr.io/home-assistant/home-assistant:stable # 镜像较大,由于国内网络问题,可以改成官方镜像源再使用镜像源加速
ShellScript启动容器进入默认8123端口,首先安装上述地址安装必备插件HACS(应用商店),到此安装可以算是轻松完成了。
集成米家/Apple

进入配置-设备与集成,搜索Xiaomi Miot Auto,添加到集成,此后登陆小米账号即可自动添加所有米家设备。
在HA中,物理意义上的设备就叫做设备,而设备的功能、传感器等被称为“实体”,因此实体一般比设备多得多,实际使用过程中需要禁用或是不显示非必要的实体。米家的大部分设备HA都有默认模版,因此平台能够自动识别。
至于Apple设备,例如apple tv,直接进入设备与集成就可以看到默认已设备,只需简单地手动匹配。按照这个流程基本能接入大部分设备,例如手机、Plex、路由器等,都只需要搜索集成然后添加,此处不再赘述。下文会挑一下比较困难的设备集成。

集成后搜索Homekit bridge(据说是前Apple大佬开发),此后根据提示添加所需的域(不建议加太多,不然手机上会出现奇奇怪怪的东西),扫码即可添加至HomeKit。
集成Sony PS5
在对接PS5之前,有必要了解一下物联网中最重要的协议之一——MQTT协议。MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎,能够实现传感器、执行器和其它设备之间的高效通信。
简单来说MQTT不需要通信双方实时地发送/接受,通过第三方MQTT服务器,可以做到一方发布、一方订阅,通过订阅信息来判断设备状态,大大减少运行压力。MQTT最重要的概念就是Topic,发布的信息以topic作为层级区分。
docker run -d --name emqx -p 18083:18083 -p 1883:1883 emqx:latest
ShellScript对于HA Container而言,由于没有加载项(Add-on)支持,需要用户自行安装MQTT服务器,这里博主选择了中文支持较好,易用的MQTT Docker服务器:Emqx。运行上述Docker Cli即可创建容器,然后进入默认端口18083,配置管理员信息,MQTT服务器就此安装完成。
谷歌如何接入PS5时,博主在HA的官方论坛里发现了国外大佬参考PSN-API写出的PS5-MQTT服务,它首先提供了HAOS一键安装,对于HA Container,则需要自行配置Docker容器,根据官方给出的配置如下(这里使用Docker-compose):
文件结构:
.
│
├─── config # we will need a separate directory to use as a volume
│ │
│ └─── run.sh # custom startup script
│
└─── docker-compose.yml # configuration of our container
Markdownyaml:
version: '3'
services:
ps5-mqtt:
container_name: PS5-MQTT # choose whatever name you like
image: ghcr.io/funkeyflo/ps5-mqtt/amd64:latest # 建议更换镜像源,国内访问ghcr.io相当慢。。。
entrypoint: /config/run.sh # the file that will be executed at startup
volumes: # we will use this volume to get our custom startup script into the container
- ./config:/config
network_mode: host # changing/omiting this option WILL BREAK the app.
environment:
- MQTT_HOST=192.168.0.132 # 这四行是之前安装的MQTT服务器,也就是Emqx的对应信息
- MQTT_PORT=1883 # port of your mqtt broker
- MQTT_USERNAME=mqttuser # username used for connecting to your mqtt broker
- MQTT_PASSWORD=mqttpassword # password used for connecting to your mqtt broker
- DEVICE_CHECK_INTERVAL=5000
- DEVICE_DISCOVERY_INTERVAL=60000
- ACCOUNT_CHECK_INTERVAL=5000
- 'PSN_ACCOUNTS=[{"username": "MyPsnUser", "npsso":"npsso_value"}]'
- INCLUDE_PS4_DEVICES=false
- FRONTEND_PORT=8645
- CREDENTIAL_STORAGE_PATH=/config/credentials.json
- DEBUG=@ha:ps5:*
YAML可以看到,除了MQTT服务器外,容器还需要配置PSN的相关信息,可以使用以下网址获取Npsso:
https://ca.account.sony.com/api/v1/ssocookie
Markdown保存yml文件后,还需要设置entrypoint:
将以下代码保存为run.sh,路径在config文件夹中。
#!/bin/sh
set -e
echo Starting PS5-MQTT...
node app/server/dist/index.js
ShellScript别忘了
chmod +x /path/to/config/run.sh #授予执行权限
ShellScript运行容器后,进入默认的8645端口,按照GUI界面配置PS5即可实现接入。

最后回到HA的Web界面,搜索集成-添加MQTT,添加之后MQTT应该会搜索到用户的PS5。进入设备选项可以查看MQTT传入的信息:

不过此时还没有结束,Mqtt服务器相当于提供了一个后端,而HA是没有与之匹配的前端的,因此需要自行编写。HA对程序开发还是挺友好的,后端可以使用javascript编写,然后在yml文件中载入,前端的开发类似于Vue的组件,这些组件可以从HACS商店下载,然后用各种框架编写成自己想要的效果,分享博主自己编写的代码如下(请自行替换PS5实体ID、安装必要的依赖):
type: custom:config-template-card
entities:
- sensor.ps5_011_activity
card:
type: vertical-stack
cards:
- type: picture
image: >-
${states['sensor.ps5_011_activity'].attributes['title_image'] ||
'https://www.home-assistant.io/images/lovelace/header-footer/balloons-header.png'}
aspect_ratio: 1/1
tap_action:
action: none
hold_action:
action: none
- type: entities
entities:
- entity: sensor.ps5_011_activity
type: custom:multiple-entity-row
tap_action:
action: call-service
service: homeassistant.toggle
service_data:
entity_id: switch.ps5_011_power
secondary_info:
attribute: power
entities:
- attribute: title_name
name: >-
${states['sensor.ps5_011_activity'].attributes['title_name'] ||
'No Game Playing'}
YAML效果如下,点击PS图标可以开启/关闭PS5,游玩游戏时显示游戏LOGO、名称等:

集成Unraid
由于HA不直接支持Unraid系统,所以无法像群晖、Truenas一样从商店直接安装,所以使用第三方工具Glances间接接入。

Unraid可以直接从商店通过模版安装Glances,运行后返回HA搜索集成“glances”。

添加集成后如同PS5-MQTT一样,实现了后端支持,但前端仍然需要手动编写,博主提供一个自己写的:
type: vertical-stack
cards:
- type: glance
title: My NAS
columns: 3
show_name: true
show_icon: true
show_state: true
entities:
- entity: sensor.localhost_used_percent
name: 磁盘使用空间
- entity: sensor.localhost_ram_used_percent
name: 内存使用率
- entity: sensor.localhost_cpu_used
name: CPU负载
- type: history-graph
title: '历史信息'
hours_to_show: 24
refresh_interval: 0
entities:
- sensor.localhost_used_percent
- sensor.localhost_ram_used_percent
- sensor.localhost_cpu_used
YAML集成雷鸟电视
其实无论是集成雷鸟还是其他安卓电视,都可以使用这个方法~

集成搜索android debug bridge,添加集成并输入电视的IP地址(需要提前打开电视的ADB模式),即可添加电视到集成,默认只有一个设备与实体,即媒体播放器。

但电视仅仅使用媒体播放器是不够的,ADB的集成意味着更多的可能。在动作-调用服务-ADB:学习发送事件中,HA可以通过ADB学习遥控器通过红外发射的指令,点击执行动作,然后遥控器按下需要学习的按键,即可将其转化为ADB命令。

复制需要的ADB指令后,即可将发送ADB命令作为自动化动作,通过这种方式可以让自动化模拟遥控器可以控制的所有功能,可玩性相当高。示例是一个检测Appletv开机、自动打开电视的自动化。
美化/暴露至公网
HA自带的卡片式控制台个人觉得并不算很美观,下文将一些简单的美化方法。

推荐安装如上所示的第三方前端卡片,其中Mushroom效果如下:


这里使用的是自动生成Mushroom仪表盘的插件,一行代码即可实现漂亮的前端:
strategy:
type: custom:mushroom-strategy
views: []
YAML最后,将HA暴露至公网,方便远程控制家中设备。博主使用的依旧是Cloudflare tunnels,映射后访问会出现400 bad request。此时查看HA日志,发现CF的Docker通过内网地址访问HA,但是被拒绝了,根据官方文档,在configuration.yml中加入:
http:
use_x_forwarded_for: true
trusted_proxies:
172.17.0.7 //内网IP地址,重启后会变
YAML重启HA Container后重新访问公网地址,正常。
PLEX
虽然前一篇文章表示不需要媒体服务器,但最后还是真香了。

商店搜索plex,映射媒体路径,部分设备可能需要提前安装显卡驱动才能支持转码。
为什么说PLEX真香了呢?虽然本地的磁盘空间不够,无法存下大量蓝光电影,但Plex可以将NAS打造成音乐流媒体服务器,保存那些主流流媒体不包含的稀有资源,又或者是对流媒体音乐规格不满的歌曲。更棒的是,使用Plex即附赠Plexamp,它可能是IOS/MAC端最棒的本地音乐播放软件。
美中不足的是,Plex默认不搜刮歌词,所以想要正确显示歌词必须手动刮削,推荐一个开源程序:Zonylrctoolsx。纯Cli启动,快速、轻量级,一行命令即可自动下载所有歌词:
./ZonyLrcTools.Cli download -d “/mnt/user/path/to/local/music” -l -n 2
ShellScript
搜刮歌词后,别忘记刷新元数据~

很难想象,音乐流媒体有一天能达到Bitrate 24576 kbps的PCM无损(相当于8分钟1.5GB),虽然本地上行带宽无法支持在公网播放,但局域网内那是非常享受~

对于电影,博主下载了几部影片测试其转码以及元数据刮削性能。毫无疑问,Plex的元数据刮削比Emby与jellyfin好得多,几乎能和infuse媲美。而且plex存储元数据的方式也有所不同,它不会将搜刮的元数据存入原始的电影文件夹内,而是保存在自身容器中,有利有弊,但对于挂载网盘来说,它是更友好的。

即使是元数据的丰富程度,我也认为Plex更胜一筹,它默认下载多张电影海报&背景,即使用户对自动刮削的结果不满意,也可以自行调整。而背景可作为毛玻璃特效,相当好看,往下划时,还可以看到来自烂番茄的评价。

值得一提的是,plex良好的体验也不是轻易得到的,想拥有它的完全体,必须购买通行证。无论是硬件转码还是远程观看,都需要通行证支持。不过博主用的还是免费版,即使是免费版也自带内网穿透(可以使用Plexamp远程听音乐)、本地观看等功能,不得不说十分良心。如果有一天能支持蓝光原盘,那就难以抵挡终身通行证等诱惑了。
内网穿透
即便Plex自带中转服务器,但普通用户限制带宽1mbps,Premium用户限制带宽2Mbps,况且官方服务器也处于海外,这意味着如不经过极低规格的转码,任何电影/音乐都无法流畅播放,因此仍然推荐手动配置内网穿透。

国内大部分教程都是通过打洞创建“虚拟局域网”的方式实现内网穿透,这种方法允许Plex自动识别局域网内的媒体服务器,但如果用Cloudflare Tunnel,配置就麻烦一些。请注意,使用CF tunnel作为媒体服务器的内网穿透,是违反Tunnel使用协议的,这意味着CF官方有理由封禁你的账号,请自行斟酌这个行为所蕴含的风险。
首先,在CF tunnel中映射Plex的局域网IP:端口号,访问该地址(如果无法跳转至登陆界面,请关闭Cloudflare rocket loader)。转到Plex设置-网络,勾选严格TLS配置,取消勾选“启用中转”(否则会默认使用Plex官方的中转服务器),最后在自定义服务器访问URL中填写Https链接(注意务必填写完整的链接加端口号443!)。最后,保存并重启Plex服务端。

完成以上操作后,在外网访问Plex客户端或者Plexamp时,将通过自定义链接访问。如上图所示,CF tunnel的网速可以达到20Mbps,即便仍不算高,但这不比B站好多了?
请问下emqx需要配置什么内容,我已经在同一物理机下使用docker部署了homeassistant core,emqx,ps5-MQTT(使用GitHub项目上的docker-compose部署),但是ps5-mqtt无法查找到PS5设备
ps5-MQTT绑定好psn信息了吗
部署ps5-mqtt的时候已经按照github上面compose.yml样例1中的信息填写了username跟npsso值
如果ps5-mqtt webui显示了ps5的信息,那么应该就是正常的,在emqx里面添加一个主题,然后ha里面就能找到了
在emax里面可以看到homeassistant的mqtt以及ps5-mqtt信息,但是ps5-mqtt的webui一直没有ps5信息只有一个Refresh device(刷新设备)按钮,点击也无法刷新出PS5信息(PS5已经打开连接到了同一个网络下)
那自然是ps5-mqtt没配置好,检查一下npsso,不行就得看看官方的文档了
services:
ps5-mqtt:
container_name: PS5-MQTT # choose whatever name you like
image: ghcr.io/funkeyflo/ps5-mqtt/amd64:latest # you can also use a specific version
entrypoint: /app/run-standalone.sh # the file that will be executed at startup
volumes: # we will use this volume to save credentials
- ./config:/config
network_mode: host # changing/omiting this option WILL BREAK the app.
environment:
- MQTT_HOST=192.168.100,1 # (ip)address of your mqtt broker
- MQTT_PORT=1883 # port of your mqtt broker
- MQTT_USERNAME=admin # username used for connecting to your mqtt broker
- MQTT_PASSWORD=19491qazwsxEDC # password used for connecting to your mqtt broker
- DISCOVERY_TOPIC=homeassistant # Home Assistant discovery topic. Only needs to be set if you've changed the discovery topic in Home Assistant. Default: homeassistant
- DEVICE_CHECK_INTERVAL=5000
- DEVICE_DISCOVERY_INTERVAL=60000
- ACCOUNT_CHECK_INTERVAL=5000
- 'PSN_ACCOUNTS=[{"username": "Virous-song", "npsso":"iiozR63MRESMTlPVKJYIrXP51VbQVNIwTt2bYZpAzMSaps84uWmCk5kkxT4D45zZ"}]'
- INCLUDE_PS4_DEVICES=false
- FRONTEND_PORT=8645
- CREDENTIAL_STORAGE_PATH=/config/credentials.json
- DEBUG=@ha:ps5:*
healthcheck: # Optional add docker healthcheck as it may be important for some setups
test: ls -l /proc/*/exe | grep node
interval: 5m00s
timeout: 10s
retries: 2
start_period: 30s
这是yml文件内容,麻烦看下是否是有参数填错了
你这mqtt地址用中文逗号写的,检查一下