Oct-03-2020, 09:30 AM
(Oct-02-2020, 11:39 PM)scidam Wrote: I expected that you modifydo_GET
, but not put it outside
StreamingHandler
.
YourStreamingHandler
should look like the following:
class StreamingHandler(server.BaseHTTPRequestHandler): def do_GET(self): if self.path == '/': self.send_response(301) self.send_header('Location', '/index.html') self.end_headers() elif self.path == '/index.html': content = PAGE.encode('utf-8') self.send_response(200) self.send_header('Content-Type', 'text/html') self.send_header('Content-Length', len(content)) self.end_headers() self.wfile.write(content) elif self.path == '/get-temp': self.send_response(200) self.send_header('Content-Type', 'application/json') self.end_headers() tf, tc = read_temp() self.wfile.write(json.dumps({'temp_c':tf, 'temp_f':tc})) elif self.path == '/stream.mjpg': self.send_response(200) self.send_header('Age', 0) self.send_header('Cache-Control', 'no-cache, private') self.send_header('Pragma', 'no-cache') self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME') self.end_headers() try: while True: with output.condition: output.condition.wait() frame = output.frame self.wfile.write(b'--FRAME\r\n') self.send_header('Content-Type', 'image/jpeg') self.send_header('Content-Length', len(frame)) self.end_headers() self.wfile.write(frame) self.wfile.write(b'\r\n') except Exception as e: logging.warning( 'Removed streaming client %s: %s', self.client_address, str(e)) else: self.send_error(404) self.end_headers()
Thank you once again scidam :) Now the code seems to be ok structurally. Unfortunately I still cannot access the xxx/get-temp and/or get the temp reading to show on the page. In the console I have this output when I run the script:
91.155.104.47 - - [03/Oct/2020 10:28:06] "GET /index.html HTTP/1.1" 200 - 91.155.104.47 - - [03/Oct/2020 10:28:06] "GET /stream.mjpg HTTP/1.1" 200 - 91.155.104.47 - - [03/Oct/2020 10:28:06] code 404, message Not Found 91.155.104.47 - - [03/Oct/2020 10:28:06] "GET /favicon.ico HTTP/1.1" 404 -Here's the complete page after the edits:
# Web streaming example # Source code from the official PiCamera package # http://picamera.readthedocs.io/en/latest/recipes2.html#web-streaming import os import glob import io import picamera import logging import socketserver from threading import Condition from http import server import time from w1thermsensor import W1ThermSensor PAGE="""\ <html> <head> <title>Kanikamera</title> <script> function updateTemp(){ window.fetch('http://your_url/get-temp', {method: 'get'}).then(r => r.json()) .then(function(data){ let el = document.getElementById('temperature') el.innerHTML = data.stringify() // you can do this better }) .catch(e => console.log("error ocurred...")) } // this executes only once, but you need to run it every second updateTemp() // You probably need to run this continuously, e.g. using SetInterval function </script> </head> <body> <center><h1>Kanikamera</h1></center> <center><h3>Lämpötila</h3><h3 id="portfolio-code"></h3></center> <center><img src="stream.mjpg" width="1280" height="720"></center> <center><div id="temperature"></div></center> <!--This is the script for displaying the temperature on the web page--> </body> </html> """ #This is the part to get the temperature #os.system('modprscriptobe w1-gpio') #os.system('modprobe w1-therm') base_dir = '/sys/bus/w1/devices/' device_folder = glob.glob(base_dir + '28*')[0] device_file = device_folder + '/w1_slave' def read_temp_raw(): f = open(device_file, 'r') lines = f.readlines() f.close() return lines def read_temp(): lines = read_temp_raw() while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = read_temp_raw() equals_pos = lines[1].find('t=') if equals_pos != -1: temp_string = lines[1][equals_pos+2:] temp_c = float(temp_string) / 1000.0 temp_f = temp_c * 9.0 / 5.0 + 32.0 return temp_c, temp_f #This is the part, which makes the endpoint for the AJAX. # def do_GET(self): # if self.path == '/': # self.send_response(301) # self.send_header('Location', '/index.html') # self.end_headers() # elif self.path == '/index.html': # content = PAGE.encode('utf-8') # self.send_response(200) # self.send_header('Content-Type', 'text/html') # self.send_header('Content-Length', len(content)) # self.end_headers() # self.wfile.write(content) # elif self.path == '/get-temp': # self.send_response(200) # self.send_header('Content-Type', 'application/json') # self.end_headers() # tf, tc = read_temp() # self.wfile.write(json.dumps({'temp_c':10, 'temp_f':10})) class StreamingOutput(object): def __init__(self): self.frame = None self.buffer = io.BytesIO() self.condition = Condition() def write(self, buf): if buf.startswith(b'\xff\xd8'): # New frame, copy the existing buffer's content and notify all # clients it's available self.buffer.truncate() with self.condition: self.frame = self.buffer.getvalue() self.condition.notify_all() self.buffer.seek(0) return self.buffer.write(buf) #This is the part for the camera class StreamingHandler(server.BaseHTTPRequestHandler): def do_GET(self): if self.path == '/': self.send_response(301) self.send_header('Location', '/index.html') self.end_headers() elif self.path == '/index.html': content = PAGE.encode('utf-8') self.send_response(200) self.send_header('Content-Type', 'text/html') self.send_header('Content-Length', len(content)) self.end_headers() self.wfile.write(content) elif self.path == '/get-temp': self.send_response(200) self.send_header('Content-Type', 'application/json') self.end_headers() tf, tc = read_temp() self.wfile.write(json.dumps({'temp_c':tf, 'temp_f':tc})) elif self.path == '/stream.mjpg': self.send_response(200) self.send_header('Age', 0) self.send_header('Cache-Control', 'no-cache, private') self.send_header('Pragma', 'no-cache') self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME') self.end_headers() try: while True: with output.condition: output.condition.wait() frame = output.frame self.wfile.write(b'--FRAME\r\n') self.send_header('Content-Type', 'image/jpeg') self.send_header('Content-Length', len(frame)) self.end_headers() self.wfile.write(frame) self.wfile.write(b'\r\n') except Exception as e: logging.warning( 'Removed streaming client %s: %s', self.client_address, str(e)) else: self.send_error(404) self.end_headers() class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer): allow_reuse_address = True daemon_threads = True with picamera.PiCamera(resolution='1280x720', framerate=24) as camera: output = StreamingOutput() #Uncomment the next line to change your Pi's Camera rotation (in degrees) #camera.rotation = 90 camera.start_recording(output, format='mjpeg') try: address = ('', 8000) server = StreamingServer(address, StreamingHandler) server.serve_forever() finally: camera.stop_recording()