wisun_download/src/main.rs

335 lines
13 KiB
Rust
Raw Normal View History

mod download_wrapper;
mod mes_service;
use std::any::Any;
use crossbeam::channel;
use std::sync::{Arc, Mutex, LazyLock};
use crossbeam::channel::Sender;
use iced::widget::{button, checkbox, column, container, radio, row, text_editor, text_input};
use iced::{event, window, Element, Event, Length, Subscription, Task, time};
use iced::application::Title;
2024-12-06 17:57:22 +08:00
use iced::widget::text_editor::Action::Scroll;
use iced::widget::text_editor::Edit;
use download_wrapper::DownloadType;
use crate::mes_service::MesService;
pub fn main() -> iced::Result {
2024-12-06 17:57:22 +08:00
iced::application("WisunDownload V0.1", MainWindow::update, MainWindow::view)
.subscription(MainWindow::subscription)
.exit_on_close_request(false)
2024-12-06 17:57:22 +08:00
.window_size((830.0, 600.0))
.run()
}
static logs: LazyLock<Arc<Mutex<Vec<String>>>> = LazyLock::new(|| {
Arc::new(Mutex::new(Vec::new()))
});
2024-12-06 17:57:22 +08:00
struct MainWindow {
is_online: bool,
mysql_config: MysqlConfig,
selection: Option<DownloadType>,
label: String,
log_content: text_editor::Content,
sender: Sender<bool>,
receiver: crossbeam::channel::Receiver<bool>,
2024-12-06 17:57:22 +08:00
}
impl Default for MainWindow {
fn default() -> Self {
let (sender, receiver) = crossbeam::channel::unbounded();
Self {
is_online: true,
mysql_config: MysqlConfig::default(),
selection: None,
label: String::new(),
log_content: text_editor::Content::default(),
sender,
receiver
}
}
}
2024-12-06 17:57:22 +08:00
#[derive(Debug, Clone, Default)]
struct MysqlConfig {
2024-12-06 17:57:22 +08:00
ip: String,
port: String,
username: String,
password: String,
database: String,
work_order: String,
}
#[derive(Debug, Clone)]
enum Message {
2024-12-06 17:57:22 +08:00
Start(),
IpChanged(String),
PortChanged(String),
UsernameChanged(String),
PasswordChanged(String),
DatabaseChanged(String),
WorkOrderChanged(String),
LabelChanged(String),
TypeSelected(DownloadType),
OnlineChecked(bool),
AddLog(String),
LogContentChanged(text_editor::Action),
SaveConfig,
DownloadEnd(bool),
WindowEvent(Event),
Tick,
2024-12-06 17:57:22 +08:00
}
pub fn add_log<'a>(msg: String) {
let time_now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
let really_msg = format!("{time_now} [Info]: {msg}");
logs.lock().unwrap().push(really_msg);
2024-12-06 17:57:22 +08:00
}
impl MainWindow {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
2024-12-06 17:57:22 +08:00
Message::Start() => {
self.start(self.sender.clone());
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::IpChanged(ip) => {
self.mysql_config.ip = ip;
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::PortChanged(port) => {
self.mysql_config.port = port;
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::UsernameChanged(username) => {
self.mysql_config.username = username;
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::PasswordChanged(password) => {
self.mysql_config.password = password;
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::DatabaseChanged(database) => {
self.mysql_config.database = database;
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::WorkOrderChanged(work_order) => {
self.mysql_config.work_order = work_order;
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::TypeSelected(download_type) => {
self.selection = Some(download_type);
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::LabelChanged(label) => {
self.label = label;
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::OnlineChecked(is_online) => {
self.is_online = is_online;
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::AddLog(log) => {
for c in log.chars() {
2024-12-06 17:57:22 +08:00
self.log_content.perform(text_editor::Action::Edit(Edit::Insert(c)))
}
self.log_content.perform(text_editor::Action::Edit(Edit::Enter));
let line_size = self.log_content.lines().count();
self.log_content.perform(Scroll { lines: line_size as i32 });
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::Tick => {
for log in logs.lock().unwrap().iter() {
for c in log.chars() {
self.log_content.perform(text_editor::Action::Edit(Edit::Insert(c)))
}
self.log_content.perform(text_editor::Action::Edit(Edit::Enter));
let line_size = self.log_content.lines().count();
self.log_content.perform(Scroll { lines: line_size as i32 });
2024-12-06 17:57:22 +08:00
}
logs.lock().unwrap().clear();
match self.receiver.try_recv() {
Ok(res) => {
self.update(Message::DownloadEnd(res));
}
Err(channel::TryRecvError::Empty) => {
}
Err(channel::TryRecvError::Disconnected) => {
println!("Disconnected");
}
};
Task::none()
2024-12-06 17:57:22 +08:00
}
Message::LogContentChanged(action) => {
match action{
Scroll { lines } => {
self.log_content.perform(Scroll { lines });
Task::none()
}
_=>{
Task::none()
}
}
}
Message::DownloadEnd(res)=>{
if res{
add_log("下载成功 By Ui Thread".to_string());
}else{
add_log("下载失败 By Ui Thread".to_string());
}
Task::none()
}
Message::WindowEvent(event) => {
//println!("{:?}", event);
if let Event::Window(window::Event::CloseRequested) = event {
println!("Request Close");
return window::get_latest().and_then(window::close);
};
Task::none()
}
_ => { Task::none() }
2024-12-06 17:57:22 +08:00
}
}
fn view(&self) -> Element<Message> {
2024-12-06 17:57:22 +08:00
let ip_input = text_input(
"IP Address",
&self.mysql_config.ip,
).on_input(Message::IpChanged);
let port_input = text_input(
"Port",
&self.mysql_config.port,
).on_input(Message::PortChanged);
let username_input = text_input(
"Username",
&self.mysql_config.username,
2024-12-06 17:57:22 +08:00
).on_input(Message::UsernameChanged);
let password_input = text_input(
"Password",
&self.mysql_config.password,
2024-12-06 17:57:22 +08:00
).on_input(Message::PasswordChanged);
let database_input = text_input(
"Database",
&self.mysql_config.database,
2024-12-06 17:57:22 +08:00
).on_input(Message::DatabaseChanged);
let work_order_input = text_input(
"WorkOrder",
&self.mysql_config.work_order,
2024-12-06 17:57:22 +08:00
).on_input(Message::WorkOrderChanged);
let label_input = text_input(
"label",
&self.label,
2024-12-06 17:57:22 +08:00
).on_input(Message::LabelChanged).on_submit(Message::Start()).width(Length::Fill);
let content = column![
row![ip_input, port_input].spacing(5),
row![username_input, password_input].spacing(5),
row![database_input, work_order_input].spacing(5),
row![
radio("BootLoader", DownloadType::Bootloader,self.selection,Message::TypeSelected),
2024-12-06 17:57:22 +08:00
radio("App", DownloadType::App,self.selection,Message::TypeSelected),
radio("Cal", DownloadType::Rail,self.selection,Message::TypeSelected),
2024-12-06 17:57:22 +08:00
checkbox("online", self.is_online).on_toggle(Message::OnlineChecked)
].spacing(10),
row![label_input,button("Start").on_press(Message::Start())].spacing(10),
text_editor(&self.log_content).on_action(Message::LogContentChanged).height(Length::Fill)
].spacing(10).padding(5);
let container = container(content).padding(20);
container.into()
}
fn subscription(&self) -> Subscription<Message> {
Subscription::batch(vec![
event::listen().map(Message::WindowEvent),
time::every(time::Duration::from_millis(50))
.map(|_| Message::Tick)
])
}
fn start(&mut self, sender: Sender<bool>) -> (){
let mes_config = self.mysql_config.clone();
let label = self.label.clone();
let download_type: DownloadType = self.selection.unwrap();
let online = self.is_online.clone();
std::thread::spawn(move || {
let mut download_wrapper = download_wrapper::DownloadWrapper::new();
let mut mes_service: MesService;
if online {
add_log("当前为在线模式, 正在连接数据库".to_string());
mes_service = MesService::new(mes_config.ip.clone(), mes_config.port.clone(), mes_config.username.clone(), mes_config.password.clone(), mes_config.database.clone());
add_log("连接成功".to_string());
add_log("正在过站检测".to_string());
let check_result = mes_service.check_station(mes_config.work_order.clone(), label.clone(), download_type);
if let Err(res) = check_result {
add_log(format!("过站检测失败: {:?}", res));
sender.send(false).unwrap();
} else if let Ok(res) = check_result {
if !res {
add_log("过站检测失败".to_string());
sender.send(false).unwrap();
}
add_log("过站检测成功".to_string());
}
}
add_log("正在检查JLink连接".to_string());
if let Err(e) = download_wrapper.check_jlink() {
add_log("JLink检查失败, 请检查是否安装驱动或连接是否异常".to_string());
sender.send(false).unwrap();
}
add_log("JLink检查成功".to_string());
add_log("正在检查设备连接".to_string());
if let Err(e) = download_wrapper.check_device() {
add_log("设备检查失败, 请检查设备是否连接".to_string());
sender.send(false).unwrap();
}
add_log("设备检查成功".to_string());
match download_type {
DownloadType::Bootloader =>{
add_log("正在擦除Flash".to_string());
if let Err(e) = download_wrapper.erase(){
add_log("擦除失败".to_string());
sender.send(false).unwrap();
}
add_log("擦除成功".to_string());
add_log("正在下载BootLoader".to_string());
if let Err(e) = download_wrapper.download(download_type){
add_log("下载BootLoader失败".to_string());
sender.send(false).unwrap();
}
add_log("下载成功".to_string());
}
DownloadType::App =>{
add_log("正在下载App".to_string());
if let Err(e) = download_wrapper.download(download_type){
add_log("下载App失败".to_string());
sender.send(false).unwrap();
}
add_log("下载成功".to_string());
}
DownloadType::Rail=>{
add_log("正在下载Rail".to_string());
if let Err(e) = download_wrapper.download(download_type){
add_log("下载Rail失败".to_string());
sender.send(false).unwrap();
}
add_log("下载成功".to_string());
}
}
return if online {
mes_service = MesService::new(mes_config.ip, mes_config.port, mes_config.username, mes_config.password, mes_config.database);
add_log("正在上传数据".to_string());
let update_result = mes_service.update_station(mes_config.work_order, label, download_type);
if let Err(e) = update_result {
add_log(format!("上传失败: {:?}", e));
sender.send(false).unwrap();
}
sender.send(true).unwrap();
} else {
add_log("当前为离线模式".to_string());
sender.send(true).unwrap();
}
});
}
2024-12-06 17:57:22 +08:00
}