在不支持DOCKER的群晖NAS上安装HomeAssistant

我知道我穷, 买不起带Docker的NAS !


  • 目标平台: DS216j
  • 目标平台类型: ARMv7
  • DSM系统版本: DSM6.1

土豪的Docker用户可以跳过以下内容

自从搬家了之后就一直想搞一个智能家居, 所以买了Broadlink的插座和遥控器(穷.jpeg). 翻箱底把树莓派找了出来装了个hassio. 但是我的树莓派是最初版的, 性能超级差. 运行一个Homeassistant已经是让她卡的苦不堪言.
所以我把目mo光zhao放在了一直在用的NAS上.
虽然我用的是最便宜最垃圾的型号, 但是我相信一定比树莓派强多了(而且网速也快, 树莓派开个灯得等半天)
HomeAssistant(以下简称hass)提供了详尽的安装指南. 我安装过程中关于hass本身的安装是直接参考官方的指南的.

不知道DSM开发者有什么问题, 系统没有能用的编译环境. 这就导致了所有需要编译的Python包都无法安装(主要是PyCrypto).
通过曲线救国我们可以用Chroot进入Debian的环境, 在chr下安装这些无法在DSM安装的包, 然后复制到DSM里去. (为什么不直接把hass放在chr下呢? 不方便! )


  • 安装Debian-Chroot并安装需要编译的包

    SynoCommunity提供了一些好用的第三方包, 其中包括Debian-Chroot
  1. 打开主菜单->套件中心->设置, 然后设置信任层级Synology Inc. 和信任的发行者
  2. 套件来源界面点击新增, 填入名称(“社群”)和地址(“http://packages.synocommunity.com/")
  3. 两次确定然后回到套件中心, 在左侧的分类里找到社群, 打开.
  4. 安装Debian Chroot
  5. ssh进入dsm, sudo -i获取root权限.
  6. 运行/var/packages/debian-chroot/scripts/start-stop-status start
  7. 等一会儿~
  8. 运行 /var/packages/debian-chroot/scripts/start-stop-status chroot
  9. 用vi或者nano打开/etc/apt/sources.list, 把里面的jessie全部替换成stretch
  10. apt-get update
  11. 用apt-get安装libpython3.5-dev, python3.5, python3-pip
  12. python3.5 -m pip install安装所需要的包. 所需要的包可能是warrant netdisco broadlink
  13. exit退出chroot环境.
  14. 回到DSM后, 确认在套件中心安装了python3
  15. 运行python3.5 -m ensurepip安装pip
  16. 运行cd $(python3.5 -m pip show pip | grep -a "Location: " | awk -F\ '{print $2}')进入DSM内python套件的地址.
  17. 运行cp /usr/local/debian-chroot/var/chroottarget/usr/local/lib/python3.5/dist-packages/* . -R 拷贝chroot环境下安装的软件包到本地.
  18. 由于PyCrypto被apt安装了, 所以我们要去/usr/local/debian-chroot/var/chroottarget/usr/lib/python3/dist-packages复制它.
  19. cp /usr/local/debian-chroot/var/chroottarget/usr/lib/python3/dist-packages/*[Cc]rypto* . -R 拷贝和PyCrypto有关的包到本地
  20. python3.5 -c "import broadlink"查看有无报错, 若无, 则成功.
  • 安装HomeAssistant并启动

  1. 创建一个共享文件夹, 叫做homeassistant(或者其他你想要的), 然后在终端里进入这个文件夹.
    注意共享文件夹的权限, 要对本地用户(以下为shiroko)有全部权限.
  2. python3.5 -m pip install homeassistant
  3. 键入文末附录的脚本. 保存为hass-daemon
  4. chmod 755 hass-daemon
  5. 如果开启了防火墙, 请让8123端口的TCP部分畅通.
  6. ./hass-daemon start 启动hass.
    start - 启动; stop - 停止; restart - 重启
    若要升级hass, python3.5 -m pip install --upgrade homeassistant
  • 附录

  1. hass-daemon
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    #!/bin/sh

    # Package
    PACKAGE="homeassistant"
    DNAME="Home Assistant"

    # Others
    USER="shiroko" # 这里填写自己的用户名
    PYTHON_DIR="/volume1/@appstore/py3k/usr/local/bin"
    PYTHON="$PYTHON_DIR/python3"
    HASS="$PYTHON_DIR/hass"
    INSTALL_DIR="/volume1/homeassistant"
    PID_FILE="$INSTALL_DIR/home-assistant.pid"
    FLAGS="-v --config $INSTALL_DIR --pid-file $PID_FILE --daemon"
    REDIRECT="> $INSTALL_DIR/home-assistant.log 2>&1"

    start_daemon ()
    {
    sudo -u ${USER} /bin/sh -c "$PYTHON $HASS $FLAGS $REDIRECT;"
    }

    stop_daemon ()
    {
    kill `cat ${PID_FILE}`
    wait_for_status 1 20 || kill -9 `cat ${PID_FILE}`
    rm -f ${PID_FILE}
    }

    daemon_status ()
    {
    if [ -f ${PID_FILE} ] && kill -0 `cat ${PID_FILE}` > /dev/null 2>&1; then
    return
    fi
    rm -f ${PID_FILE}
    return 1
    }

    wait_for_status ()
    {
    counter=$2
    while [ ${counter} -gt 0 ]; do
    daemon_status
    [ $? -eq $1 ] && return
    let counter=counter-1
    sleep 1
    done
    return 1
    }

    case $1 in
    start)
    if daemon_status; then
    echo ${DNAME} is already running
    exit 0
    else
    echo Starting ${DNAME} ...
    start_daemon
    exit $?
    fi
    ;;
    stop)
    if daemon_status; then
    echo Stopping ${DNAME} ...
    stop_daemon
    exit $?
    else
    echo ${DNAME} is not running
    exit 0
    fi
    ;;
    restart)
    if daemon_status; then
    echo Stopping ${DNAME} ...
    stop_daemon
    echo Starting ${DNAME} ...
    start_daemon
    exit $?
    else
    echo ${DNAME} is not running
    echo Starting ${DNAME} ...
    start_daemon
    exit $?
    fi
    ;;
    status)
    if daemon_status; then
    echo ${DNAME} is running
    exit 0
    else
    echo ${DNAME} is not running
    exit 1
    fi
    ;;
    log)
    echo ${LOG_FILE}
    exit 0
    ;;
    *)
    exit 1
    ;;
    esac