全部 / 兴趣交流 / 技术交流 / 软件交流 · 2023年11月8日 0

NAS折腾记2️⃣:玩转HomeAssistant与Plex

智能家居的进一步入门。

前言

NAS折腾记1️⃣:从OpenWrt到Unraid - hiRipple
All in One Or All in Boom?
hiripple.com
Unraid

在如上文所写购入迷你主机后,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😂),会导致后续的折腾遇到不少麻烦。

Linux - Home Assistant
Install Home Assistant on a Linux
www.home-assistant.io

只需前往官网下载对应虚拟机的镜像,即可部署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
hacs-china · GitHub
🇨🇳 HACS 极速版. hacs-china has 4 repositories available. Follow their code on GitHub.
github.com

启动容器进入默认8123端口,首先安装上述地址安装必备插件HACS(应用商店),到此安装可以算是轻松完成了。

集成米家/Apple

进入配置-设备与集成,搜索Xiaomi Miot Auto,添加到集成,此后登陆小米账号即可自动添加所有米家设备。

在HA中,物理意义上的设备就叫做设备,而设备的功能、传感器等被称为“实体”,因此实体一般比设备多得多,实际使用过程中需要禁用或是不显示非必要的实体。米家的大部分设备HA都有默认模版,因此平台能够自动识别。

至于Apple设备,例如apple tv,直接进入设备与集成就可以看到默认已设备,只需简单地手动匹配。按照这个流程基本能接入大部分设备,例如手机、Plex、路由器等,都只需要搜索集成然后添加,此处不再赘述。下文会挑一下比较困难的设备集成。

Homekit bridge

集成后搜索Homekit bridge(据说是前Apple大佬开发),此后根据提示添加所需的域(不建议加太多,不然手机上会出现奇奇怪怪的东西),扫码即可添加至HomeKit。

集成Sony PS5

Docker
hub.docker.com

在对接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服务器就此安装完成。

GitHub - FunkeyFlo/ps5-mqtt: Integrate your PlayStation 5 with Home Assistant
Integrate your PlayStation 5 with Home Assistant. Contribute to FunkeyFlo/ps5-mqtt development by creating an account on GitHub.
github.com

谷歌如何接入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
Markdown

yaml:

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即可实现接入。

MQTT

最后回到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间接接入。

Glances安装

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

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

集成雷鸟电视

其实无论是集成雷鸟还是其他安卓电视,都可以使用这个方法~

adb

集成搜索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真香了呢?虽然本地的磁盘空间不够,无法存下大量蓝光电影,但Plex可以将NAS打造成音乐流媒体服务器,保存那些主流流媒体不包含的稀有资源,又或者是对流媒体音乐规格不满的歌曲。更棒的是,使用Plex即附赠Plexamp,它可能是IOS/MAC端最棒的本地音乐播放软件。

美中不足的是,Plex默认不搜刮歌词,所以想要正确显示歌词必须手动刮削,推荐一个开源程序:Zonylrctoolsx。纯Cli启动,快速、轻量级,一行命令即可自动下载所有歌词:

./ZonyLrcTools.Cli download -d “/mnt/user/path/to/local/music” -l -n 2
ShellScript
ZonyLrcToolsX - Docs
Description
docs.myzony.com
我的音乐流媒体

搜刮歌词后,别忘记刷新元数据~

歌词效果

很难想象,音乐流媒体有一天能达到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站好多了?