树梅派智能家居助理回家检测功能的实现
1如何实现屋内是否有人的判断?
- 首先能够想得到的思路是,在树梅派安装红外人体感应模块,当有人走动的时候,这时候就可以判断家里是有人的,但是光靠这个模块并不能够准确的判断,人是否出入。经过测试我使用的CH-RS501人体红外感应模块,有这几个特性:1.感应速度灵敏,当检测到有人,输出引脚迅速会从低电平转换为高电平。2.输出高电平后会保留一段时间,此时不接受外界的信号,这个时间的长短可以那螺丝刀扭动模块上的旋钮调节,3.也是一个很烦的问题,模块只能检测到移动的人体,比如说你在床上睡着了一动不动,他就跟个瞎子一样。所以仅根据红外模块无法判断人是否在房间内。
- 那么问题来了那怎么判断人是否在房间呢?这里有两个思路,第一个给门上安装一个装置,检测门是否被打开,装置和树梅派通信,再结合红外模块判定出门或者是进门。(这种装置我不会做,果断抛弃这个方案)。下一个思路就是监听路由器信息,看手机是否连入到wifi来判断。
2.开始整理代码结构
3. 开始着手完成代码部分
- CH-RS501模块部分代,CH-RS501有三个管脚,分别是电源,io,接地。我这里将io管脚接到树梅派的gpio 17,Vcc连接5v电源,GND接地。代码如下:
import RPi.GPIO as GPIO
import time
class RS_501():
def __init__(self):
self.inter_io = 27 # 将pgio设置为27
GPIO.setmode(GPIO.BCM)
GPIO.setup(27,GPIO.IN)
self.is_some_body_in_home = 0
def get_gpio_data(self): # 循环检查红外输出,把结果传给 self.is_some_body_in_home方便后面模块的检查
while True:
self.is_some_body_in_home = GPIO.input(self.inter_io)
time.sleep(1)
-TP-link 路由器连接检查模块代码,这部分使用selenium来帮我们获取需要的连接信息(主要是懒得去破解路由器登录的时候密码的加密算法,如果破解了的话,可以省去一个运行浏览器的负载。)好了上代码:
from selenium import webdriver
import os
import time
class TP_Link:
def __init__(self): #chromedriver初始设置
self.chromedriver='/usr/bin/chromedriver'
os.environ["webdriver.chrome.driver"] = self.chromedriver
self.browser = webdriver.Chrome(self.chromedriver,)
self.phone_name = ['vivo-X20A','Honor_Magi'] #存放认证的用户成员
self.is_some_body_in_home = 0
self.user = ''
def login(self):
self.browser.get('http://192.168.1.1') # 注意填写自己路由器的网关地址
try:
login_btn = self.browser.find_element_by_id('btnfunc') # 检测登录按钮是否存在,不存在则无须登录
input_class = self.browser.find_element_by_id('lgPwd')
input_class.send_keys('******') # 这里填写自己路由器的登录密码
login_btn.click()
except:
print('已经登录')
def get_user_str_in_wlan(self):
try:
name_list = self.browser.find_elements_by_class_name('bEptList') #获取列表信息
name_str = name_list[0].text
except:
self.login()
time.sleep(3)
try:
name_list = self.browser.find_elements_by_class_name('bEptList')
name_str = name_list[0].text
except:
print('路由器出错')
name_str = 'link_err'
return name_str
def is_user_in_home(self, name_str):
if name_str == 'link_err':
return name_str
if self.phone_name[0] in name_str or self.phone_name[1] in name_str:
self.is_some_body_in_home = 1
if self.phone_name[1] in name_str :
self.user = '孟令严'
elif self.phone_name[0] in name_str:
self.user = '武全'
return True
else:
self.is_some_body_in_home = 0
self.user = ''
return False
def main (self):
while True:
name_str = self.get_user_str_in_wlan()
self.is_user_in_home(name_str)
time.sleep(5)
- ok现在就可以编写manager.py了
from HC_SR501 import RS_501 # 红外模块
from TPlink import TP_Link # 路由器模块
import threading
import time
# 主要目的是开启两个线程实时检测两个模块的状态,状态信息都可以从Home_Manager实例中获取到。
class Home_Manager:
def __init__(self):
self.is_some_body_in_home = 0
self.TP_link = TP_Link()
self.rs_501 = RS_501()
def RS_501_thread (self):
t = threading.Thread(name='rs_501', target=self.rs_501.get_gpio_data, daemon=True)
t.start()
def TP_link_thread(self):
t = threading.Thread(name='TP_link', target=self.TP_link.main, daemon=True)
t.start()
- ok了,现在在智能语音模块中只要写一下,判断人出门后把屏幕,音乐播放器关闭,回来的时候,报告屋内气温湿度情况,有能力地华可以把灯光窗帘,电器连接进来,实现一个友好的智能化的家居系统。下一步计划是根据检测到的主人,个性化的安排舒适的设置,打开对应的日程计划提醒。
后话:
现在感觉智能化家居,各大厂都在做,但大家都是自己玩自己,扩展信没有,不开放协议,大多由手机app直接管理,将真心的,希望能有人牵个头,搞一个标准的协议标准,可能对于大厂来说影响他们的利益,但是这个东西早晚都是要流行下来的。齐心协力才能更好的发展起来,把大家开发者的创意集中起来,用户安自己的需求自己搭积木,这样才更为个性化通用化。