Homebridge和Node-RED组合 | 宁静致远

Homebridge和Node-RED组合

正在加载一言...


最近有开始折腾了,树莓派又整出来了。之前系统总是崩,所以这次给他刷原生的系统。准备把路由器上的Node-REDHomebridge给迁移到这个上面。虽然之前运行的狠稳定,但是树莓派总吃灰也不好。

0.树莓派散热


树莓派之前壳子上的风扇坏了,转起来的声音贼大,所以考虑给他换一个风扇,这不网上买了一个,回来装上后,效果非常不错,温度基本稳定在50度以下,而且非常的静音。这个风扇是PWN调速的,照着设置了下。

# 修改/boot/config.txt 增加如下内容
dtoverlay=gpio-fan,gpiopin=18,temp=55000

下图是我买的风扇。做工不错,值得推荐
PWN风扇

1.家庭中枢自动充电


之前路由器重启了下,Homebridge的相关配置就没了,这就更加坚定了迁移到树莓派上的决心。所以就三下五除二整了起来,整好之后想在外面控制的话就得有家庭中枢之前的iPad mini就派上用场了,用了一段时间,遇到了一个问题,就是这个iPad平时不会用,所以就不会充电,用一段时间后,电池没电了,导致在外面就控制不了家中的设备了。所以就开始找解决方案了。最后终于给我整到了,下面就和大家分享一下我的整的流程吧。

0.Homebridge安装

这个过程就不多说了,网上都有的,所以咱就不整了参看HomeBridge 操作指南:从零开始,将你的米家设备接入 Homekit这个文章吧。

1.安装Node-RED

这边也不说了,放个官网的连接Running on Raspberry Pi,参看这个就安装Node-RED。下面就开始整了

2.流程简介

首先得能获得iPad的当前的状态,在GitHub上找了下,找到了这个node-red-contrib-apple-find-me插件,通过他就能获得我们所有设备的状态。里面的信息很多,其他的都不要,要当前手机的电量和是否在充电的状态就行。这个结果也被我推到路由器的上面。这个后面用来做Homebridge的插件。搞完之后的流程是这样的。

流

流程是通过Apple Find Me拿到相关状态,然后经过逻辑判断,发送报文到MQTTplugswitch这个主题上。在路由器上写了一个订阅这个主题的程序,接收到后,通过python-miio来控制开关的状态,当然这一步你可以直接安装miio插件完成也是可以的。到此就完成了家庭中枢的自动充电了。

2.Homebridge的周边


0.电池状态显示

上面推到路由器上的数据写了一个获得当前状态的插件。
插件展示
目录结构是这样的:

homebridge-appledevice/
		├── index.js
		└── package.json

下面的是代码:

'use strict';

const http = require('http');
const inherits = require('util').inherits;
const version = require('./package.json').version;
let Service;
let Characteristic;
let logger;
let API;

module.exports = function (homebridge) {
    API=homebridge;
	Service = homebridge.hap.Service;
	Characteristic = homebridge.hap.Characteristic;
	homebridge.registerAccessory('homebridge-appledevice', 'AppleDevice', AppleDevice);
}

function AppleDevice(log, config) {
	logger = log;
	this.services = [];
	this.name = config.name || 'iPad';
    this.num = config.num || 0;
    this.interval = Number(config.interval) || 360000;
    this.displayName = "";
    this.statusLowBattery = 0;
	this.batteryLevel = 0;
	this.chargingState = 0;
}

AppleDevice.prototype = {
	updateStatus: function () {
		const that = this;
        http.get('http://192.168.xxx.xxx/_api/home', (resp) => {
            let data = '';
            resp.on('data', (chunk) => {
                data += chunk;
            });
            
            resp.on('end', () => {
                let ret = JSON.parse(data);
                let devices = ret.result[0].home_devices;
                let devList = JSON.parse(devices);
                that.batteryLevel = devList[that.name][that.num].batteryLevel;
                that.displayName = devList[that.name][that.num].displayName;
                let status = devList[that.name][that.num].batteryState;
                //console.log("batteryLevel: " + that.batteryLevel);
                //console.log("status: " + status);

                if(status.indexOf("NotCharging") >= 0){
                    that.batteryService.setCharacteristic(Characteristic.ChargingState, Characteristic.ChargingState.NOT_CHARGING);
                }else{
                    that.batteryService.setCharacteristic(Characteristic.ChargingState, Characteristic.ChargingState.CHARGING);
                }
                
                if(that.batteryLevel <= 20){
                    that.batteryService.setCharacteristic(Characteristic.StatusLowBattery, Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);
                }else{
                    that.batteryService.setCharacteristic(Characteristic.StatusLowBattery, Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);
                }
                
                that.batteryService.getCharacteristic(Characteristic.BatteryLevel).updateValue(this.batteryLevel)
            }); 

        }).on("error", (err) => {
            console.log("Error: " + err.message);
        });
		
		setTimeout(function () {
			this.updateStatus();
		}.bind(this), this.interval);

	},

	identify: function (callback) {
		callback();
	},

	getServices: function () {

        this.serviceInfo = new Service.AccessoryInformation();

        this.serviceInfo
        .setCharacteristic(Characteristic.Manufacturer, 'Apple')
        .setCharacteristic(Characteristic.Model, "Battery")
        .setCharacteristic(Characteristic.SerialNumber, "1353234")
        .setCharacteristic(Characteristic.FirmwareRevision, version);

        this.batteryService = new Service.BatteryService(this.name);

        this.updateStatus();
       
		return [this.serviceInfo , this.batteryService];
	}
};

1.Scriptable插件

这个插件是真的好看,不过一开始遇到一个坑,上面的图标不能下载下来,一直报错,最后自己下载下来放进去就可以的。
小组件

3.总结


后面在优化再整哈,学无止境。


文章作者: 彤爸比
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 彤爸比 !
评论
  目录