From 317fdb93ed6ab155b439abf8d63b13fefb5421f9 Mon Sep 17 00:00:00 2001 From: Senad Uka Date: Sat, 1 Oct 2016 17:01:37 +0200 Subject: [PATCH] picture client side ready --- controller/README.md | 10 +++++++++ controller/config/copy__init__.py.example | 5 ++++- controller/drivers/camera/__init__.py | 27 +++++++++++++++++++++++ controller/sensors.py | 8 ++++++- controller/state/changer.py | 9 ++++++++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 controller/drivers/camera/__init__.py diff --git a/controller/README.md b/controller/README.md index 78dbd22..14a7a80 100644 --- a/controller/README.md +++ b/controller/README.md @@ -19,3 +19,13 @@ crontab -e -u root python /home/pi/projects/tfm/controller/lockdown.py python /home/pi/projects/tfm/controller/dweet.py ``` + +5. create directory +``` +mkdir -p /mnt/zoblakdata +``` + +6. add following line to /etc/fstab for ramdisk +``` +tmpfs /mnt/zoblakdata tmpfs nodev,nosuid,size=100M 0 0 +``` diff --git a/controller/config/copy__init__.py.example b/controller/config/copy__init__.py.example index 52ec8d4..4708f59 100644 --- a/controller/config/copy__init__.py.example +++ b/controller/config/copy__init__.py.example @@ -14,4 +14,7 @@ START_PUMPING_AT = 'TANKFULL' # start pumping when this level = 0 STOP_PUMPING_AT = 'TANKFULL' # stop pumping when this level = 1 API_BASE_URL = 'http://agrar.zoblak.com/api/v1.0' CONTROLLER_ID = '120' # every controller must have a different one -STATE_FILE = '/var/run/controller_state' +STATE_FILE = '/mnt/zoblakdata/controller_state' +PICTURE_TRANSFER_FILE='/mnt/zoblakdata/picture_transfer_ready.jpg' +PICTURE_INPUT_FILE='/mnt/zoblakdata/picture.jpg' # must match file in PICTURE_COMMAND +PICTURE_COMMAND='avconv -i rtsp://192.168.1.10:554//user=admin_password=_channel=1_stream=0.sdp -f image2 -vframes 1 /mnt/zoblakdata/picture.jpg' # filename must match PICTURE_FILE path diff --git a/controller/drivers/camera/__init__.py b/controller/drivers/camera/__init__.py new file mode 100644 index 0000000..c76bc05 --- /dev/null +++ b/controller/drivers/camera/__init__.py @@ -0,0 +1,27 @@ +import config +import os +import base64; +from shutil import copyfile + +def capture_picture(): + os.system(config.PICTURE_COMMAND) + +def get_transfer_picture_base64(): + try: + with open(config.PICTURE_TRANSFER_FILE, "rb") as image_file: + return base64.b64encode(image_file.read()) + except: + print("Unexpected error:", sys.exc_info()[0]) + return None + +def remove_transfer_picture(): + try: + os.remove(config.PICTURE_TRANSFER_FILE) + except: + print("Error removing: ", config.PICTURE_TRANSFER_FILE ) + +def make_transfer_picture(): + try: + copyfile(config.PICTURE_INPUT_FILE, config.PICTURE_TRANSFER_FILE) + except: + print("Error copying: ", config.PICTURE_INPUT_FILE, config.PICTURE_TRANSFER_FILE ) diff --git a/controller/sensors.py b/controller/sensors.py index 9c8ff9d..19b898e 100644 --- a/controller/sensors.py +++ b/controller/sensors.py @@ -4,6 +4,7 @@ import requests import Adafruit_DHT import config import RPi.GPIO as GPIO +import camera # Try to read the state of GPIO_PIN_TANKLEVELx and GPIO_PIN_TANKFULL GPIO.setmode(GPIO.BCM) @@ -42,6 +43,10 @@ stopPumpingAt = config.STOP_PUMPING_AT # to 15 times to get a sensor reading (waiting 2 seconds between each retry). humidity, temperature = Adafruit_DHT.read_retry(SENSOR_TYPE, config.GPIO_PIN_DHT) +picture_base64 = camera.get_transfer_picture_base64() +if picture_base64 is not None: + camera.remove_transfer_picture() + # Un-comment the line below to convert the temperature to Fahrenheit. # temperature = temperature * 9/5.0 + 32 @@ -51,7 +56,8 @@ humidity, temperature = Adafruit_DHT.read_retry(SENSOR_TYPE, config.GPIO_PIN_DHT # If this happens try again! if tankFull is not None: response = requests.post(config.SENSORDATA_URL, json={"owner": owner, "temperatureValue": temperature, "humidityValue":humidity, "tankLevel0": "1" if tankLevel0 else "0","tankLevel1": "1" if tankLevel1 else "0","tankLevel2": "1" if tankLevel2 else "0","tankLevel3": "1" if tankLevel3 else "0", "tankLevel4": "1" if tankLevel4 else "0", "tankFull": "1" if tankFull else "0", - "startPumpingAt": startPumpingAt,"stopPumpingAt": stopPumpingAt,"controllerId": controller_id + "startPumpingAt": startPumpingAt,"stopPumpingAt": stopPumpingAt,"controllerId": controller_id, + 'picture': picture_base64 }) print 'Temp={0:0.1f}*C'.format(temperature) print 'Humidity={0:0.1f}%'.format(humidity) diff --git a/controller/state/changer.py b/controller/state/changer.py index 3c6f4f0..e377cad 100644 --- a/controller/state/changer.py +++ b/controller/state/changer.py @@ -1,5 +1,6 @@ import RPi.GPIO as GPIO import config +from camera import make_transfer_picture class Changer(object): @@ -45,6 +46,8 @@ class Changer(object): if in_valve_change is not None: in_valve_change() + self.fulfill_picture_request() + return self.local_state def open_in_valve(self): @@ -63,6 +66,12 @@ class Changer(object): GPIO.output(config.GPIO_PIN_OUT_VALVE, GPIO.LOW) self.local_state['out_valve'] = 'closed' + def fulfill_picture_request(self): + if self.remote_state['transfer_picture'] == 'true': + make_transfer_picture() + self.local_state['transfer_picture'] = 'false' + + def validate_states(self): if self.local_state is None or self.remote_state is None: raise ClassNotReadyException("Both local and remote states must be present!")