Here some Python code to fix the focus issue, and send commands to the cameras.I'm not the best programmer but it would be good place to start.
=================================================================================================================
import sys
import os
import brainboxes
import r_setup as s #you need a r_setup.py to initialize the public variables
import datetime
import time
import math
import requests
import subprocess
from decimal import Decimal
from requests.auth import HTTPDigestAuth
Here some Python code to fix the focus issue, and send commands to the cameras.I'm not the best programmer but it would be good place to start.
=================================================================================================================
import sys
import os
import brainboxes
import r_setup as s #you need a r_setup.py
import datetime
import time
import math
import requests
import subprocess
from decimal import Decimal
from subprocess import Popen, PIPE
from decimal import Decimal
from requests.auth import HTTPDigestAuth
def save_Log(errorLog):
now = datetime.datetime.now()
currdatetime = now.strftime("%Y-%m-%d %H:%M:%S")
errorLogtmp = currdatetime + " - " + errorLog
cr ="\n"
text = open("r_error.log","a")
print(errorLogtmp, file = text)
text.close()
def wait_key():
''' Wait for a key press on the console and return it. '''
result = None
if os.name == 'nt':
import msvcrt
result = msvcrt.getch()
else:
import termios
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
try:
result = sys.stdin.read(1)
except IOError:
pass
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
return result
def is_locked(filepath):
"""Checks if a file is locked by opening it in append mode.
If no exception thrown, then the file is not locked.
"""
locked = None
file_object = None
if os.path.exists(filepath):
try:
#print ("Trying to open %s." % filepath)
buffer_size = 8
# Opening file in append mode and read the first 8 characters.
file_object = open(filepath, 'a', buffer_size)
if file_object:
#print ("%s is not locked." % filepath)
locked = False
except IOError:
print ("File is locked (unable to open in append mode).")
locked = True
finally:
if file_object:
file_object.close()
print ("%s closed." % filepath)
else:
print ("%s not found." % filepath)
return locked
def wait_for_files(filepath):
"""Checks if the files are ready.
For a file to be ready it must exist and can be opened in append
mode.
"""
count = 0
wait_time = 5
#for filepath in filepaths:
# If the file doesn't exist, wait wait_time seconds and try again
# until it's found. Give up after 5 rounds
while (not os.path.exists(filepath)) & (count < 4):
print (filepath)
print (filepath + " hasn't arrived. Waiting " + str(wait_time) + " seconds.")
time.sleep(wait_time)
count = count + 1
# If the file exists but locked, wait wait_time seconds and check
# again until it's no longer locked by another process.
while is_locked(filepath):
print (filepath + " is currently in use. Waiting " + str(wait_time) + " seconds.")
time.sleep(wait_time)
########################
# #
# Functions #
# #
# Read from Comm Port #
def _readline(self):
eol = b'\r'
leneol = len(eol)
line = bytearray()
if (serialData.inWaiting()>0): #if incoming bytes are waiting to be read from the serial input buffer
while True:
c = serialData.read(1)
if c:
line += c
if line[-leneol:] == eol:
break
else:
break
return bytes(line)
def insert_plate():
sql = "INSERT INTO platedata "
sql = sql + "(camera_label, epoch, events, vehicle_time, vehicle_jpg, vehicle_plate, vehicle_confidence, vehicle_region, vehicle_make_model, vehicle_year, vehicle_body_type, vehicle_make, vehicle_color)"
sql = sql + " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
val = (s.cameraName, s.eventStart, s.events, s.videodatetime, s.picture, s.vehicle_plate, s.vehicle_confidence, s.vehicle_region, s.vehicle_make_model, s.vehicle_year, s.vehicle_body_type, s.vehicle_make, s.vehicle_color)
print(sql)
print(val)
s.cursor.execute(sql, val)
s.dbConn.commit() #commit the insert
return
def update_plate():
sql = "UPDATE platedata SET "
sql = sql + "events = " + "'" + s.events + "'"
sql = sql + ", vehicle_jpg = " + "'" + s.picture + "'"
sql = sql + ", vehicle_plate_alias = " + "'" + s.last_vehicle_plate + "'"
sql = sql + " WHERE vehicle_plate = " + "'" + s.vehicle_plate + "'"
print(sql)
s.cursor.execute(sql)
s.dbConn.commit() #commit the insert
return
def insert_speeddata():
sql = "INSERT INTO speeddata "
sql = sql + "(direction, MeasuredSpeed, minSpeed, maxSpeed, eventStart, currentUnixTime, Street, City, State, Zip, maxhourlyspeed, hourlyAverage, eventCounter, eventDuration, speedStart, speedEnd, speedersPerHour, videoRight, videoLeft, videodatetime, day, hour, quarter, minute)"
sql = sql + " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
val = (LastDirection, eventSpeed, minSpeedData, maxSpeedData, eventStart, currentUnixTime, s.Street, s.City, s.State, s.Zip, maxHourlySpeed, hourlyAverage, eventCounter, eventDuration, speedStart, speedEnd, speedersPerHour, videoRight, videoLeft, videodatetime, DayofWeek, hour, quarter, minute)
#print (sql)
#print (val)
s.cursor.execute(sql, val)
s.dbConn.commit() #commit the insert
def insert_hourly():
sql = "INSERT INTO HourlyReport "
sql = sql + "(date, Hour, Events, Overspeeds, MaxHourly, AvgHourly, Percent, Day, eventStart)"
sql = sql + " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)"
val = (date, LastTopOfHour, eventCounter, speedersPerHour, maxHourlySpeed, hourlyAverage, Percent, DayofWeek, maxEvent)
s.cursor.execute(sql, val)
s.dbConn.commit() #commit the insert
return
def insert_quarterly():
sql = "INSERT INTO QuarterlyReport "
sql = sql + "(date, day, hour, minute, quarter, eventCounterQ, speedersPerQ, maxSpeedQ, AverageQ, PercentQ, eventStart)"
sql = sql + " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
val = (date, DayofWeek, hour, minute, quarter, eventCounterQ, speedersPerQ, maxSpeedQ, AverageQ, PercentQ, maxEventQ)
s.cursor.execute(sql, val)
s.dbConn.commit() #commit the insert
return
def write_speed_overlay():
cr ="\n"
overlay = "" + s.Street + " - " + s.City + ", " + s.State + cr
overlay = overlay + "CST " + currdatetime + cr
overlay = overlay + "Curr Epoch " + str(s.currentUnixTime) + cr
overlay = overlay + "Start " + str(s.eventStart) + cr
overlay = overlay + "Event Dur " + str(s.eventDuration) + cr
overlay = overlay + "Events/Hr " + str(s.eventCounter) + cr
overlay = overlay + "Direction " + str(s.direction) + cr
overlay = overlay + "Curr Speed " + str(s.MeasuredSpeed) + cr
overlay = overlay + "Max Speed " + str(s.maxSpeedData) + cr
overlay = overlay + "Min Speed " + str(s.minSpeedData) + cr
overlay = overlay + "Hourly Max " + str(s.maxHourlySpeed) + cr
overlay = overlay + "Hourly Avg " + str(s.hourlyAverage) + cr
overlay = overlay + "OverSpd/Hr " + str(s.speedersPerHour)
print (overlay)
print (wait_for_files("speed.txt"))
text= open("speed.txt","w")
print(overlay, file = text)
text.close()
return
def dstTest():
dstTest = time.localtime().tm_isdst # localtime() returns a tuple
# dstTest 0 = No DST 1 = DST Active -1 = DST unknown
return dstTest
def date_to_jd(year,month,day):
# Convert a date to Julian Day.
# Algorithm from 'Practical Astronomy with your Calculator or Spreadsheet',
# 4th ed., Duffet-Smith and Zwart, 2011.
# This function extracted from
if month == 1 or month == 2:
yearp = year - 1
monthp = month + 12
else:
yearp = year
monthp = month
# this checks where we are in relation to October 15, 1582, the beginning
# of the Gregorian calendar.
if ((year < 1582) or
(year == 1582 and month < 10) or
(year == 1582 and month == 10 and day < 15)):
# before start of Gregorian calendar
B = 0
else:
# after start of Gregorian calendar
A = math.trunc(yearp / 100.)
B = 2 - A + math.trunc(A / 4.)
if yearp < 0:
C = math.trunc((365.25 * yearp) - 0.75)
else:
C = math.trunc(365.25 * yearp)
D = math.trunc(30.6001 * (monthp + 1))
jd = B + C + D + day + 1720994.5
return jd
# end of date_to_jd
def sunrise():
latitude_deg = s.lat
longitude_deg = s.long
timezone = s.timezone #we check for Daylight Savings Time and add 1 hour
x = dstTest()
if x == 1:
timezone = timezone + 1
print("DST is Active")
pi=3.14159265359
latitude_radians = math.radians(latitude_deg)
longitude__radians = math.radians(longitude_deg)
jd2000 = 2451545 #the julian date for Jan 1 2000 at noon
currentDT = datetime.datetime.now()
current_year = currentDT.year
current_month = currentDT.month
current_day = currentDT.day
current_hour = currentDT.hour
jd_now = date_to_jd(current_year,current_month,current_day)
n = jd_now - jd2000 + 0.0008
jstar = n - longitude_deg/360
M_deg = (357.5291 + 0.98560028 * jstar)%360
M = M_deg * pi/180
C = 1.9148 * math.sin(M) + 0.0200 * math.sin(2*M) + 0.0003 * math.sin(3*M)
lamda_deg = math.fmod(M_deg + C + 180 + 102.9372,360)
lamda = lamda_deg * pi/180
Jtransit = 2451545.5 + jstar + 0.0053 * math.sin(M) - 0.0069 * math.sin(2*lamda)
earth_tilt_deg = 23.44
earth_tilt_rad = math.radians(earth_tilt_deg)
sin_delta = math.sin(lamda) * math.sin(earth_tilt_rad)
angle_delta = math.asin(sin_delta)
sun_disc_deg = -0.83
sun_disc_rad = math.radians(sun_disc_deg)
cos_omega = (math.sin(sun_disc_rad) - math.sin(latitude_radians) * math.sin(angle_delta))/(math.cos(latitude_radians) * math.cos(angle_delta))
omega_radians = math.acos(cos_omega)
omega_degrees = math.degrees(omega_radians)
#Output section
print("------------------------------")
print("Today's date is " + currentDT.strftime("%Y-%m-%d"))
print("------------------------------")
#("%Y-%m-%d %H:%M")
print("Latitude = " + str(latitude_deg))
print("Longitude = " + str(longitude_deg))
print("Timezone = " + str(timezone))
print("------------------------------")
Jrise = Jtransit - omega_degrees/360
numdays = Jrise - jd2000
numdays = numdays + 0.5 #offset because Julian dates start at noon
numdays = numdays + timezone/24 #offset for time zone
sunrise = datetime.datetime(2000, 1, 1) + datetime.timedelta(numdays)
print("Sunrise is at " + sunrise.strftime("%H:%M"))
sunriseMidnight = (int(sunrise.strftime("%H"))*60) + int(sunrise.strftime("%M"))
Jset = Jtransit + omega_degrees/360
numdays = Jset - jd2000
numdays = numdays + 0.5 #offset because Julian dates start at noon
numdays = numdays + timezone/24 #offset for time zone
sunset = datetime.datetime(2000, 1, 1) + datetime.timedelta(numdays)
print("Sunset is at " + sunset.strftime("%H:%M"))
print("------------------------------")
sunsetMidnight = (int(sunset.strftime("%H"))*60) + int(sunset.strftime("%M"))
now = datetime.datetime.now()
nowMinSinceMidnight = (int(now.strftime("%H"))*60) + int(now.strftime("%M"))
s.sunRise = sunriseMidnight + 15
s.sunSet = sunsetMidnight - 15 #15 minutes seems to work
s.dayNight = ""
if nowMinSinceMidnight < s.sunRise:
set_all_cameras_night()
if (nowMinSinceMidnight > s.sunRise) and (nowMinSinceMidnight < s.sunSet):
set_all_cameras_day()
if nowMinSinceMidnight > s.sunSet:
set_all_cameras_night()
return s.dayNight
def dayNightAdjust():
now = datetime.datetime.now()
nowMinSinceMidnight = (int(now.strftime("%H"))*60) + int(now.strftime("%M"))
if (nowMinSinceMidnight < s.sunRise) and s.dayNight != "night":
set_all_cameras_night()
if (nowMinSinceMidnight > s.sunRise) and (nowMinSinceMidnight < s.sunSet) and s.dayNight != "day":
set_all_cameras_day()
if (nowMinSinceMidnight > s.sunSet) and s.dayNight != "night":
set_all_cameras_night()
return
def set_all_cameras_day():
s.dayNight = "day"
set_camera_day(s.ipCAM1)
set_camera_day(s.ipCAM2)
set_camera_day(s.ipCAM3)
now = datetime.datetime.now()
nowMinSinceMidnight = (int(now.strftime("%H"))*60) + int(now.strftime("%M"))
save_Log("Set Day ** Sunrise ** All Cams " + str(nowMinSinceMidnight) + " - " + str(s.sunRise) + " - " + str(s.sunSet))
set_manual_focus(0, s.ipCAM1) # day mode
set_camera_color_mode(0, s.ipCAM1)
time.sleep(.1)
mode =1 # day mode
set_focus_position(0, s.ipCAM1, s.focusCam1Day, s.zoomCam1Day)
return
def set_all_cameras_night():
s.dayNight = "night"
set_camera_night(s.ipCAM1)
set_camera_night(s.ipCAM2)
set_camera_night(s.ipCAM3)
now = datetime.datetime.now()
nowMinSinceMidnight = (int(now.strftime("%H"))*60) + int(now.strftime("%M"))
save_Log("Set Night ** Sunset ** All Cams " + str(nowMinSinceMidnight) + " - " + str(s.sunRise) + " - " + str(s.sunSet))
set_manual_focus(1, s.ipCAM1) #night mode
set_camera_bw_mode(1, s.ipCAM1)
time.sleep(.1)
set_focus_position(1, s.ipCAM1, s.focusCam1Night, s.zoomCam1Night)
return
##########################################################################
# request() gets from url, and returns the information in a Python list. #
# if an error is return it logs the command #
##########################################################################
def request(self):
url = self
r = requests.get(url, auth=HTTPDigestAuth(s.userCam, s.passwordCam))
result = r.text.splitlines()
if result[0] == 'Error':
f.save_Log("**Error** - Request -> " + url)
return result
######################################################
# These Dahua commnds may not work for every camera. #
# It depends on version and features #
# send your ip address and it returns a list #
######################################################
def set_camera_night(ipCAM):
s.dayNight = "night"
cmd = "/cgi-bin/configManager.cgi?action=setConfig&VideoInMode[0].Config[0]=1"
cmdCAM = "http://" + ipCAM + cmd
result = request(cmdCAM)
if result[0] == 'Error':
f.save_Log("**Error** - Set Camera Night -> " + ipCAM)
return
def set_camera_day(ipCAM):
s.dayNight = "day"
cmd = "/cgi-bin/configManager.cgi?action=setConfig&VideoInMode[0].Config[0]=0"
cmdCAM = "http://" + ipCAM + cmd
result = request(cmdCAM)
if result[0] == 'Error':
f.save_Log("**Error** - Set Camera Day-> " + ipCAM)
return
def set_camera_color_mode(mode, ipCAM): # 0 - day, 1 = night
cmd = "/cgi-bin/configManager.cgi?action=setConfig&VideoInDayNight[0].Config[" + str(mode) + "].Mode=Color"
cmdCAM = "http://" + ipCAM + cmd
result = request(cmdCAM)
if result[0] == 'Error':
f.save_Log("**Error** - Set Camera Color -> " + ipCAM)
return
def set_camera_bw_mode(mode, ipCAM): # 0 - day, 1 = night
cmd = "/cgi-bin/configManager.cgi?action=setConfig&VideoInDayNight[0].Config[" + str(mode) + "].Mode=BlackWhite"
cmdCAM = "http://" + ipCAM + cmd
result = request(cmdCAM)
if result[0] == 'Error':
f.save_Log("**Error** - Set Cmaer BW -> " + ipCAM)
return
def camera_reboot(ipCAM):
cmd = "/cgi-bin/magicBox.cgi?action=reboot"
cmdCAM = "http://" + ipCAM + cmd
result = request(cmdCAM)
time.sleep(2)
result = request(cmdCAM)
if result[0] == 'Error':
f.save_Log("**Error** - Camera Reboot -> " + ipCAM)
return
def get_camera_exposure(ipCAM):
cmdGetExposure = "/cgi-bin/configManager.cgi?action=getConfig&name=VideoInExposure"
cmdCAM = "http://" + ipCAM + cmdGetExposure
result = request(cmdCAM)
if result[0] == 'Error':
f.save_Log("**Error** - Get Camera Exposure -> " + ipCAM)
return result
def set_manual_focus(mode, ipCAM): # mode = 0 day mode, 1 = day mode
cmd = "/cgi-bin/configManager.cgi?action=setConfig&VideoInDayNight[0].Config[" + str(mode) + "].Mode=4"
cmdCAM = "http://" + ipCAM + cmd
result = request(cmdCAM)
if result[0] == 'Error':
f.save_Log("**Error** - Set Manual Focus -> " + ipCAM)
return
def set_focus_position(mode, ipCAM, focus, zoom): # we approach position from same direction each time
read_focus_settings()
get_camera_focus_status(ipCAM)
if s.focusReal != focus:
cmd = "/cgi-bin/devVideoInput.cgi?action=adjustFocus&focus=" + str(focus - Decimal(0.01)) +"&zoom=" + str(zoom)
cmdCAM = "http://" + ipCAM + cmd
result = request(cmdCAM)
time.sleep(.3)
cmd = "/cgi-bin/devVideoInput.cgi?action=adjustFocus&focus=" + str(focus) +"&zoom=" + str(zoom)
cmdCAM = "http://" + ipCAM + cmd
result = request(cmdCAM)
if result[0] == 'Error':
f.save_Log("**Error** - Focus Set Position -> " + ipCAM)
return
def get_camera_focus_status(ipCAM):
cmdGetFocus = "/cgi-bin/devVideoInput.cgi?action=getFocusStatus"
cmdCAM = "http://" + ipCAM + cmdGetFocus
result = request(cmdCAM)
temp = result[0].partition("=")[2]
s.focusReal = int(Decimal(temp))
temp = result[5].partition("=")[2]
s.zoomReal = int(Decimal(temp))
if result[0] == 'Error':
f.save_Log("**Error** - Focus Status -> " + ipCAM)
return
def read_focus_settings():
sql = "SELECT focusCam1Day, zoomCam1Day, focusCam1Night, zoomCam1Night FROM settings"
s.cursor.execute(sql)
result = s.cursor.fetchone()
s.focusCam1Day = result[0]
s.zoomCam1Day = result[1]
s.focusCam1Night = result[2]
s.zoomCam1Night = result[3]
return