方便的Pebble,稳定的Noolite和价格合理的esp8266实现自动化

从上一篇文章开始( 链接已使用了将近一年。在这一年中,我重新考虑了一些东西,互联网,结果证明是IoT :)→物联网)。

我将尝试总结积累的知识的新部分,描述我的努力方向和想要实现的目标→请您阅读。

Noolite F v2.0


在标题中,我得到了这样的字眼:卵石和硅藻土。 让我们继续前进吧!
我仍然用卵石来管理我的诺莱特灯,车库和大门。 搜索已经显示了很多有关Noolite的有用信息, 搜索显示了新文章。

除了Noolite系统的第一代装置外,我还有新的装置:带反馈功能的动力装置SLF-1-200(nooLite-F)( 以及新一代加密装置 )。

图片

电源块SB-1-150

图片

并更新了USB适配器MTRF-64 USB。

图片

Noolite系统上我家的所有灯都亮着。

直到最近,我还拥有一个第一代USB适配器,该适配器具有16个设备,现在在“系统家用抽筋”中具有64个通道(MTRF-64 USB),还用于带反馈的新一代设备(noolite F)。 但是技术正在朝着正确的方向发展,创造了新的现代设备。

新设备有2个最重要的选项:反馈和通过地址标识设备的原理:ID。 现在,您不必将设备写入通道1并控制该通道。 现在,您可以通过其ID在一个通道中访问特定设备,并向其发送执行命令。

新一代模块的文档在制造商的网站上找到。

一切都可以使用python代码通过串行端口工作。
# -*- coding: utf-8 -*- #!/usr/bin/env python import serial import time class NooLiteCommand: def __init__(self, ch, cmd, mode=0, ctr=0, res=0, fmt=0, d0=0, d1=0, d2=0, d3=0, id0=0, id1=0, id2=0, id3=0): self.st = 171 self.mode = mode self.ctr = ctr self.res = res self.ch = ch self.cmd = cmd self.fmt = fmt self.d0 = d0 self.d1 = d1 self.d2 = d2 self.d3 = d3 self.id0 = id0 self.id1 = id1 self.id2 = id2 self.id3 = id3 self.sp = 172 @property def crc(self): crc = sum([ self.st, self.mode, self.ctr, self.res, self.ch, self.cmd, self.fmt, self.d0, self.d1, self.d2, self.d3, self.id0, self.id1, self.id2, self.id3, ]) return crc if crc < 256 else divmod(crc, 256)[1] def to_bytes(self): return bytearray([ self.st, self.mode, self.ctr, self.res, self.ch, self.cmd, self.fmt, self.d0, self.d1, self.d2, self.d3, self.id0, self.id1, self.id2, self.id3, self.crc, self.sp ]) class NooliteSerial: def __init__(self, tty_name): self.tty = self._get_tty(tty_name) def on(self, ch): self.send_command(ch, 2, 2, 0) pass def off(self, ch): self.send_command(ch, 0, 2, 0) pass def status(self, ch): m = self.send_command(ch, 128, 2, 0) pass def send_command(self, ch, cmd, mode=0, ctr=0, res=0, fmt=0, d0=0, d1=0, d2=0, d3=0, id0=0, id1=0, id2=0, id3=0): command = NooLiteCommand(ch, cmd, mode, ctr, res, fmt, d0, d1, d2, d3, id0, id1, id2, id3) self.tty.write(command.to_bytes()) while True: bytes_response = list(self.tty.read(117)) if bytes_response: all_responses.append(bytes_response) if bytes_response[3] == 0: break else: break return all_responses @staticmethod def _get_tty(tty_name): serial_port = serial.Serial(tty_name, timeout=0.1) if not serial_port.is_open: serial_port.open() serial_port.flushInput() serial_port.flushOutput() return serial_port noo_serial = NooliteSerial('/dev/ttyUSB0') #ch, cmd, mode, ctr #noo_serial.send_command(1, 15, 2, 0) #    1 #noo_serial.send_command(0, 4, 2, 0) #switch #noo_serial.send_command(0, 2, 2, 0) #turn on #noo_serial.send_command(0, 3, 2, 0) #   #noo_serial.send_command(0, 0, 2, 0) #turn off #noo_serial.send_command(0, 15, 2, 0) #  #noo_serial.send_command(0, 128, 2, 0,0,1) #CMD_Read_State + fmt = 1 #noo_serial.on(0) #noo_serial.status(0) #noo_serial.off(0) #noo_serial.off(0) #noo_serial.status(0) #noo_serial.send_command(ch=0,ctr=8, cmd=4, id0=0,id1=0,id2=48,id3=114) #switch noolite ID 0.0.48.114 


