Skip to content

Commit e632c2b

Browse files
authored
Merge pull request #3 from shiv3/add/experimental-feature
Add experimental feature
2 parents cf2b5d4 + a455e42 commit e632c2b

13 files changed

+611
-282
lines changed

package-lock.json

Lines changed: 285 additions & 137 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
},
1212
"dependencies": {
1313
"@voltbras/ts-ocpp": "^2.7.3",
14+
"flowbite": "^2.4.1",
15+
"flowbite-react": "^0.10.1",
1416
"react": "^18.3.1",
1517
"react-dom": "^18.3.1",
1618
"react-router-dom": "^6.24.0",

src/App.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
// App.tsx
22
import React from "react";
3-
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
3+
import {BrowserRouter as Router, Route, Routes } from "react-router-dom";
44
import Navbar from "./components/Navbar.tsx";
5-
import ChargePoint from "./components/ChargePoint.tsx";
65
import Settings from "./components/Settings.tsx";
6+
import TopPage from "./components/TopPage.tsx";
77

88
const App: React.FC = () => {
9+
10+
911
return (
1012
<Router basename={import.meta.env.VITE_BASE_URL}>
1113
<div className="min-h-screen bg-gray-100">
1214
<Navbar />
1315
<div className="container mx-auto my-auto p-4">
1416
<Routes>
15-
<Route path="/" element={<ChargePoint />} />
17+
<Route path="/" element={<TopPage />} />
1618
<Route path="/settings" element={<Settings />} />
1719
</Routes>
1820
</div>

src/components/ChargePoint.tsx

Lines changed: 40 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,58 @@
1-
import React, { useState, useEffect } from "react";
2-
import { ChargePoint as OCPPChargePoint } from "../cp/ChargePoint";
1+
import React, {useState, useEffect} from "react";
2+
import {ChargePoint as OCPPChargePoint} from "../cp/ChargePoint";
33
import Connector from "./Connector.tsx";
4-
import { useLocation } from "react-router-dom";
54
import Logger from "./Logger.tsx";
65
import * as ocpp from "../cp/OcppTypes";
76

8-
const ChargePoint: React.FC = () => {
9-
const [cpStatus, setCpStatus] = useState<string>(ocpp.OCPPStatus.Unavailable);
7+
interface ChargePointProps {
8+
cp : OCPPChargePoint;
9+
TagID: string;
10+
}
11+
12+
const ChargePoint: React.FC<ChargePointProps> = (props) => {
1013
const [cp, setCp] = useState<OCPPChargePoint | null>(null);
14+
const [cpStatus, setCpStatus] = useState<string>(ocpp.OCPPStatus.Unavailable);
1115
const [cpError, setCpError] = useState<string>("");
12-
13-
const search = useLocation().search;
14-
const query = new URLSearchParams(search);
16+
const [logs , setLogs] = useState<string[]>([]);
1517

1618
useEffect(() => {
17-
const connectorNumber = parseInt(
18-
query.get("connectors") || localStorage.getItem("CONNECTORS") || "2"
19-
);
20-
const wsURL = query.get("wsurl") || localStorage.getItem("WSURL") || "";
21-
const cpID = query.get("cpid") || localStorage.getItem("CPID") || "CP-001";
22-
const tagID = query.get("tag") || localStorage.getItem("TAG") || "DEADBEEF";
23-
24-
localStorage.setItem("WSURL", wsURL);
25-
localStorage.setItem("CONNECTORS", connectorNumber.toString());
26-
localStorage.setItem("CPID", cpID);
27-
localStorage.setItem("TAG", tagID);
28-
29-
const newCp = new OCPPChargePoint(cpID, connectorNumber, wsURL);
30-
newCp.statusChangeCallback = statusChangeCb;
31-
newCp.loggingCallback = logMsg;
32-
newCp.errorCallback = setCpError;
33-
setCp(newCp);
34-
}, []);
19+
console.log("ChargePointProps", props);
20+
props.cp.statusChangeCallback = statusChangeCb;
21+
props.cp.loggingCallback = logMsg;
22+
props.cp.errorCallback = setCpError;
23+
setCp(props.cp);
24+
}, [props]);
3525

3626
const statusChangeCb = (s: string) => {
3727
setCpStatus(s);
3828
};
3929

4030
const logMsg = (msg: string) => {
4131
console.log(msg);
32+
setLogs((prevLogs) => [...prevLogs, msg]);
4233
};
4334

4435
return (
4536
<div className="bg-white shadow-md rounded px-2 pt-2 pb-1 h-screen">
46-
<SettingsView />
37+
<SettingsView {...props}/>
4738
<div className="flex flex-col md:flex-row">
48-
<ChargePointControls cp={cp} cpStatus={cpStatus} cpError={cpError} />
39+
<ChargePointControls cp={cp} cpStatus={cpStatus} cpError={cpError}/>
4940
<div className="flex-1">
50-
<AuthView cp={cp} cpStatus={cpStatus} />
41+
<AuthView cp={cp} cpStatus={cpStatus} tagID={props.TagID}/>
5142
<div className="flex flex-col md:flex-row mt-4">
5243
{cp?.connectors &&
5344
Array.from(Array(cp.connectors.size).keys()).map((i) => (
54-
<Connector key={i + 1} id={i + 1} cp={cp} />
45+
<Connector key={i + 1} id={i + 1} cp={cp}/>
5546
))}
5647
</div>
5748
</div>
5849
</div>
59-
<Logger />
50+
<Logger logs={logs}/>
6051
</div>
6152
);
6253
};
6354

64-
const CPStatus: React.FC<{ status: string }> = ({ status }) => {
55+
const CPStatus: React.FC<{ status: string }> = ({status}) => {
6556
const statusColor = (s: string) => {
6657
switch (s) {
6758
case ocpp.OCPPStatus.Unavailable:
@@ -87,19 +78,15 @@ const CPStatus: React.FC<{ status: string }> = ({ status }) => {
8778
interface AuthViewProps {
8879
cp: OCPPChargePoint | null;
8980
cpStatus: string;
81+
tagID: string;
9082
}
9183

92-
const AuthView: React.FC<AuthViewProps> = ({ cp, cpStatus }) => {
93-
const [tagID, setTagID] = useState<string>("");
94-
95-
useEffect(() => {
96-
setTagID(localStorage.getItem("TAG") || "");
97-
}, []);
84+
const AuthView: React.FC<AuthViewProps> = (props) => {
85+
const [tagID, setTagID] = useState<string>(props.tagID);
9886

9987
const handleAuthorize = () => {
100-
if (cp) {
101-
const tagId = localStorage.getItem("TAG") || "DEADBEEF";
102-
cp.authorize(tagId);
88+
if (props.cp) {
89+
props.cp.authorize(tagID);
10390
}
10491
};
10592

@@ -120,18 +107,18 @@ const AuthView: React.FC<AuthViewProps> = ({ cp, cpStatus }) => {
120107
value={tagID}
121108
onChange={(e) => setTagID(e.target.value)}
122109
placeholder="DEADBEEF"
123-
style={{ maxWidth: "20ch" }}
110+
style={{maxWidth: "20ch"}}
124111
/>
125112
<p className="text-gray-600 text-xs italic mt-1">
126113
The ID of the simulated RFID tag
127114
</p>
128115
</div>
129116
<button
130117
onClick={handleAuthorize}
131-
className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded w-full
118+
className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded
132119
disabled:bg-green-300
133120
"
134-
disabled={cpStatus !== ocpp.OCPPStatus.Available}
121+
disabled={props.cpStatus !== ocpp.OCPPStatus.Available}
135122
>
136123
Authorize
137124
</button>
@@ -146,10 +133,10 @@ interface ChargePointControlsProps {
146133
}
147134

148135
const ChargePointControls: React.FC<ChargePointControlsProps> = ({
149-
cp,
150-
cpStatus,
151-
cpError,
152-
}) => {
136+
cp,
137+
cpStatus,
138+
cpError,
139+
}) => {
153140
const [isHeartbeatEnabled, setIsHeartbeatEnabled] = useState<boolean>(false);
154141

155142
const handleConnect = () => {
@@ -182,7 +169,7 @@ const ChargePointControls: React.FC<ChargePointControlsProps> = ({
182169
return (
183170
<div className="bg-gray-100 rounded p-4 mr-4">
184171
<div className="bg-gray-100 rounded p-4 mr-4">
185-
<CPStatus status={cpStatus} />
172+
<CPStatus status={cpStatus}/>
186173
</div>
187174
<div>
188175
{cpError !== "" && (
@@ -236,22 +223,13 @@ const ChargePointControls: React.FC<ChargePointControlsProps> = ({
236223
);
237224
};
238225

239-
const SettingsView: React.FC = () => {
240-
const [wsURL] = useState<string>(localStorage.getItem("WSURL") || "");
241-
const [connectorNumber] = useState<number>(
242-
parseInt(localStorage.getItem("CONNECTORS") || "2")
243-
);
244-
const [cpID] = useState<string>(localStorage.getItem("CPID") || "CP-001");
245-
const [ocppVersion] = useState<string>(
246-
localStorage.getItem("OCPP") || "OCPP-1.6J"
247-
);
226+
const SettingsView: React.FC<ChargePointProps> = (props) => {
248227
return (
249228
<div className="mb-1 bg-gray-100 rounded p-2">
250229
<p className="text-lg font-semibold">settings</p>
251-
<li>WSURL: {wsURL}</li>
252-
<li>CONNECTORS: {connectorNumber}</li>
253-
<li>CPID: {cpID}</li>
254-
<li>OCPP: {ocppVersion}</li>
230+
<li>CPID: {props.cp.id}</li>
231+
<li>CONNECTORS: {props.cp.connectorNumber}</li>
232+
<li>WSURL: {props.cp.wsUrl}</li>
255233
</div>
256234
);
257235
};

src/components/Logger.tsx

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,10 @@
1-
import React, { useState, useEffect, useRef } from "react";
1+
import React, { useEffect, useRef} from "react";
22

3-
const Logger: React.FC = () => {
4-
const [logs, setLogs] = useState<string[]>([]);
5-
6-
useEffect(() => {
7-
// You might want to implement a more sophisticated logging system
8-
// This is just a basic example
9-
const oldConsoleLog = console.log;
10-
console.log = (message: string) => {
11-
setLogs((prevLogs) => [...prevLogs, message]);
12-
};
13-
14-
return () => {
15-
console.log = oldConsoleLog;
16-
};
17-
}, []);
3+
interface LoggerProps {
4+
logs: string[];
5+
}
186

7+
const Logger: React.FC<LoggerProps> = ({logs}) => {
198
return (
209
<div className="mt-2 border-0 border-blue-500 h-screen">
2110
<AutoScrollingTextarea

src/components/Settings.tsx

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
import React, { useState, useEffect } from "react";
1+
import React, {useState, useEffect} from "react";
22

33
const Settings: React.FC = () => {
44
const [wsURL, setWsURL] = useState<string>("");
55
const [connectorNumber, setConnectorNumber] = useState<number>(2);
66
const [cpID, setCpID] = useState<string>("");
77
const [tagID, setTagID] = useState<string>("");
88
const [ocppVersion, setOcppVersion] = useState<string>("OCPP-1.6J");
9+
const [experimental, setExperimental] = useState<string>();
910

1011
useEffect(() => {
1112
setWsURL(localStorage.getItem("WSURL") || "");
1213
setConnectorNumber(parseInt(localStorage.getItem("CONNECTORS") || "2"));
1314
setCpID(localStorage.getItem("CPID") || "");
1415
setTagID(localStorage.getItem("TAG") || "");
16+
setOcppVersion(localStorage.getItem("OCPP") || "OCPP-1.6J");
17+
setExperimental(localStorage.getItem("EXPERIMENTAL") || "");
1518
}, []);
1619

1720
const handleSubmit = (e: React.FormEvent) => {
@@ -20,6 +23,8 @@ const Settings: React.FC = () => {
2023
localStorage.setItem("CONNECTORS", connectorNumber.toString());
2124
localStorage.setItem("CPID", cpID);
2225
localStorage.setItem("TAG", tagID);
26+
localStorage.setItem("OCPP", ocppVersion);
27+
localStorage.setItem("EXPERIMENTAL", btoa(experimental ?? "") || "");
2328
alert("Settings saved successfully!");
2429
};
2530

@@ -60,7 +65,7 @@ const Settings: React.FC = () => {
6065
value={connectorNumber}
6166
onChange={(e) => setConnectorNumber(parseInt(e.target.value))}
6267
placeholder="2"
63-
style={{ maxWidth: "20ch" }}
68+
style={{maxWidth: "20ch"}}
6469
/>
6570
</div>
6671

@@ -78,7 +83,7 @@ const Settings: React.FC = () => {
7883
value={cpID}
7984
onChange={(e) => setCpID(e.target.value)}
8085
placeholder="CP001"
81-
style={{ maxWidth: "20ch" }}
86+
style={{maxWidth: "20ch"}}
8287
/>
8388
</div>
8489
<div className="mb-4">
@@ -93,11 +98,26 @@ const Settings: React.FC = () => {
9398
id="OCPP"
9499
value={ocppVersion}
95100
onChange={(e) => setOcppVersion(e.target.value)}
96-
style={{ maxWidth: "20ch" }}
101+
style={{maxWidth: "20ch"}}
97102
>
98103
<option value="OCPP-1.6J">OCPP-1.6J</option>
99104
</select>
100105
</div>
106+
<div className="mb-4">
107+
<label
108+
className="block text-gray-700 text-sm font-bold mb-2"
109+
htmlFor="Experimental"
110+
>
111+
Experimental
112+
</label>
113+
<textarea
114+
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
115+
id="Experimental"
116+
placeholder="Experimental features"
117+
style={{height: "100px"}}
118+
onChange={(e) => setExperimental(e.target.value)
119+
}></textarea>
120+
</div>
101121
<div className="flex items-center justify-between">
102122
<button
103123
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"

src/components/Tab.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

0 commit comments

Comments
 (0)