alpha
Login
or
Join now
dunkirk.sh
/
inky
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
This repository has no description
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
feat: add auto reload with websockets
author
Kieran Klukas
date
1 year ago
(Apr 11, 2025, 7:47 PM -0400)
commit
db2dea2c
db2dea2c03eb7b12cfe28847afda3b63fc05ce10
parent
d794e531
d794e531b18e084c3d6082fc5572b94968e4eb3b
+40
1 changed file
Expand all
Collapse all
Unified
Split
src
camera_server.py
+40
src/camera_server.py
Reviewed
···
7
7
import http.server
8
8
import socketserver
9
9
import threading
10
10
+
import websockets
11
11
+
import asyncio
10
12
11
13
# Setup logging
12
14
logger = logging.getLogger('camera_server')
···
23
25
BUTTON_PIN = 17
24
26
PHOTO_DIR = "/home/kierank/photos"
25
27
WEB_PORT = 80
28
28
+
WS_PORT = 8765
26
29
PHOTO_RESOLUTION = (2592, 1944)
27
30
CAMERA_SETTLE_TIME = 1
28
31
DEBOUNCE_DELAY = 0.2
···
42
45
GPIO.setmode(GPIO.BCM)
43
46
GPIO.setup(Config.BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
44
47
48
48
+
# WebSocket clients set
49
49
+
connected_clients = set()
50
50
+
45
51
# Create a simple HTML gallery template - using triple quotes properly
46
52
HTML_TEMPLATE = """<!DOCTYPE html>
47
53
<html>
···
56
62
.photo img {{ width: 100%; height: auto; }}
57
63
.photo a {{ display: block; text-align: center; margin-top: 5px; }}
58
64
</style>
65
65
+
<script>
66
66
+
const ws = new WebSocket('ws://' + window.location.hostname + ':8765');
67
67
+
ws.onmessage = function(event) {{
68
68
+
if(event.data === 'reload') {{
69
69
+
window.location.reload();
70
70
+
}}
71
71
+
}};
72
72
+
</script>
59
73
</head>
60
74
<body>
61
75
<h1>Inkpress: Gallery</h1>
···
104
118
else:
105
119
super().do_GET()
106
120
121
121
+
async def websocket_handler(websocket, path):
122
122
+
connected_clients.add(websocket)
123
123
+
try:
124
124
+
await websocket.wait_closed()
125
125
+
finally:
126
126
+
connected_clients.remove(websocket)
127
127
+
128
128
+
async def notify_clients():
129
129
+
if connected_clients:
130
130
+
await asyncio.gather(
131
131
+
*[client.send('reload') for client in connected_clients]
132
132
+
)
133
133
+
107
134
def take_photo():
108
135
"""
109
136
Captures a photo using the Raspberry Pi camera.
···
127
154
128
155
picam2.capture_file(filename)
129
156
logger.info("Photo taken successfully")
157
157
+
158
158
+
# Notify websocket clients to reload
159
159
+
asyncio.run(notify_clients())
130
160
except IOError as e:
131
161
logger.error(f"IO Error while taking photo: {str(e)}")
132
162
except Exception as e:
···
146
176
server = None
147
177
148
178
try:
179
179
+
# Start HTTP server
149
180
server = socketserver.TCPServer(("", Config.WEB_PORT), PhotoHandler)
150
181
server_thread = threading.Thread(target=server.serve_forever, daemon=True)
151
182
server_thread.start()
183
183
+
184
184
+
# Start WebSocket server
185
185
+
ws_server = websockets.serve(websocket_handler, "0.0.0.0", Config.WS_PORT)
186
186
+
asyncio.get_event_loop().run_until_complete(ws_server)
187
187
+
ws_thread = threading.Thread(
188
188
+
target=asyncio.get_event_loop().run_forever,
189
189
+
daemon=True
190
190
+
)
191
191
+
ws_thread.start()
152
192
153
193
previous_state = GPIO.input(Config.BUTTON_PIN)
154
194
while True: