fmt, update deps, random tweaks
This commit is contained in:
parent
3a997c0f7b
commit
67e42eaa37
|
@ -68,9 +68,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i2c-linux-sys"
|
name = "i2c-linux-sys"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b70fd3d30157850c87f4c7c09c0857d9c2e8c996bcbe23ec1299126e0479ec"
|
checksum = "55cd060ed0016621d3da4ed3a23b0158084de90d1f3a8e59f3d391aacd3bbcf8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
@ -79,9 +79,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.121"
|
version = "0.2.125"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
|
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libudev-sys"
|
name = "libudev-sys"
|
||||||
|
@ -104,9 +104,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.4.1"
|
version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
|
@ -126,9 +126,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.24"
|
version = "0.3.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "resize-slice"
|
name = "resize-slice"
|
||||||
|
|
71
flake.lock
71
flake.lock
|
@ -6,11 +6,11 @@
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1647857022,
|
"lastModified": 1649691969,
|
||||||
"narHash": "sha256-Aw70NWLOIwKhT60MHDGjgWis3DP3faCzr6ap9CSayek=",
|
"narHash": "sha256-nY1aUWIyh3TcGVo3sn+3vyCh+tOiEZL4JtMX3aOZSeY=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "devshell",
|
"repo": "devshell",
|
||||||
"rev": "0a5ff74dacb9ea22614f64e61aeb3ca0bf0e7311",
|
"rev": "e22633b05fec2fe196888c593d4d9b3f4f648a25",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -36,11 +36,26 @@
|
||||||
},
|
},
|
||||||
"flake-utils_2": {
|
"flake-utils_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1648297722,
|
"lastModified": 1649676176,
|
||||||
"narHash": "sha256-W+qlPsiZd8F3XkzXOzAoR+mpFqzm3ekQkJNa+PIh1BQ=",
|
"narHash": "sha256-OWKJratjt2RW151VUlJPRALb7OU2S5s+f0vLj4o1bHM=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "0f8662f1319ad6abf89b3380dd2722369fc51ade",
|
"rev": "a4b154ebbdc88c8498a5c7b01589addc9e9cb678",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1637014545,
|
||||||
|
"narHash": "sha256-26IZAc5yzlD9FlDT54io1oqG/bBoyka+FJk5guaX4x4=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "bba5dcc8e0b20ab664967ad83d24d64cb64ec4f4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -54,11 +69,11 @@
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1648544490,
|
"lastModified": 1649096192,
|
||||||
"narHash": "sha256-EoBDcccV70tfz2LAs5lK0BjC7en5mzUVlgLsd5E6DW4=",
|
"narHash": "sha256-7O8e+eZEYeU+ET98u/zW5epuoN/xYx9G+CIh4DjZVzY=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "naersk",
|
"repo": "naersk",
|
||||||
"rev": "e30ef9a5ce9b3de8bb438f15829c50f9525ca730",
|
"rev": "d626f73332a8f587b613b0afe7293dd0777be07d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -109,12 +124,48 @@
|
||||||
"type": "indirect"
|
"type": "indirect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs_4": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1637453606,
|
||||||
|
"narHash": "sha256-Gy6cwUswft9xqsjWxFYEnx/63/qzaFUwatcbV5GF/GQ=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "8afc4e543663ca0a6a4f496262cd05233737e732",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"devshell": "devshell",
|
"devshell": "devshell",
|
||||||
"flake-utils": "flake-utils_2",
|
"flake-utils": "flake-utils_2",
|
||||||
"naersk": "naersk",
|
"naersk": "naersk",
|
||||||
"nixpkgs": "nixpkgs_3"
|
"nixpkgs": "nixpkgs_3",
|
||||||
|
"rust-overlay": "rust-overlay"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils_3",
|
||||||
|
"nixpkgs": "nixpkgs_4"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1649644592,
|
||||||
|
"narHash": "sha256-q4vQ54pmCC+b5+bdsH2/90jIeiydTAJhF2IvP13r3yA=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "4770c6c6cb518d2c5b660c5099816c3512d8bdad",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
13
flake.nix
13
flake.nix
|
@ -4,12 +4,17 @@
|
||||||
inputs.devshell.url = "github:numtide/devshell";
|
inputs.devshell.url = "github:numtide/devshell";
|
||||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||||
inputs.naersk.url = "github:nix-community/naersk";
|
inputs.naersk.url = "github:nix-community/naersk";
|
||||||
|
inputs.rust-overlay.url = "github:oxalica/rust-overlay";
|
||||||
|
|
||||||
outputs = { self, flake-utils, devshell, nixpkgs, naersk }:
|
outputs = { self, flake-utils, devshell, nixpkgs, naersk, rust-overlay }:
|
||||||
flake-utils.lib.eachDefaultSystem (system: let
|
flake-utils.lib.eachDefaultSystem (system: let
|
||||||
pkgs = nixpkgs.legacyPackages."${system}";
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = [ (import rust-overlay) ];
|
||||||
|
};
|
||||||
naersk-lib = naersk.lib."${system}";
|
naersk-lib = naersk.lib."${system}";
|
||||||
in {
|
in {
|
||||||
|
/*
|
||||||
defaultPackage = naersk-lib.buildPackage {
|
defaultPackage = naersk-lib.buildPackage {
|
||||||
pname = "ddcmqtt";
|
pname = "ddcmqtt";
|
||||||
root = ./.;
|
root = ./.;
|
||||||
|
@ -28,8 +33,8 @@
|
||||||
nativeBuildInputs = with pkgs; [ libudev pkgconfig ];
|
nativeBuildInputs = with pkgs; [ libudev pkgconfig ];
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
devshell = pkgs.mkShell{
|
devShell = pkgs.mkShell{
|
||||||
nativeBuildInputs = with pkgs; [ rustc cargo libudev pkgconfig ];
|
nativeBuildInputs = with pkgs; [ rust-bin.stable.latest.default libudev pkgconfig ];
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use ::ddcmqtt::{main as main_, StdError};
|
use ::ddcmqtt::{main as main_, StdError};
|
||||||
|
|
||||||
|
|
||||||
fn main() -> StdError<()> {
|
fn main() -> StdError<()> {
|
||||||
main_()
|
main_()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use ddc_i2c::{I2cDeviceEnumerator, I2cDeviceDdc};
|
|
||||||
use ddc::Ddc;
|
use ddc::Ddc;
|
||||||
|
use ddc_i2c::{I2cDeviceDdc, I2cDeviceEnumerator};
|
||||||
|
|
||||||
use ::ddcmqtt::{StdError};
|
use ::ddcmqtt::StdError;
|
||||||
|
|
||||||
fn main() -> StdError<()> {
|
fn main() -> StdError<()> {
|
||||||
let args_: Vec<_> = std::env::args().skip(1).collect();
|
let args_: Vec<_> = std::env::args().skip(1).collect();
|
||||||
|
@ -10,14 +10,14 @@ fn main() -> StdError<()> {
|
||||||
["brightness", arg] => ddc_all(0x10, arg.parse::<u16>()?),
|
["brightness", arg] => ddc_all(0x10, arg.parse::<u16>()?),
|
||||||
["input", arg] => ddc_all(0x60, arg.parse::<u16>()?),
|
["input", arg] => ddc_all(0x60, arg.parse::<u16>()?),
|
||||||
_ => Err("Bad usage".into()),
|
_ => Err("Bad usage".into()),
|
||||||
|
|
||||||
}?;
|
}?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ddc_all(feat: u8, val: u16) -> StdError<()> {
|
fn ddc_all(feat: u8, val: u16) -> StdError<()> {
|
||||||
for mut display in I2cDeviceEnumerator::new()? {
|
let mut m1 = ddc_i2c::from_i2c_device("/dev/i2c-20")?;
|
||||||
display.set_vcp_feature(feat, val)?;
|
let mut m2 = ddc_i2c::from_i2c_device("/dev/i2c-21")?;
|
||||||
}
|
m1.set_vcp_feature(feat, val)?;
|
||||||
|
m2.set_vcp_feature(feat, val)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
57
src/lib.rs
57
src/lib.rs
|
@ -1,14 +1,12 @@
|
||||||
#![allow(unreachable_code)]
|
|
||||||
use ddc::Ddc;
|
use ddc::Ddc;
|
||||||
use ddc_i2c::{I2cDeviceEnumerator, I2cDeviceDdc};
|
use ddc_i2c::{I2cDeviceDdc, I2cDeviceEnumerator};
|
||||||
use rosc;
|
|
||||||
use std::net::UdpSocket;
|
|
||||||
use std::thread;
|
|
||||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
|
||||||
use std::time::{Duration, Instant};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::net::UdpSocket;
|
||||||
|
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||||
|
use std::thread;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
use rosc;
|
||||||
|
|
||||||
pub type StdError<T> = Result<T, Box<dyn Error>>;
|
pub type StdError<T> = Result<T, Box<dyn Error>>;
|
||||||
|
|
||||||
|
@ -18,7 +16,7 @@ enum Command {
|
||||||
|
|
||||||
enum MonitorCommand {
|
enum MonitorCommand {
|
||||||
Brightness(u8),
|
Brightness(u8),
|
||||||
Input(u8)
|
Input(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonitorCommand {
|
impl MonitorCommand {
|
||||||
|
@ -37,10 +35,9 @@ impl MonitorCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Run an i2c command handler for a specific i2c device, rate limiting each type of command
|
// Run an i2c command handler for a specific i2c device, rate limiting each type of command
|
||||||
fn run_i2c(mut dev: I2cDeviceDdc, command_channel: Receiver<MonitorCommand>) {
|
fn run_i2c(mut dev: I2cDeviceDdc, command_channel: Receiver<MonitorCommand>) {
|
||||||
let mut last_sent_command: HashMap<&str, Option<Instant>> = HashMap::new();
|
let mut last_sent_command: HashMap<&str, Option<Instant>> = HashMap::new();
|
||||||
loop {
|
loop {
|
||||||
let cmd = command_channel.recv().unwrap();
|
let cmd = command_channel.recv().unwrap();
|
||||||
if let Some(last) = last_sent_command.entry(cmd.cmd_str()).or_insert(None) {
|
if let Some(last) = last_sent_command.entry(cmd.cmd_str()).or_insert(None) {
|
||||||
|
@ -52,7 +49,7 @@ fn run_i2c(mut dev: I2cDeviceDdc, command_channel: Receiver<MonitorCommand>) {
|
||||||
match cmd {
|
match cmd {
|
||||||
MonitorCommand::Brightness(b) => dev.set_vcp_feature(0x10, b.into()).unwrap(),
|
MonitorCommand::Brightness(b) => dev.set_vcp_feature(0x10, b.into()).unwrap(),
|
||||||
// Hack - add 15 to align with DELL monitors
|
// Hack - add 15 to align with DELL monitors
|
||||||
MonitorCommand::Input(i) => dev.set_vcp_feature(0x60, (i+15).into()).unwrap(),
|
MonitorCommand::Input(i) => dev.set_vcp_feature(0x60, (i + 15).into()).unwrap(),
|
||||||
}
|
}
|
||||||
last_sent_command.insert(cmd.cmd_str(), Some(Instant::now()));
|
last_sent_command.insert(cmd.cmd_str(), Some(Instant::now()));
|
||||||
}
|
}
|
||||||
|
@ -61,24 +58,29 @@ fn run_i2c(mut dev: I2cDeviceDdc, command_channel: Receiver<MonitorCommand>) {
|
||||||
pub fn main() -> StdError<()> {
|
pub fn main() -> StdError<()> {
|
||||||
let displays = I2cDeviceEnumerator::new().unwrap().collect::<Vec<_>>();
|
let displays = I2cDeviceEnumerator::new().unwrap().collect::<Vec<_>>();
|
||||||
println!("Enumerated {} displays", displays.len());
|
println!("Enumerated {} displays", displays.len());
|
||||||
let txes: Vec<_> = displays.into_iter().map(|d| {
|
let txes: Vec<_> = displays
|
||||||
let (tx, rx) = channel();
|
.into_iter()
|
||||||
thread::spawn(move|| run_i2c(d, rx));
|
.map(|d| {
|
||||||
tx
|
let (tx, rx) = channel();
|
||||||
}).collect();
|
thread::spawn(move || run_i2c(d, rx));
|
||||||
|
tx
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
let sock = UdpSocket::bind("0.0.0.0:1234").unwrap();
|
let sock = UdpSocket::bind("0.0.0.0:1234").unwrap();
|
||||||
let mut buf = [0u8; rosc::decoder::MTU];
|
let mut buf = [0u8; rosc::decoder::MTU];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let (size, addr) = sock.recv_from(&mut buf).unwrap();
|
let (size, addr) = sock.recv_from(&mut buf).unwrap();
|
||||||
println!("Got {} bytes from {}", size, addr);
|
println!("Got {} bytes from {}", size, addr);
|
||||||
let (_, pack) = rosc::decoder::decode_udp(&buf[..size]).unwrap();
|
let (_, pack) = rosc::decoder::decode_udp(&buf[..size]).unwrap();
|
||||||
match pack {
|
match pack {
|
||||||
rosc::OscPacket::Message(msg) => {
|
rosc::OscPacket::Message(msg) => {
|
||||||
match osc_message_to_command(msg) {
|
match osc_message_to_command(msg) {
|
||||||
Ok(cmd) => if let Err(e) = handle_cmd(cmd, &txes) {
|
Ok(cmd) => {
|
||||||
println!("Error handling command: {:?}", e);
|
if let Err(e) = handle_cmd(cmd, &txes) {
|
||||||
},
|
println!("Error handling command: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(e) => println!("Unrecognised OSC command: {:?}", e),
|
Err(e) => println!("Unrecognised OSC command: {:?}", e),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -103,13 +105,18 @@ fn osc_message_to_command(msg: rosc::OscMessage) -> StdError<Command> {
|
||||||
["monitor", idx, control] => {
|
["monitor", idx, control] => {
|
||||||
println!("Monitor {}, control {}, args {:?}", idx, control, msg.args);
|
println!("Monitor {}, control {}, args {:?}", idx, control, msg.args);
|
||||||
let command = match *control {
|
let command = match *control {
|
||||||
"brightness" => Some(MonitorCommand::Brightness((msg.args[0].clone().float().unwrap() * 100.0) as u8)),
|
"brightness" => Some(MonitorCommand::Brightness(
|
||||||
"input" => Some(MonitorCommand::Input((msg.args[0].clone().int().unwrap()) as u8)),
|
(msg.args[0].clone().float().unwrap() * 100.0) as u8,
|
||||||
|
)),
|
||||||
|
"input" => Some(MonitorCommand::Input(
|
||||||
|
(msg.args[0].clone().int().unwrap()) as u8,
|
||||||
|
)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}.ok_or(format!("Unrecognised monitor control: {}", *control))?;
|
}
|
||||||
|
.ok_or(format!("Unrecognised monitor control: {}", *control))?;
|
||||||
let idx = idx.parse::<usize>().or(Err("Bad monitor index"))?;
|
let idx = idx.parse::<usize>().or(Err("Bad monitor index"))?;
|
||||||
Ok(Command::Monitor((idx, command)))
|
Ok(Command::Monitor((idx, command)))
|
||||||
},
|
}
|
||||||
_ => Err("Unsupported osc address, ignoring".into()),
|
_ => Err("Unsupported osc address, ignoring".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue