智能电源插座是使家庭自动化的最简单方法,但是基于Wi-Fi或ZWave的插座每个售价约40美元,您购买的数量不多。
您可能会购买但是已经有一些廉价的基于RF的插座了,它们带有自己的自定义遥控器,并且背面有一些通道和ID选择器。不幸的是,市场上没有与之兼容的智能家居集线器。如果可以将它们以某种方式链接到自己的DIY智能家居系统中,那不是很好吗?好吧,实际上,您可以很容易地用大约10美元的零件来购买。
再多做一些工作,您还可以集成其他一些基于RF的定制远程硬件,例如这个廉价的电影院屏幕。
您需要什么:
如果这是您第一次对NodeMCU板进行编程,则需要为其下载Arduino插件:以及适用于NodeMCU / ESP8266芯片的Arduino Killer入门指南的第一部分。您还需要 CH430驱动程序。您可以在这里或Windows上找到签名的macOS CH430驱动程序。
我使用了Arduino v1.6.5,因为任何更高版本都带来了比它要解决的问题更多的问题。
在您继续之前,请降级。
在继续之前,我将假定您具有有关Arduino编程的基本知识,并且您已经在板管理器中安装了NodeMCU,并且能够正确上传一些演示代码。您还应该将下载中包含的库添加到您的 Arduino / libraries 文件夹中。
如果您已有现有的 PubSubClient或MQTT库,请返回并删除它–我下载的文件是我可以在NodeMCU上可靠接收消息的唯一文件,我尝试了很多!
RF嗅探(可选)
如果您只想控制DIP开关或拨号选择器插头插座,则不需要此步骤-即插即用的插座,并且只需进行最小的代码修改(这仍然是不过,首先要做的很有趣,所以您将了解幕后的情况。
如果您想尝试添加其他RF遥控器,则需要先“嗅探" "正在发送的RF代码。为此,请从菜单->示例-> RCSwitch 文件夹中加载 ReceiveDemo_Advanced 草图,并将以下行从0更改为
mySwitch.enableReceive(0); // Receiver on interrupt 0 => that is pin #2
2。
mySwitch.enableReceive(2); // Receiver on GPIO 2 / D4.
按如下所示连接接收器模块。看着接收器板的正面(是两者中的较长者,发射器是方形的)–组件在以下的一侧:
现在上传修改后的 ReceiveDemo_Advanced ,并打开它。串行监视器,然后开始按遥控器上的按钮。按下按钮时,请复制小数点(包括位长),脉冲长度和协议。
这样做之后,我发现我的投影仪屏幕正在使用
继续按需要的任意数量的按钮。
测试发送器
接下来,我们将尝试使用发送器发送代码。按如下所示连接发射器模块(方形)。注意:这些引脚上的标签是可怕的。
VCC引脚实际上在中间,而不是在左侧侧。我在弄清楚这一点的过程中销毁了一个模块。倒写“ ATAD"的实际上是“ DATA"。再次,数据到达D4,从VCC到VIN,从GND到GND(移除接收器模块,您不再需要它)。
加载示例-> RCSwitch-> TypeB_WithRotaryOrSlidingSwitches ,然后再次更改数据引脚:
mySwitch.enableTransmit(10);
更改为
mySwitch.enableTransmit(2);
注意,该库中包含各种示例,并且适合您的一个示例取决于您使用的开关的确切类型。类型A(拨动开关)和类型B(拨盘或滑块)是最常见的-请参阅RCSwitch页面上的图片。对于类型B,打开和关闭套接字很简单:
mySwitch.switchOn(1, 4);mySwitch.switchOff(1, 4);
其中1是通道ID(顶部刻度盘),而4是套接字ID(底部刻度盘)。这些用罗马数字写在我的插座上。因此,最多可以访问16个单独的插槽,但是如果您一次打开多个设备,则多个插槽可以使用相同的地址。
但是,我的投影机屏幕有点不同–它使用了一个不同的脉冲长度。因此,要操作这些,以下工作。请注意,如果您的遥控器需要,您还可以定义其他协议,但是请确保在脉冲长度之前定义协议。更改协议时,脉冲长度将被覆盖。
// Note that my screen actually requires TWO button presses (not a long press, but two physical presses), so I'm delaying a bit then sending the same signal againvoid screenUp(){ mySwitch.setPulseLength(358); mySwitch.send(8694273,24); // (decimal code, number of bits) delay(2000); mySwitch.send(8694273,24);}void screenDown(){ mySwitch.setPulseLength(358); mySwitch.send(8694276,24); delay(2000); mySwitch.send(8694276,24);}
在继续下一步之前,首先测试所有代码是否正常工作。
通过MQTT控制
打开从Github下载的名为 mqtt_rcswitch.ino的草图,然后首先修改您家庭的网络SSID和密码。然后,根据需要更改通道名称,并设置MQTT服务器。如果您尚未在OpenHAB安装上运行MQTT服务器,请阅读《 OpenHAB入门指南》的第2部分。请注意,我的代码是为B型(旋转开关)插座设计的,尽管您也可以为DIP开关轻松地对其进行修改。
代码中最重要的部分是 messageReceived()
void messageReceived(String topic, String payload, char * bytes, unsigned int length) { if (topic.indexOf("switch") >=0){ //switch control, parse out the channel and plug id int channel = getValue(topic,'/',3).toInt(); int plug = getValue(topic,'/',4).toInt(); if(payload == "on"){ mySwitch.switchOn(channel, plug); } else{ mySwitch.switchOff(channel, plug); } } else if (topic.indexOf("screen") >=0){ //screen control if(payload == "up"){ screenUp(); } else if(payload == "down"){ screenDown(); } } /* add another else if here to listen for more commands (or just modify the one above if you dont want screen) */}
默认情况下,以下MQTT命令起作用:
livingroom/control/switch/X/Y (where X is channel, and Y is plug ID; with message body on or off)
livingroom/control/screen (with message body up or down)
在添加之前,请使用命令行或GUI MQTT客户端来测试设备
添加到OpenHAB
As a last step, we just need to create some items for these switches in OpenHAB. I’ve defined the following items for now, but you should be able to figure out how to add more:
/* RF433mHz devices */Switch CinemaScreen "Screen" (Cinema) { mqtt=">[broker:livingroom/control/screen:command:ON:down],>[broker:livingroom/control/screen:command:OFF:up]"}Switch Switch41 "Switch41" (Cinema) {mqtt=">[broker:livingroom/control/switch/4/1:command:ON:on],>[broker:livingroom/control/switch/4/1:command:OFF:off]"}Switch Switch42 "Switch42" (Cinema) {mqtt=">[broker:livingroom/control/switch/4/2:command:ON:on],>[broker:livingroom/control/switch/4/2:command:OFF:off]"}
您现在应该可以从OpenHAB控制RF设备了!令我惊讶的一件事是范围-一个节点就能覆盖我的大部分房屋。当然,如果需要进一步的覆盖,您当然可以添加另一个节点,侦听相同的频道,只需重复相同的命令即可。
唯一需要记住的限制是套接字本身无法报告它们的状态,因此,如果您使用原始遥控器,则在OpenHAB中可能无法准确反映套接字的状态。坚持只使用OpenHAB界面,就可以了。
有疑问或问题吗?在评论中提问,我会尽力提供帮助。如果您想改进我的代码,请随时提交请求。