Skip to content

Commit 6d3c615

Browse files
Provide preliminary state machine model (#39)
- Create basic `StateMachine` which periodically emits sample data - Handle basic transition logic, to be improved later - An extra global state variable still needs to be cleaned up - Send socket messages from pod action buttons in control station --------- Co-authored-by: Sam Der <[email protected]>
1 parent 2e318d9 commit 6d3c615

File tree

9 files changed

+310
-53
lines changed

9 files changed

+310
-53
lines changed

control-station/src/components/ControlPanel/ControlPanel.tsx

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
import "./ControlPanel.css";
2+
import usePodData from "@/services/usePodData";
23

34
function ControlPanel() {
5+
const { podSocketClient } = usePodData();
46
return (
57
<div className="controlpanel">
6-
<button className="button start">Start</button>
7-
<button className="button stop">Stop</button>
8-
<button className="button force">Force Stop</button>
9-
<button className="button load">Load</button>
8+
<button className="button start" onClick={() => podSocketClient.sendStart()}>
9+
Start
10+
</button>
11+
<button className="button stop" onClick={() => podSocketClient.sendStop()}>
12+
Stop
13+
</button>
14+
<button className="button force" onClick={() => podSocketClient.sendForcestop()}>
15+
Force Stop
16+
</button>
17+
<button className="button load" onClick={() => podSocketClient.sendLoad()}>
18+
Load
19+
</button>
1020
</div>
1121
);
1222
}

control-station/src/services/PodSocketClient.ts

+47-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,20 @@ interface ServerToClientEvents {
66
connect: () => void;
77
disconnect: (reason: Socket.DisconnectReason) => void;
88
pong: (data: string) => void;
9+
greet: (data: string) => void;
10+
stop: (data: string) => void;
11+
forcestop: (data: string) => void;
12+
load: (data: string) => void;
13+
start: (data: string) => void;
914
}
1015

1116
interface ClientToServerEvents {
1217
ping: (data: string, ack: (data: string) => void) => void;
18+
greet: (data: string, ack: (data: string) => void) => void;
19+
stop: (data: string, ack: (data: string) => void) => void;
20+
forcestop: (data: string, ack: (data: string) => void) => void;
21+
load: (data: string, ack: (data: string) => void) => void;
22+
start: (data: string, ack: (data: string) => void) => void;
1323
}
1424

1525
export interface PodData {
@@ -34,7 +44,12 @@ class PodSocketClient {
3444
this.serverEvents = {
3545
connect: this.onConnect.bind(this),
3646
disconnect: this.onDisconnect.bind(this),
37-
pong: this.onPong.bind(this),
47+
pong: this.onData.bind(this),
48+
greet: this.onData.bind(this),
49+
stop: this.onData.bind(this),
50+
forcestop: this.onData.bind(this),
51+
load: this.onData.bind(this),
52+
start: this.onData.bind(this),
3853
} as const;
3954
this.setPodData = setPodData;
4055
}
@@ -64,6 +79,36 @@ class PodSocketClient {
6479
});
6580
}
6681

