inspbot and apis

parent b35eacb8
#TODO: 2nd progress presentation
This folder contains python based backend code
\ No newline at end of file
import RPi.GPIO as GPIO
from time import sleep
import subprocess
# Direction pin from controller
DIR = 5
CDIR = 10
# Step pin from controller
STEP = 3
CSTEP = 8
# 0/1 used to signify clockwise or counterclockwise.
CW = 1
CCW = 0
#motor steps
tower_steps = 0
found_row = 0
plant_index = [[4,5,14],[3,6,13],[2,7,12],[1,8,11],[0,9,10]]
rows = len(plant_index)
columns = len(plant_index[0])
# Setup pin layout on PI
GPIO.setmode(GPIO.BOARD)
# Establish Pins in software
GPIO.setup(DIR, GPIO.OUT)
GPIO.setup(STEP, GPIO.OUT)
GPIO.setup(CDIR, GPIO.OUT)
GPIO.setup(CSTEP, GPIO.OUT)
# Set the first direction you want it to spin
#GPIO.output(DIR, CW)
def Main(index):
#display plant 2D array
for x in plant_index: # outer loop
for i in x: # inner loop
print(i, end = " ") # print the elements
print()
#get plant index
# input_index = int(input("Enter plant index: "))
# print("plant_index",input_index)
input_index = index
#navigate plant location
#live camera on
#execfile("livestreamng.py")
#exec(open("livestreamng.py").read())
if (input_index != 0):
navigation(input_index)
f = open("steps.txt", "w")
f.write(str(tower_steps) + " " + str(found_row))
else:
f = open("steps.txt", "r")
c = [int(x) for x in f.read().split()]
camera_default(c[1])
tower_default(c[0])
f = open("steps.txt", "w")
f.write(str(0) + " " + str(0))
#navigatige defualt location
# print("tower_default",tower_steps)
# print("camera_default",found_row)
# input_defualt = bool(input("Do you want to stop inspection: "))
# if input_defualt:
# camera_default(found_row)
# tower_default(tower_steps)
# else:
# camera_default(found_row)
# tower_default(tower_steps)
# Once finished clean everything up
def tower_rotate(x):
print("Tower Rotate",x)
GPIO.output(DIR,CW)
for x in range(x):
GPIO.output(STEP,GPIO.HIGH)
sleep(.00005)
GPIO.output(STEP,GPIO.LOW)
sleep(.00005)
def camera_movement(y):
distance_palnts = 64000 #plant distance
degrees = (y-1)* distance_palnts
print("Camera Location",degrees)
GPIO.output(CDIR,CW)
for degrees in range(degrees):
GPIO.output(CSTEP,GPIO.HIGH)
sleep(.00005)
GPIO.output(CSTEP,GPIO.LOW)
sleep(.00005)
def tower_default(x):
print("Tower Rerotate",x)
GPIO.output(DIR,CCW)
for x in range(x):
GPIO.output(STEP,GPIO.HIGH)
sleep(.00005)
GPIO.output(STEP,GPIO.LOW)
sleep(.00005)
def camera_default(y):
distance_palnts = 64000 #plant distance
degrees = (y-1)* distance_palnts
print("Camera_defualt",degrees)
GPIO.output(CDIR,CCW)
for degrees in range(degrees):
GPIO.output(CSTEP,GPIO.HIGH)
sleep(.00005)
GPIO.output(CSTEP,GPIO.LOW)
sleep(.00005)
def navigation(input_index):
#search and identify respective row and column
global tower_steps
global found_row
flag = False
for i in range(rows):
for j in range(columns):
if plant_index[i][j]==input_index:
print("Plant Found!")
print('row',5-i)
print("column",j+1)
found_column = j+1
found_row = 5-i
#print(found_row)
#switch case for motor commands
if found_column == 1:
tower_steps = 0
tower_rotate(tower_steps)
sleep(1.0)
camera_movement(found_row)
elif found_column == 2:
tower_steps = 12200
tower_rotate(tower_steps)
sleep(1.0)
camera_movement(found_row)
elif found_column == 3:
tower_steps = 24400
tower_rotate(tower_steps)
sleep(1.0)
camera_movement(found_row)
flag = True
break
if flag == False:
print ("Plant Not found!")
if __name__ == "__main__":
Main()
print("cleanup")
GPIO.cleanup()
This diff is collapsed.
sed 's/allow_embedding = false/allow_embedding = true/' grafana.ini
allow_embedding = false
/etc/grafana
7beef9634ee0
docker run -d --mount type=bind,source=$PWD/grafana.ini,target=/etc/grafana/grafana.ini -p 3000:3000 grafana/grafana
sudo docker run -d --rm -e "GF_SECURITY_ALLOW_EMBEDDING=true" -e "GF_AUTH_ANONYMOUS_ENABLED=true" -e "GF_ORG_ANONYMOUS_ORG_NAME=Main Org." -e "GF_ORG_ANONYMOUS_ORG_ROLE=Viewer" -p 3000:3000 grafana/grafana
GF_SECURITY_ALLOW_EMBEDDING=true
-e "GF_AUTH_ANONYMOUS_ENABLED=true"
-e "GF_ORG_ANONYMOUS_ORG_NAME=Main Org."
-e "GF_ORG_ANONYMOUS_ORG_ROLE=Viewer"
\ No newline at end of file
30.40 91.50 900.00 174.00
from(bucket: "SensorData")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "Emp")
|> filter(fn: (r) => r._field == "Humidity")
|> map(fn: (r) => ({r with _value: float(v: r._value)}))
|> yield(name: "_editor_composition")
import json
import time
import serial
import os
import influxdb_client, os, time
from influxdb_client import InfluxDBClient, Point, WritePrecision
from influxdb_client.client.write_api import SYNCHRONOUS
SCREEN_DISPLAY=True
SAVE_TO_FILE=True
DELIMITER=','
#SERIAL_PORT='/dev/ttyACM0' # serial port terminal
SERIAL_PORT='/dev/ttyACM0'
scale=serial.Serial(SERIAL_PORT,timeout=20,baudrate=115200)
while True:
t_end = time.time() + 1 * 1
while time.time() < t_end:
file_name= 'output.txt'
fid= open(file_name,'wb')
str_scale=scale.readline()
str_scale.decode('utf').rstrip('\n')
time_now=time.strftime("%Y-%m-%d %H:%M:%S")
if SCREEN_DISPLAY: print(str_scale)
time.sleep(0.01) # in seconds
if SAVE_TO_FILE: fid.write(str_scale)
print ("end ")
# the file to be converted
filename = 'output.txt'
# resultant dictionary
dict1 = {}
# fields in the sample file
fields =['EcLevel', 'Moisture']
with open(filename) as fh:
# count variable for employee id creation
l = 1
for line in fh:
# reading line by line from the text file
description = list( line.strip().split(None, 4))
# for output see below
print(description)
# for automatic creation of id for each employee
sno ='emp'+str(l)
# loop variable
i = 0
# intermediate dictionary
dict2 = {}
while i<len(fields):
# creating dictionary for each employee
dict2[fields[i]]= description[i]
i = i + 1
# appending the record of each employee to
# the main dictionary
dict1[sno]= dict2
l = l + 1
# creating json file
out_file = open("test2.json", "w")
json.dump(dict1, out_file, indent = 4)
out_file.close()
token = "CrvRV1Ywxrb0osbdGThFJUtsiSpSC5GhSL1oiwrBCI02yWXw7AcEa2wVwtKvka_p1gpGEaC1vAIIlP7MxBhUYw=="
org = "shenalsamaranayakejfx@gmail.com"
url = "https://eastus-1.azure.cloud2.influxdata.com"
client = influxdb_client.InfluxDBClient(url=url, token=token, org=org)
bucket="SensorData"
write_api = client.write_api(write_options=SYNCHRONOUS)
for x,y in dict1.items():
point = (
Point("Emp")
.tag("EC", "EC")
.field("EC", y["EcLevel"])
)
point2 = (
Point("Emp")
.tag("Moisture", "Moisture")
.field("Moisture", y["Moisture"])
)
write_api.write(bucket=bucket, org="shenalsamaranayakejfx@gmail.com", record=point)
write_api.write(bucket=bucket, org="shenalsamaranayakejfx@gmail.com", record=point2)
time.sleep(.1) # separate points by .5 second
# for x,y in dict1.items():
# print(x)
# print(y["name"])
# print(y["time"])
# creating json file
import json
import time
import serial
import os
import influxdb_client, os, time
from influxdb_client import InfluxDBClient, Point, WritePrecision
from influxdb_client.client.write_api import SYNCHRONOUS
SCREEN_DISPLAY=True
SAVE_TO_FILE=True
DELIMITER=','
#SERIAL_PORT='/dev/ttyACM0' # serial port terminal
SERIAL_PORT='/dev/ttyACM1'
scale=serial.Serial(SERIAL_PORT,timeout=20,baudrate=9600)
while True:
t_end = time.time() + 1 * 1
while time.time() < t_end:
file_name= 'outputENV.txt'
fid= open(file_name,'wb')
str_scale=scale.readline()
str_scale.decode('utf').rstrip('\n')
time_now=time.strftime("%Y-%m-%d %H:%M:%S")
if SCREEN_DISPLAY: print(str_scale)
time.sleep(0.01) # in seconds
if SAVE_TO_FILE: fid.write(str_scale)
print ("end ")
# the file to be converted
filename = 'outputENV.txt'
# resultant dictionary
dict1 = {}
# fields in the sample file
fields =['Temperature', 'Humidity', 'LightIntensity', 'AirQuality']
with open(filename) as fh:
# count variable for employee id creation
l = 1
for line in fh:
# reading line by line from the text file
description = list( line.strip().split(None, 4))
# for output see below
print(description)
# for automatic creation of id for each employee
sno ='emp'+str(l)
# loop variable
i = 0
# intermediate dictionary
dict2 = {}
while i<len(fields):
# creating dictionary for each employee
dict2[fields[i]]= description[i]
i = i + 1
# appending the record of each employee to
# the main dictionary
dict1[sno]= dict2
l = l + 1
# creating json file
out_file = open("testenv.json", "w")
json.dump(dict1, out_file, indent = 4)
out_file.close()
token = "CrvRV1Ywxrb0osbdGThFJUtsiSpSC5GhSL1oiwrBCI02yWXw7AcEa2wVwtKvka_p1gpGEaC1vAIIlP7MxBhUYw=="
org = "shenalsamaranayakejfx@gmail.com"
url = "https://eastus-1.azure.cloud2.influxdata.com"
client = influxdb_client.InfluxDBClient(url=url, token=token, org=org)
bucket="SensorData"
write_api = client.write_api(write_options=SYNCHRONOUS)
for x,y in dict1.items():
point3 = (
Point("Emp")
.tag("Temperature", "Temperature")
.field("Temperature", y["Temperature"])
)
point4 = (
Point("Emp")
.tag("Humidity", "Humidity")
.field("Humidity", y["Humidity"])
)
point5 = (
Point("Emp")
.tag("LightIntensity", "LightIntensity")
.field("LightIntensity", y["LightIntensity"])
)
point6 = (
Point("Emp")
.tag("AirQuality", "AirQuality")
.field("AirQuality", y["AirQuality"])
)
write_api.write(bucket=bucket, org="shenalsamaranayakejfx@gmail.com", record=point3)
write_api.write(bucket=bucket, org="shenalsamaranayakejfx@gmail.com", record=point4)
write_api.write(bucket=bucket, org="shenalsamaranayakejfx@gmail.com", record=point5)
write_api.write(bucket=bucket, org="shenalsamaranayakejfx@gmail.com", record=point6)
time.sleep(.1) # separate points by .5 second
# for x,y in dict1.items():
# print(x)
# print(y["name"])
# print(y["time"])
# creating json file
{
"emp1": {
"EcLevel": "0",
"Moisture": "Dry"
}
}
\ No newline at end of file
{
"emp1": {
"Temperature": "30.40",
"Humidity": "91.50",
"LightIntensity": "900.00",
"AirQuality": "175.00"
}
}
\ No newline at end of file
<a href="http://192.168.1.5:8000/index.html">Live Stream</a>
import io
import picamera
import logging
import socketserver
from threading import Condition
from http import server
PAGE="""\
<html>
<head>
<title>See Live</title>
</head>
<body>
<center><h1>Live Streamer</h1></center>
<center><img src="stream.mjpg" width="640" height="480"></center>
</body>
</html>
"""
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)
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 == '/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='640x480', 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 = ('', 8007)
server = StreamingServer(address, StreamingHandler)
server.serve_forever()
finally:
camera.stop_recording()
from typing import Union
from fastapi import FastAPI
import Stepper_Live
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = [
"http://localhost",
"http://localhost:8080",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/navigate/manual/{index_id}")
def read_item(index_id: int):
Stepper_Live.Main(index_id)
return {"Response": "index " + str(index_id)}
uvicorn main:app --reload --host 0.0.0.0 --port 8080
\ No newline at end of file
0 0
\ No newline at end of file
-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
MrY=
-----END CERTIFICATE-----
This folder contains python based backend code
\ No newline at end of file
......@@ -11,11 +11,11 @@ import matplotlib.pyplot
import numpy as np
# Direction pin from controller
DIR = 10
CDIR = 5
DIR = 5
CDIR = 10
# Step pin from controller
STEP = 8
CSTEP = 3
STEP = 3
CSTEP = 8
# 0/1 used to signify clockwise or counterclockwise.
CW = 1
CCW = 0
......@@ -37,10 +37,10 @@ camera = PiCamera()
# Obtain connection string information from the portal
config = {
'host':'azdbmysqltest.mysql.database.azure.com',
'user':'ThyagaSenatilaka@azdbmysqltest',
'password':'Thagi.12345',
'database':'agroengine',
'host':'132.145.158.63',
'user':'root',
'password':'shenal@7788',
'database':'AgroEngineDB',
'client_flags': [mysql.connector.ClientFlag.SSL],
'ssl_ca': 'DigiCertGlobalRootG2.crt.pem'
}
......@@ -51,7 +51,7 @@ if conn.is_connected():
cursor = conn.cursor()
sql_insert_blob_query = """ INSERT INTO plant_images
sql_insert_blob_query = """ INSERT INTO plant_imgs
(img_ID, plant_ID, date, image) VALUES (%s,%s,%s,%s)"""
sql_insert_blob_query_procssed = """ INSERT INTO processed_images
......@@ -155,18 +155,18 @@ def tower_rotate_cw(x):
GPIO.output(DIR,CW)
for x in range(x):
GPIO.output(STEP,GPIO.HIGH)
sleep(.0005)
sleep(.00005)
GPIO.output(STEP,GPIO.LOW)
sleep(.0005)
sleep(.00005)
def tower_rotate_ccw(x):
print("tower ccw rotate ",x)
GPIO.output(DIR,CCW)
for x in range(x):
GPIO.output(STEP,GPIO.HIGH)
sleep(.0005)
sleep(.00005)
GPIO.output(STEP,GPIO.LOW)
sleep(.0005)
sleep(.00005)
def camera_movement_cw(y):
distance_palnts = 64000 #plant distance
......@@ -174,9 +174,9 @@ def camera_movement_cw(y):
GPIO.output(CDIR,CW)
for degrees in range(distance_palnts):
GPIO.output(CSTEP,GPIO.HIGH)
sleep(.0005)
sleep(.00005)
GPIO.output(CSTEP,GPIO.LOW)
sleep(.0005)
sleep(.00005)
def camera_movement_ccw(y):
distance_palnts = 64000 #plant distance
......@@ -184,9 +184,9 @@ def camera_movement_ccw(y):
GPIO.output(CDIR,CCW)
for degrees in range(distance_palnts):
GPIO.output(CSTEP,GPIO.HIGH)
sleep(.0005)
sleep(.00005)
GPIO.output(CSTEP,GPIO.LOW)
sleep(.0005)
sleep(.00005)
def convertToBinaryData(filename):
# Convert digital data to binary format
......
import RPi.GPIO as GPIO
from time import sleep
# Direction pin from controller
DIR = 5
# Step pin from controller
STEP = 3
# 0/1 used to signify clockwise or counterclockwise.
CW = 1
CCW = 0
# Setup pin layout on PI
GPIO.setmode(GPIO.BOARD)
# Establish Pins in software
GPIO.setup(DIR, GPIO.OUT)
GPIO.setup(STEP, GPIO.OUT)
# Set the first direction you want it to spin
GPIO.output(DIR, CW)
try:
# Run forever.
"""Change Direction: Changing direction requires time to switch. The
time is dictated by the stepper motor and controller. """
'''sleep(1.0)
# Esablish the direction you want to go
GPIO.output(DIR,CW)
# Run for 200 steps. This will change based on how you set you controller
for x in range(240000):
# Set one coil winding to high
GPIO.output(STEP,GPIO.HIGH)
# Allow it to get there.
sleep(.00005) # Dictates how fast stepper motor will run
# Set coil winding to low
GPIO.output(STEP,GPIO.LOW)
sleep(.00005) # Dictates how fast stepper motor will run
"""Change Direction: Changing direction requires time to switch. The
time is dictated by the stepper motor and controller. """
sleep(1.0)'''
GPIO.output(DIR,CW)
for x in range(96000):
GPIO.output(STEP,GPIO.HIGH)
sleep(.00005)
GPIO.output(STEP,GPIO.LOW)
sleep(.00005)
# Once finished clean everything up
except KeyboardInterrupt:
print("cleanup")
GPIO.cleanup()
from picamera import PiCamera
import time
camera = PiCamera()
camera.start_preview()
time.sleep(2)
camera.capture("test.jpg")
<a href="http://192.168.1.5:8000/index.html">Live Stream</a>
......@@ -8,10 +8,10 @@ from http import server
PAGE="""\
<html>
<head>
<title>Raspberry Pi - Surveillance Camera</title>
<title>See Live</title>
</head>
<body>
<center><h1>Raspberry Pi - Surveillance Camera</h1></center>
<center><h1>Live Streamer</h1></center>
<center><img src="stream.mjpg" width="640" height="480"></center>
</body>
</html>
......
print("hello world")
import RPi.GPIO as GPIO
from time import sleep
# Direction pin from controller
DIR = 10
# Step pin from controller
STEP = 8
# 0/1 used to signify clockwise or counterclockwise.
CW = 1
CCW = 0
# Setup pin layout on PI
GPIO.setmode(GPIO.BOARD)
# Establish Pins in software
GPIO.setup(DIR, GPIO.OUT)
GPIO.setup(STEP, GPIO.OUT)
# Set the first direction you want it to spin
GPIO.output(DIR, CW)
try:
# Run forever.
"""Change Direction: Changing direction requires time to switch. The
time is dictated by the stepper motor and controller. """
'''sleep(1.0)
# Esablish the direction you want to go
GPIO.output(DIR,CW)
# Run for 200 steps. This will change based on how you set you controller
for x in range(240000):
# Set one coil winding to high
GPIO.output(STEP,GPIO.HIGH)
# Allow it to get there.
sleep(.00005) # Dictates how fast stepper motor will run
# Set coil winding to low
GPIO.output(STEP,GPIO.LOW)
sleep(.00005) # Dictates how fast stepper motor will run
"""Change Direction: Changing direction requires time to switch. The
time is dictated by the stepper motor and controller. """
sleep(1.0)'''
GPIO.output(DIR,CCW)
for x in range(24400):
GPIO.output(STEP,GPIO.HIGH)
sleep(.000005)
GPIO.output(STEP,GPIO.LOW)
sleep(.000005)
# Once finished clean everything up
except KeyboardInterrupt:
print("cleanup")
GPIO.cleanup()
from picamera import PiCamera
import time
camera = PiCamera()
camera.resolution = (640,480)
camera.vflip = True
camera.start_preview()
time.sleep(2)
camera.start_recording("video.h264")
time.sleep(5)
camera.stop_recording()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment