Add monitor brightness support
This commit is contained in:
parent
3f789410a9
commit
63c86ab80e
43
src/lib.rs
43
src/lib.rs
|
@ -17,9 +17,15 @@ enum Command {
|
|||
Monitor((usize, MonitorCommand)),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MonitorBrightnessCmd {
|
||||
Absolute(u8),
|
||||
Relative(i8),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MonitorCommand {
|
||||
Brightness(u8),
|
||||
Brightness(MonitorBrightnessCmd),
|
||||
Input(u8),
|
||||
}
|
||||
|
||||
|
@ -51,17 +57,42 @@ fn run_i2c(idx: usize, mut dev: I2cDeviceDdc, command_channel: Receiver<MonitorC
|
|||
}
|
||||
}
|
||||
event!(Level::INFO, monitor_index = idx, ?cmd, "Sending DDC comand");
|
||||
if let Err(e) = match cmd {
|
||||
MonitorCommand::Brightness(b) => dev.set_vcp_feature(cmd.vcp(), b.into()),
|
||||
// Hack - add 15 to align with DELL monitors
|
||||
MonitorCommand::Input(i) => dev.set_vcp_feature(cmd.vcp(), (i + 15).into()),
|
||||
} {
|
||||
if let Err(e) = handle_monitor_cmd(&cmd, &mut dev) {
|
||||
event!(Level::WARN, err = %e, "Error sending DDC command");
|
||||
}
|
||||
last_sent_command.insert(cmd.cmd_str(), Some(Instant::now()));
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_monitor_cmd(cmd: &MonitorCommand, dev: &mut I2cDeviceDdc) -> StdError<()> {
|
||||
match cmd {
|
||||
MonitorCommand::Brightness(MonitorBrightnessCmd::Absolute(b)) => {
|
||||
event!(Level::INFO, brightness = b, "Setting monitor brightness");
|
||||
dev.set_vcp_feature(cmd.vcp(), (*b).into())
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
MonitorCommand::Brightness(MonitorBrightnessCmd::Relative(b)) => {
|
||||
let current = dev.get_vcp_feature(cmd.vcp())?;
|
||||
let (current, max) = (current.value(), current.maximum());
|
||||
event!(Level::INFO, current, max, "Got brightness of monitor");
|
||||
if max != 100 {
|
||||
return Err(format!("Expected maximum brightness to be 100, got {}", max).into());
|
||||
}
|
||||
let mut new = current.saturating_add_signed(*b as i16);
|
||||
// Clamp to 0-100
|
||||
if new > 100 {
|
||||
new = 100;
|
||||
}
|
||||
event!(Level::INFO, brightness = new, "Setting monitor brightness");
|
||||
dev.set_vcp_feature(cmd.vcp(), new).map_err(|e| e.into())
|
||||
}
|
||||
// Hack - add 15 to align with DELL monitors
|
||||
MonitorCommand::Input(i) => dev
|
||||
.set_vcp_feature(cmd.vcp(), (i + 15).into())
|
||||
.map_err(|e| e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() -> StdError<()> {
|
||||
event!(Level::INFO, "Starting");
|
||||
let displays = I2cDeviceEnumerator::new().unwrap().collect::<Vec<_>>();
|
||||
|
|
19
src/mqtt.rs
19
src/mqtt.rs
|
@ -1,4 +1,4 @@
|
|||
use crate::{handle_cmd, Command, MonitorCommand, StdError};
|
||||
use crate::{handle_cmd, Command, MonitorBrightnessCmd, MonitorCommand, StdError};
|
||||
use rumqttc::mqttbytes::v4::Packet;
|
||||
use rumqttc::{Client, Event, MqttOptions, QoS};
|
||||
use std::env;
|
||||
|
@ -8,6 +8,7 @@ use tracing::{event, Level};
|
|||
|
||||
pub fn run_mqtt(txes: &Vec<Sender<MonitorCommand>>) -> StdError<()> {
|
||||
let client_id = env::var("MQTT_CLIENT_ID").unwrap_or("ddcmqtt".into());
|
||||
let topic_prefix = env::var("MQTT_TOPIC_PREFIX").unwrap_or("ddcmqtt".into());
|
||||
let mqtt_host = env::var("MQTT_HOST").unwrap_or("localhost".into());
|
||||
let mqtt_port = env::var("MQTT_PORT")
|
||||
.unwrap_or("1883".into())
|
||||
|
@ -24,7 +25,7 @@ pub fn run_mqtt(txes: &Vec<Sender<MonitorCommand>>) -> StdError<()> {
|
|||
mqttoptions.set_keep_alive(Duration::from_secs(5));
|
||||
|
||||
let (mut client, mut connection) = Client::new(mqttoptions, 10);
|
||||
client.subscribe("ddcmqtt/#", QoS::AtMostOnce)?;
|
||||
client.subscribe([&topic_prefix, "#"].join("/"), QoS::AtMostOnce)?;
|
||||
|
||||
event!(Level::INFO, mqtt_host, mqtt_port, "Running MQTT client");
|
||||
|
||||
|
@ -40,7 +41,7 @@ pub fn run_mqtt(txes: &Vec<Sender<MonitorCommand>>) -> StdError<()> {
|
|||
);
|
||||
continue;
|
||||
}
|
||||
if topic[0] != "ddcmqtt" {
|
||||
if topic[0] != topic_prefix {
|
||||
event!(
|
||||
Level::ERROR,
|
||||
?topic,
|
||||
|
@ -58,6 +59,18 @@ pub fn run_mqtt(txes: &Vec<Sender<MonitorCommand>>) -> StdError<()> {
|
|||
&txes,
|
||||
)?;
|
||||
}
|
||||
(Ok(idx), "brightness") => {
|
||||
let brightness = std::str::from_utf8(&p.payload)?;
|
||||
let cmd = if brightness.starts_with('+') | brightness.starts_with('-') {
|
||||
MonitorBrightnessCmd::Relative(brightness.parse::<i8>()?)
|
||||
} else {
|
||||
MonitorBrightnessCmd::Absolute(brightness.parse::<u8>()?)
|
||||
};
|
||||
handle_cmd(
|
||||
Command::Monitor((idx.into(), MonitorCommand::Brightness(cmd))),
|
||||
&txes,
|
||||
)?;
|
||||
}
|
||||
_ => {
|
||||
event!(Level::ERROR, ?topic, "Unrecognised or invalid topic");
|
||||
continue;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{handle_cmd, Command, MonitorCommand, StdError};
|
||||
use crate::{handle_cmd, Command, MonitorBrightnessCmd, MonitorCommand, StdError};
|
||||
use rosc;
|
||||
use std::net::UdpSocket;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
@ -36,9 +36,9 @@ fn osc_message_to_command(msg: rosc::OscMessage) -> StdError<Command> {
|
|||
["monitor", idx, control] => {
|
||||
println!("Monitor {}, control {}, args {:?}", idx, control, msg.args);
|
||||
let command = match *control {
|
||||
"brightness" => Some(MonitorCommand::Brightness(
|
||||
"brightness" => Some(MonitorCommand::Brightness(MonitorBrightnessCmd::Absolute(
|
||||
(msg.args[0].clone().float().unwrap() * 100.0) as u8,
|
||||
)),
|
||||
))),
|
||||
"input" => Some(MonitorCommand::Input(
|
||||
(msg.args[0].clone().int().unwrap()) as u8,
|
||||
)),
|
||||
|
|
Loading…
Reference in New Issue