First implementation of redux connection system

This commit is contained in:
GHOSCHT 2021-08-27 12:13:41 +02:00
parent 751c981daf
commit c31f3b19ac
6 changed files with 132 additions and 37 deletions

View file

@ -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>
);

View file

@ -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;

View file

@ -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;

View 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 };

View file

@ -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);

View file

@ -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;