在正确的时间使用必要的功能,我们可以控制Noolite块并从新块接收状态。 由于我有99%的这些旧块,因此考虑到USB适配器支持旧块和新块的事实,我仍然可以使用将1个块写入1个通道的旧方案(感谢开发人员的兼容性,无需铃鼓跳舞)。 在运行中,您可以管理和接收新块的状态以及管理旧块的状态。

直到最近,屋子里还没有一个按钮开关。 我不得不在车库里加光(我刚到那儿整理东西:D),化妆镜的背光灯上也出现了一个开关。 知道有一个SB-1-150电源设备后 ,我设置了普通开关并连接了电源设备。 镜子的背光由一块白板制成,3w的灯泡4000 K,白光。 SB-1-150的独特之处在于,它可以在现有电路环境中放置在墙壁开关(开关)的盒子中,并且可以通过将按钮开关连接到设备本身来放置。

正是我的女孩需要化妆:)
图片

卵石


当我开始涉足自动化领域时,主要因素之一是:称职且方便的管理。

用智能手机进行控制似乎很方便,但是...每次在不舒服的小按钮,左撇子广告或直到您按下按钮之前,每次加载应用程序都不方便,所有的欲望都消失了。 语音控制消失了,因为它也很不方便和奇怪:)-让它保留在科幻电影的情节中。

图片

然后,我以另一种方式解决了这个问题-通过一块手表,它与我在一起时不会占用空间,并且将所有便利设施,移动性和控制速度结合在一起。 通常-小卵石还活着! 但是最重​​要的是,您仍然可以随时编写应用程序-您自己的应用程序,以管理自动化系统。 实际上是炸弹。

小卵石还活着!

关闭pebble.com公司的悲剧(Fitbit购买了所有pebble.com以获得专利)并没有影响其业绩和业绩。 最近,有一个iOS安卓系统更新-手表与卵石云服务(如果终止支持)和授权无关。

从视觉上看 -没有任何变化,但服务仍然存在cloudpebble.net -WTF? 这是非常有用的事情。 如果您可以用JS编写代码(并且不希望在C ++上花费很多时间)-请在板上:)-云卵石可让您快速地“抛出”应用程序。 嗯,这就是我做到的方式。 当然,JS的性能不应该与C ++(这是神圣的)相提并论。 是的!

用于API的Pebble Cloud JS代码
 var UI = require('ui'); var ajax = require('ajax'); var noolite = [ ['','http://your-home-server-ip-address:1183/mqtt/gate/slidegate', 'images/gate.png'], ['','http://your-home-server-ip-address:1183/mqtt/gate/garage', 'images/door.png'], ['!','http://your-home-server-ip-address:1183/noolite/switch/103', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/100', 'images/system2.png'], ['1  ','', 'images/light.png'], ['2  ','', 'images/light.png'], [' 1','http://your-home-server-ip-address:1183/noolite/switch/101', 'images/light.png'], [' 2','http://your-home-server-ip-address:1183/noolite/switch/102', 'images/light.png'], ['','', 'images/water.png'], ['','http://your-home-server-ip-address:1183/admin/system/1', 'images/system1.png'], ]; var water = [ [' ','http://your-home-server-ip-address:1183/admin/poliv/1', 'images/water.png'], [' ','http://your-home-server-ip-address:1183/admin/poliv/2', 'images/water.png'], [' 1 ','http://your-home-server-ip-address:1183/noolite/switch/20', 'images/water.png'], [' 2 ','http://your-home-server-ip-address:1183/noolite/switch/21', 'images/water.png'], [' 3 ','http://your-home-server-ip-address:1183/noolite/switch/22', 'images/water.png'], [' 4 ','http://your-home-server-ip-address:1183/noolite/switch/23', 'images/water.png'], [' 5 ','http://your-home-server-ip-address:1183/admin/poliv/switch/5', 'images/water.png'], [' 6 ','http://your-home-server-ip-address:1183/admin/poliv/switch/6', 'images/water.png'], [' 7 ','http://your-home-server-ip-address:1183/admin/poliv/switch/7', 'images/water.png'], [' 8 ','http://your-home-server-ip-address:1183/admin/poliv/switch/8', 'images/water.png'], [' 9 ','http://your-home-server-ip-address:1183/admin/poliv/switch/9', 'images/water.png'], ]; var light1 = [ [' ','http://your-home-server-ip-address:1183/noolite/switch/6', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/0', 'images/light.png'], ['  ','http://your-home-server-ip-address:1183/noolite/switch/1', 'images/light.png'], ['  ','http://your-home-server-ip-address:1183/noolite/switch/7', 'images/light.png'], ['  ','http://your-home-server-ip-address:1183/noolite/switch/8', 'images/light.png'], [' 1 ','http://your-home-server-ip-address:1183/noolite/switch/2', 'images/light.png'], [' 1 ','http://your-home-server-ip-address:1183/noolite/switch/3', 'images/light.png'], [' 1 ','http://your-home-server-ip-address:1183/noolite/switch/4', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/5', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/9', 'images/light.png'], ]; var light2 = [ [' ','http://your-home-server-ip-address:1183/noolite/switch/15', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/16', 'images/light.png'], [' 2 ','http://your-home-server-ip-address:1183/noolite/switch/10', 'images/light.png'], [' 2 ','http://your-home-server-ip-address:1183/noolite/switch/11', 'images/light.png'], [' 2 ','http://your-home-server-ip-address:1183/noolite/switch/12', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/13', 'images/light.png'], ['  ','http://your-home-server-ip-address:1183/noolite/switch/14', 'images/light.png'], ]; var menu = new UI.Menu({ sections: [{ items: [{ title: '', subtitle: '' }] }] }); var menu1 = new UI.Menu({ sections: [{ items: [{ title: '', subtitle: '' }] }] }); var menu2 = new UI.Menu({ sections: [{ items: [{ title: '', subtitle: '' }] }] }); var menu3 = new UI.Menu({ sections: [{ items: [{ title: '', subtitle: '' }] }] }); var items = []; for (var i=0; i<noolite.length; i++) { items[i] = { title: noolite[i][0], subtitle: '', icon: noolite[i][2] }; } var items1 = []; for (var i=0; i<light1.length; i++) { items1[i] = { title: light1[i][0], subtitle: '', icon: light1[i][2] }; } var items2 = []; for (var i=0; i<light2.length; i++) { items2[i] = { title: light2[i][0], subtitle: '', icon: light2[i][2] }; } var items3 = []; for (var i=0; i<water.length; i++) { items3[i] = { title: water[i][0], subtitle: '', icon: water[i][2] }; } menu.items(0, items); menu1.items(0, items1); menu2.items(0, items2); menu3.items(0, items3); menu.show(); menu.on('select', function(e) { if (e.itemIndex == 4) { menu1.show(); } else if (e.itemIndex == 5) { menu2.show(); } else if (e.itemIndex ==8) { menu3.show(); } else { var url = noolite[e.itemIndex][1]; console.log(url); ajax({ url: url, method: 'get' }, function(data) { console.log('switched OK'); }, function(error) { // Failure! console.log('error'); } ); } }); menu1.on('select', function(e) { var url = light1[e.itemIndex][1]; console.log(url); ajax({ url: url, method: 'get' }, function(data) { console.log('switched OK'); }, function(error) { // Failure! console.log('error'); } ); }); menu2.on('select', function(e) { var url = light2[e.itemIndex][1]; console.log(url); ajax({ url: url, method: 'get' }, function(data) { console.log('switched OK'); }, function(error) { // Failure! console.log('error'); } ); }); menu3.on('select', function(e) { var url = water[e.itemIndex][1]; ajax({ url: url, method: 'get' }, function(data) { console.log('switched OK'); }, function(error) { // Failure! console.log('error'); } ); }); 


可以直接在Pebble的云网站上编写,编译代码,并可以通过电话下载已编译的应用程序,从而可以按秒安装时钟。 一切都很简单,任何年轻的自动化工程师都可以处理;)

真可惜...可惜的是,Pebble不再存在,目前我没有其他选择。 卵石时间永远在我们心中!

MQTT


去年,我遇到了一个很棒的协议,例如MQTT(历史记录:该协议的第一个版本是由Andy Stanford-Clark博士(IBM)和Arlene Nipper(Arcom)于1999年开发,并在免版税的许可下发布的。MQTT3.1.1规范是由OASIS联盟于2014年标准化。

关于协议如何工作以及客户端是什么的信息很多,而令我非常失望的是,没有真正的移动应用程序客户端,只有在android上。

了解缺乏好的移动应用程序是物联网领域的一个大问题(很多人说,但是他们做的很少..)-我和我的团队在工作中决定为android,ios,wp创建一个客户端使其符合所有标准且舒适。 稍后我将介绍有关客户端的信息,以及我们如何结交ESP8266 + MTRF64(Noolite)朋友并准备Nodemcu固件的方法。 它将是伟大,方便,便宜和美丽的! 在此处关注应用程序新闻。

图片

现在,您无需任何家用服务器和USB适配器即可控制Noolite照明,价格为50-100美元!

家庭自动化的总体方案


仍然存在以下方案:

视频监控:xeoma视频监控[网络摄像机]
系统单元上的服务器:nginx + gunicorn + python + mqtt代理
管理:Pebble watch + MQTT客户端
控制模块(系统节点):ESP8266 +光耦合器\ ds18b20,dht11传感器[22]

由于我看到了MQTT协议中的许多便利性,从订阅体系结构和与最终IoT设备的即时通信开始,到最后一个事实是MQTT消息可以通过路由器飞行而无需“转发”那里的任何端口并铃鼓跳舞。 方便! 玩得开心! 热情地:)

所有这些导致我分散了系统的分散性,也就是说,避免了一个“家庭暴力”并切换到许多所谓的节点,并使用了一个云MQTT代理(有免费的MQTT代理,例如: mqtt.ximxim.com (在站点登录并通过访问权限) ))-由于esp8266解决了所有问题,因此它又使用MQTT协议通过wifi工作。

