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}