空调风机启停时长统计的系统开发

方案1:图形识别

用 Python 图像识别 + 自动化操作 来实现风机时长的监控与统计:

1.1用python 编程思想实现思路

✅ 总体实现目标拆解

🎯 你的目标: 1. 识别所有风机当前状态(绿色 = 开,灰色 = 关); 2. 定时检测状态变更并记录起止时间; 3. 自动翻页切换不同楼层(右上角点击); 4. 周期性汇总统计开机时间并导出 Excel。

✅ 建议方案:使用 Python 自动化框架

技术模块工具/库
图像识别(颜色识别)PIL 或 OpenCV
屏幕截图pyautogui 或 mss
自动点击楼层切换按钮pyautogui
数据存储/导出pandas + openpyxl
后台定时运行threading + schedule(可选)

🧠 基础原理说明 1. 每个风机是一个“卡片”,中间是一个 风扇图标,颜色为绿或灰; 2. 每页图标数量固定、排布整齐,因此可以用网格方式计算每个图标的坐标中心点; 3. 每隔 1 分钟截图,检测每个点的颜色变化,并更新运行时间记录; 4. 每页监测完后,点击右上角箭头(你提供图中那个 蓝色圆形图标),进入下一页继续识别; 5. 所有页完成后,等待一分钟继续下一轮。

✅ 核心流程与代码框架

🖼️ 1. 获取风机位置坐标(手动标一次)

你只需在屏幕分辨率一致的前提下,用截图工具标出第一排第一个风机图标中心坐标,比如:(120, 240),每个风机宽约 120px,高约 100px,则:

假设界面有6行 × 8列风机卡片

 fan_positions = []
 start_x, start_y = 120, 240
 x_spacing, y_spacing = 120, 100
 rows, cols = 6, 8
 ​
 for r in range(rows):
     for c in range(cols):
         fan_positions.append((
             start_x + c * x_spacing,
             start_y + r * y_spacing
        ))

🎨 2. 判断图标颜色是否为绿色

 from PIL import ImageGrab
 ​
 def is_fan_on(pixel):
     r, g, b = pixel
     return g > 180 and r < 100 and b < 100  # 绿色
 ​
 def check_fan_status(x, y):
     screenshot = ImageGrab.grab()
     pixel = screenshot.getpixel((x, y))
     return "ON" if is_fan_on(pixel) else "OFF"

🖱️ 3. 自动点击右上角翻页按钮

 import pyautogui
 ​
 def click_next_floor():
     pyautogui.moveTo(990, 140)  # 此为右上角按钮的大致位置,请用 pyautogui.position() 精调
     pyautogui.click()
 ​

你可以先运行:

pyautogui.position()

将鼠标移动到你截图中那个 “右上角翻页箭头按钮” 上,记录其坐标值。

📊 4. 记录状态切换与持续时间

 from datetime import datetime
 ​
 status_log = {}
 run_records = []
 ​
 def update_fan_status(fan_id, new_status):
     now = datetime.now()
     last_status, start_time = status_log.get(fan_id, (None, None))
 ​
 if new_status != last_status:
     if new_status == "ON":
         status_log[fan_id] = ("ON", now)
     elif new_status == "OFF" and start_time:
         duration = (now - start_time).total_seconds() / 60
         run_records.append({
             "FanID": fan_id,
             "StartTime": start_time,
             "EndTime": now,
             "Duration(min)": duration
        })
         status_log[fan_id] = ("OFF", None)

📦 5. 导出为 Excel

 import pandas as pd
 def export_to_excel():
     df = pd.DataFrame(run_records)
     df.to_excel("fan_log.xlsx", index=False)

🔁 6. 总循环(多页轮询)

 def monitor_all_pages(total_pages=8):
     for page in range(total_pages):
         for idx, (x, y) in enumerate(fan_positions):
             fan_id = f"P{page+1}-F{idx+1}"
             status = check_fan_status(x, y)
             update_fan_status(fan_id, status)
         click_next_floor()
         time.sleep(3)  # 等页面刷新

1.2完整实现方案与下一步计划

✅ 项目目标概述

