如何在Python中计算传感器的开机时长(基于日期时间差)
用Python计算传感器开机时长(日期时间差值)
你已经处理得到结构化的传感器状态数据listaDivisa,每条记录格式如下:
['2009-10-16', '21:06:34.00044', 'kitchen sensor', 'ON'] ['2009-10-16', '21:13:22.00016', 'kitchen sensor', 'OFF'] ['2009-10-16', '12:53:29.00004', 'bathroom sensor', 'ON'] ['2009-10-16', '14:02:51.00056', 'bathroom sensor', 'OFF']
需要计算每个传感器每天的开机总时长,优先以分钟为单位。
之前方法的问题分析
第一种方法的问题
differenza函数使用return语句,找到第一组匹配的ON/OFF对就直接终止,无法处理所有传感器的全部状态段- 外层循环对每个条目重复调用
differenza,且字典赋值逻辑错误,会覆盖已有数据
第二种方法的问题
- 同样用
return提前终止,仅能返回第一个匹配结果 - 手动拆分时间的逻辑错误:
timeStart[0]是字符串,直接与整数相乘会触发类型错误;同时忽略日期信息,无法处理跨天的开机记录
正确实现思路
- 按传感器分组:将所有记录按传感器名称归类,方便单独处理每个传感器的状态变化
- 按时间排序:对每个传感器的记录按时间戳排序,确保ON事件在对应的OFF事件之前(兼容原始数据乱序的情况)
- 配对ON/OFF并计算时长:遍历排序后的记录,匹配连续的ON和OFF事件,计算单段开机时长并按日期累加
- 格式化输出:将结果整理为按传感器、日期分类的字典,以分钟为单位显示总时长
完整代码实现
from datetime import datetime # 假设你已经处理好的listaDivisa数据 listaDivisa = [ ['2009-10-16', '21:06:34.00044', 'kitchen sensor', 'ON'], ['2009-10-16', '21:13:22.00016', 'kitchen sensor', 'OFF'], ['2009-10-16', '12:53:29.00004', 'bathroom sensor', 'ON'], ['2009-10-16', '14:02:51.00056', 'bathroom sensor', 'OFF'], # 添加跨天测试数据 ['2009-10-16', '23:50:00.00000', 'kitchen sensor', 'ON'], ['2009-10-17', '00:15:00.00000', 'kitchen sensor', 'OFF'] ] # 1. 按传感器分组,同时解析datetime对象 sensor_records = {} for record in listaDivisa: date_str, time_str, sensor_name, status = record dt_str = f"{date_str} {time_str}" dt = datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S.%f') if sensor_name not in sensor_records: sensor_records[sensor_name] = [] sensor_records[sensor_name].append((dt, status)) # 2. 对每个传感器的记录按时间排序 for sensor in sensor_records: sensor_records[sensor].sort(key=lambda x: x[0]) # 3. 计算每个传感器每天的开机总时长 sensor_daily_duration = {} for sensor_name, records in sensor_records.items(): sensor_daily_duration[sensor_name] = {} on_dt = None # 记录当前开机时间 for dt, status in records: date_key = dt.strftime('%Y-%m-%d') if status == "ON": on_dt = dt elif status == "OFF" and on_dt is not None: # 计算单段时长并转换为分钟 duration_minutes = (dt - on_dt).total_seconds() / 60 # 按日期累加时长 if date_key not in sensor_daily_duration[sensor_name]: sensor_daily_duration[sensor_name][date_key] = 0.0 sensor_daily_duration[sensor_name][date_key] += duration_minutes on_dt = None # 重置开机记录 # 4. 格式化输出结果 for sensor, daily_data in sensor_daily_duration.items(): print(f"传感器: {sensor}") for date, total_minutes in daily_data.items(): print(f" 日期 {date}: 开机总时长 {round(total_minutes, 2)} 分钟")
代码说明
- 分组与排序:确保每个传感器的状态记录按时间顺序排列,避免因数据乱序导致配对错误
- datetime处理:使用
datetime.strptime解析完整时间戳,支持跨天的时长计算 - 累加逻辑:支持同一天内多次开关的场景,自动累加对应日期的总开机时长
- 容错处理:仅当存在有效的ON记录时,才计算对应的OFF时长,避免无效配对
内容的提问来源于stack exchange,提问作者Ari
相关产品推荐
相关产品推荐

