一、系统结构demo
系统结构大致分为3部分:原始信息提取、建模信息提取、建模与修复。
原始信息提取通过Home Assistant集成提取Rule和Device相关信息。
建模信息提取对原始信息做进一步的处理。
建模与修复,用建模信息进行建模并应用修复算法。
二、原始信息提取
2.1 Home Assistant 集成
configflow.py管前端配置,__ init __.py注册栏以及HAView。HAView根据request.type调用相应的处理函数,并将结果转为json显示到前端。安排一个前端文件夹,用VUE编写前端界面。
2.2 Rule相关信息提取
Rules Set从automation.yaml中提取。
从Rules Set提取出 trigger和action的映射 以及 规则的语义和配置。
2.3 Device相关信息提取
Device、Device Info去core\config.storage\core.entity_registry文件里找。
Area去core\config.storage\core.area_registry文件里找。
例如,小米WIFI开关的indicator_light capability如下:
{
"area_id": null,
"capabilities": {
"supported_color_modes": [
"onoff"
]
},
"config_entry_id": "5e12af8b8041a2f935651f18db778a8e",
"device_class": null,
"device_id": "4bc0125d618128c6354d1f2ecbd8b085",
"disabled_by": null,
"entity_category": null,
"entity_id": "light.chuangmi_212a01_b208_indicator_light",
"hidden_by": null,
"icon": null,
"id": "cc63787734841020988d349e81cd65af",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "Xiaomi Miot Indicator Light",
"platform": "xiaomi_miot",
"supported_features": 0,
"unique_id": "54:48:e6:7c:b2:08-3",
"unit_of_measurement": null
}
三、建模信息提取
3.1 Property Selection
有些类型的缺陷不好用property来描述,比如A.1更偏向于一种模板而不是具体的描述。Property来源于之前的文章:AutoTap、Cross-APP、TAPInspector、之前我列举的一些例子。根据Device,选出与现有设备相关的Property。
3.2 Device Selection
根据property,从property中获取建模需要的原始Device。
选出原始Device相关的TAP规则,从中获取与原始设备相关的其它设备。选出的设备以及它们对应的TAP规则作为建模输入的一部分。
这种方法的问题是:待检测的TAP规则本身可能有缺陷,不一定能选中(之前有讨论过)。
3.3 Unsafe State生成
Unsafe State大致分为两类:单状态、双状态。对第一类Unsafe的判定需要判断单个状态。对第二类Unsafe的判定需要判断两个状态。根据property,生成对应的Unsafe State。
可能还要提取导致unsafe的潜在event 、 对应的safe state。
unsafe state的阻碍是F和->,但可以用双状态解决
泛化学术化一下该部分,unsafe state不断缩小
3.3.1 第一类: 单状态
immediate的:
The [window] should always be closed when [weather] is raining对应的Unsafe State:
extend的:
The fan should’t be interrupted when working under the alarm state对应的Unsafe State:
3.3.2 第二类: 双状态
A.1
非loop Trigger-Interference中的短时间内切换:
loop型 Trigger-Interference中的短时间内切换:
四、建模与修复
4.1 建模
随机变化的自然条件必须维持两回合,用于与A.1区别
使用Device、相应的TAP规则、延时进行常规建模。加入单点、A.1的新特性。加入修复方法。
一句话概括refine:对于修复rule要在bridge处触发而不在其它地方误触,现有rule不在bridge处触发而在其它地方触发,这就要求修复rule的trigger比AP弱,越弱越会走到bridge处,同时要修复rule的trigger event和现有rule的trigger event冲突,一种可行的方法是narrow现有rule的trigger event。同时,修复rule的action也有自己的方法。
4.2 修复
之前的修复是建模后,根据模型的反例路径生成修复措。
现在是将修复和建模同时进行,模型的反例路径就包含修复措施。
如何获取修复措施? G(flag=1 -> !F(冲突解决 / 直到达到safe state))
可以看反例中的config_flow值 如果有反例说明修复成功。没有说明修复失败。
4.2.1 如何识别缺陷?使用Unsafe State
Unsafe State用于解决如何识别缺陷的问题。
第一类对应的识别语法为(next(相关属性) = 相关值)。
next(flag_onestate):=
case
-- unsafe对应的相关属性
next(attribute1)=1 & next(change_attribute)=1: 1;
-- TRUE: 0
TRUE:0;
esac;
第二类对应的识别语法为(flag_open和flag_close,若当前状态满足trigger则相应置为1,如果flag_open=flag_close,说明下一状态存在A.1)。
next(window.switch):=
case
next(flag_open)=1 & next(flag_close)=1:uncertain;
esac;
next(flag_open):=
case
humidity > 60: 1;
TRUE:0;
esac;
next(flag_close):=
case
temperature < 20: 1;
TRUE:0;
esac;
第三类对应的识别语法为连续两个state出现属性变化且不同值(loop / 开了马上关)。
4.2.2 变化哪些对象?Action、规则配置、规则语义
trigger根据当前状态的属性值决定了本次的action,action改变下一状态的属性值
变化action(偏向AutoTap);变化当前状态的某些属性值 = 变化trigger的配置;变化trigger的语义(后两者偏向于修改现有规则,而不是AutoTap新增规则)。
4.2.3 变化Action(偏向AutoTap)
如果下一状态unsafe,flag使copy类型的变量生效,用copy去变化,使其safe。查trigger action映射表,变化action,自然状态不变,其它变为非。
init(change_attribute_copy):= 0;
next(change_attribute_copy):=
case
-- 变化为非
next(flag_onesate)=1:0;
-- 安全的情况下让其等于原属性
TRUE:next(change_attribute);
esac;
4.2.4 变化规则配置——只改变规则配置解决Trigger-Interference中的loop
规则1: when illuminance < 100 , turn on light
规则2: when illuminace > 500 , turn off light
只会在illuminace < 100时出现缺陷
正常的修复方式:
100 + turn on light(可能实际是500但误判为300,是错在这) + 400 - light预期值300
可能smv 581就算修复好了,如何获得600、700
1.将常量配置信息light > 500改为变量light > config_value,其初始值为配置值
2.往大于500的值变化,因为light > 500
3.config_value:
flag:变化
TRUE:不变
4.2.5 变化规则语义——只改变语义解决A.1
if 8:00 am while Temperature < 20℃ , close window
if 8:00 am while humidity > 60% , open window
正常的修复方式:
生成新规则 if 8:00 am while Temperature < 20℃ and humidity > 60% ,让用户选择open、close window
改变老规则,调整为 Temperature < 20℃ & humidity < 60%;humidity > 60% & Temperature > 20℃
可能的方式:
因为trigger在建模前要写入文件,且不能像配置随意变化,所以考虑提前准备语义模板
如该例中,温度和湿度的模板
temperature_copy在flag时生效,用于修复,原属性代表实际环境
4.2.6
容易变为不trigger就没问题
if sunset,要不要用原方法
五、实验代码
实验一
MODULE main
VAR
attribute1:0..1;
change_attribute:0..1;
change_attribute_copy:0..1;
another_trigger:{on, off};
flag_onesate:0..1;
ASSIGN
init(attribute1):= 0;
-- 模拟不可变的自然现象
next(attribute1):= 1;
init(another_trigger):= on;
init(change_attribute):= 0;
next(change_attribute):=
case
another_trigger = off:1;
another_trigger = on:0;
TRUE:change_attribute;
esac;
init(change_attribute_copy):= 0;
next(change_attribute_copy):=
case
-- 变化为非
next(flag_onesate)=1:0;
-- 安全的情况下让其等于原属性
TRUE:next(change_attribute);
esac;
init(flag_onesate):= 0;
next(flag_onesate):=
case
-- unsafe对应的相关属性
next(attribute1)=1 & next(change_attribute)=1: 1;
-- TRUE: 0
TRUE:0;
esac;
实验二
MODULE main
VAR
window.switch:{open, close, uncertain};
window.switch_old:{open, close, uncertain};
temperature:0..10;
humidity:10..20;
flag_open:0..1;
flag_close:0..1;
ASSIGN
init(temperature) := 5;
init(humidity) := 10;
init(window.switch) := close;
next(window.switch):=
case
next(flag_open)=1 & next(flag_close)=1:uncertain;
temperature < 5: close;
TRUE:window.switch;
esac union
case
next(flag_open)=1 & next(flag_close)=1:uncertain;
humidity > 15: open;
TRUE:window.switch;
esac;
init(window.switch_old) := close;
next(window.switch_old) := window.switch;
init(flag_open) := 0;
next(flag_open):=
case
humidity > 15: 1;
TRUE:0;
esac;
init(flag_close) := 0;
next(flag_close):=
case
temperature < 5: 1;
TRUE:0;
esac;