前言
冬天到了,早上醒来懒得出被窝,但是为了大家,我还是抵抗住了寒冷,冒着生命危险给大家准备了这一期的文章,就冲这一点值不值得你们给我一个赞o(´^`)o,当然,这么久了,知道你们不见货是不会点赞的,那我还是先干为敬,你们随意。
之前做了这么多铺垫,现在终于到了收束的时刻!这一定是石头门的选择!在之前的文章里我分别完成了光照传感器,远程灯控开关,人体存在传感器,远程空调遥控器。今天所有的细线已经串成了一条,计划至此进入最终阶段!今天将带大家完成我们的自动化房屋能源控制核心!
我这边的话也已经把我家里的一个房间改造了一下,效果还是不错的。可以根据房间人员检测自动进行控制空调和灯光。当然,冬天了,可能很多人睡觉都不愿意下床去开关灯或者空调啥的,这里应用也提供了手动模式进行控制灯光和空调的功能,让你在被窝里玩手机也可以控制。
设备讲解
涉及到的场景设备之前也已经介绍过了,这里就不再过多介绍,直接给大家放传送门:
应用讲解
天太冷了,敲着手疼,这里就简短介绍一下。
实现这个场景的目的主要是为了减少一下家里的用电(毕竟家里有好几个空调和大灯)
感兴趣的朋友可以前往:灵感桌面的秘密宝库 下载代码。
或者直接 git clone:
https://gitee.com/inspiration...
应用的实现思路大致就是以下逻辑了:
首先光照传感器会定时去获取最新实时数据,接着当人体感应器检测到人体变化时会进行逻辑处理,如果在控制时间段内,这时候房间内没人了,会去开启关闭空调和灯光的定时器。在定时器时间段内,如果房间再次出现人,则移除定时器处理(因为可能有人去上了个厕所就回来了)。否则在定时器触发时候,房间依然没有人,这时候会先去关掉空调,然后再去比对光照传感器数据,检测当前室内灯是否开启,如果开启,则回去关掉房间内的所有灯设备。
注意:这里需要利用光照传感器,因为我这边的灯光控制设备无法保存状态,所以需要对比光照,同时我这边的灯光控制生效时间一般设置的是晚上的时候,所以说还是有点瑕疵的。
代码分析
由于这个场景比较综合复杂,在写代码时候有很多需要注意的点。这里就简单的讲一下代码。
和之前的一系列一样,用的是JSRE
的一个Device
模块,主要用来去获取设备传递给爱智的信息,同时也是应用通过爱智向设备发送指令的途径。
首先这边光照和温度传感器的数据不是主动上报的,而是把这部分的逻辑让爱智应用去分担,这样我的设备就可以更加轻便,所以我这边应用后端添加了定时器去定时获取最新的数据状态。
...
switch (type) {
case 'illu-sensor':
// 光照
times[devid] = setInterval(() => {
devManager.sendDeviceInfo(devid, { method: 'get', obj: ['illu'] });
}, 5 * 1000);
break;
case 'temp-sensor':
times[devid] = setInterval(() => {
devManager.sendDeviceInfo(devid, { method: 'get', obj: ['temp'] });
}, 30 * 60 * 1000);
break;
default:
break;
}
...
而这边获取到数据之后,就会对数据进行相应的处理,由于代码量比较大,所以处理的代码这边就简单讲一下;
在获取到光照和温度的值后,将数据同步到前端,同时保存日志;
主要逻辑是当检测到人体感应变化时候,会去对空调和灯光进行控制,这里需要进行控制时间段的处理和延迟响应处理。
...
value = data.data['micro_state'] === 'ON';
// 状态存入日志中
if (data.method === 'report') {
saveLog(room_id, 'operation', `房间【${room.name}】中检测${value ? '有' : '没'}人!`);
}
// 控制空调和灯光
if (value) {
clearTimeout(roomTimes[`ac-${room_id}`]);
clearTimeout(roomTimes[`light-${room_id}`]);
roomTimes[`ac-${room_id}`] = undefined;
roomTimes[`light-${room_id}`] = undefined;
} else {
if (dev && roomTimes[`ac-${room_id}`] === undefined && roomTimes[`light-${room_id}`] === undefined) {
const date = new Date();
const curTimeMinute = date.getHours() * 60 + date.getMinutes();
const {devids,settings: { ac_cp, light_cp }} = room;
const ac_devids = []; // 房间内在线的空调设备
const light_devids = []; // 房间内在线的灯设备
devids.map((item) => {
const d = devManager.devMap.get(item);
if (d) {
const type = getDeviceType(d);
if (type === 'ac-control') {
ac_devids.push(item);
} else if (type === 'light-control') {
light_devids.push(item);
}
}
});
if (ac_devids.length) {
const ac_start_times = ac_cp[0].split(':');
const ac_end_times = ac_cp[1].split(':');
const ac_start_time_minute = Number(ac_start_times[0]) * 60 + Number(ac_start_times[1]);
const ac_end_time_minute = Number(ac_end_times[0]) * 60 + Number(ac_end_times[1]);
if (ac_start_time_minute <= ac_end_time_minute) {
// 如果开始时间小于等于结束时间,说明没有跨越次日零点
// 取开始时间-结束时间之间
if (curTimeMinute >= ac_start_time_minute && curTimeMinute < ac_end_time_minute) {
// 在空调控制时间内
// 关闭空调
// 添加定时器延时
roomTimes[`ac-${room_id}`] = setTimeout(() => {
ac_devids.forEach((id) => {
devManager.sendDeviceInfo(id, { method: 'set', ac: 'OFF' });
});
// saveLog(room_id, 'operation', `房间【${room.name}】空调被关掉了!`);
}, 30 * 1000);
}
} else {
// 如果开始时间大于结束时间,说明跨越了次日零点
// 去开始时间-23:59 和 00:00-结束时间
if (curTimeMinute > ac_start_time_minute || curTimeMinute < ac_end_time_minute) {
// 在空调控制时间内
// 关闭空调
// 添加定时器延时
roomTimes[`ac-${room_id}`] = setTimeout(() => {
ac_devids.forEach((id) => {
devManager.sendDeviceInfo(id, { method: 'set', ac: 'OFF' });
});
// saveLog(room_id, 'operation', `房间【${room.name}】空调被关掉了!`);
}, 30 * 1000);
}
}
}
if (light_devids.length) {
const light_start_times = light_cp[0].split(':');
const light_end_times = light_cp[1].split(':');
const light_start_time_minute = Number(light_start_times[0]) * 60 + Number(light_start_times[1]);
const light_end_time_minute = Number(light_end_times[0]) * 60 + Number(light_end_times[1]);
if (light_start_time_minute <= light_end_time_minute) {
// 如果开始时间小于等于结束时间,说明没有跨越次日零点
// 取开始时间-结束时间之间
if (curTimeMinute >= light_start_time_minute && curTimeMinute < light_end_time_minute) {
// 在灯控制时间内
// 关闭灯
// 添加定时器延时
roomTimes[`light-${room_id}`] = setTimeout(() => {
if (roomRealValue[room_id] &&
roomRealValue[room_id]['illu'] &&
roomRealValue[room_id]['illu'] > 30
) {
// 光照强度 > 30 判定为开灯状态
light_devids.forEach((id) => {
devManager.sendDeviceInfo(id, { method: 'set', SW_ctrl: 'OFF' });
});
// 保存操作日志
saveLog(room_id, 'operation', `房间【${room.name}】灯被关掉了!`, 'success');
}
}, 30 * 1000);
}
} else {
// 如果开始时间大于结束时间,说明跨越了次日零点
// 去开始时间-23:59 和 00:00-结束时间
if (curTimeMinute > light_start_time_minute || curTimeMinute < light_end_time_minute) {
// 在灯控制时间内
// 关闭灯
// 添加定时器延时
roomTimes[`light-${room_id}`] = setTimeout(() => {
if (roomRealValue[room_id] &&
roomRealValue[room_id]['illu'] &&
roomRealValue[room_id]['illu'] > 30
) {
// 光照强度 > 30 判定为开灯状态
light_devids.forEach((id) => {
devManager.sendDeviceInfo(id, { method: 'set', SW_ctrl: 'OFF' });
});
// 保存操作日志
saveLog(room_id, 'operation', `房间【${room.name}】灯被关掉了!`, 'success');
}
}, 30 * 1000);
}
}
}
}
}
...
场景演示
这里的话不太方便给大家演示现场,直接给大家看一下实现的应用的场景吧。
总结
今天把之前的所有设备给整合到一起了,效果还是不错的。简直是我这种经常忘记关家电的笨蛋,不想起床关灯和空调的懒鬼,但是又舍不得电费的穷鬼的救星,哈哈哈哈。
我的手已经失去知觉了,太冷了,幸好本人养了俩只猫,冬天到了,刚好可以当暖手宝︿( ̄︶ ̄)︿,今天就到这就草草结束吧,我去选个暖手宝暖暖手。
本文仅个人学习使用,如有错误,欢迎指正, ( ੭ ˙ᗜ˙ )੭谢谢老板!