Skip to content

Commit

Permalink
Bridge rework almost done
Browse files Browse the repository at this point in the history
  • Loading branch information
newcat committed Feb 1, 2024
1 parent 342de6d commit a302e12
Show file tree
Hide file tree
Showing 23 changed files with 337 additions and 125 deletions.
2 changes: 1 addition & 1 deletion lms_bridge/bindings/ControllerType.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

export type ControllerType = "Wled" | "Dmx";
export type ControllerType = "WLED" | "DMX";
3 changes: 3 additions & 0 deletions lms_bridge/bindings/DmxControllerConfiguration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

export interface DmxControllerConfiguration { port: string, }
3 changes: 3 additions & 0 deletions lms_bridge/bindings/DmxControllerData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

export interface DmxControllerData { data: Array<number>, }
5 changes: 5 additions & 0 deletions lms_bridge/bindings/DmxControllerMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { DmxControllerConfiguration } from "./DmxControllerConfiguration";
import type { DmxControllerData } from "./DmxControllerData";

export type DmxControllerMessage = { type: "UpdateConfiguration" } & DmxControllerConfiguration | { type: "Data" } & DmxControllerData;
3 changes: 3 additions & 0 deletions lms_bridge/bindings/WledControllerData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

export interface WledControllerData { data: Array<number>, }
3 changes: 2 additions & 1 deletion lms_bridge/bindings/WledControllerMessage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { WledControllerConfiguration } from "./WledControllerConfiguration";
import type { WledControllerData } from "./WledControllerData";

export type WledControllerMessage = { UpdateConfiguration: WledControllerConfiguration } | { Data: Array<number> };
export type WledControllerMessage = { type: "UpdateConfiguration" } & WledControllerConfiguration | { type: "Data" } & WledControllerData;
47 changes: 30 additions & 17 deletions lms_bridge/src/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,40 +34,53 @@ impl Bridge {
println!("Adding controller: {} (type {:?})", id, controller_type);
let bridge_to_controller = channel();

let mut controller = match controller_type {
crate::types::ControllerType::Wled => {
crate::controllers::wled_controller::WledController::new(
self.controller_to_bridge_tx.clone(),
bridge_to_controller.1,
)
}
crate::types::ControllerType::Dmx => {
panic!("DMX controller not implemented yet");
}
};

self.controllers
.insert(id.to_owned(), bridge_to_controller.0);

let id_copy = id.to_owned();
thread::spawn(move || {
controller.run();
println!("Controller {} exited", id_copy)
});
self.spawn_and_run_controller(
id.clone(),
bridge_to_controller.1,
controller_type.clone(),
)
}
WsMessage::RemoveController { id } => {
println!("Removing controller: {}", id);
if let Some(tx) = self.controllers.get(id) {
let _ = tx.send(BridgeToControllerMessage::Dispose);
} else {
println!("Controller {} not found", id);
}
self.controllers.remove(id);
}
WsMessage::CallController { id, message } => {
println!("Calling controller: {} with message: {}", id, message);
if let Some(tx) = self.controllers.get(id) {
let _ = tx.send(BridgeToControllerMessage::Message(message.to_owned()));
} else {
println!("Controller {} not found", id);
}
}
}
}

fn spawn_and_run_controller(
self: &Self,
id: String,
btc: Receiver<BridgeToControllerMessage>,
controller_type: crate::types::ControllerType,
) {
let ctb = self.controller_to_bridge_tx.clone();
thread::spawn(move || {
let mut controller: Box<dyn Controller> = match controller_type {
crate::types::ControllerType::WLED => Box::new(
crate::controllers::wled_controller::WledController::new(ctb, btc),
),
crate::types::ControllerType::DMX => Box::new(
crate::controllers::dmx_controller::DmxController::new(ctb, btc),
),
};
controller.run();
println!("Controller {} exited", id)
});
}
}
98 changes: 98 additions & 0 deletions lms_bridge/src/controllers/dmx_controller.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use serde::{Deserialize, Serialize};
use serialport::SerialPort;
use std::sync::mpsc::{Receiver, Sender};
use ts_rs::TS;

use super::controller::{BridgeToControllerMessage, Controller, ControllerToBridgeMessage};

#[derive(Debug, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct DmxControllerConfiguration {
pub port: String,
}

#[derive(Debug, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct DmxControllerData {
pub data: Vec<u8>,
}

#[derive(Debug, Serialize, Deserialize, TS)]
#[serde(tag = "type")]
#[ts(export)]
pub enum DmxControllerMessage {
UpdateConfiguration(DmxControllerConfiguration),
Data(DmxControllerData),
}

