Remote send status messages
This commit is contained in:
32
Cargo.lock
generated
32
Cargo.lock
generated
@@ -530,6 +530,12 @@ dependencies = [
|
|||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jobserver"
|
name = "jobserver"
|
||||||
version = "0.1.31"
|
version = "0.1.31"
|
||||||
@@ -1007,6 +1013,15 @@ dependencies = [
|
|||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "remote_send"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rgb"
|
name = "rgb"
|
||||||
version = "0.8.37"
|
version = "0.8.37"
|
||||||
@@ -1016,6 +1031,12 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "safe_arch"
|
name = "safe_arch"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
@@ -1051,6 +1072,17 @@ dependencies = [
|
|||||||
"syn 2.0.66",
|
"syn 2.0.66",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.117"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_spanned"
|
name = "serde_spanned"
|
||||||
version = "0.6.6"
|
version = "0.6.6"
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = ["slicer", "common", "goo_format"]
|
members = ["slicer", "common", "goo_format", "remote_send"]
|
||||||
|
9
remote_send/Cargo.toml
Normal file
9
remote_send/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "remote_send"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.86"
|
||||||
|
serde = { version = "1.0.203", features = ["derive"] }
|
||||||
|
serde_json = "1.0.117"
|
4
remote_send/README.md
Normal file
4
remote_send/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# `remote_send`
|
||||||
|
|
||||||
|
Library / tool for remote control of ChiTu-mainboard resin printers.
|
||||||
|
Thank you to [Vladimir Vukicevic](https://github.com/vvuk) for figuring all of the protocol communication stuff out, find his writeup and implementation of the protocol [here](https://github.com/vvuk/cassini).
|
31
remote_send/src/lib.rs
Normal file
31
remote_send/src/lib.rs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use serde::{Deserialize, Deserializer};
|
||||||
|
|
||||||
|
pub mod status;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct Response<Data> {
|
||||||
|
id: String,
|
||||||
|
data: Data,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Resolution {
|
||||||
|
x: u16,
|
||||||
|
y: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_resolution<'de, D>(from: D) -> Result<Resolution, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let str = String::deserialize(from)?;
|
||||||
|
let (x, y) = str
|
||||||
|
.split_once('x')
|
||||||
|
.ok_or_else(|| serde::de::Error::custom("Invalid resolution"))?;
|
||||||
|
Ok(Resolution {
|
||||||
|
x: x.parse().map_err(serde::de::Error::custom)?,
|
||||||
|
y: y.parse().map_err(serde::de::Error::custom)?,
|
||||||
|
})
|
||||||
|
}
|
21
remote_send/src/main.rs
Normal file
21
remote_send/src/main.rs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
use std::net::UdpSocket;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use remote_send::{status::StatusData, Response};
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
let socket = UdpSocket::bind("0.0.0.0:3000")?;
|
||||||
|
|
||||||
|
let msg = b"M99999";
|
||||||
|
socket.send_to(msg, "192.168.1.233:3000")?;
|
||||||
|
|
||||||
|
let mut buffer = [0; 1024];
|
||||||
|
let (len, _addr) = socket.recv_from(&mut buffer)?;
|
||||||
|
|
||||||
|
let received = String::from_utf8_lossy(&buffer[..len]);
|
||||||
|
let response = serde_json::from_str::<Response<StatusData>>(&received)?;
|
||||||
|
dbg!(response);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
70
remote_send/src/status.rs
Normal file
70
remote_send/src/status.rs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use crate::{parse_resolution, Resolution};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct StatusData {
|
||||||
|
pub attributes: Attributes,
|
||||||
|
pub status: Status,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct Attributes {
|
||||||
|
name: String,
|
||||||
|
machine_name: String,
|
||||||
|
protocol_version: String,
|
||||||
|
firmware_version: String,
|
||||||
|
#[serde(deserialize_with = "parse_resolution")]
|
||||||
|
resolution: Resolution,
|
||||||
|
#[serde(rename = "MainboardIP")]
|
||||||
|
mainboard_ip: String,
|
||||||
|
#[serde(rename = "MainboardID")]
|
||||||
|
mainboard_id: String,
|
||||||
|
#[serde(rename = "SDCPStatus")]
|
||||||
|
sdcp_status: u8,
|
||||||
|
#[serde(rename = "LocalSDCPAddress")]
|
||||||
|
local_sdcp_address: String,
|
||||||
|
#[serde(rename = "SDCPAddress")]
|
||||||
|
sdcp_address: String,
|
||||||
|
capabilities: Vec<Capability>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
pub enum Capability {
|
||||||
|
FileTransfer,
|
||||||
|
PrintControl,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct Status {
|
||||||
|
current_status: u8,
|
||||||
|
previous_status: u8,
|
||||||
|
print_info: PrintInfo,
|
||||||
|
file_transfer_info: FileTransferInfo,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct PrintInfo {
|
||||||
|
status: u8,
|
||||||
|
current_layer: u32,
|
||||||
|
total_layer: u32,
|
||||||
|
current_ticks: u32,
|
||||||
|
total_ticks: u32,
|
||||||
|
error_number: u8,
|
||||||
|
filename: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct FileTransferInfo {
|
||||||
|
status: u8,
|
||||||
|
download_offset: u32,
|
||||||
|
check_offset: u32,
|
||||||
|
file_total_size: u32,
|
||||||
|
filename: String,
|
||||||
|
}
|
Reference in New Issue
Block a user