8

前言

最近入手了一台斐讯K3路由器,可是博通的芯片发热太严重,想要随时了解路由器的温度,于是自己动手实现了一组程序来将路由器温度通过MQTT加入Homeassistant及Homekit.

准备

  1. 已经获取root权限的K3路由器
  2. 部署好HomeAssistant的内网服务器
  3. 部署好Node.js的内网服务器

前置知识

  • 基本的Shell编程
  • 基本的HTTP及web服务器知识
  • 基本的MQTT原理
  • 基础JavaScript编程

软件结构

最早的想法是直接在路由器上通过Python获取数据及通过MQTT发送至HASS服务器,但是一个是opkg的源太慢了,另一个是不想给路由器增加额外负担(万一加了测温软件温度涨几度就尴尬了),最终采用了如下的软件结构

  • 路由器---> Node.js Server ---> Homeassistant

其中路由器到Node.js通过简单的HTTP,将温度数据通过JSON发送过来.
Node.js通过Express.js实现web服务器用于接受路由器数据,mqtt包实现mqtt通讯,发送给Homeassistant.

服务器端Shell程序

温度获取

首先第一步是获取路由器的温度数据:

  • CPU
cat /proc/dmu/temperature #CPU温度
wl -i eth1 phy_tempsense  #2.4GHz无线芯片温度
wl -i eth2 phy_tempsense  #5GHz无线芯片温度

运行结果如下:
clipboard.png

需要注意的是这里有一个坑,CPU温度的文件中又不符合UTF-8的字符,直接用curl发的话会导致错误,这里我们直接用cut进行处理,这里暂时不考虑温度为或3位的情况(事实上不太可能发生)
cat /proc/dmu/temperature|cut -c19-20

同理我们对另外两项数据也进行处理

wl -i eth1 phy_tempsense|cut -c0-2
wl -i eth2 phy_tempsense|cut -c0-2

发送温度数据

HTTP数据约定

GET Method
数据位于data参数下,内容封装于JSON中,格式如下
{"type":"data","CPU":61,"W24G":51,"W5G":65}

curl实现

这里我们通过curl来发送数据,这里是用GET方法,为了以后增加控制信息方便,数据包格式如下

{"type":"data","CPU":61,"W24G":51,"W5G":65}

经过url encode的结果为

%7B%22type%22:%22data%22,%22CPU%22:61,%22W24G%22:51,%22W5G%22:65%7D

我的Node.js服务器地址是192.168.2.103,端口3000所以我们的url是

url="http://192.168.2.103:3000/?data=%7B%22type%22:%22data%22,%22CPU%22:$cpu,%22W24G%22:$w24,%22W5G%22:$w5%7D"

增加无限循环后的完整程序

#!/bin/sh

echo " run.. "
while true
do
    cpu=$(cat /proc/dmu/temperature|cut -c19-20)
    w24=$(wl -i eth1 phy_tempsense|cut -c0-2)
    w5=$(wl -i eth2 phy_tempsense|cut -c0-2)
    url="http://192.168.2.103:3000/?data=%7B%22type%22:%22data%22,%22CPU%22:$cpu,%22W24G%22:$w24,%22W5G%22:$w5%7D"
    curl $url
    sleep 60    #设置1分钟的查询周期
    continue
done
echo " end.. "
为了让程序不断运行,推荐用screen来管理

Node端程序

HTTP服务器

这里我们基本使用了模版提供的功能,由于我们这里只对数据进行透明传输,所以JSON不需要反序列化

router.get('/', function(req, res, next) {
  var data = req.query.data
  res.render('index', { title: 'Express' });
});

MQTT客户端

MQTT数据约定

我们的数据分别放在三个Topic下

homeassistant/sensor/K3/CPU/state
homeassistant/sensor/K3/24G/state
homeassistant/sensor/K3/5G/state

MQTT实现

Node端程序为了方便,我们直接通过webstorm创建Express.js程序模版,我们的程序之间放在router/index.js
记得用npm安装mqtt包
npm install mqtt

首先我们需要初始化mqtt,填入你的MQTT服务器账号密码(如果未设置匿名)

var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://192.168.2.103',{
    username: 'homeassistant',
    password: 'password',
    clientId: 'K3Server'
}); //连接到服务端
client.subscribe('presence');
注意,mqtt中客户端id不可重复,后来者将踢出原先的客户端

Node完整程序

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  var data = req.query.data
    client.publish('homeassistant/sensor/K3/CPU/state', data, { qos: 0, retain: true });
    client.publish('homeassistant/sensor/K3/24G/state', data, { qos: 0, retain: true });
    client.publish('homeassistant/sensor/K3/5G/state', data, { qos: 0, retain: true });
  res.render('index', { title: 'Express' });
});

var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://192.168.2.103',{
    username: 'homeassistant',
    password: 'hello',
    clientId: 'K3Server'
}); //连接到服务端
client.subscribe('presence');

module.exports = router;

HomeAssistant配置

我们这里使用HA自带的MQTT代理,配置如下

# Sensors
sensor:
  - platform: mqtt
    name: 'K3_CPU'
    state_topic: 'homeassistant/sensor/K3/CPU/state'
    unit_of_measurement: '°C'
    value_template: '{{ value_json.CPU }}'
  
  - platform: mqtt
    name: 'K3_24'
    state_topic: 'homeassistant/sensor/K3/24G/state'
    unit_of_measurement: '°C'
    value_template: '{{ value_json.W24G }}'

  - platform: mqtt
    name: 'K3_5'
    state_topic: 'homeassistant/sensor/K3/5G/state'
    unit_of_measurement: '°C'
    value_template: '{{ value_json.W5G }}'

效果

clipboard.png

clipboard.png


Hydrogen
2.5k 声望73 粉丝

Write code for fun.