#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
import logging
import sys
from os import path
import xml.etree.ElementTree as ET
from typing import List
from concurrent.futures import ThreadPoolExecutor, as_completed
import datetime, os
# ========== 基础模块 ==========
from VigiIpcControl import VigiIpcControl
from HKIpcControl import HKIpcControl
from DHIpcControl import DHIpcControl
from SmartBulbBatchCtrl import SmartBulbBatchCtrl
from CarSerialCtrl import CarSerialCtrl
from VigiVideo import VigiVideo
from log_config import Log
import xlrd
# --------------------- 日志 -------------------
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
log_filename = f"{timestamp}_diff_Lux.log"
logger = Log(name=log_filename, log_level=logging.INFO)
# ----------- 灯泡配置 -----------
bulb_config_path = r'E:\dcc\实验室资料\ControlScript\Light_Contrl\BulbConfigArea1.xls'
bulb_config_table = 'config'
nic_ip = '192.168.0.11'
# 读取智能灯泡配置表格
workbook = xlrd.open_workbook(bulb_config_path)
table = workbook.sheet_by_name(bulb_config_table)
# 创建列值索引map
row0_value = table.row_values(0)
column_index_map = {}
index = 0
for item in row0_value:
column_index_map[item] = index
index = index+1
# 创建智能灯泡配置map
bulb_config_map = {}
bulb_index_map = {}
rowc = table.nrows
for row in range(1, rowc):
row_value = table.row_values(row)
bulb_config_map[row_value[column_index_map['location']]] = {'ip':row_value[column_index_map['ip']], \
'type':row_value[column_index_map['type']], \
'username':row_value[column_index_map['username']], \
'password':row_value[column_index_map['password']]}
bulb_index_map[row_value[column_index_map['location']]] = int(row_value[column_index_map['index']])
def build_rows(start: int, end: int, j_start: int = 1, j_end: int = 5):
"""生成 ['i_j', ...] 列表,i∈[start,end), j∈[j_start,j_end)"""
return ['%d_%d' % (i, j) for i in range(start, end) for j in range(j_start, j_end)]
# 形成灯泡字典
def get_bulb_conf_list(bulb_loc_list=[], bulb_config_map=None):
bulb_conf_list = []
for loc in bulb_loc_list:
bulb_conf_list.append(bulb_config_map[loc])
return bulb_conf_list
def _init_one(ctrl_list=None, nic_ip=nic_ip,
brightness=None, color_temp=None, on_off=None,
max_fail=6):
"""
批量控制灯泡(亮度/色温/开关),直到全部成功或某设备连续失败 max_fail 次被永久跳过。
:param ctrl_list: 初始灯泡列表 [{'ip': 'x.x.x.x', ...}, ...]
:param nic_ip: 本地网卡 IP
:param brightness: 亮度 0-100
:param color_temp: 色温 2700-6500
:param on_off: 开关 0/1
:param max_fail: 单个 IP 最大允许连续失败次数
"""
if ctrl_list is None:
ctrl_list = []
# 1) 记录每个 IP 连续失败次数
fail_counter = {item['ip']: 0 for item in ctrl_list}
for rnd in range(10):
print(f'round {rnd} ctrl_list={ctrl_list}')
if not ctrl_list: # 全部成功或被跳过
break
try:
# 2) 本轮批量控制
bulb_control = SmartBulbBatchCtrl.SmartBulbBatchCtrl(bulb_list=ctrl_list, nic_ip=nic_ip)
batch_ctrl = bulb_control.batch_ctrl_bulbs(brightness=brightness,
color_temp=color_temp,
on_off=on_off)
success_ip_set = set(batch_ctrl["batch_ctrl_success_list"])
except Exception as e:
logger.warning(f"灯泡控制异常/超时,本轮当全部失败: {e}")
success_ip_set = set() # 空集 = 全部失败
# 3) 更新失败计数 & 剔除永远失败的设备
new_ctrl_list = []
for item in ctrl_list:
ip = item['ip']
if ip in success_ip_set:
fail_counter[ip] = 0 # 成功清零
else:
fail_counter[ip] += 1
if fail_counter[ip] < max_fail:
new_ctrl_list.append(item)
else:
logger.warning(f'[SKIP] {ip} 连续失败 {max_fail} 次,永久跳过')
ctrl_list = new_ctrl_list
def _init_one_close(ctrl_list=None, nic_ip=nic_ip, max_fail=6):
"""
批量关灯,直到全部成功或某设备连续失败 max_fail 次被永久跳过。
:param ctrl_list: 初始灯泡列表 [{'ip': 'x.x.x.x', ...}, ...]
:param nic_ip: 本地网卡 IP
:param max_fail: 单个 IP 最大允许连续失败次数
"""
if ctrl_list is None:
ctrl_list = []
# 1) 记录每个 IP 连续失败次数
fail_counter = {item['ip']: 0 for item in ctrl_list}
for rnd in range(10):
print(f'round {rnd} ctrl_list={ctrl_list}')
try:
# 2) 本轮批量关灯
bulb_control = SmartBulbBatchCtrl(bulb_list=ctrl_list, nic_ip=nic_ip)
batch_ctrl = bulb_control.batch_ctrl_bulbs(on_off=0)
success_ip_set = set(batch_ctrl["batch_ctrl_success_list"])
except Exception as e:
logger.warning(f"灯泡控制异常/超时,本轮当全部失败: {e}")
success_ip_set = set() # 空集 = 全部失败
# 3) 更新失败计数 & 剔除永远失败的设备
new_ctrl_list = []
for item in ctrl_list:
ip = item['ip']
if ip in success_ip_set:
fail_counter[ip] = 0 # 成功就清零
new_ctrl_list.append(item) # 成功后一般就不再需要继续关了,这里保留仅作演示
else:
fail_counter[ip] += 1
if fail_counter[ip] < max_fail:
new_ctrl_list.append(item)
else:
logger.info(f'[SKIP] {ip} 连续失败 {max_fail} 次,永久跳过')
ctrl_list = new_ctrl_list
if not ctrl_list: # 全部成功或被跳过
break
# --------------------------- 初始化IPC配置信息 -----------------------------------
# 读取设备配置文件,返回配置信息+py路径信息字典
def start_test_get_config():
logging.debug('加载配置文件.........')
element_dict = {}
if hasattr(sys, 'frozen'):
py_path = path.dirname(sys.executable)
else:
py_path = path.dirname(__file__)
# 添加py文件或exe文件所在路径
element_dict["py_path"] = py_path
# 读取配置文件
xml_path = path.join(py_path, 'ipc_test_info.xml')
info_tree = ET.parse(xml_path)
root = info_tree.getroot() # 加载根节点
element_name = root.iter() # 遍历根节点所有后代
for e in element_name:
if e.attrib and e.attrib["load"] == "False":
logging.debug(f"节点{e.tag}:{e.text}属性为False,不加载")
else:
element_dict[e.tag] = e.text
logging.debug('加载配置文件结束......')
return element_dict
config =start_test_get_config()
# 初始化小车
car = CarSerialCtrl.CarControl(logger=logger, port="COM5")
# 初始化设备
vigi_ipc = VigiIpcControl.VigiIpcControl(config)
vigi_video = VigiVideo.VigiVideo(config)
hk_ipc = HKIpcControl.HKIpcControl(config)
hk_ipc.hk_start_test_web()
dh_ipc = DHIpcControl.DHIpcControl(config)
dh_ipc.dh_start_test_web()
# # 初始化窗帘
# cur4 = SmartCurtainsCtrl.CurtainsCtrl(4, 'com2')
# cur2 = SmartCurtainsCtrl.CurtainsCtrl(2, 'com2')
# 登录设备,初始化
vigi_ipc.vigi_start_test_tdcp()
vigi_ipc.image_restore()
# 关闭补光灯,防止环境过暗导致补光灯打开
vigi_ipc.close_light()
time.sleep(2)
hk_ipc.day_mode()
time.sleep(2)
hk_ipc.close_white()
dh_ipc.off_supplement(mode="Off", light_type="IR")
# ---------------- 工具函数 ----------------
def open_ir():
try:
vigi_ipc.open_ir()
hk_ipc.night_mode()
hk_ipc.close_ir()
dh_ipc.day_night_mode(mdoe='IR')
dh_ipc.off_supplement()
except Exception as e:
logger.warning("打开补光灯时出现异常%s" % e)
def close_ir():
try:
vigi_ipc.close_light()
hk_ipc.day_mode()
hk_ipc.close_ir()
dh_ipc.day_night_mode(mode='Color')
dh_ipc.off_supplement()
except Exception as e:
logger.warning("关闭补光灯时出现异常%s" %e)
# 截图函数
def ipc_capture(filename):
try:
vigi_video.capture(custom_name=filename)
hk_ipc.capture()
dh_ipc.capture()
except Exception as e:
logger.warning("截图过程中发生异常{e},请检查图片")
# 录像开始
def ipc_record_start(filename):
try:
vigi_video.record_start(output_file=filename)
hk_ipc.record_start()
dh_ipc.record_start()
except Exception as e:
logger.warning("启动录像过程中发生异常{e},请检查录像")
# 录像停止
def ipc_record_stop():
try:
vigi_video.record_stop()
hk_ipc.record_stop()
dh_ipc.record_stop()
except Exception as e:
logger.warning("结束录像过程中发生异常{e},请检查录像")
def stop_test():
dh_ipc.close_web()
hk_ipc.close_web()
# 小车归位
def car_move_to_home():
car.go_to_site(1)
# 小车停止
def car_stop():
car.stop()
#小车运动
def car_video_track():
cur = car.get_car_status()['current_site']
if cur == 0:
car.set_current_site(1)
for i in range(2):
car.set_speed(100)
car.go_to_site(1)
time.sleep(2)
car.go_to_site(4)
time.sleep(2)
car.go_to_site(1)
car.go_to_site(1)
time.sleep(1)
def main():
logger.info("---------------------------------------IPC day_mode_illumin_change测试---------------------------------------")
ipc_capture('ir_mode_illumin_change')
ipc_record_start('ir_mode_illumin_change')
time.sleep(15)
open_ir()
#将第一排灯光持续调整至低亮并关闭
lx_2 = build_rows(1,2, 1,9)
lx_list2 = get_bulb_conf_list(bulb_loc_list=lx_2, bulb_config_map=bulb_config_map)
_init_one(ctrl_list=lx_list2, brightness=10, color_temp=6500, on_off=1, max_fail=2)
_init_one(ctrl_list=lx_list2, brightness=1, color_temp=6500, on_off=1, max_fail=2)
_init_one(ctrl_list=lx_list2, brightness=1, color_temp=6500, on_off=0)
#再次开启第一排灯光,随后关闭灯光
_init_one(ctrl_list=lx_list2, brightness=50, color_temp=6500, on_off=1, max_fail=5)
_init_one(ctrl_list=lx_list2, brightness=50, color_temp=6500, on_off=0, max_fail=5)
ipc_record_stop()
logger.info("------------------红外模式下的曝光收敛测试完成------------------")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
logging.debug("用户中断,退出")
finally:
stop_test()
all_bulb_list = build_rows(1,13, 1,9)
all_bulb = get_bulb_conf_list(bulb_loc_list=all_bulb_list, bulb_config_map=bulb_config_map)
_init_one_close(ctrl_list=all_bulb)
car_move_to_home()
car.stop()
我有如上的代码,现在我想对它进行优化,主要是是为了能够争对hk_ipc和dh_ipc的控制做优化,我会从config =start_test_get_config()中读出多个大华摄像头IP和海康IP,现在我想要能够保证后续的对海康大华的这些样机做同样的操作,如截图、录像等,该如何优化