Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Newbie help combining two scripts
#11
Woo-hoo, almost there. Some kind of a decoding issue apparently :) Now I can get the actual temperature reading from xxx:8000/get-temp and the camera stream from xxx:8000/index.html

The only problem now is, that for some reason (the js-part?) I cannot fetch the temp data into the div.

# 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 json
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>

</head>
<body>
<center><h1>Kanikamera</h1></center>
<center><h3>L&auml;mp&ouml;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-->

<script>
function updateTemp(){
window.fetch('http://xxxxx.xxxxx.org:8000/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>

</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

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}).encode('utf-8'))
        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()
Reply
#12
You likely need to debug what is happening with js-part of the code. Open browser with your url,
Output:
let el = document.getElementById('temperature') el.innerHTML = data.stringify() // you can do this better
open developer tools (e.g. via inspecting some element on the page),
and put a breakpoint to let el .... or el.innerHTML .... The main question here is to inspect data variable (its value, does updateTemp read temp value correctly?).
Reply
#13
(Oct-03-2020, 06:03 PM)emuola Wrote: Woo-hoo, almost there. Some kind of a decoding issue apparently :) Now I can get the actual temperature reading from xxx:8000/get-temp and the camera stream from xxx:8000/index.html

The only problem now is, that for some reason (the js-part?) I cannot fetch the temp data into the div.

# 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 json
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>

</head>
<body>
<center><h1>Kanikamera</h1></center>
<center><h3>L&auml;mp&ouml;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-->

<script>
function updateTemp(){
window.fetch('http://xxxxx.xxxxx.org:8000/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>

</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

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}).encode('utf-8'))
        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()

Works!! :) Now I only need to make it look a bit nicer. How could "formulate" the JSON response displayed in the div? At the moment it looks like in the screen shot attached. How could I display only the temperature reading without the brackets and stuff?

Thank you soo much for your support scidam! Dance

Attached Files

Thumbnail(s)
   
Reply
#14
Try the following:
PAGE="""\
<html>
<head>
<title>Kanikamera</title>
 
</head>
<body>
<center><h1>Kanikamera</h1></center>
<center><h3>L&auml;mp&ouml;tila</h3><h3 id="portfolio-code"></h3></center>
<center><img src="stream.mjpg" width="1280" height="720"></center>
<center><div id="temperature" style="font-size: 20px;"></div></center>
 
<!--This is the script for displaying the temperature on the web page-->
 
<script>
function updateTemp(){
window.fetch('http://xxxxx.xxxxx.org:8000/get-temp', {method: 'get'}).then(r => r.json())
  .then(function(data){
   let el = document.getElementById('temperature')
    el.innerHTML = data['temp_c'] + " degrees. Time of the last measurement: " + getDateTime();

})
  .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
  


function getDateTime() {
    var now     = new Date(); 
    var year    = now.getFullYear();
    var month   = now.getMonth()+1; 
    var day     = now.getDate();
    var hour    = now.getHours();
    var minute  = now.getMinutes();
    var second  = now.getSeconds(); 
    if(month.toString().length == 1) {
            month = '0'+month;
    }
    if(day.toString().length == 1) {
            day = '0'+day;
    }   
    if(hour.toString().length == 1) {
            hour = '0'+hour;
    }
    if(minute.toString().length == 1) {
            minute = '0'+minute;
    }
    if(second.toString().length == 1) {
            second = '0'+second;
    }   
    var dateTime = year+'/'+month+'/'+day+' '+hour+':'+minute+':'+second;   
        return dateTime;
}

updateTemp();
setInterval(updateTemp, 5000);  // update measurements every 5 sec

</script>
 
</body>
</html>
"""
There are still a lot of possibilities to change your page appearance. Try to define custom style for your div,
use span tags to change style of the text inside div, etc.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Combining 2 scripts wpothers 5 4,711 Feb-21-2017, 12:38 PM
Last Post: wavic

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020