物联网联动策略表结构设计
1、需求
实现温湿度传感器联动,当某个温度传感器或者某几个温度传感器 满足温度高于某个值时 空调状态开启、模式制冷、温度26、风速低,当温度低于某个值空调关闭。
实现门禁联动,当某个门禁或者某几个门禁 开时,空调空调状态开启、模式制冷、温度26、风速低,罗普开关开启,时控开关开启。由于门禁人进门后就关了,无法实现无人设备关闭的需求。另外如果人频繁进入该房间,会造成多次触发,我们可以加个生效时长,第一个人进入房间触发后,该时长内只触发一次。
2、设计思路
(1)肯定需要一张策略主表
CREATE TABLE `t_strategy_linkage` (`id` bigint(11) NOT NULL AUTO_INCREMENT,`strategy_name` varchar(255) NOT NULL COMMENT '策略名称',`linkage_type` int(11) DEFAULT NULL COMMENT '联动类型(1传感器联动 2门禁联动)',`delay_seconds` int(11) DEFAULT NULL COMMENT '延迟时间',`start_time` time DEFAULT NULL COMMENT '开始时间',`end_time` time DEFAULT NULL COMMENT '结束时间',`execute_flag` int(11) NOT NULL COMMENT '是否已执行标志(防重复)0未执行 1已执行低于最低温度 2已执行高于最高温度',`debounce_minutes` int(11) DEFAULT NULL COMMENT '防抖时长(分钟,门禁联动用)',`status` char(1) DEFAULT NULL COMMENT '状态0正常 1停用',`create_time` datetime DEFAULT NULL COMMENT '创建时间',`update_time` datetime DEFAULT NULL COMMENT '修改时间',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
(2)需要一张触发设备表,存放该条策略需要有哪些设备触发,因为可能会有 多个温度传感器都高于某个值时才开启空调 这样的需求,因此一个策略对应多个触发设备
CREATE TABLE `t_strategy_linkage_trigger_device` (`strategy_id` bigint(20) NOT NULL COMMENT '策略id',`device_number` varchar(255) NOT NULL COMMENT '触发设备编号'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
(3)联动规则表,因为一个策略中,对于温度传感器,可能有多个规则,如温度高于某个值触发,温度低于某个值触发,湿度高于或者低于某个值触发等等,对于门禁,目前只有一个规则,就是门禁开触发,因次一个策略对应多个规则,存储策略id、触发条件、动作
CREATE TABLE `t_strategy_linkage_rule` (`strategy_id` bigint(20) NOT NULL COMMENT '策略id',`trigger_condition` varchar(255) NOT NULL COMMENT '触发条件',`action` varchar(255) NOT NULL COMMENT '执行动作'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
(4)联动目标设备表,因为联动可能触发多个目标设备,因次需要一张表存放策略id、目标设备编号
CREATE TABLE `t_strategy_linkage_target_device` (`strategy_id` bigint(20) NOT NULL COMMENT '策略id',`device_number` varchar(255) NOT NULL COMMENT '被控设备编号'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
3、思考
以上表结构满足需求吗?
对于传感器来说,比如,当多个传感器触发温度大于30度时,空调1、空调2、...、空调10 动作开启、温度26、模式制冷、风速高,那么后端逻辑就是,传感器每3分钟上报一次,每上报一次,去触发设备表中查询该设备编号关联的策略,判断时间、是否执行,若都满足,则查询该策略关联的所有传感器,然后查询规则表,若均满足触发条件,则去目标设备表中查询所有该策略关联的目标设备编号,执行动作,这样看来,能满足传感器的需求。
对于门禁来说,如门禁1开,要实现空调1、空调2、...、空调10 动作开启、温度26、模式制冷、风速高,罗普1~10开,时控开关1~10开等,目标设备类型可能有很多,每种设备类型的动作可能不一样,如果不区分,会变成如下表数据
t_strategy_linkage_rule
stragety_id | trigger_condition | action |
1 | 门禁1开 | 开启、温度26、模式制冷、风速高 |
1 | 门禁1开 | 开 |
1 | 门禁1开 | 开 |
t_strategy_linkage_target_device
stragety_id | device_number |
1 | 空调1 |
1 | 空调2 |
1 | 空调3........... |
1 | 罗普1..... |
t_strategy_linkage_rule t3 INNER JOIN t_strategy_linkage_target_device t4 ON t3.strategy_id = t4.strategy_id会出现门禁开--罗普开启、温度26、模式制冷、风速高,这肯定不对,因此要加目标设备类型字段。
CREATE TABLE `t_strategy_linkage_rule` (`strategy_id` bigint(20) NOT NULL COMMENT '策略id',`target_device_type_no` varchar(20) NOT NULL COMMENT '目标设备类型',`trigger_condition` varchar(255) NOT NULL COMMENT '触发条件',`action` varchar(255) NOT NULL COMMENT '执行动作'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE `t_strategy_linkage_target_device` (`strategy_id` bigint(20) NOT NULL COMMENT '策略id',`device_type_no` varchar(50) NOT NULL COMMENT '设备编号大类',`device_number` varchar(255) NOT NULL COMMENT '被控设备编号'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
加上之后门禁表数据示例如下:
t_strategy_linkage_rule
stragety_id | target_device_type_no | trigger_condition | action |
1 | 2 | 门禁1开 | 开启、温度26、模式制冷、风速高 |
1 | 23 | 门禁1开 | 开 |
1 | 38 | 门禁1开 | 开 |
t_strategy_linkage_target_device
stragety_id | device_type_no | device_number |
1 | 2 | 空调1 |
1 | 2 | 空调2 |
1 | 2 | 空调3........... |
1 | 23 | 罗普1..... |
t_strategy_linkage_rule t3 INNER JOIN t_strategy_linkage_target_device t4 ON t3.strategy_id = t4.strategy_id AND t3.target_device_type_no = t4.device_type_no就没问题了。
4、优化
其实t_strategy_linkage_rule表是一个策略对应多个触发规则,一条规则有策略id、触发条件、目标设备类型、执行动作,而一个规则对应多个目标设备,因此t_strategy_linkage_target_device存放规则表id、目标设备编号即可。且上面方案有个缺点,比如 改一下需求,要实现温度传感器,温度高于30度时空调1~10 开启,温度低于20度时空调1~5关闭 空调6~10保持不变,如下,
t_strategy_linkage_rule
stragety_id | target_device_type_no | trigger_condition | action |
1 | 2 | 温度高于30度 | 开启、温度26、模式制冷、风速高 |
1 | 2 | 温度低于20度 | 关闭 |
t_strategy_linkage_target_device
stragety_id | device_type_no | device_number |
1 | 2 | 空调1... |
1 | 2 | 空调10 |
1 | 2 | 空调1... |
1 | 2 | 空调5 |
INNER JOIN之后变成空调1~10温度>30 开启、温度26、模式制冷、风速高,温度<20 关闭;空调1~5温度>30 开启、温度26、模式制冷、风速高,温度<20 关闭,不满足需求,问题出在同一种设备类型区分不了触发条件和动作。
但是用优化过后的方案,表数据就变成,
t_strategy_linkage_rule
rule_id | stragety_id | trigger_condition | action |
1 | 1 | 温度高于30度 | 开启、温度26、模式制冷、风速高 |
2 | 1 | 温度低于20度 | 关闭 |
t_strategy_linkage_target_device
rule_id | device_number |
1 | 空调1... |
1 | 空调10 |
2 | 空调1... |
2 | 空调5 |
通过rule_id关联,即使同一种设备类型,也可以找到对应的触发条件和动作。