功能模块内容
① 图像识别自动识别屏幕上风机的状态(绿=开,灰=关)
② 状态监控定时识别各风机状态变化,记录开关时间
③ 楼层切换自动点击右上角按钮,轮询8个楼层
④ 数据存储记录每次风机开关的持续时间
⑤ 统计分析按月/季度/年统计开机时长
⑥ 导出 Excel将记录导出为 .xlsx 报表
⑦ GUI 面板提供可视化按钮与启动、查看状态等功能(可选)

🛠️ 接下来的步骤安排

✅ Step 1:图像识别坐标 & 初始测试脚本

我们先生成: • 基于你图中页面识别的 48 个风机位置坐标; • 提供一个可运行的 .py 脚本,定时截图识别风机状态,并输出当前页风机状态列表。

✅ Step 2:状态变化记录逻辑

接下来我将实现以下功能: • 每个风机状态从“灰→绿→灰”算一次运行; • 记录开始时间、结束时间、持续分钟; • 保存在 CSV/Excel 中,并可定期汇总。

✅ Step 3:楼层轮询 & 自动点击

系统会: • 识别当前页风机; • 自动点击右上角按钮; • 继续识别下一页,直到全部页完成。

✅ Step 4:统计汇总与导出

将提供: • 月度、季度、年度统计汇总函数; • 每台风机的开机时长、频次、图表(可选); • 导出为 Excel 报表格式(EPPlus or pandas)。

✅ Step 5(可选):带 GUI 的监控工具

你可以拥有: • 图形界面带按钮启动监控; • 可视化状态显示(例如绿红灯标志); • 导出一键点击。

1.3生成一个完整可运行的 Python 脚本

实现:

✅ 图像识别风机状态 ✅ 每5分钟自动轮询识别所有页面(8页) ✅ 自动点击右上角切页按钮 ✅ 记录每台风机开启(绿色)持续时间 ✅ 导出运行记录为 Excel 表格

🧠 实现前提 • 界面排布为 6 行 × 8 列(共 48 台风机); • 每页风机位置一致; • 鼠标自动点击右上角箭头翻页(我默认其坐标为 (1840, 140),你可微调); • 状态判断基于中心像素是否为绿色。

📦 文件结构

 fan_monitor/
 ├── fan_monitor.py           # 主程序(轮询+识别+记录+导出)
 ├── fan_log.xlsx             # 导出的运行日志

✅ 完整脚本(fan_monitor.py)

 import pyautogui
 import time
 from datetime import datetime
 from PIL import ImageGrab
 import pandas as pd
 import os
 ​
 ========== 配置部分 ==========
 ​
 ROWS = 6
 COLS = 8
 PAGES = 8
 X0, Y0 = 190, 270  # 第一个风机图标中心坐标(参考截图)
 X_GAP = 172        # 横向间距
 Y_GAP = 120        # 纵向间距
 NEXT_BUTTON_POS = (1840, 140)  # 翻页按钮坐标(右上角)
 SCREEN_REGION = (0, 0, 1920, 1080)
 CHECK_INTERVAL = 300  # 轮询间隔(秒)
 ​
 ========== 数据结构 ==========
 ​
 status_log = {}  # {fan_id: ("ON"/"OFF", start_time)}
 run_records = []  # 运行时间段记录列表
 ​
 def get_fan_positions():
     positions = []
     for row in range(ROWS):
         for col in range(COLS):
             x = X0 + col * X_GAP
             y = Y0 + row * Y_GAP
             positions.append((x, y))
     return positions
 ​
 def is_green(pixel):
     r, g, b = pixel
     return g > 180 and r < 100 and b < 100
 ​
 def check_status(screenshot, pos):
     pixel = screenshot.getpixel(pos)
     return "ON" if is_green(pixel) else "OFF"
 ​
 def update_status(fan_id, new_status):
     now = datetime.now()
     last_status, start_time = status_log.get(fan_id, (None, None))
     if new_status != last_status:
         if new_status == "ON":
             status_log[fan_id] = ("ON", now)
         elif new_status == "OFF" and start_time:
             duration = (now - start_time).total_seconds() / 60
             run_records.append({
                 "FanID": fan_id,
                 "StartTime": start_time,
                 "EndTime": now,
                 "Duration(min)": duration
            })
             status_log[fan_id] = ("OFF", None)
 ​
 def click_next_page():
     pyautogui.moveTo(*NEXT_BUTTON_POS)
     pyautogui.click()
     time.sleep(2)  # 等待页面刷新
 ​
 def monitor_once():
     fan_positions = get_fan_positions()
     for page in range(PAGES):
         screenshot = ImageGrab.grab(SCREEN_REGION)
         for idx, pos in enumerate(fan_positions):
             fan_id = f"P{page+1}-F{idx+1}"
             status = check_status(screenshot, pos)
             update_status(fan_id, status)
         if page < PAGES - 1:
             click_next_page()
 ​
 def export_log():
     if not run_records:
         return
     df = pd.DataFrame(run_records)
     os.makedirs("export", exist_ok=True)
     df.to_excel(f"export/fan_log_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx", index=False)
 ​
 def run_monitor():
     print("启动风机监控...")
     try:
         while True:
             print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 轮询中...")
             monitor_once()
             export_log()
             time.sleep(CHECK_INTERVAL)
     except KeyboardInterrupt:
         print("监控中断,导出记录...")
         export_log()
 ​
 if __name__ == "__main__":
     run_monitor()

✅ 使用说明 1. 安装依赖(确保用 Python 3.9+):

pip install pyautogui pillow pandas openpyxl
  1. 运行脚本(记得先打开风机监控界面):
python fan_monitor.py
  1. 结果导出:

• 每轮运行后,会在 export/ 文件夹中生成 fan_log_*.xlsx 文件; • 文件包含每个风机的运行时间段及持续时间。

✅ 后续可加功能(可按需添加)

功能实现方式
GUI 可视化监控界面使用 Tkinter or PyQt
异常报警(连续运行超时)加阈值判断
分析图表(运行趋势)用 matplotlib 绘图
按月/季度/年统计用 groupby 统计汇总

1.4为现有的脚本添加功能

✅ 统计每台风机的总运行时长(按月、季度、年) ✅ 自动在导出 Excel 中加入统计汇总页

✅ 修改步骤概览

🧩 目标效果: • 每轮导出日志时,自动新增一个 汇总 工作表; • 汇总包含每台风机在该时间段内的: • 月运行时长 • 季度运行时长 • 年运行时长(当前年度)

✅ 代码修改部分

替换原脚本中的 export_log() 函数为以下内容:

def export_log():
if not run_records:
return
df = pd.DataFrame(run_records)
df['StartTime'] = pd.to_datetime(df['StartTime'])
df['Year'] = df['StartTime'].dt.year
df['Month'] = df['StartTime'].dt.to_period('M')
df['Quarter'] = df['StartTime'].dt.to_period('Q')
# 分组统计总运行时长(分钟)
df_month = df.groupby(['FanID', 'Month'])['Duration(min)'].sum().reset_index()
df_quarter = df.groupby(['FanID', 'Quarter'])['Duration(min)'].sum().reset_index()
df_year = df.groupby(['FanID', 'Year'])['Duration(min)'].sum().reset_index()

# 创建工作簿
now = datetime.now().strftime('%Y%m%d_%H%M%S')
out_path = f"export/fan_log_{now}.xlsx"
with pd.ExcelWriter(out_path, engine='openpyxl') as writer:
df.to_excel(writer, sheet_name='运行记录', index=False)
df_month.to_excel(writer, sheet_name='月统计', index=False)
df_quarter.to_excel(writer, sheet_name='季度统计', index=False)
df_year.to_excel(writer, sheet_name='年度统计', index=False)

1.5最终生成 Excel 内容结构示例

📄 Sheet 1:运行记录

FanIDStartTimeEndTimeDuration(min)
P1-F012025-07-01 10:002025-07-01 11:3090

📄 Sheet 2:月统计

FanIDMonthDuration(min)
P1-F012025-07300

📄 Sheet 3:季度统计

FanIDQuarterDuration(min)
P1-F012025Q3300

📄 Sheet 4:年度统计

FanIDYearDuration(min)
P1-F012025300

✅ 下一步建议(可选扩展)

功能描述
图表可视化(柱状/折线)用 matplotlib 或 openpyxl 绘图
GUI 交互界面启动/停止/查看运行状态按钮
开关日志分离按页保存每页一个日志文件更易审计
自动定时启动加入 Windows 任务计划或用 PyInstaller 打包服务


方案2:反编译

用dnspy反编译软件尝试对【touchvew】实现在原有系统上进行功能增添,看源程序界面是基于winform框架开发的:

安装dnspy进行软件反编译:

无法正常破解,方案2失效。

发表回复