Files
cjgc_data/actions.py

294 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import logging
import os
import time
import subprocess
from tkinter import E
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from page_objects.download_tabbar_page import DownloadTabbarPage
from page_objects.measure_tabbar_page import MeasureTabbarPage
from page_objects.section_mileage_config_page import SectionMileageConfigPage
from page_objects.upload_config_page import UploadConfigPage
from page_objects.more_download_page import MoreDownloadPage
from page_objects.screenshot_page import ScreenshotPage
from check_station import CheckStation
import globals.driver_utils as driver_utils # 导入驱动工具模块
import globals.global_variable as global_variable
from page_objects.login_page import LoginPage
import globals.apis as apis
import globals.create_link as create_link
class DeviceAutomation:
def __init__(self, driver=None, wait=None, device_id=None):
self.driver = driver
self.wait = wait
self.device_id = device_id
if not self.device_id:
logging.error("设备 ID 为空,无法初始化自动化")
return
# 初始化权限
if driver_utils.grant_appium_permissions(self.device_id):
logging.info(f"设备 {self.device_id} 授予Appium权限成功")
else:
logging.warning(f"设备 {self.device_id} 授予Appium权限失败")
# 确保Appium服务器正在运行,不在运行则启动
if not driver_utils.check_server_status(4723):
driver_utils.start_appium_server()
# 初始化Appium驱动和页面对象
self.init_driver()
# @staticmethod
# def get_device_id() -> str:
# """
# 获取设备ID优先使用已连接设备否则使用全局配置
# """
# try:
# # 检查已连接设备
# result = subprocess.run(
# ["adb", "devices"],
# capture_output=True,
# text=True,
# timeout=10
# )
# target_port = "4723"
# for line in result.stdout.strip().split('\n')[1:]:
# if line.strip() and "device" in line and "offline" not in line:
# device_id = line.split('\t')[0]
# # 检查是否为无线设备且端口为4723
# if ':' in device_id:
# ip_port = device_id.split(':')
# if len(ip_port) == 2 and ip_port[1] == target_port:
# logging.info(f"找到目标无线设备(端口{target_port}): {device_id}")
# global_variable.GLOBAL_DEVICE_ID = device_id
# return device_id
# # 如果没有找到端口4723的设备找其他无线设备
# for line in result.stdout.strip().split('\n')[1:]:
# if line.strip() and "device" in line and "offline" not in line:
# device_id = line.split('\t')[0]
# # 检查是否为无线设备(任何端口)
# if ':' in device_id and device_id.split(':')[-1].isdigit():
# logging.info(f"未找到端口{target_port}的设备,使用其他无线设备: {device_id}")
# global_variable.GLOBAL_DEVICE_ID = device_id
# return device_id
# # 如果没有任何无线设备,找有线设备
# for line in result.stdout.strip().split('\n')[1:]:
# if line.strip() and "device" in line and "offline" not in line:
# device_id = line.split('\t')[0]
# logging.info(f"未找到无线设备,使用有线设备: {device_id}")
# global_variable.GLOBAL_DEVICE_ID = device_id
# return device_id
# logging.error("未找到任何可用设备")
# return None
# except Exception as e:
# logging.warning(f"设备检测失败: {e}")
# # 使用全局配置
# device_id = global_variable.GLOBAL_DEVICE_ID
# logging.info(f"使用全局配置设备: {device_id}")
# return device_id
def init_driver(self):
"""初始化Appium驱动"""
try:
try:
if not driver_utils.check_session_valid(self.driver, self.device_id):
logging.warning(f"设备 {self.device_id} 会话无效,尝试重新连接驱动...")
self.driver, self.wait = driver_utils.reconnect_driver(self.device_id, self.driver)
if not self.driver:
logging.error(f"设备 {self.device_id} 驱动重连失败")
return False
except Exception as inner_e:
logging.warning(f"设备 {self.device_id} 检查会话状态时出错: {str(inner_e)}")
return False
# # 使用全局函数初始化驱动
self.results_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_results')
# self.driver, self.wait = driver_utils.init_appium_driver(self.device_id)
# 初始化页面对象
logging.info(f"设备 {self.device_id} 开始初始化页面对象")
self.login_page = LoginPage(self.driver, self.wait)
self.download_tabbar_page = DownloadTabbarPage(self.driver, self.wait, self.device_id)
self.measure_tabbar_page = MeasureTabbarPage(self.driver, self.wait,self.device_id)
self.section_mileage_config_page = SectionMileageConfigPage(self.driver, self.wait, self.device_id)
self.upload_config_page = UploadConfigPage(self.driver, self.wait, self.device_id)
self.more_download_page = MoreDownloadPage(self.driver, self.wait,self.device_id)
self.screenshot_page = ScreenshotPage(self.driver, self.wait, self.device_id)
self.check_station = CheckStation(self.driver, self.wait, self.device_id)
logging.info(f"设备 {self.device_id} 所有页面对象初始化完成")
# 检查应用是否成功启动
if driver_utils.is_app_launched(self.driver):
logging.info(f"设备 {self.device_id} 沉降观测App已成功启动")
else:
logging.warning(f"设备 {self.device_id} 应用可能未正确启动init_driver")
driver_utils.launch_app_manually(self.driver)
except Exception as e:
logging.error(f"设备 {self.device_id} 初始化驱动失败: {str(e)}")
raise
def run_automation(self):
"""根据当前应用状态处理相应的操作"""
try:
max_retry = 3 # 限制最大重试次数
retry_count = 0
while retry_count < max_retry:
login_btn_exists = self.login_page.is_login_page()
if not login_btn_exists:
logging.error(f"设备 {self.device_id} 未知应用状态,无法确定当前页面,跳转到登录页面")
if self.login_page.navigate_to_login_page(self.driver, self.device_id):
logging.info(f"设备 {self.device_id} 成功跳转到登录页面")
else:
logging.error(f"设备 {self.device_id} 跳转到登录页面失败")
retry_count += 1
continue
# 处理登录页面状态
logging.info(f"设备 {self.device_id} 检测到登录页面,执行登录操作")
max_retries_login = 3
login_success = False
for attempt in range(max_retries_login + 1):
if self.login_page.login("czsczq115ykl"):
login_success = True
break
else:
if attempt < max_retries_login:
logging.warning(f"设备 {self.device_id} 登录失败,准备重试 ({attempt + 1}/{max_retries_login})")
time.sleep(2) # 等待2秒后重试
else:
logging.error(f"设备 {self.device_id} 登录失败,已达到最大重试次数")
if login_success:
break
elif retry_count == max_retry-1:
logging.error(f"设备 {self.device_id} 处理登录页面失败,已达到最大重试次数")
return False
else:
retry_count += 1
logging.info(f"设备 {self.device_id} 登录成功,继续执行更新操作")
time.sleep(1)
# 执行更新操作
if not self.download_tabbar_page.download_tabbar_page_manager():
logging.error(f"设备 {self.device_id} 更新操作执行失败")
return False
task_count = 0
# 获取测量任务
logging.info(f"设备 {self.device_id} 获取测量任务 (第{task_count + 1}次)")
# task_data = apis.get_measurement_task()
# logging.info(f"设备 {self.device_id} 获取到的测量任务: {task_data}")
task_data = {
"id": 21,
"user_name": "czsczq115ykl",
"name": "czsczq115ykl",
"line_num": "L220076",
"line_name": "CZSCZQ-11-五工区-列衣隧道进口-D3K638+507-D3K638+607-山区",
"remaining": "0",
"status": 0
}
if not task_data:
logging.info(f"设备 {self.device_id} 未获取到状态为1的测量任务等待后重试")
time.sleep(1) # 等待1秒后重试
# break
# continue
# 设置全局变量
global_variable.GLOBAL_USERNAME = task_data.get('user_name', '')
global_variable.GLOBAL_CURRENT_PROJECT_NAME = task_data.get('line_name', '')
global_variable.GLOBAL_LINE_NUM = task_data.get('line_num', '')
global_variable.GLOBAL_ACCOUNT_ID = task_data.get('id', 0)
logging.info(f"设备 {self.device_id} 当前要处理的项目名称:{global_variable.GLOBAL_CURRENT_PROJECT_NAME}")
# 执行测量操作
if not self.measure_tabbar_page.measure_tabbar_page_manager():
logging.error(f"设备 {self.device_id} 测量操作执行失败")
logging.info(f"设备 {self.device_id} 测量页面操作执行成功")
# 在测量操作完成后执行断面里程配置
logging.info(f"设备 {self.device_id} 开始执行断面里程配置")
if not self.section_mileage_config_page.section_mileage_config_page_manager():
logging.error(f"设备 {self.device_id} 断面里程配置执行失败")
# 任务完成后短暂等待
logging.info(f"设备 {self.device_id}{task_count}个任务完成")
task_count += 1
# # 执行打数据加转点
# if not self.check_station.run():
# logging.error(f"设备 {self.device_id} 打数据加转点执行失败")
# return False
# # 执行上传配置管理,传入当前断点名称
# breakpoint_name = global_variable.GLOBAL_CURRENT_PROJECT_NAME
# line_num = global_variable.GLOBAL_LINE_NUM
# if self.upload_config_page.upload_config_page_manager(self.results_dir, breakpoint_name, line_num):
# logging.info(f"设备 {self.device_id} 断点 '{breakpoint_name}' 上传成功")
# upload_success_count += 1
# else:
# logging.error(f"设备 {self.device_id} 断点 '{breakpoint_name}' 上传失败")
# for i in range(3):
# if self.upload_config_page.upload_config_page_manager(self.results_dir, breakpoint_name, line_num):
# logging.info(f"设备 {self.device_id} 断点 '{breakpoint_name}' 重试上传成功")
# upload_success_count += 1
# break
# else:
# logging.error(f"设备 {self.device_id} 断点 '{breakpoint_name}' 上传失败,第 {i+1} 次重试")
# return task_count > 0
except Exception as e:
logging.error(f"设备 {self.device_id} 处理应用状态时出错: {str(e)}")
return False
# 主执行逻辑
if __name__ == "__main__":
device_id = create_link.setup_adb_wireless()
automation = None
try:
if not device_id:
logging.error("未能获取设备 ID无法继续执行自动化流程")
else:
automation = DeviceAutomation(device_id=device_id)
success = automation.run_automation()
if success:
logging.info(f"设备 {automation.device_id} 自动化流程执行成功")
else:
logging.error(f"设备 {automation.device_id} 自动化流程执行失败")
# 保持脚本运行,不关闭连接
logging.info("自动化流程执行完成,保持连接状态...")
logging.info("按 Ctrl+C 退出并关闭连接")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
logging.info("用户中断,准备关闭连接...")
except Exception as e:
logging.error(f"设备执行出错: {str(e)}")
finally:
if automation:
driver_utils.safe_quit_driver(automation.driver, automation.device_id)