Skip to content

Commit a406ccb

Browse files
authored
Add files via upload
1 parent 24766ba commit a406ccb

File tree

6 files changed

+268
-0
lines changed

6 files changed

+268
-0
lines changed

Arduino_server/Arduino_server.ino

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include <SPI.h>
2+
#include <Ethernet.h>
3+
#include <WebSocket.h>
4+
5+
6+
WebSocketServer wsServer;
7+
8+
9+
byte mac[] = { 0x52, 0x4F, 0x43, 0x4B, 0x45, 0x54 };
10+
byte ip[] = { 192, 168, 1 , 10 }; // Any IP address, according to your network adapter settings. Attention, there must be one subnet with the client!
11+
12+
13+
void onConnect(WebSocket &socket) {
14+
Serial.println("onConnect called");
15+
}
16+
17+
18+
void onData(WebSocket &socket, char* dataString, byte frameLength) {
19+
// Just echo back data for fun.
20+
socket.send(dataString, strlen(dataString));
21+
}
22+
23+
24+
void onDisconnect(WebSocket &socket) {
25+
Serial.println("onDisconnect called");
26+
}
27+
28+
29+
int get_response_len(int value){
30+
int len = 0;
31+
32+
for(int j=abs(value); j>0; j/=10){
33+
len++;
34+
}
35+
36+
if(value<0){ // If the number is negative, space is added for the minus
37+
len++;
38+
}
39+
40+
return len;
41+
}
42+
43+
44+
void setup() {
45+
Ethernet.begin(mac, ip);
46+
wsServer.registerConnectCallback(&onConnect);
47+
wsServer.registerDataCallback(&onData);
48+
wsServer.registerDisconnectCallback(&onDisconnect);
49+
wsServer.begin();
50+
51+
delay(10); // Give Ethernet time to get ready
52+
}
53+
54+
55+
void loop() {
56+
wsServer.listen();
57+
58+
int value = random(1000); //For example, we will send random integer values.
59+
60+
int response_len = get_response_len(value);
61+
62+
char response[response_len];
63+
sprintf(response, "%d", value);
64+
65+
Serial.print("Response: ");
66+
Serial.println(response);
67+
Serial.print("Response_len: ");
68+
Serial.println(response_len);
69+
Serial.print("Connections: ");
70+
Serial.println(wsServer.connectionCount());;
71+
72+
if (wsServer.connectionCount() > 0) {
73+
wsServer.send(response, response_len);
74+
}
75+
76+
delay(10);
77+
}

data.csv

Whitespace-only changes.

requirements.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
annotated-types==0.6.0
2+
anyio==4.3.0
3+
fastapi==0.110.0
4+
idna==3.6
5+
Jinja2==3.1.3
6+
MarkupSafe==2.1.5
7+
pydantic==2.6.4
8+
pydantic_core==2.16.3
9+
sniffio==1.3.1
10+
starlette==0.36.3
11+
typing_extensions==4.10.0
12+
websockets==12.0

