First implementation of redux connection system
This commit is contained in:
parent
751c981daf
commit
c31f3b19ac
6 changed files with 132 additions and 37 deletions
|
@ -1,8 +1,10 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { createGlobalStyle } from "styled-components";
|
||||
import SerialPort from "serialport";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { RootState } from "typesafe-actions";
|
||||
import Knob from "./Components/Knob";
|
||||
import { port, parser } from "./SerialConnection";
|
||||
import { connect, disconnect } from "./redux/actions/asyncSerialConnectionActions";
|
||||
import { setSerialPort } from "./redux/actions/serialConnectionActions";
|
||||
|
||||
const GlobalStyle = createGlobalStyle`
|
||||
html {
|
||||
|
@ -18,6 +20,9 @@ const GlobalStyle = createGlobalStyle`
|
|||
|
||||
const App = () => {
|
||||
const [status, setStatus] = useState(0);
|
||||
const dispatch = useDispatch();
|
||||
const serialConnection = useSelector<RootState, RootState["serialConnection"]>((state) => state.serialConnection);
|
||||
|
||||
const SerialDataListener = (data: string) => {
|
||||
const parsedData = data.split(",");
|
||||
console.log(parsedData);
|
||||
|
@ -25,24 +30,34 @@ const App = () => {
|
|||
};
|
||||
|
||||
useEffect(() => {
|
||||
parser.on("data", SerialDataListener);
|
||||
port.open();
|
||||
if (serialConnection.portController !== null) {
|
||||
serialConnection.portController.parser.on("data", SerialDataListener);
|
||||
}
|
||||
|
||||
return () => {
|
||||
parser.removeListener("data", SerialDataListener);
|
||||
port.close();
|
||||
if (serialConnection.portController !== null) {
|
||||
serialConnection.portController.parser.removeListener("data", SerialDataListener);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
}, [serialConnection]);
|
||||
|
||||
const sendIncreaseHandler = () => {
|
||||
setStatus(status + 1);
|
||||
port.write("2i");
|
||||
if (serialConnection.portController !== null && serialConnection.portController.port !== null) {
|
||||
setStatus(status + 1);
|
||||
serialConnection.portController.port.write("2i");
|
||||
}
|
||||
};
|
||||
const sendDecreaseHandler = () => {
|
||||
setStatus(status - 1);
|
||||
port.write("2d");
|
||||
if (serialConnection.portController !== null && serialConnection.portController.port !== null) {
|
||||
setStatus(status - 1);
|
||||
serialConnection.portController.port.write("2d");
|
||||
}
|
||||
};
|
||||
const sendToggleHandler = () => {
|
||||
port.write("2t");
|
||||
if (serialConnection.portController !== null && serialConnection.portController.port !== null) {
|
||||
setStatus(status - 1);
|
||||
serialConnection.portController.port.write("2t");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -57,29 +72,19 @@ const App = () => {
|
|||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
port.open();
|
||||
dispatch(setSerialPort("COM5"));
|
||||
dispatch(connect());
|
||||
}}
|
||||
>
|
||||
open
|
||||
connect
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
port.close();
|
||||
dispatch(disconnect());
|
||||
}}
|
||||
>
|
||||
close
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
const list = SerialPort.list();
|
||||
list.then((arg) => {
|
||||
console.log(arg);
|
||||
});
|
||||
}}
|
||||
>
|
||||
list
|
||||
disconnect
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,10 +1,51 @@
|
|||
import SerialPort, { parsers } from "serialport";
|
||||
|
||||
const port = new SerialPort("COM5", {
|
||||
baudRate: 9600,
|
||||
autoOpen: false,
|
||||
});
|
||||
class PortController {
|
||||
path: null | string;
|
||||
|
||||
const parser = port.pipe(new parsers.Readline({ delimiter: "\r\n" }));
|
||||
port: null | SerialPort;
|
||||
|
||||
export { port, parser };
|
||||
parser: any;
|
||||
|
||||
constructor() {
|
||||
this.path = null;
|
||||
this.port = null;
|
||||
}
|
||||
|
||||
get isOpen() {
|
||||
if (!this.port) {
|
||||
return false;
|
||||
}
|
||||
return this.port.isOpen;
|
||||
}
|
||||
|
||||
create(path: string) {
|
||||
this.path = path;
|
||||
this.port = new SerialPort(path, {
|
||||
baudRate: 9600,
|
||||
autoOpen: false,
|
||||
});
|
||||
|
||||
this.parser = this.port.pipe(new parsers.Readline({ delimiter: "\r\n" }));
|
||||
}
|
||||
|
||||
open(callback: (error:Error | null | undefined)=>void) {
|
||||
if (this.isOpen) {
|
||||
throw new Error("Port already open");
|
||||
}
|
||||
|
||||
if (this.port === null) {
|
||||
throw new Error("Port must be created first");
|
||||
}
|
||||
|
||||
this.port.open((error) => callback(error));
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this.port) {
|
||||
this.port.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default PortController;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import PortController from "../SerialConnection";
|
||||
|
||||
export default interface ISerialConnectionState {
|
||||
port: null | string;
|
||||
port: string | null;
|
||||
portController: PortController | null;
|
||||
status: {
|
||||
connecting: boolean;
|
||||
connected: boolean;
|
||||
|
|
36
Dashboard/src/redux/actions/asyncSerialConnectionActions.ts
Normal file
36
Dashboard/src/redux/actions/asyncSerialConnectionActions.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { ThunkResult } from "typesafe-actions";
|
||||
import {
|
||||
connectionStart, connectionSuccess, connectionFailure, setPortController, connectionEnd,
|
||||
} from "./serialConnectionActions";
|
||||
import PortController from "../../SerialConnection";
|
||||
|
||||
const connect = (): ThunkResult<void> => async (dispatch, getState) => {
|
||||
const state = getState();
|
||||
dispatch(connectionStart());
|
||||
|
||||
if (state.serialConnection.port === null) {
|
||||
dispatch(connectionFailure(new Error("No Serial Port set")));
|
||||
return;
|
||||
}
|
||||
|
||||
const controller = new PortController();
|
||||
controller.create(state.serialConnection.port);
|
||||
|
||||
dispatch(setPortController(controller));
|
||||
|
||||
controller.open((error) => {
|
||||
if (error === null || error === undefined) {
|
||||
dispatch(connectionSuccess());
|
||||
} else {
|
||||
dispatch(connectionFailure(error));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const disconnect = (): ThunkResult<void> => async (dispatch, getState) => {
|
||||
const state = getState();
|
||||
state.serialConnection.portController?.close();
|
||||
dispatch(connectionEnd());
|
||||
};
|
||||
|
||||
export { connect, disconnect };
|
|
@ -1,11 +1,13 @@
|
|||
import { action } from "typesafe-actions";
|
||||
import PortController from "../../SerialConnection";
|
||||
|
||||
export enum SerialConnectionActionTypes {
|
||||
SET_SERIAL_PORT = "SET_SERIAL_PORT",
|
||||
CONNECTION_START = "CONNECTION_START",
|
||||
CONNECTION_SUCCESS = "CONNECTION_SUCCESS",
|
||||
CONNECTION_FAILURE = "CONNECTION_FAILURE",
|
||||
DISCONNECT = "DISCONNECT",
|
||||
CONNECTION_END = "CONNECTION_END",
|
||||
SET_PORT_CONTROLLER = "SET_PORT_CONTROLLER"
|
||||
}
|
||||
|
||||
export const setSerialPort = (port: string) => action(SerialConnectionActionTypes.SET_SERIAL_PORT, port);
|
||||
|
@ -16,4 +18,6 @@ export const connectionSuccess = () => action(SerialConnectionActionTypes.CONNEC
|
|||
|
||||
export const connectionFailure = (error: Error) => action(SerialConnectionActionTypes.CONNECTION_FAILURE, error);
|
||||
|
||||
export const disconnect = () => action(SerialConnectionActionTypes.DISCONNECT);
|
||||
export const connectionEnd = () => action(SerialConnectionActionTypes.CONNECTION_END);
|
||||
|
||||
export const setPortController = (controller: PortController) => action(SerialConnectionActionTypes.SET_PORT_CONTROLLER, controller);
|
||||
|
|
|
@ -4,6 +4,7 @@ import { SerialConnectionActionTypes } from "../actions/serialConnectionActions"
|
|||
|
||||
const initialState: ISerialConnectionState = {
|
||||
port: null,
|
||||
portController: null,
|
||||
status: {
|
||||
connecting: false,
|
||||
connected: false,
|
||||
|
@ -40,13 +41,18 @@ const SerialConnectionReducer = createReducer(initialState)
|
|||
error: null,
|
||||
},
|
||||
}))
|
||||
.handleType(SerialConnectionActionTypes.DISCONNECT, (state) => ({
|
||||
.handleType(SerialConnectionActionTypes.CONNECTION_END, (state) => ({
|
||||
...state,
|
||||
portController: null,
|
||||
status: {
|
||||
connecting: false,
|
||||
connected: false,
|
||||
error: null,
|
||||
},
|
||||
}))
|
||||
.handleType(SerialConnectionActionTypes.SET_PORT_CONTROLLER, (state, action) => ({
|
||||
...state,
|
||||
portController: action.payload,
|
||||
}));
|
||||
|
||||
export default SerialConnectionReducer;
|
||||
|
|
Reference in a new issue