Files
llmiotsafe/DPODataGen/scenario_bank.py
2026-05-12 17:01:39 +08:00

1075 lines
55 KiB
Python

from __future__ import annotations
from copy import deepcopy
from typing import Dict, List
def attr(time: str, device: str, cluster: str, attribute: str, value, note: str | None = None) -> Dict:
item = {
"time": time,
"device": device,
"cluster": cluster,
"attribute": attribute,
"value": value,
}
if note:
item["note"] = note
return item
def evt(time: str, device: str, event_name: str, fields: Dict | None = None, note: str | None = None) -> Dict:
item = {
"time": time,
"device": device,
"event_name": event_name,
"fields": fields or {},
}
if note:
item["note"] = note
return item
def scenario(
scenario_id: str,
*,
name: str,
category: str,
threat_type: str,
room_selector: str,
query_families: List[str],
anomaly_events: List[Dict],
fp_events: List[Dict],
fp_key_difference: str,
key_evidence: List[str],
expected_response: str,
applicable_layouts: List[str],
applicable_profiles: List[str] | None = None,
difficulty_level: int = 2,
) -> Dict:
dims_by_level = {
1: {
"D1_evidence_count": 1,
"D2_signal_directness": 1,
"D3_cross_device": 1,
"D4_temporal_span": 1,
"D5_fp_similarity": 1,
},
2: {
"D1_evidence_count": 2,
"D2_signal_directness": 2,
"D3_cross_device": 2,
"D4_temporal_span": 2,
"D5_fp_similarity": 2,
},
3: {
"D1_evidence_count": 3,
"D2_signal_directness": 3,
"D3_cross_device": 3,
"D4_temporal_span": 3,
"D5_fp_similarity": 3,
},
}
score_by_level = {1: 6, 2: 9, 3: 12}
return {
"scenario_id": scenario_id,
"name": name,
"category": category,
"threat_type": threat_type,
"room_selector": room_selector,
"query_families": query_families,
"anomaly_events": anomaly_events,
"false_positive_variant": {
"events": fp_events,
"key_difference": fp_key_difference,
},
"ground_truth": {
"is_anomaly": True,
"threat_type": threat_type,
"key_evidence": key_evidence,
"expected_response": expected_response,
"difficulty_score": score_by_level[difficulty_level],
"difficulty_level": difficulty_level,
"difficulty_label": f"L{difficulty_level}",
"difficulty_dimensions": dims_by_level[difficulty_level],
},
"applicable_layouts": applicable_layouts,
"applicable_profiles": applicable_profiles,
}
SCENARIOS: Dict[str, Dict] = {
"T-INS-01": scenario(
"T-INS-01",
name="临时访客码在非预约时段使用",
category="intrusion",
threat_type="credential_theft",
room_selector="entrance",
query_families=["sq2", "sq3", "sq5"],
anomaly_events=[
attr("Day1 02:11", "front_door_lock", "DoorLock", "LockState", 2, "凌晨异常解锁"),
attr("Day1 02:11", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day1 02:12", "entrance_light", "OnOff", "OnOff", True),
attr("Day1 02:13", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_events=[
attr("Day1 14:05", "front_door_lock", "DoorLock", "LockState", 2, "预约访客白天进门"),
attr("Day1 14:05", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day1 14:06", "entrance_light", "OnOff", "OnOff", True),
attr("Day1 14:07", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_key_difference="白天按预约时段进入,后续室内活动连续,符合正常访客到访。",
key_evidence=["凌晨 02:11 门锁解锁并开门", "玄关灯随后开启", "紧接着出现室内活动,不像误触"],
expected_response="标记为异常入户,建议检查临时访客码使用记录并立即重置。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=2,
),
"T-INS-02": scenario(
"T-INS-02",
name="连续多天同一时段出现陌生运动模式",
category="intrusion",
threat_type="intrusion",
room_selector="living_area",
query_families=["sq3"],
anomaly_events=[
attr("Day1 03:14", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day2 03:14", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day3 03:14", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day3 03:15", "kitchen_light", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 06:35", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day2 06:48", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day3 06:41", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day3 06:42", "kitchen_light", "OnOff", "OnOff", True),
],
fp_key_difference="触发时间位于清晨起床窗口且有轻微抖动,不是固定的可疑重复模式。",
key_evidence=["连续 3 天都在 03:14 出现客厅运动", "时间点高度一致", "第 3 天继续延伸到厨房活动"],
expected_response="标记为重复异常夜间活动,建议排查入侵或异常访客。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=3,
),
"T-INS-03": scenario(
"T-INS-03",
name="门锁解锁后无对应入口触发",
category="intrusion",
threat_type="intrusion",
room_selector="entrance",
query_families=["sq2", "sq3"],
anomaly_events=[
attr("Day1 01:22", "front_door_lock", "DoorLock", "LockState", 2),
attr("Day1 01:24", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 01:26", "kitchen_light", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 18:40", "front_door_lock", "DoorLock", "LockState", 2),
attr("Day1 18:41", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day1 18:42", "entrance_light", "OnOff", "OnOff", True),
attr("Day1 18:43", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_key_difference="正常入户会伴随门磁、玄关灯或入口相关活动;异常样本只有解锁结果和室内后续活动。",
key_evidence=["门锁状态切到 Unlocked", "未见对应的前门接触事件", "数分钟后却出现室内活动"],
expected_response="判定为可疑解锁链路,建议核查远程解锁或锁日志完整性。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=3,
),
"T-INS-04": scenario(
"T-INS-04",
name="阳台门深夜打开且室内无对应活动",
category="intrusion",
threat_type="intrusion",
room_selector="balcony",
query_families=["sq2", "sq3"],
anomaly_events=[
attr("Day1 02:07", "balcony_door_contact", "BooleanState", "StateValue", False),
attr("Day1 02:08", "balcony_light", "OnOff", "OnOff", True),
attr("Day1 02:09", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_events=[
attr("Day1 17:20", "balcony_door_contact", "BooleanState", "StateValue", False),
attr("Day1 17:20", "balcony_light", "OnOff", "OnOff", True),
attr("Day1 17:21", "balcony_laundry_washer", "OperationalState", "OperationalState", 1),
],
fp_key_difference="正常样本是傍晚去阳台洗衣,伴随洗衣机启动;异常样本发生在深夜且后续转入室内活动。",
key_evidence=["深夜阳台门突然打开", "阳台灯随即被点亮", "随后出现客厅活动"],
expected_response="判定为高风险边界入侵,建议立即检查阳台出入口。",
applicable_layouts=["B", "C"],
difficulty_level=2,
),
"T-INS-05": scenario(
"T-INS-05",
name="多个窗户传感器短时依次触发",
category="intrusion",
threat_type="intrusion",
room_selector="contact_room_pair",
query_families=["sq2", "sq3"],
anomaly_events=[
attr("Day1 02:31", "living_room_window_contact", "BooleanState", "StateValue", False),
attr("Day1 02:32", "bedroom_window_contact", "BooleanState", "StateValue", False),
attr("Day1 02:34", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_events=[
attr("Day1 10:05", "living_room_window_contact", "BooleanState", "StateValue", False),
attr("Day1 10:06", "bedroom_window_contact", "BooleanState", "StateValue", False),
attr("Day1 10:07", "living_room_light_1", "OnOff", "OnOff", True),
],
fp_key_difference="白天集中通风可能连续开窗,但通常伴随正常居家活动;异常样本发生在夜间。",
key_evidence=["短时间内两个不同房间窗户先后打开", "触发时间位于深夜", "随后出现室内运动"],
expected_response="判定为扫描式入侵尝试,建议重点检查窗户和周边摄像头。",
applicable_layouts=["A", "D"],
difficulty_level=3,
),
"T-INS-06": scenario(
"T-INS-06",
name="远程解锁后室内活动延迟出现",
category="intrusion",
threat_type="credential_theft",
room_selector="entrance",
query_families=["sq2", "sq5"],
anomaly_events=[
attr("Day1 23:18", "front_door_lock", "DoorLock", "LockState", 2),
attr("Day1 23:24", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 23:25", "kitchen_light", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 20:02", "front_door_lock", "DoorLock", "LockState", 2),
attr("Day1 20:03", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day1 20:04", "entrance_light", "OnOff", "OnOff", True),
],
fp_key_difference="正常样本解锁后立即出现进门链路;异常样本解锁和室内活动之间存在不自然延迟。",
key_evidence=["先出现远程解锁结果", "几分钟后才有室内活动", "中间缺乏正常进门链路"],
expected_response="标记为可疑远程开锁事件,建议核查账户凭证与远程授权。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=3,
),
"T-INS-07": scenario(
"T-INS-07",
name="门锁状态变化但没有对应开门链路",
category="intrusion",
threat_type="intrusion",
room_selector="entrance",
query_families=["sq2"],
anomaly_events=[
attr("Day1 04:06", "front_door_lock", "DoorLock", "LockState", 2),
attr("Day1 04:07", "front_door_lock", "DoorLock", "LockState", 1),
attr("Day1 04:09", "living_room_light_1", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 08:02", "front_door_lock", "DoorLock", "LockState", 2),
attr("Day1 08:02", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day1 08:03", "front_door_lock", "DoorLock", "LockState", 1),
],
fp_key_difference="正常样本是短时取快递后重新上锁;异常样本缺少门磁与入口活动链路。",
key_evidence=["门锁状态先解锁再回锁", "缺乏门磁开关记录", "却伴随室内灯光变化"],
expected_response="判为异常门锁状态切换,建议核查锁日志与物理门状态。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=2,
),
"T-INS-08": scenario(
"T-INS-08",
name="出门后家中连续多天规律性运动",
category="intrusion",
threat_type="intrusion",
room_selector="living_area",
query_families=["sq3", "sq5"],
anomaly_events=[
attr("Day1 08:05", "front_door_lock", "DoorLock", "LockState", 1),
attr("Day1 13:00", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day2 13:00", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day3 13:00", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_events=[
attr("Day1 08:05", "front_door_lock", "DoorLock", "LockState", 1),
attr("Day1 18:10", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day2 17:55", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day3 18:20", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_key_difference="正常样本是每天傍晚回家时间略有波动;异常样本是在固定下午时点出现活动。",
key_evidence=["住户出门后仍在固定时间出现室内运动", "连续三天模式重复", "缺少对应回家链路"],
expected_response="判定为空置期间异常活动,建议按入侵事件处理。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=3,
),
"T-FG-01": scenario(
"T-FG-01",
name="多个房间温度同时异常上升",
category="fire_gas",
threat_type="fire_risk",
room_selector="living_area",
query_families=["sq2", "sq4", "sq5"],
anomaly_events=[
attr("Day1 18:02", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2840),
attr("Day1 18:04", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2810),
attr("Day1 18:06", "kitchen_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2960),
],
fp_events=[
attr("Day1 12:05", "kitchen_cook_surface", "OnOff", "OnOff", True),
attr("Day1 12:12", "kitchen_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2920),
attr("Day1 12:16", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2520),
],
fp_key_difference="正常样本只有厨房局部升温并伴随灶具开启;异常样本是多房间同步升温。",
key_evidence=["客厅和卧室温度同时异常上升", "厨房也同步升温", "不是单一热源可解释的局部变化"],
expected_response="按全屋热异常处理,建议检查火源或电器过热。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=2,
),
"T-FG-02": scenario(
"T-FG-02",
name="灶具关闭后温度仍持续上升",
category="fire_gas",
threat_type="fire_risk",
room_selector="kitchen",
query_families=["sq2", "sq4", "sq5"],
anomaly_events=[
attr("Day1 19:00", "kitchen_cook_surface", "OnOff", "OnOff", True),
attr("Day1 19:20", "kitchen_cook_surface", "OnOff", "OnOff", False),
attr("Day1 19:25", "kitchen_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 3050),
attr("Day1 19:35", "kitchen_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 3220),
],
fp_events=[
attr("Day1 19:00", "kitchen_cook_surface", "OnOff", "OnOff", True),
attr("Day1 19:20", "kitchen_cook_surface", "OnOff", "OnOff", False),
attr("Day1 19:25", "kitchen_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2860),
attr("Day1 19:35", "kitchen_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2740),
],
fp_key_difference="正常余热会逐步回落;异常样本在关火后温度继续上升。",
key_evidence=["灶具已关闭", "厨房温度没有回落反而继续升高", "升温趋势持续超过一个采样点"],
expected_response="判为异常余热/火源风险,建议立即复查灶具与周边热源。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=2,
),
"T-FG-03": scenario(
"T-FG-03",
name="烟雾报警器污染状态逐步恶化",
category="fire_gas",
threat_type="safety_device_failure",
room_selector="kitchen",
query_families=["sq2", "sq4"],
anomaly_events=[
attr("Day1 08:00", "kitchen_smoke_alarm", "SmokeCoAlarm", "ContaminationState", 1),
attr("Day2 08:00", "kitchen_smoke_alarm", "SmokeCoAlarm", "ContaminationState", 2),
attr("Day3 08:00", "kitchen_smoke_alarm", "SmokeCoAlarm", "ContaminationState", 3),
],
fp_events=[
attr("Day1 08:00", "kitchen_smoke_alarm", "SmokeCoAlarm", "TestInProgress", True),
attr("Day1 08:05", "kitchen_smoke_alarm", "SmokeCoAlarm", "TestInProgress", False),
attr("Day1 08:05", "kitchen_smoke_alarm", "SmokeCoAlarm", "ContaminationState", 0),
],
fp_key_difference="正常样本是短暂自检;异常样本是污染状态跨天单向恶化。",
key_evidence=["污染状态从正常逐步恶化", "跨多天持续出现", "会削弱烟雾报警可靠性"],
expected_response="判定为安全设备退化,建议尽快清洁或更换报警器。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=3,
),
"T-FG-04": scenario(
"T-FG-04",
name="CO 指标缓慢上升但未触发报警",
category="fire_gas",
threat_type="carbon_monoxide",
room_selector="kitchen",
query_families=["sq4", "sq5"],
anomaly_events=[
attr("Day1 21:00", "kitchen_smoke_alarm", "CarbonMonoxideConcentrationMeasurement", "MeasuredValue", 35),
attr("Day1 21:20", "kitchen_smoke_alarm", "CarbonMonoxideConcentrationMeasurement", "MeasuredValue", 48),
attr("Day1 21:40", "kitchen_smoke_alarm", "CarbonMonoxideConcentrationMeasurement", "MeasuredValue", 59),
],
fp_events=[
attr("Day1 12:00", "kitchen_cook_surface", "OnOff", "OnOff", True),
attr("Day1 12:10", "kitchen_smoke_alarm", "CarbonMonoxideConcentrationMeasurement", "MeasuredValue", 18),
attr("Day1 12:25", "kitchen_smoke_alarm", "CarbonMonoxideConcentrationMeasurement", "MeasuredValue", 10),
],
fp_key_difference="正常样本是短暂低幅波动并回落;异常样本是缓慢连续上升。",
key_evidence=["CO 数值持续单向上升", "没有快速回落", "虽然未到报警阈值但趋势危险"],
expected_response="判为潜在 CO 风险,建议通风并检查燃气与排烟。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=3,
),
"T-FG-05": scenario(
"T-FG-05",
name="电器运行时间异常长",
category="fire_gas",
threat_type="fire_risk",
room_selector="kitchen",
query_families=["sq2", "sq4"],
anomaly_events=[
attr("Day1 14:00", "kitchen_dishwasher", "OperationalState", "OperationalState", 1),
attr("Day1 15:00", "kitchen_dishwasher", "OperationalState", "CountdownTime", 5400),
attr("Day1 17:05", "kitchen_dishwasher", "OperationalState", "CountdownTime", 5200),
],
fp_events=[
attr("Day1 14:00", "kitchen_dishwasher", "OperationalState", "OperationalState", 1),
attr("Day1 14:30", "kitchen_dishwasher", "OperationalState", "CountdownTime", 1800),
attr("Day1 14:55", "kitchen_dishwasher", "OperationalState", "OperationalState", 0),
],
fp_key_difference="正常样本倒计时持续减少并按时停止;异常样本长时间运行且倒计时几乎不变。",
key_evidence=["设备持续运行超过常规时长", "倒计时未按预期减少", "存在过热或故障风险"],
expected_response="标记为设备异常长运行,建议停机检查。",
applicable_layouts=["A", "B", "C"],
difficulty_level=2,
),
"T-FG-06": scenario(
"T-FG-06",
name="多个烟雾报警器互联触发",
category="fire_gas",
threat_type="fire_risk",
room_selector="living_area",
query_families=["sq2", "sq4", "sq5"],
anomaly_events=[
attr("Day1 03:16", "kitchen_smoke_alarm", "SmokeCoAlarm", "SmokeState", 1),
attr("Day1 03:16", "living_room_smoke_alarm", "SmokeCoAlarm", "InterconnectSmokeAlarm", 1),
attr("Day1 03:17", "living_room_smoke_alarm", "SmokeCoAlarm", "ExpressedState", 1),
],
fp_events=[
attr("Day1 10:00", "kitchen_smoke_alarm", "SmokeCoAlarm", "TestInProgress", True),
attr("Day1 10:01", "living_room_smoke_alarm", "SmokeCoAlarm", "TestInProgress", True),
attr("Day1 10:04", "kitchen_smoke_alarm", "SmokeCoAlarm", "TestInProgress", False),
],
fp_key_difference="正常样本是多设备同步自检;异常样本是真实烟雾和互联联动。",
key_evidence=["厨房烟雾状态异常", "客厅互联烟雾告警被带起", "表达状态同步异常"],
expected_response="按多点烟雾告警处理,建议立刻排查火情并疏散。",
applicable_layouts=["C", "D"],
difficulty_level=2,
),
"T-WD-01": scenario(
"T-WD-01",
name="漏水传感器间歇性触发",
category="water_damage",
threat_type="water_leak",
room_selector="bathroom",
query_families=["sq2", "sq5"],
anomaly_events=[
attr("Day1 07:10", "bathroom_water_leak", "BooleanState", "StateValue", True),
attr("Day1 12:25", "bathroom_water_leak", "BooleanState", "StateValue", True),
attr("Day1 18:40", "bathroom_water_leak", "BooleanState", "StateValue", True),
],
fp_events=[
attr("Day1 07:10", "bathroom_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 07:12", "bathroom_water_leak", "BooleanState", "StateValue", True),
attr("Day1 07:18", "bathroom_water_leak", "BooleanState", "StateValue", False),
],
fp_key_difference="正常样本有明确使用上下文且很快恢复;异常样本在多时段重复触发。",
key_evidence=["同一传感器多次间歇性报漏水", "触发分散在不同时间段", "不像一次性溅水误报"],
expected_response="标记为隐蔽性漏水,建议检查管道和地漏。",
applicable_layouts=["A", "B", "D"],
difficulty_level=2,
),
"T-WD-02": scenario(
"T-WD-02",
name="无人使用时浴室仍出现漏水信号",
category="water_damage",
threat_type="water_leak",
room_selector="bathroom",
query_families=["sq2", "sq5"],
anomaly_events=[
attr("Day1 15:05", "bathroom_water_leak", "BooleanState", "StateValue", True),
attr("Day1 15:15", "bathroom_water_leak", "BooleanState", "StateValue", True),
attr("Day1 15:25", "bathroom_water_leak", "BooleanState", "StateValue", True),
],
fp_events=[
attr("Day1 21:10", "bathroom_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 21:12", "bathroom_water_leak", "BooleanState", "StateValue", True),
attr("Day1 21:16", "bathroom_water_leak", "BooleanState", "StateValue", False),
],
fp_key_difference="正常样本有浴室使用上下文;异常样本无人在场但漏水重复持续。",
key_evidence=["漏水信号持续出现", "前后没有对应的人体活动", "更像隐蔽渗漏而非使用溅水"],
expected_response="判定为无人时漏水异常,建议立即检查供水与排水。",
applicable_layouts=["A", "B", "D"],
difficulty_level=2,
),
"T-WD-03": scenario(
"T-WD-03",
name="洗衣结束后延迟出现漏水",
category="water_damage",
threat_type="water_leak",
room_selector="balcony",
query_families=["sq2", "sq5"],
anomaly_events=[
attr("Day1 16:00", "balcony_laundry_washer", "OperationalState", "OperationalState", 1),
attr("Day1 16:45", "balcony_laundry_washer", "OperationalState", "OperationalState", 0),
attr("Day1 16:58", "balcony_door_contact", "BooleanState", "StateValue", True),
attr("Day1 17:02", "bathroom_water_leak", "BooleanState", "StateValue", True),
],
fp_events=[
attr("Day1 16:00", "balcony_laundry_washer", "OperationalState", "OperationalState", 1),
attr("Day1 16:45", "balcony_laundry_washer", "OperationalState", "OperationalState", 0),
attr("Day1 16:47", "balcony_door_contact", "BooleanState", "StateValue", False),
],
fp_key_difference="正常样本洗衣结束后住户去阳台处理衣物;异常样本结束后延迟出现漏水信号。",
key_evidence=["洗衣机已经结束", "延迟若干分钟后出现漏水", "符合排水管或残余渗漏模式"],
expected_response="按排水系统异常处理,建议检查洗衣机和排水管。",
applicable_layouts=["B", "C"],
difficulty_level=3,
),
"T-WD-04": scenario(
"T-WD-04",
name="多个漏水点先后触发",
category="water_damage",
threat_type="water_leak",
room_selector="bathroom_pair",
query_families=["sq2", "sq5"],
anomaly_events=[
attr("Day1 11:05", "master_bathroom_water_leak", "BooleanState", "StateValue", True),
attr("Day1 11:18", "second_bathroom_water_leak", "BooleanState", "StateValue", True),
attr("Day1 11:30", "kitchen_water_leak", "BooleanState", "StateValue", True),
],
fp_events=[
attr("Day1 09:00", "master_bathroom_light", "OnOff", "OnOff", True),
attr("Day1 09:02", "master_bathroom_water_leak", "BooleanState", "StateValue", True),
attr("Day1 09:05", "master_bathroom_water_leak", "BooleanState", "StateValue", False),
],
fp_key_difference="正常样本只在单点短时触发;异常样本呈现跨区域蔓延。",
key_evidence=["多个漏水传感器依次触发", "时间顺序符合扩散", "不是单点误报可解释"],
expected_response="判定为扩散性漏水,建议立即关闭总阀并定位源头。",
applicable_layouts=["C"],
difficulty_level=3,
),
"T-DF-01": scenario(
"T-DF-01",
name="空调运行但温度不下降",
category="device_fault",
threat_type="sensor_malfunction",
room_selector="ac_room",
query_families=["sq1"],
anomaly_events=[
attr("Day1 13:00", "living_room_ac", "OnOff", "OnOff", True),
attr("Day1 13:15", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2920),
attr("Day1 13:35", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2940),
attr("Day1 13:55", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2960),
],
fp_events=[
attr("Day1 13:00", "living_room_ac", "OnOff", "OnOff", True),
attr("Day1 13:15", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2840),
attr("Day1 13:35", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2720),
attr("Day1 13:55", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2610),
],
fp_key_difference="正常样本空调开启后温度逐步下降;异常样本持续不降反升。",
key_evidence=["空调已开启", "室温没有向设定值靠近", "多个采样点都显示反向趋势"],
expected_response="判断为空调侧制冷失效或相关传感异常,建议检修。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=2,
),
"T-DF-02": scenario(
"T-DF-02",
name="相邻房间温度读数差异突然增大",
category="device_fault",
threat_type="sensor_drift",
room_selector="paired_temp_rooms",
query_families=["sq1"],
anomaly_events=[
attr("Day1 15:00", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2410),
attr("Day1 15:00", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2420),
attr("Day1 17:00", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2440),
attr("Day1 17:00", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2920),
],
fp_events=[
attr("Day1 15:00", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2410),
attr("Day1 15:00", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2420),
attr("Day1 17:00", "living_room_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2520),
attr("Day1 17:00", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2580),
],
fp_key_difference="正常样本两房间仍保持接近;异常样本差值突然扩大且只有一侧偏移。",
key_evidence=["初始两房间读数相近", "后续只有一侧突增", "差值异常扩大不符合同户环境"],
expected_response="判断为传感器漂移或局部测量故障。",
applicable_layouts=["A", "D"],
difficulty_level=3,
),
"T-DF-03": scenario(
"T-DF-03",
name="洗衣机运行但倒计时不减少",
category="device_fault",
threat_type="sensor_malfunction",
room_selector="balcony",
query_families=["sq1"],
anomaly_events=[
attr("Day1 10:00", "balcony_laundry_washer", "OperationalState", "OperationalState", 1),
attr("Day1 10:20", "balcony_laundry_washer", "OperationalState", "CountdownTime", 2400),
attr("Day1 10:40", "balcony_laundry_washer", "OperationalState", "CountdownTime", 2400),
attr("Day1 11:00", "balcony_laundry_washer", "OperationalState", "CountdownTime", 2400),
],
fp_events=[
attr("Day1 10:00", "balcony_laundry_washer", "OperationalState", "OperationalState", 1),
attr("Day1 10:20", "balcony_laundry_washer", "OperationalState", "CountdownTime", 2400),
attr("Day1 10:40", "balcony_laundry_washer", "OperationalState", "CountdownTime", 1200),
attr("Day1 11:00", "balcony_laundry_washer", "OperationalState", "OperationalState", 0),
],
fp_key_difference="正常样本倒计时递减并停止;异常样本数值长时间固定。",
key_evidence=["运行状态为 Running", "倒计时连续多个采样点不变", "与正常过程矛盾"],
expected_response="标记为运行状态/计时链路异常,建议检查洗衣机控制模块。",
applicable_layouts=["B", "C"],
difficulty_level=2,
),
"T-DF-04": scenario(
"T-DF-04",
name="运动传感器持续报 Occupied",
category="device_fault",
threat_type="sensor_stuck",
room_selector="occupancy_room",
query_families=["sq1"],
anomaly_events=[
attr("Day1 01:00", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 03:00", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 05:00", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 07:00", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_events=[
attr("Day1 06:55", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 07:05", "bedroom_light", "OnOff", "OnOff", True),
attr("Day1 07:10", "bathroom_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_key_difference="正常样本是起床链路的短时活动;异常样本是长时间单点持续 Occupied。",
key_evidence=["同一传感器跨长时间持续 Occupied", "缺少合理的人体移动链路", "更像卡死而非真实活动"],
expected_response="判断为占用传感器卡死,建议检修或重置。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=2,
),
"T-DF-05": scenario(
"T-DF-05",
name="门窗传感器状态与窗帘位置矛盾",
category="device_fault",
threat_type="sensor_malfunction",
room_selector="window_room",
query_families=["sq1"],
anomaly_events=[
attr("Day1 09:10", "living_room_window", "WindowCovering", "CurrentPositionLiftPercent100ths", 0),
attr("Day1 09:10", "living_room_window_contact", "BooleanState", "StateValue", True),
attr("Day1 09:12", "living_room_window_contact", "BooleanState", "StateValue", False),
attr("Day1 09:15", "living_room_window", "WindowCovering", "CurrentPositionLiftPercent100ths", 0),
],
fp_events=[
attr("Day1 09:10", "living_room_window", "WindowCovering", "CurrentPositionLiftPercent100ths", 5000),
attr("Day1 09:10", "living_room_window_contact", "BooleanState", "StateValue", False),
attr("Day1 09:20", "living_room_window_contact", "BooleanState", "StateValue", True),
],
fp_key_difference="正常样本窗户/窗帘状态变化一致;异常样本存在重复矛盾读数。",
key_evidence=["窗户/窗帘相关状态前后矛盾", "没有配套的合理位置变化", "更像传感链路异常"],
expected_response="判断为开闭状态感知异常,建议检查相关传感器。",
applicable_layouts=["A", "D"],
difficulty_level=2,
),
"T-DF-06": scenario(
"T-DF-06",
name="温度读数出现物理不可能跳变",
category="device_fault",
threat_type="sensor_malfunction",
room_selector="temp_room",
query_families=["sq1"],
anomaly_events=[
attr("Day1 14:00", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2430),
attr("Day1 14:05", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", -500),
attr("Day1 14:10", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2440),
],
fp_events=[
attr("Day1 14:00", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2430),
attr("Day1 14:05", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2550),
attr("Day1 14:10", "bedroom_temp_sensor", "TemperatureMeasurement", "MeasuredValue", 2470),
],
fp_key_difference="正常样本是小幅波动;异常样本出现不可能的极端跳变。",
key_evidence=["温度瞬时跳到不合理值", "随后又回到正常范围", "典型测量错误或通信故障"],
expected_response="标记为温度传感器异常跳变,建议检查硬件或链路。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=1,
),
"T-DF-07": scenario(
"T-DF-07",
name="灯的 OnOff 与 Level 矛盾",
category="device_fault",
threat_type="actuator_stuck",
room_selector="light_room",
query_families=["sq1"],
anomaly_events=[
attr("Day1 20:10", "bedroom_light", "OnOff", "OnOff", False),
attr("Day1 20:10", "bedroom_light", "LevelControl", "CurrentLevel", 180),
attr("Day1 20:12", "bedroom_light", "OnOff", "OnOff", False),
],
fp_events=[
attr("Day1 20:10", "bedroom_light", "OnOff", "OnOff", True),
attr("Day1 20:10", "bedroom_light", "LevelControl", "CurrentLevel", 180),
attr("Day1 20:18", "bedroom_light", "LevelControl", "CurrentLevel", 30),
],
fp_key_difference="正常样本 OnOff 和亮度值一致变化;异常样本存在持续矛盾状态。",
key_evidence=["同一时刻 OnOff=False 但亮度非零", "矛盾状态持续而非瞬时", "更像执行/上报故障"],
expected_response="判断为灯具状态机异常,建议检查执行器或状态同步。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=2,
),
"T-DF-08": scenario(
"T-DF-08",
name="设备频繁离线重连",
category="device_fault",
threat_type="sensor_malfunction",
room_selector="living_area",
query_families=["sq1"],
anomaly_events=[
evt("Day1 09:00", "living_room_ac", "DeviceOffline"),
evt("Day1 09:02", "living_room_ac", "DeviceOnline"),
evt("Day1 09:08", "living_room_ac", "DeviceOffline"),
evt("Day1 09:10", "living_room_ac", "DeviceOnline"),
evt("Day1 09:18", "living_room_ac", "DeviceOffline"),
],
fp_events=[
evt("Day1 09:00", "living_room_ac", "DeviceOffline"),
evt("Day1 09:02", "living_room_ac", "DeviceOnline"),
],
fp_key_difference="正常样本是一次性短暂重连;异常样本在短时间内反复抖动。",
key_evidence=["同一设备频繁离线/上线", "时间间隔很短", "符合通信不稳定故障特征"],
expected_response="判断为通信层不稳定,建议检查设备网络连接。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=2,
),
"T-EL-01": scenario(
"T-EL-01",
name="老人连续多天活动范围缩小",
category="elderly_specific",
threat_type="health_concern",
room_selector="elderly",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 09:00", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day2 09:00", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day3 09:00", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day3 12:00", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_events=[
attr("Day1 09:00", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day2 09:20", "kitchen_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day3 09:10", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_key_difference="正常样本仍保持多房间活动;异常样本逐渐收缩到卧室附近。",
key_evidence=["活动由多房间收缩到单一区域", "跨天持续出现", "提示功能退化或健康问题"],
expected_response="判定为老人活动范围异常缩小,建议关注健康状态。",
applicable_layouts=["D"],
applicable_profiles=["elderly_living_alone"],
difficulty_level=3,
),
"T-EL-02": scenario(
"T-EL-02",
name="老人用餐时间逐步推迟",
category="elderly_specific",
threat_type="behavioral_anomaly",
room_selector="elderly",
query_families=["sq3"],
anomaly_events=[
attr("Day1 12:05", "kitchen_light", "OnOff", "OnOff", True),
attr("Day2 14:20", "kitchen_light", "OnOff", "OnOff", True),
attr("Day3 16:40", "kitchen_light", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 12:05", "kitchen_light", "OnOff", "OnOff", True),
attr("Day2 12:35", "kitchen_light", "OnOff", "OnOff", True),
attr("Day3 12:15", "kitchen_light", "OnOff", "OnOff", True),
],
fp_key_difference="正常样本午餐时间有小幅波动;异常样本跨天明显后移。",
key_evidence=["厨房活动时间逐日明显变晚", "偏移幅度持续增大", "提示作息漂移异常"],
expected_response="标记为作息异常漂移,建议结合健康状况进一步关注。",
applicable_layouts=["D"],
applicable_profiles=["elderly_living_alone"],
difficulty_level=3,
),
"T-EL-03": scenario(
"T-EL-03",
name="夜间长期停留在非卧室区域",
category="elderly_specific",
threat_type="health_concern",
room_selector="elderly",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 02:10", "kitchen_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 02:35", "kitchen_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 02:50", "kitchen_light", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 02:10", "bathroom_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 02:15", "bathroom_occupancy", "OccupancySensing", "Occupancy", 0),
attr("Day1 02:18", "bedroom_light", "OnOff", "OnOff", True),
],
fp_key_difference="正常样本是短时起夜;异常样本在厨房等非卧室区域停留过久。",
key_evidence=["深夜在非卧室区域持续活动", "时长明显超出普通起夜", "可能是迷路或意识混乱"],
expected_response="按老人夜间异常活动处理,建议家属关注。",
applicable_layouts=["D"],
applicable_profiles=["elderly_living_alone"],
difficulty_level=2,
),
"T-EL-04": scenario(
"T-EL-04",
name="出门频率突然下降",
category="elderly_specific",
threat_type="behavioral_anomaly",
room_selector="elderly",
query_families=["sq3"],
anomaly_events=[
attr("Day1 09:00", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day1 09:01", "front_door_lock", "DoorLock", "LockState", 2),
attr("Day3 09:00", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_events=[
attr("Day1 09:00", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day2 10:20", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day3 08:50", "front_door_contact", "BooleanState", "StateValue", False),
],
fp_key_difference="正常样本仍保持日常出门;异常样本后续数天只剩室内活动。",
key_evidence=["首日仍有出门链路", "后续明显缺少外出相关事件", "可能反映社交/功能退缩"],
expected_response="标记为出门频率异常下降,建议结合老人状态持续观察。",
applicable_layouts=["D"],
applicable_profiles=["elderly_living_alone"],
difficulty_level=3,
),
"T-EL-05": scenario(
"T-EL-05",
name="做饭时间异常短",
category="elderly_specific",
threat_type="health_concern",
room_selector="elderly",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 12:00", "kitchen_cook_surface", "OnOff", "OnOff", True),
attr("Day1 12:05", "kitchen_cook_surface", "OnOff", "OnOff", False),
attr("Day2 12:00", "kitchen_cook_surface", "OnOff", "OnOff", True),
attr("Day2 12:04", "kitchen_cook_surface", "OnOff", "OnOff", False),
],
fp_events=[
attr("Day1 12:00", "kitchen_cook_surface", "OnOff", "OnOff", True),
attr("Day1 12:22", "kitchen_cook_surface", "OnOff", "OnOff", False),
attr("Day2 12:05", "kitchen_cook_surface", "OnOff", "OnOff", True),
attr("Day2 12:28", "kitchen_cook_surface", "OnOff", "OnOff", False),
],
fp_key_difference="正常样本做饭持续 20 分钟左右;异常样本连续两天都只持续约 5 分钟。",
key_evidence=["做饭时长明显缩短", "跨天重复出现", "可能提示进食不足或功能下降"],
expected_response="标记为进食相关异常,建议关注老人营养与健康状态。",
applicable_layouts=["D"],
applicable_profiles=["elderly_living_alone"],
difficulty_level=2,
),
"T-EL-06": scenario(
"T-EL-06",
name="半夜反复开关同一盏灯",
category="elderly_specific",
threat_type="behavioral_anomaly",
room_selector="elderly",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 02:10", "living_room_light", "OnOff", "OnOff", True),
attr("Day1 02:12", "living_room_light", "OnOff", "OnOff", False),
attr("Day1 02:14", "living_room_light", "OnOff", "OnOff", True),
attr("Day1 02:16", "living_room_light", "OnOff", "OnOff", False),
],
fp_events=[
attr("Day1 06:20", "living_room_light", "OnOff", "OnOff", True),
attr("Day1 06:45", "living_room_light", "OnOff", "OnOff", False),
],
fp_key_difference="正常样本是早起单次开关灯;异常样本在深夜短时反复切换。",
key_evidence=["深夜反复开关同一设备", "间隔很短", "符合意识混乱或异常行为模式"],
expected_response="判定为夜间行为异常,建议关注老人认知状态。",
applicable_layouts=["D"],
applicable_profiles=["elderly_living_alone"],
difficulty_level=2,
),
"T-CH-01": scenario(
"T-CH-01",
name="家长睡后儿童使用厨房电器",
category="child_specific",
threat_type="child_safety",
room_selector="child",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 23:20", "kids_room_occupancy", "OccupancySensing", "Occupancy", 0),
attr("Day1 23:24", "kitchen_light", "OnOff", "OnOff", True),
attr("Day1 23:25", "kitchen_cook_surface", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 19:00", "kitchen_light", "OnOff", "OnOff", True),
attr("Day1 19:01", "kitchen_cook_surface", "OnOff", "OnOff", True),
attr("Day1 19:02", "master_bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_key_difference="正常样本是晚餐时间且有成人活动;异常样本发生在夜间儿童应睡时段。",
key_evidence=["深夜厨房灯和灶具被打开", "儿童房活动状态变化", "缺乏成人陪同上下文"],
expected_response="按儿童厨房危险行为处理,建议立即干预。",
applicable_layouts=["C"],
applicable_profiles=["family_with_children"],
difficulty_level=2,
),
"T-CH-02": scenario(
"T-CH-02",
name="儿童反复尝试打开受限区域",
category="child_specific",
threat_type="child_safety",
room_selector="child",
query_families=["sq3", "sq4"],
anomaly_events=[
evt("Day1 18:05", "front_door_lock", "LockOperationError", {"source": "Keypad"}),
evt("Day1 18:06", "front_door_lock", "LockOperationError", {"source": "Keypad"}),
evt("Day1 18:07", "front_door_lock", "LockOperationError", {"source": "Keypad"}),
],
fp_events=[
evt("Day1 18:05", "front_door_lock", "LockOperationError", {"source": "Keypad"}),
attr("Day1 18:06", "front_door_lock", "DoorLock", "LockState", 2),
attr("Day1 18:07", "entrance_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_key_difference="正常样本是一两次失败后由成人成功开门;异常样本是短时连续失败尝试。",
key_evidence=["同一门锁短时间连续操作失败", "来源为按键输入", "符合儿童尝试受限区域的风险模式"],
expected_response="判为儿童高风险尝试开门,建议加强门锁与看护。",
applicable_layouts=["C"],
applicable_profiles=["family_with_children"],
difficulty_level=2,
),
"T-CH-03": scenario(
"T-CH-03",
name="儿童活动从儿童房转移到阳台",
category="child_specific",
threat_type="child_safety",
room_selector="child",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 16:10", "kids_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 16:14", "balcony_door_contact", "BooleanState", "StateValue", False),
attr("Day1 16:15", "balcony_light", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 16:10", "kids_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 16:12", "balcony_door_contact", "BooleanState", "StateValue", False),
attr("Day1 16:13", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_key_difference="正常样本有客厅成人活动作为陪同上下文;异常样本直达阳台更危险。",
key_evidence=["儿童房活动后很快打开阳台门", "阳台灯被打开", "缺少明确陪同信号"],
expected_response="判定为儿童接近高处风险区域,建议立即干预。",
applicable_layouts=["C"],
applicable_profiles=["family_with_children"],
difficulty_level=2,
),
"T-CH-04": scenario(
"T-CH-04",
name="放学后长期只有浴室活动",
category="child_specific",
threat_type="child_safety",
room_selector="child",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 16:30", "second_bathroom_light", "OnOff", "OnOff", True),
attr("Day1 16:45", "second_bathroom_light", "OnOff", "OnOff", True),
attr("Day1 17:00", "second_bathroom_light", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 16:30", "second_bathroom_light", "OnOff", "OnOff", True),
attr("Day1 16:36", "kids_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day1 16:40", "kitchen_light", "OnOff", "OnOff", True),
],
fp_key_difference="正常样本浴室活动后很快回到正常房间链路;异常样本长时间停留单一敏感区域。",
key_evidence=["放学后长时间只有浴室相关信号", "缺少回到儿童房或公共区域的链路", "存在异常风险"],
expected_response="标记为儿童异常停留风险,建议人工确认安全。",
applicable_layouts=["C"],
applicable_profiles=["family_with_children"],
difficulty_level=3,
),
"T-BA-01": scenario(
"T-BA-01",
name="回家后跳过常规过渡行为直接进卧室",
category="behavioral_anomaly",
threat_type="behavioral_anomaly",
room_selector="behavioral",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 18:20", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day1 18:21", "bedroom_light", "OnOff", "OnOff", True),
attr("Day1 18:22", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_events=[
attr("Day1 18:20", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day1 18:21", "living_room_light_1", "OnOff", "OnOff", True),
attr("Day1 18:24", "kitchen_light", "OnOff", "OnOff", True),
],
fp_key_difference="正常样本回家后有客厅/厨房过渡活动;异常样本直接进入卧室。",
key_evidence=["入户后缺少常见过渡动作", "直接切到卧室活动", "偏离既往居家路径"],
expected_response="判定为行为模式异常,建议结合其他迹象评估状态。",
applicable_layouts=["A", "B", "C"],
difficulty_level=2,
),
"T-BA-02": scenario(
"T-BA-02",
name="设备使用频率突然翻倍",
category="behavioral_anomaly",
threat_type="behavioral_anomaly",
room_selector="behavioral",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 19:00", "living_room_light_1", "OnOff", "OnOff", True),
attr("Day1 19:05", "living_room_light_1", "OnOff", "OnOff", False),
attr("Day1 19:10", "living_room_light_1", "OnOff", "OnOff", True),
attr("Day1 19:15", "living_room_light_1", "OnOff", "OnOff", False),
attr("Day1 19:20", "living_room_light_1", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 19:00", "living_room_light_1", "OnOff", "OnOff", True),
attr("Day1 21:30", "living_room_light_1", "OnOff", "OnOff", False),
],
fp_key_difference="正常样本只是晚间一次开关灯;异常样本短时间内重复高频操作。",
key_evidence=["同一设备短时间高频重复使用", "频率显著高于普通居家行为", "更像异常强迫式操作"],
expected_response="标记为异常设备交互模式,建议持续观察。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=2,
),
"T-BA-03": scenario(
"T-BA-03",
name="连续多天不使用厨房",
category="behavioral_anomaly",
threat_type="behavioral_anomaly",
room_selector="behavioral",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 08:00", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day2 08:15", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day3 08:05", "bedroom_occupancy", "OccupancySensing", "Occupancy", 1),
],
fp_events=[
attr("Day1 08:00", "living_room_occupancy", "OccupancySensing", "Occupancy", 1),
attr("Day2 12:10", "kitchen_light", "OnOff", "OnOff", True),
attr("Day3 18:40", "kitchen_light", "OnOff", "OnOff", True),
],
fp_key_difference="正常样本仍有零星厨房活动;异常样本连续多天完全缺失相关使用。",
key_evidence=["多天都有居家活动", "却始终没有厨房使用线索", "可能反映生活能力或情绪异常"],
expected_response="判定为连续行为缺失异常,建议结合住户状态评估。",
applicable_layouts=["A", "B", "C", "D"],
difficulty_level=3,
),
"T-BA-04": scenario(
"T-BA-04",
name="两个住户活动时间完全不重叠",
category="behavioral_anomaly",
threat_type="behavioral_anomaly",
room_selector="behavioral",
query_families=["sq3", "sq4"],
anomaly_events=[
attr("Day1 07:00", "kitchen_light", "OnOff", "OnOff", True),
attr("Day1 07:20", "front_door_contact", "BooleanState", "StateValue", False),
attr("Day1 21:40", "living_room_light_1", "OnOff", "OnOff", True),
attr("Day1 22:10", "bedroom_light", "OnOff", "OnOff", True),
],
fp_events=[
attr("Day1 07:00", "kitchen_light", "OnOff", "OnOff", True),
attr("Day1 18:30", "living_room_light_1", "OnOff", "OnOff", True),
attr("Day1 18:35", "kitchen_light", "OnOff", "OnOff", True),
],
fp_key_difference="正常样本晚间有共享公共区域活动;异常样本只表现为早晚完全割裂。",
key_evidence=["公共区域活动时间完全分离", "缺少正常交叠时段", "提示回避型异常模式"],
expected_response="标记为家庭互动模式异常,建议结合上下文进一步分析。",
applicable_layouts=["B", "C"],
difficulty_level=3,
),
}
DEV_SCENARIO_IDS = {
"T-INS-03",
"T-INS-08",
"T-FG-04",
"T-WD-04",
"T-DF-08",
"T-EL-06",
"T-CH-04",
"T-BA-04",
}
def get_scenarios_for_split(split: str) -> Dict[str, Dict]:
if split == "dev":
return {sid: deepcopy(sc) for sid, sc in SCENARIOS.items() if sid in DEV_SCENARIO_IDS}
return {sid: deepcopy(sc) for sid, sc in SCENARIOS.items() if sid not in DEV_SCENARIO_IDS}