82+
sendGreet(): void {
83+
this.socket.emit("greet", "Hello from client", (ack: string) => {
84+
console.log(`Server responds to greet with ${ack}`);
85+
});
86+
}
87+
88+
sendStop(): void {
89+
this.socket.emit("stop", "Hello from client", (ack: string) => {
90+
console.log(`Server responds to stop with ${ack}`);
91+
});
92+
}
93+
94+
sendForcestop(): void {
95+
this.socket.emit("forcestop", "Hello from client", (ack: string) => {
96+
console.log(`Server responds to stop with ${ack}`);
97+
});
98+
}
99+
100+
sendLoad(): void {
101+
this.socket.emit("load", "Hello from client", (ack: string) => {
102+
console.log(`Server responds to stop with ${ack}`);
103+
});
104+
}
105+
106+
sendStart(): void {
107+
this.socket.emit("start", "Hello from client", (ack: string) => {
108+
console.log(`Server responds to stop with ${ack}`);
109+
});
110+
}
111+
67112
private onConnect(): void {
68113
console.log("Connected to server as", this.socket.id);
69114
this.setPodData((d) => ({ ...d, connected: true }));
@@ -74,7 +119,7 @@ class PodSocketClient {
74119
this.setPodData((d) => ({ ...d, connected: false }));
75120
}
76121

77-
private onPong(data: string): void {
122+
private onData(data: string): void {
78123
console.log("server says", data);
79124
}
80125
}

control-station/src/views/Dashboard/Dashboard.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ function Dashboard() {
99
<h1>Dashboard</h1>
1010
<Status />
1111
<p>{podData.connected ? "connected" : "disconnected"}</p>
12-
<button onClick={() => podSocketClient.sendPing()}>Send Ping</button>
12+
<button onClick={() => podSocketClient.sendStop()}>Send Stop</button>
13+
<button onClick={() => podSocketClient.sendForcestop()}>Send Forcestop</button>
14+
<button onClick={() => podSocketClient.sendLoad()}>Send Load</button>
15+
<button onClick={() => podSocketClient.sendStart()}>Send Start</button>
1316
</div>
1417
);
1518
}

pod-operation/Cargo.lock

+32-24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pod-operation/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ serde = { version = "1.0.192", features = ["derive"] }
1313
serde_json = "1.0.108"
1414
tracing = "0.1.40"
1515
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
16+
lazy_static = "1.4.0"
1617
rppal = { version = "0.17.1", features = ["hal"] }
1718
ina219 = "0.1.0"

pod-operation/src/demo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use tracing::info;
33
use crate::components::pressure_transducer::PressureTransducer;
44
use crate::components::signal_light::SignalLight;
55

6-
pub async fn blink(mut signal_light: SignalLight) {
6+
pub async fn _blink(mut signal_light: SignalLight) {
77
let mut i = 0;
88

99
info!("Starting blink demo.");

pod-operation/src/handlers.rs

-8
This file was deleted.

pod-operation/src/main.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
1+
use crate::components::pressure_transducer::PressureTransducer;
12
use axum::Server;
2-
use socketioxide::{extract::SocketRef, SocketIo};
3+
use socketioxide::SocketIo;
34
use tracing::{error, info};
45
use tracing_subscriber::FmtSubscriber;
5-
66
mod components;
77
mod demo;
8-
mod handlers;
9-
10-
use crate::components::pressure_transducer::PressureTransducer;
11-
use crate::components::signal_light::SignalLight;
8+
mod state_machine;
9+
use crate::state_machine::StateMachine;
10+
use std::{thread, time::Duration};
1211

1312
#[tokio::main]
1413
async fn main() -> Result<(), Box<dyn std::error::Error>> {
1514
tracing::subscriber::set_global_default(FmtSubscriber::default())?;
1615

1716
let (layer, io) = SocketIo::new_layer();
1817

19-
io.ns("/control-station", |socket: SocketRef| {
20-
info!("Socket.IO connected: {:?} {:?}", socket.ns(), socket.id);
21-
socket.on("ping", handlers::handle_ping);
22-
});
23-
24-
let signal_light = SignalLight::new();
25-
tokio::spawn(demo::blink(signal_light));
18+
thread::sleep(Duration::from_millis(1));
2619

2720
let pressure_transducer = PressureTransducer::new(0x40);
2821
tokio::spawn(demo::read_pressure_transducer(pressure_transducer));
2922

23+
thread::spawn(move || {
24+
let mut state_machine = StateMachine::new(io);
25+
state_machine.run();
26+
});
27+
3028
let app = axum::Router::new().layer(layer);
3129

3230
info!("Starting server on port 5000");
31+
3332
let server = Server::bind(&"127.0.0.1:5000".parse().unwrap()).serve(app.into_make_service());
3433

3534
if let Err(e) = server.await {

0 commit comments

Comments
 (0)