templates/index.html

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
2+
<!DOCTYPE html>
3+
<html lang="en">
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>Arduino Connect</title>
7+
<!--suppress JSUnresolvedLibraryURL -->
8+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.1/css/bootstrap.min.css"
9+
integrity="sha512-T584yQ/tdRR5QwOpfvDfVQUidzfgc2339Lc8uBDtcp/wYu80d7jwBgAxbyMh0a9YM9F8N3tdErpFI8iaGx6x5g=="
10+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
11+
<!--suppress JSUnresolvedLibraryURL -->
12+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.css"
13+
integrity="sha512-/zs32ZEJh+/EO2N1b0PEdoA10JkdC3zJ8L5FTiQu82LR9S/rOQNfQN7U59U9BC12swNeRAz3HSzIL2vpp4fv3w=="
14+
crossorigin="anonymous" referrerpolicy="no-referrer"/>
15+
</head>
16+
<body>
17+
<div class="container">
18+
<div class="row">
19+
<div class="col-12">
20+
<div class="card">
21+
<div class="card-body">
22+
<canvas id="canvas_1"></canvas>
23+
</div>
24+
</div>
25+
</div>
26+
</div>
27+
</div>
28+
<!--suppress JSUnresolvedLibraryURL -->
29+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
30+
integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
31+
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
32+
<!--suppress JSUnresolvedLibraryURL -->
33+
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.1/js/bootstrap.bundle.min.js"
34+
integrity="sha512-mULnawDVcCnsk9a4aG1QLZZ6rcce/jSzEGqUkeOLy0b6q0+T6syHrxlsAGH7ZVoqC93Pd0lBqd6WguPWih7VHA=="
35+
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
36+
<!--suppress JSUnresolvedLibraryURL -->
37+
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"
38+
integrity="sha512-d9xgZrVZpmmQlfonhQUvTR7lMPtO7NkZMkA0ABN3PHCbKA5nqylQ/yWlFAyY6hYgdF1Qh6nYiuADWwKB4C2WSw=="
39+
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
40+
<script>
41+
$(document).ready(function () {
42+
const config_1 = {
43+
type: 'line',
44+
data: {
45+
labels: Array(200).fill("0000-00-00 00:00:00"),
46+
datasets: [{
47+
label: "Value",
48+
backgroundColor: 'rgb(255, 99, 132)',
49+
borderColor: 'rgb(255, 99, 132)',
50+
data: Array(210).fill(null),
51+
fill: false,
52+
}],
53+
},
54+
options: {
55+
responsive: true,
56+
title: {
57+
display: true,
58+
text: 'Value'
59+
},
60+
tooltips: {
61+
mode: 'index',
62+
intersect: false,
63+
},
64+
hover: {
65+
mode: 'nearest',
66+
intersect: true
67+
},
68+
scales: {
69+
xAxes: [{
70+
display: true,
71+
scaleLabel: {
72+
display: true,
73+
labelString: 'Time'
74+
}
75+
}],
76+
yAxes: [{
77+
display: true,
78+
scaleLabel: {
79+
display: true,
80+
labelString: 'Value'
81+
}
82+
}]
83+
}
84+
}
85+
}
86+
87+
const context_1 = document.getElementById('canvas_1').getContext('2d');
88+
const lineChart_1 = new Chart(context_1, config_1);
89+
90+
91+
92+
const source = new EventSource("/chart-data");
93+
94+
source.onmessage = function (event) {
95+
const data = JSON.parse(event.data);
96+
if (config_1.data.labels.length === 200) {
97+
config_1.data.labels.shift();
98+
config_1.data.datasets[0].data.shift();
99+
}
100+
101+
config_1.data.labels.push(data.time);
102+
config_1.data.datasets[0].data.push(data.value);
103+
lineChart_1.update();
104+
}
105+
});
106+
</script>
107+
</body>
108+
</html>

webclient.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import websockets
2+
import asyncio
3+
import json
4+
import logging
5+
import sys
6+
from datetime import datetime
7+
from typing import Iterator
8+
from fastapi import FastAPI
9+
from fastapi.requests import Request
10+
from fastapi.responses import HTMLResponse, StreamingResponse
11+
from fastapi.templating import Jinja2Templates
12+
from starlette.responses import Response
13+
import uvicorn
14+
15+
16+
server_ip = "192.168.1.10"
17+
18+
19+
logging.basicConfig(stream=sys.stdout, level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
20+
logger = logging.getLogger(__name__)
21+
22+
23+
application = FastAPI()
24+
templates = Jinja2Templates(directory="templates")
25+
26+
27+
@application.get("/", response_class=HTMLResponse)
28+
async def index(request: Request) -> Response:
29+
return templates.TemplateResponse("index.html", {"request": request})
30+
31+
32+
async def generate_random_data(request: Request) -> Iterator[str]:
33+
client_ip = request.client.host
34+
logger.info("Client %s connected", client_ip)
35+
36+
async with websockets.connect(f"ws://{server_ip}", ping_interval=None) as websocket:
37+
38+
while True:
39+
date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
40+
value = await websocket.recv()
41+
json_data = json.dumps(
42+
{
43+
"time": date,
44+
"value": value,
45+
}
46+
)
47+
yield f"data:{json_data}\n\n"
48+
49+
await asyncio.sleep(0.0005)
50+
51+
52+
@application.get("/chart-data")
53+
async def chart_data(request: Request) -> StreamingResponse:
54+
response = StreamingResponse(generate_random_data(request), media_type="text/event-stream")
55+
response.headers["Cache-Control"] = "no-cache"
56+
response.headers["X-Accel-Buffering"] = "no"
57+
return response
58+
59+
if __name__=="__main__":
60+
uvicorn.run("webclient:application", port=80)

websocket_client.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import asyncio
2+
import websockets
3+
4+
async def listen_server():
5+
async with websockets.connect("ws://192.168.1.10") as websocket:
6+
while True:
7+
response = await websocket.recv()
8+
print(response)
9+
10+
11+
asyncio.get_event_loop().run_until_complete(listen_server())

0 commit comments

Comments
 (0)