pub struct DmxController {
tx: Sender<ControllerToBridgeMessage>,
rx: Receiver<BridgeToControllerMessage>,
serialport: Option<Box<dyn SerialPort>>,
}

impl DmxController {
fn handle_message(self: &mut Self, msg: DmxControllerMessage) {
match msg {
DmxControllerMessage::UpdateConfiguration(configuration) => {
println!("Updating configuration: {:?}", configuration);

let mut port = serialport::new(&configuration.port, 115200)
.parity(serialport::Parity::None)
.data_bits(serialport::DataBits::Eight)
.stop_bits(serialport::StopBits::One)
.open();

match port {
Ok(ref mut p) => {
let _ = p.as_mut().write(&[99]);
}
Err(ref err) => {
println!("Failed to open port {}: {}", configuration.port, err);
}
}
}
DmxControllerMessage::Data(data) => {
println!("Sending data: {:?}", data);
if let Some(ref mut port) = self.serialport {
let _ = port.write(&data.data[..]);
};
}
}
}
}

impl Controller for DmxController {
fn new(tx: Sender<ControllerToBridgeMessage>, rx: Receiver<BridgeToControllerMessage>) -> Self
where
Self: Sized,
{
return Self {
tx,
rx,
serialport: None,
};
}

fn run(&mut self) -> () {
loop {
match self.rx.recv() {
Ok(msg) => match msg {
BridgeToControllerMessage::Message(str_message) => {
println!("Received message: {}", str_message);
let parsed_message: DmxControllerMessage =
serde_json::from_str(&str_message).unwrap();
self.handle_message(parsed_message);
}
BridgeToControllerMessage::Dispose => {
break;
}
},
Err(err) => {
println!("Error receiving message: {}", err);
break;
}
}
}
}
}
1 change: 1 addition & 0 deletions lms_bridge/src/controllers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod controller;
pub mod dmx_controller;
pub mod wled_controller;
19 changes: 13 additions & 6 deletions lms_bridge/src/controllers/wled_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,16 @@ pub struct WledControllerConfiguration {

#[derive(Debug, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct WledControllerData {
pub data: Vec<u8>,
}

#[derive(Debug, Serialize, Deserialize, TS)]
#[serde(tag = "type")]
#[ts(export)]
pub enum WledControllerMessage {
UpdateConfiguration(WledControllerConfiguration),
Data(Vec<u8>),
Data(WledControllerData),
}

pub struct WledController {
Expand All @@ -43,7 +50,7 @@ impl WledController {
return;
};
socket
.send_to(&data[..], format!("{}:{}", self.host, self.port))
.send_to(&data.data[..], format!("{}:{}", self.host, self.port))
.unwrap();
}
}
Expand All @@ -68,19 +75,19 @@ impl Controller for WledController {
loop {
match self.rx.recv() {
Ok(msg) => match msg {
BridgeToControllerMessage::Message(strMessage) => {
println!("Received message: {}", strMessage);
BridgeToControllerMessage::Message(str_message) => {
println!("Received message: {}", str_message);
let parsed_message: WledControllerMessage =
serde_json::from_str(&strMessage).unwrap();
serde_json::from_str(&str_message).unwrap();
self.handle_message(parsed_message);
}
BridgeToControllerMessage::Dispose => {
println!("Received dispose message");
break;
}
},
Err(err) => {
println!("Error receiving message: {}", err);
break;
}
}
}
Expand Down
43 changes: 0 additions & 43 deletions lms_bridge/src/dmx_output.rs

This file was deleted.

2 changes: 1 addition & 1 deletion lms_bridge/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mod bridge;
mod controllers;
mod dmx_output;
mod types;

use std::net::TcpListener;
Expand Down Expand Up @@ -33,6 +32,7 @@ fn main() {
}
Err(e) => {
println!("Error reading message: {:?}", e);
break;
}
};
}
Expand Down
6 changes: 3 additions & 3 deletions lms_bridge/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use serde::{Deserialize, Serialize};
use ts_rs::TS;

#[derive(Debug, Serialize, Deserialize, TS)]
#[derive(Debug, Serialize, Deserialize, TS, Clone, Copy)]
#[ts(export)]
pub enum ControllerType {
Wled,
Dmx,
WLED,
DMX,
}

#[derive(Debug, Serialize, Deserialize, TS)]
Expand Down
Loading

0 comments on commit a302e12

Please sign in to comment.