鉴于MQTT Buddy将提供脚本服务,我不会考虑编写任何家庭脚本,我只会在云解决方案中创建它们,这将是真正的物联网,并且可以工作! 从言语到行动!

ESP8266


当我熟悉该开发板时,开发板很小,就给我留下了深刻的印象,它支持Nodemcu固件上的LUA编程语言。 您需要的是+ MQTT模块。 在自动化领域,简单可靠的解决方案是基础。 费用从2美元到5美元不等(使用板载USB适配器的第5个型号立即收费),您可以快速部署子系统。

WiFi连接速度很快,可能性很多。 例如:大门/车库\浇水\照明控制。 我有30%的草坪灌溉由Noolite系统(干式接触块)驱动,其余70%的esp8266开发板通过使用MQTT协议的LUA语言控制。

示例esp8266的LUA代码,获取ip并使用MQTT调用工作文件
 --load credentials dofile("credentials.lua") function init(name, pass) wifi.setmode(wifi.STATION) wifi.sta.config(name, pass) wifi.sta.connect() tmr.alarm(0, 1000, 1, function() if wifi.sta.getip()== nil then print("IP unavaiable, Waiting...") else tmr.stop(0) print("Config done, IP is "..wifi.sta.getip()) print("mac : "..wifi.sta.getmac()) dofile("mqtt.lua") end end) end print("START!") init(SSID,PASSWORD) 


-mqtt.lua文件

 local door = 7 -- gpio13 local window = 6 -- gpio12 local cooler = 5 --gpio14 local led = 4 --GPIO2 board led! LOW == turn ON local light1 = 8 --gpio 15 local light2 = 1 --gpio 5 local light3 = 2 -- gpio 4 function register_myself() m:subscribe("mqtt_buddy/#",0,function(conn) print ("subscribed to Xim mqtt.ximxim.com server") end) end m = mqtt.Client("MQTT_BUDDY_SHOW_ROOM", 120, MQTT_USER, MQTT_PASS) m:on("connect", function(client) print ("connected to Xim mqtt.ximxim.com server") end) m:on("offline", function(client) reconnect_mqtt() end) m:on("message", function(client, topic, data) --print(topic.." data:"..data) if topic == "mqtt_buddy/window" and data == "1" then print "open-close window..." gpio.write(window, gpio.HIGH) gpio.write(led, gpio.LOW) tmr.alarm(1, 1000, tmr.ALARM_SINGLE, function() gpio.write(window, gpio.LOW) gpio.write(led, gpio.HIGH) print "command to close\open window is sent!" end) elseif topic == "mqtt_buddy/door" and data == "1" then print "open-close door..." gpio.write(door, gpio.HIGH) gpio.write(led, gpio.LOW) tmr.alarm(2, 1000, tmr.ALARM_SINGLE, function() gpio.write(door, gpio.LOW) gpio.write(led, gpio.HIGH) print "command to close\open door is sent!" end) elseif topic == "mqtt_buddy/cooler" then if data == "1" then print "switch on fan..." gpio.write(cooler, gpio.HIGH) gpio.write(led, gpio.LOW) else print "switch off fan..." gpio.write(cooler, gpio.LOW) gpio.write(led, gpio.HIGH) end elseif topic == "mqtt_buddy/light1" then if data == "1" then print "switch light1 ON..." gpio.write(light1, gpio.HIGH) gpio.write(led, gpio.LOW) else print "switch light1 off..." gpio.write(light1, gpio.LOW) gpio.write(led, gpio.HIGH) end elseif topic == "mqtt_buddy/light2" then if data == "1" then print "switch light2 ON..." gpio.write(light2, gpio.HIGH) gpio.write(led, gpio.LOW) else print "switch light2 off..." gpio.write(light2, gpio.LOW) gpio.write(led, gpio.HIGH) end elseif topic == "mqtt_buddy/light3" then if data == "1" then print "switch light3 ON..." gpio.write(light3, gpio.HIGH) gpio.write(led, gpio.LOW) else print "switch light3 off..." gpio.write(light3, gpio.LOW) gpio.write(led, gpio.HIGH) end end end) m:connect(MQTT_SERVER, MQTT_SERVER_PORT, 0, function(conn) register_myself() end) 


问题


在一个庞大的有思想的社区中,我想谈一个非常重要的话题,或者是我想解决的问题,但是没有足够的时间进行更深入的研究/知识。

底线是:通过权力下放,视频监视仍然存在,这需要一种或多种方式(至少)将主机图像传输到视频监视服务器(例如ivideon)或什至在xeoma之类的家用计算机上处​​理视频的主机(尽管它们也有云)-一种或另一种方式-您需要“转发”视频流,具有最终计算能力的图片(云解决方案)(反之亦然),以使流传输变得简单。

有想法从相机接收源图像(这里还有一个问题,不是每个相机都有一个用于从相机接收图片的URL,通常不清楚其他人将如何识别此URL ....)并转发到支持二进制数据的MQTT通道(即有一张图片可以很容易地通过mqtt协议以二进制形式传输)。

也许有人已经尝试实现这样的事情= ESP8266 + IP网络摄像头?
请回复(bogdanovich.alex [@] gmail.com)。 我将非常感谢!

当实施probros时,家庭服务器的问题将消失。 怎么了 因为他吃电并加热我的炉子:)

图片

一切顺利,心情愉快!

Source: https://habr.com/ru/post/zh-CN403273/


All Articles