前言
最近入手了一台斐讯K3路由器,可是博通的芯片发热太严重,想要随时了解路由器的温度,于是自己动手实现了一组程序来将路由器温度通过MQTT加入Homeassistant及Homekit.
准备
- 已经获取root权限的K3路由器
- 部署好HomeAssistant的内网服务器
- 部署好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无线芯片温度
运行结果如下:
需要注意的是这里有一个坑,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 }}'
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。