Skip to content

Commit 685b79d

Browse files
EricEric
authored andcommitted
v0.8.8 Added Camera Reset
1 parent 1be8ae7 commit 685b79d

File tree

3 files changed

+67
-9
lines changed

3 files changed

+67
-9
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mudpi-core",
3-
"version": "0.8.7",
3+
"version": "0.8.8",
44
"description": "Configurable automated smart garden for raspberry pi",
55
"bugs": "https://github.com/mudpi/mudpi-core/issues",
66
"contributors": [

tools/event_send_tool.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import redis
22
import threading
3-
import redis_sub
43
import json
54
import time
65

workers/camera_worker.py

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import redis
55
import threading
66
import sys
7+
import os
78
import RPi.GPIO as GPIO
89
from picamera import PiCamera
910
sys.path.append('..')
@@ -17,6 +18,7 @@ class CameraWorker():
1718
def __init__(self, config, main_thread_running, system_ready, camera_available):
1819
#self.config = {**config, **self.config}
1920
self.config = config
21+
self.pending_reset = False
2022

2123
#Events
2224
self.main_thread_running = main_thread_running
@@ -40,26 +42,42 @@ def __init__(self, config, main_thread_running, system_ready, camera_available):
4042
def init(self):
4143
try:
4244
self.camera = PiCamera(resolution=(self.resolutionX, self.resolutionY))
45+
# Below we calibrate the camera for consistent imaging
46+
camera.framerate = 30
47+
# Wait for the automatic gain control to settle
48+
time.sleep(2)
49+
# Now fix the values
50+
camera.shutter_speed = camera.exposure_speed
51+
camera.exposure_mode = 'off'
52+
g = camera.awb_gains
53+
camera.awb_mode = 'off'
54+
camera.awb_gains = g
4355
except:
4456
self.camera = PiCamera()
45-
#camera.start_preview()
57+
58+
#Pubsub Listeners
59+
self.pubsub = variables.r.pubsub()
60+
self.pubsub.subscribe(**{self.topic: self.handleEvent})
61+
4662
print('Camera Worker...\t\t\t\033[1;32m Ready\033[0;0m')
4763
return
4864

4965
def run(self):
5066
t = threading.Thread(target=self.work, args=())
5167
t.start()
68+
self.listener = threading.Thread(target=self.listen, args=())
69+
self.listener.start()
5270
print('Camera Worker...\t\t\t\033[1;32m Running\033[0;0m')
5371
return t
5472

5573
def wait(self):
5674
# Calculate the delay
5775
try:
58-
next_time = (datetime.datetime.now() + datetime.timedelta(hours=self.hours, minutes=self.minutes, seconds=self.seconds)).replace(microsecond=0)
76+
self.next_time = (datetime.datetime.now() + datetime.timedelta(hours=self.hours, minutes=self.minutes, seconds=self.seconds)).replace(microsecond=0)
5977
except:
6078
#Default every hour
61-
next_time = (datetime.datetime.now() + datetime.timedelta(hours=1)).replace(minute=0, second=0, microsecond=0)
62-
delay = (next_time - datetime.datetime.now()).seconds
79+
self.next_time = (datetime.datetime.now() + datetime.timedelta(hours=1)).replace(minute=0, second=0, microsecond=0)
80+
delay = (self.next_time - datetime.datetime.now()).seconds
6381
time.sleep(delay)
6482

6583
def elapsedTime(self):
@@ -70,24 +88,63 @@ def resetElapsedTime(self):
7088
self.time_start = time.perf_counter()
7189
pass
7290

91+
def handleEvent(self, message):
92+
data = message['data']
93+
decoded_message = None
94+
if data is not None:
95+
try:
96+
if isinstance(data, dict):
97+
decoded_message = data
98+
elif isinstance(data.decode('utf-8'), str):
99+
temp = json.loads(data.decode('utf-8'))
100+
decoded_message = temp
101+
if decoded_message['event'] == 'Timelapse':
102+
print("Camera Signaled for Reset")
103+
camera_available.clear()
104+
self.pending_reset = True
105+
except:
106+
print('Error Handling Event for Camera')
107+
108+
def listen(self):
109+
while self.main_thread_running.is_set():
110+
if self.system_ready.is_set():
111+
if self.camera_available.is_set():
112+
self.pubsub.get_message()
113+
time.sleep(1)
114+
else:
115+
delay = (self.next_time - datetime.datetime.now()).seconds + 15
116+
time.sleep(delay) #wait 15 seconds after next scheduled picture
117+
self.camera_available.set()
118+
else:
119+
time.sleep(2)
120+
return
121+
73122
def work(self):
74123
self.resetElapsedTime()
75124
while self.main_thread_running.is_set():
76125
if self.system_ready.is_set():
77126
if self.camera_available.is_set():
78127
# try:
79128
for i, filename in enumerate(self.camera.capture_continuous(self.path + 'mudpi-{counter:05d}.jpg')):
129+
if not self.camera_available.is_set():
130+
if self.pending_reset:
131+
try:
132+
os.remove(filename) #cleanup previous file
133+
self.pending_reset = False
134+
except:
135+
print("Error During Camera Reset Cleanup")
136+
break;
80137
message = {'event':'StateChanged', 'data':filename}
81138
variables.r.set('last_camera_image', filename)
82139
variables.r.publish(self.topic, json.dumps(message))
83140
print('Image Captured \033[1;36m%s\033[0;0m' % filename)
84141
self.wait()
85-
if not self.camera_available.is_set():
86-
break;
87142
# except:
88143
# print("Camera Worker \t\033[1;31m Unexpected Error\033[0;0m")
89144
# time.sleep(30)
90-
145+
else:
146+
time.sleep(1)
147+
self.resetElapsedTime()
91148
else:
92149
#System not ready camera should be off
93150
time.sleep(1)
@@ -97,4 +154,6 @@ def work(self):
97154

98155
#This is only ran after the main thread is shut down
99156
self.camera.close()
157+
self.listener.join()
158+
self.pubsub.close()
100159
print("Camera Worker Shutting Down...\t\t\033[1;32m Complete\033[0;0m")

0 commit comments

Comments
 (0)