月度存档: 九月 2017

玩玩智能家居6:接入杜亚电动窗帘

之前还没有玩上 Domoticz 的时候,家里全套系统都是用的 Broadlink,在买窗帘的时候也想着要买电动的,因此很自然的买了支持 Broadlink 的杜亚窗帘电机,可以方便地与 Broadlink 的传感器进行联动。

后来用了 Domoticz,但是 Broadlink 的系统并没有开放 API,想要接入 Domotiz 系统就比较麻烦了。在网上看了一堆帖子之后,发现可以通过分析窗帘电机遥控器信号,然后自己使用 433M 射频模块来自己控制。

Controlling Blinds.com RF Dooya Motors with Arduino and Vera 这篇帖子中提供了一个 PDF,详细介绍了如何嗅探信号,以及杜亚窗帘电机遥控器信号的格式。

准备材料

发射和接收 433M 射频信号需要的材料很简单,只需要 433M 发送和接收模块就可以了,不超过 5 块钱。

再加上需要接入 Domoticz,加个 NodeMCU,完事。

嗅探信号

首先需要嗅探一下窗帘遥控器发出的信号,如果有专业的机器的话可以直接去嗅探 433M 射频信号,如果没有的话,也可以使用 433M 模块自制一个。

根据前面提到的 PDF 中介绍的方法,将一个 433M 模块与 3.5mm 耳机线连接,然后插在电脑上。

因为 MacBook Pro 没有自带专用麦克风插孔,因此还得去买一个 USB 转耳机接口模块,方便接入。另外为了给 433M 模块供电,直接把模块的 VCC 跟 GND 跟 NodeMCU 的 VIN 和 GND 在面包板上连接起来了。

接着就可以使用 Audacity 进行录音操作了:

找到有规律的波形之后放大,开始数格子:

数完格子就知道一个遥控器指令的格式了。

指令格式

一个完整杜亚窗帘遥控器指令是 32 位 + 16 位或 8 位命令位,前 32 位可能包含了窗帘 ID 信息,不过我并没有仔细研究,每个遥控器的都不太一样,也不用太纠结。

例如一个打开窗帘的指令可以像下面这样:

10111101010000011001101101100001 00010001 00011110

每个指令需要发送 6 遍,在发送指令之前,还有一个间隙指令,需要发送三遍。

其实理论上,杜亚窗帘电机使用固定码,并不需要知道指令格式是什么意义,只需要按采集到的波形原样重放就可以了。

发射信号

有了波形,有了指令,就很方便的去重放射频信号了,反正也没什么加密措施,窗帘电机是不认识是由遥控器发出的指令,还是由 433M 模块发出的指令。

把 433M 射频发射模块与一个 NodeMCU 相连,然后使用之前帖子里提供的 BlindsVera.ino 中的代码就可以发射信号了。天线可以简单的使用一根 16cm 左右的导线。

BlindsVera.ino 中的代码都有注释,下面说说关键的几部分。

定义发送管脚,以及指令 1 和 0 所占用的时间

#define SEND_DATA 3 //Data pin for RF Transmitter
#define ZERO_HIGH 395 //Delay for the high part of a 0 in microseconds
#define ZERO_LOW 687 //Delay for the low part of a 0 in microseconds
#define ONE_HIGH 750 //Delay for the high part of a 1 in microseconds
#define ONE_LOW 333//Delay for the low part of a 1 in microseconds

指令中的标准位

unsigned char standardBits1 = 0b00000111;
unsigned char standardBits2 = 0b01110000;
unsigned char standardBits3 = 0b01010101;
unsigned char standardBits4 = 0b11001011;

BlindsVera.ino 中把窗帘 ID 与标准位分离了,但是在实际使用中,其实标准位并不统一,每个遥控器的都会不一致,因此在实际使用中需要把这里的标准位替换为实际的标准位,也就是数格子得到的指令中的前 28 位。

发送指令

void separatorDelay(boolean upDown);
void endDelay();
void blindAction(int c, int a);

最后就是发送指令了,根据之前采集的格式,按顺序发送相应的指令就可以了。

换个思路

杜亚窗帘电机上本身已经带了有线接口,可以直接使用 NodeMCU+继电器的方式来控制,不用去模拟射频信号,每个电机都是使用一样的线序,处理起来更简单一点。

更好的选择

呃,小米的窗帘电机?也许 miio 或者 python-mirobo 会支持吧,相对而言小米还是开放一些的。

参考资料

  1. Controlling Blinds.com RF Dooya Motors with Arduino and Vera
  2. 智能家居:窗帘篇

玩玩智能家居5:DIY水浸传感器

之前总是担心厨房水槽下水管会漏水,所以直接用雨水传感器做了一个水浸传感器,这样在漏水的时候,就可以直接收到通知,从而及时去检查并修复下水管漏水问题。

要 DIY 一个水浸传感器还是很简单的,只需要一个雨水传感器和一个 NodeMCU 就可以了。

雨水传感器

给 NodeMCU 刷上 ESPEasy,配置一个 Switch 设备,将 GPIO 设置为 NodeMCU 与雨水传感器 DO 针脚连接的 IO 就可以了。

然后再在 Domoticz 中配置好一个 Virtual Sensor,类型改为 Switch 就可以了。

报警声音

有些时候推送通知会比较慢,又或者手机不在身边,那么是否可以直接在 NodeMCU 这一端直接使用声音报警呢?这很简单,加个蜂鸣器模块,再写点代码就好了。

先给 ESPEasy 写个蜂鸣器插件,关键代码就是使用 Arduino 的 tone 函数了:

#define Plugin158_Do 262
#define Plugin158_Re 294
#define Plugin158_Mi 330
#define Plugin158_Fa 349
#define Plugin158_Sol 392
#define Plugin158_La 440
#define Plugin158_Si 494

static int Plugin158_TonesFreq[] = { Plugin158_Do, Plugin158_Re, Plugin158_Mi, Plugin158_Fa, Plugin158_Sol, Plugin158_La, Plugin158_Si };

static void Plugin158_PlayTones(int taskIndex) {
  int pin = Settings.TaskDevicePin1[taskIndex];

  char *tonesStr = "616161";

  pinMode(pin, OUTPUT);
  int len = strlen(tonesStr);
  if (Plugin158_TonesPlayingCharIndex < len) {
    char c = tonesStr[Plugin158_TonesPlayingCharIndex];
    int index = c - '0';
    if (index > 0 && index <= 7) {
      tone(pin, Plugin158_TonesFreq[index]);
    } else {
      noTone(pin);
    }
  }

  Plugin158_TonesPlayingCharIndex++;
  if (Plugin158_TonesPlayingCharIndex >= len) {
    Plugin158_TonesPlayingCharIndex = 0;
  }
}

为了能在有漏水时,马上报警,或者为了在没有网络情况不好时也能马上使用声音报警,需要在 ESPEasy 的本地规则里检测到漏水时来报警。

要实现这个功能,只需要使用 ESPEasy 的 Rules 功能,在 Rules 里检测到有漏水时,直接调用蜂鸣器插件进行报警:

on WATER#VAL=1 do
    buzzer,2,1
endon
on WATER#VAL=0 do
    buzzer,2,0
endon

更好的选择

当然,如果已经有小米网关了,可以直接购买 Aqara 水浸传感器,使用电池,方便部署,还美观 🙈。

而且小米的东西也可以不借助于 Domoticz 直接使用,可以将水浸传感器设置自动化,触发时直接使用小米网关播放警报音。

参考资料

  1. Domoticz
  2. Arduino – Tone

玩玩智能家居4:InfluxDB & Grafana

在接入了很多传感器到 Domoticz 之后,终于可以全面监控家里的各种环境参数了,例如温度、湿度、PM 2.5、二氧化碳浓度等等。

Domoticz 虽然已经自带了传感器数据日志,但是一来详细数据最多只能保存七天,二来只能单独查看每个传感器的数据,而不能将多个传感器数据放在一起对比查看,所以就需要使用其他方式去保存和展示传感器历史数据。

InfluxDB

InfluxDB 是一个时序数据库,很方便用来保存时间序列数据,而各种传感器数据其实就是一个时间序列化数据,InfluxDB 的介绍页面也说了很适合于 IoT Sensors 数据的保存。

使用 InfluxDB 最方便的方式就是用 Docker 了,直接在 DSM 的 Docker 中添加 influxdb 镜像,然后启动一个容器就可以了。

当然这里要记得添加一下端口映射,后面在配置 Domoticz Data Push 的时候需要用到。

Domoticz Data Push

部署好了 InfluxDB,就可以在 Domoticz 里面配置把接收到的传感器数据同时推送到 InfluxDB 中保存了。

Domoticz 提供了两种方式可以用来将传感器数据推送到 InfluxDB 中,一种使用 HTTP 调用 InfluxDB 的 HTTP API,还有一种是直接使用 Domoticz 内建的 InfluxDB 支持。

使用内建 InfluxDB 支持

使用内建 InfluxDB 的功能很简单,直接填写好 InfluxDB 服务器的 IP 和端口以及数据库名称就可以了

使用 InfluxDB HTTP API

使用 HTTP API 来向 InfluxDB 来写入数据稍微麻烦一点,需要自己定义一下发送数据的格式,但是其实这样更有利于控制写入 InfluxDB 中数据的名称。

URL 需要填写 InfluxDB 的 API 地址:

http://192.168.9.16:9800/write?db=domoticz&u=root&p=root&precision=ms

其中:

  • 192.168.9.16:9800 需要替换为实际的 InfluxDB 服务器地址和端口
  • db=domoticz 需要将数据库名称替换为实际的数据库名称

Data 填写:

device_%V value=%v %t3

配置需要 Push 的数据

在设置完 InfluxDB 推送,还需要选择需要推送哪些传感器的数据到 InfluxDB,这个在 Data Push 页面中直接选择添加就可以了。

Grafana

有了数据,就可以来展示了。Grafana 是一个很好的展示时序数据的工具,它直接支持读取 InfluxDB 的数据,可以提供多种形式的展示方式,例如曲线图、柱状图等。

Grafana 同样可以直接使用 Docker 来安装部署。

在 Grafana 中配置好 InfluxDB 数据源,就可以开始使用 Grafana 的面板来展示数据了。

在 Dashboard 中创建一个 Graph Panel,然后直接选择一下需要显示的数据字段,填一下采样的时间间隔,就可以显示出好看的曲线啦。如果需要对比多个数据,可以直接添加,选择不同的字段就可以了。

Grafana 还有其他很强大的图表显示功能,这个就可以根据自己的需要去组合排布,也可以创建多个 Dashboard 来展示不同类型的数据。如果有条件,还可以用一个 iPad 来展示 Dashboard,可以直接看到数据而不用去电脑上打开网页了。

参考资料

  1. Influxdb
  2. Grafana
  3. Domoticz HTTP Link

— EOF —

玩玩智能家居3:PlatformIO

ESPEasy 虽然方便,但是毕竟很久没有维护了,里面对硬件的支持也不是很完全,并且在使用有些模块时,与 Domoticz 对接可能会有一些问题,例如 CO2 传感器在发送数据到 Domoticz 时,发送的数据字段就不正确。

在这个时候就需要自己来修改 ESPEasy 代码,重新编译并烧录到 NodeMCU 中,而修改代码就需要用到 IDE 了。ESPEasy 是一个 Arduino 项目,自然用 Arduino IDE 来开发是最直接的。

但是 Arduino IDE 是一个相当古老的程序了,虽然版本号更新到了 1.8,但是在使用的时候有很多功能都不够完善,例如代码自动补全、符号定位、语法着色等。

这个时候就在网上找到了 PlatformIO 这个项目,它提供了基于 Atom 或者 Visual Studio Code 的 IDE 项目 PlatforIO IDE。

PlatformIO IDE

要安装 PlatformIO IDE 很简单,在 Atom 的设置中打开 Packages,直接搜索 platformio ,安装platformio-ide 扩展即可。

项目开发

安装完 PlatformIO IDE,就可以开始用 Atom 来开发 Arduino 项目啦,使用 Atom 侧边工具栏里面的 Home 图标即可打开 PlatformIO IDE 首页。

如果原来的项目是纯 Arduino IDE 项目,即项目文件都在一个文件夹并且扩展名为 .ino,可以使用 PlatformIO 的导入 Arduino 项目功能。PlatformIO IDE 会将项目文件组织方式转换为 PlatformIO 项目格式,这个转换操作会将所有源代码文件移动到 src 目录中,并且给每一个 .ino 文件头部加上 include <arduino .h>

导入完成之后,就可以直接使用 Atom 编译固件并烧录到 NodeMCU 上了。

串口监视器

当然 PlatformIO IDE 也提供了串口监视器功能,直接在左侧工具栏中找到插头图标,点击之后就会出现串口选择,选择 NodeMCU 对应的串口设备以及波特率,即可在终端中看到 NodeMCU 串口输出的数据。

PlatformIO 平台

当然 PlatformIO 并不是只有 IDE 功能,它同样还有库管理功能,在 PlatformIO 的平台上有超过 1800 多个开源库可以使用,进入 PlatformIO IDE 主页之后,在左侧菜单中找到 Libraries,就可以快速添加开源库到 Arduino 项目中。

使用 Arduino IDE 中安装的库

当然在 PlatformIO 中也可以使用在 Arduino IDE 中安装的开源库,因为有一些库可能只上传到了 Arduino 的平台,而没有提交 PlatformIO 生态。

要在 PlatformIO 项目中使用 Arduino IDE 安装的开源库,只需要在 platformio.ini 这个配置文件中加下以下两行就可以了:

[platformio]
lib_dir=~/Documents/Arduino/Libraries

参考资料

  1. PlatforIO
  2. PlatformIO IDE for Atom
  3. PlatformIO Libraries

— EOF —