Skip to content

Commit

Permalink
Add Camera: HTTP Address
Browse files Browse the repository at this point in the history
  • Loading branch information
kizniche committed May 1, 2020
1 parent a0e02eb commit 231d452
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 9 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -21,7 +21,8 @@ With this release comes a new method of switching Outputs that use Python code (
- Add Force Command option for Command/Python/Wireless Outputs ([#728](https://github.com/kizniche/mycodo/issues/728))
- Add Input: AS7262 Spectral Sensor (measures 450, 500, 550, 570, 600, and 650 nm wavelengths)
- Add ability to create custom Input actions
- Add MH-Z19/MH-Z19B Input actions: zero and span point calibrations
- Add MH-Z19/MH-Z19B Input actions: zero and span point calibrations
- Add Camera: HTTP Address ([Feature Request - IP Camera/Network Camera](https://kylegabriel.com/forum/general-discussion/feature-request-ip-camera-network-camera-stream))

### Miscellaneous

Expand Down
32 changes: 32 additions & 0 deletions databases/alembic/versions/4b5f6207cbdf_add_camera_options.py
@@ -0,0 +1,32 @@
"""Add Camera options
Revision ID: 4b5f6207cbdf
Revises: 267dc913a062
Create Date: 2020-04-30 19:45:55.844301
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '4b5f6207cbdf'
down_revision = '267dc913a062'
branch_labels = None
depends_on = None


def upgrade():
# import sys
# import os
# sys.path.append(os.path.abspath(os.path.join(__file__, "../../../..")))
# from databases.alembic_post_utils import write_revision_post_alembic
# write_revision_post_alembic(revision)

with op.batch_alter_table("camera") as batch_op:
batch_op.add_column(sa.Column('url', sa.Text))


def downgrade():
with op.batch_alter_table("camera") as batch_op:
batch_op.drop_column('url')
23 changes: 19 additions & 4 deletions mycodo/config.py
Expand Up @@ -14,7 +14,7 @@
from config_translations import TRANSLATIONS

MYCODO_VERSION = '8.4.0'
ALEMBIC_VERSION = '267dc913a062'
ALEMBIC_VERSION = '4b5f6207cbdf'

# FORCE_UPGRADE_MASTER
# Set True to enable upgrading to the master branch of the Mycodo repository.
Expand Down Expand Up @@ -66,20 +66,35 @@
'name': 'fswebcam',
'dependencies_module': [
('apt', 'fswebcam', 'fswebcam')
]
],
'capable_image': True,
'capable_stream': True
},
'opencv': {
'name': 'OpenCV',
'dependencies_module': [
('pip-pypi', 'imutils', 'imutils'),
('apt', 'python3-opencv', 'python3-opencv'),
]
],
'capable_image': True,
'capable_stream': True
},
'picamera': {
'name': 'PiCamera',
'dependencies_module': [
('pip-pypi', 'picamera', 'picamera')
]
],
'capable_image': True,
'capable_stream': True
},
'http_address': {
'name': 'HTTP Address',
'dependencies_module': [
('pip-pypi', 'imutils', 'imutils'),
('apt', 'python3-opencv', 'python3-opencv'),
],
'capable_image': True,
'capable_stream': False
},
}

Expand Down
1 change: 1 addition & 0 deletions mycodo/databases/models/camera.py
Expand Up @@ -32,6 +32,7 @@ class Camera(CRUDMixin, db.Model):
stream_started = db.Column(db.Boolean, default=False)
hide_still = db.Column(db.Boolean, default=False)
hide_timelapse = db.Column(db.Boolean, default=False)
url = db.Column(db.Text, default='')

# Timelapse
timelapse_started = db.Column(db.Boolean, default=False)
Expand Down
36 changes: 34 additions & 2 deletions mycodo/devices/camera.py
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
import datetime
import logging
import time

import os
import time
from urllib.error import HTTPError
from urllib.request import urlretrieve

from mycodo.config import PATH_CAMERAS
from mycodo.databases.models import Camera
Expand Down Expand Up @@ -229,6 +230,37 @@ def camera_record(record_type, unique_id, duration_sec=None, tmp_filename=None):
"{err}".format(err=e))
else:
return

elif settings.library == 'http_address':
import cv2
import imutils

if record_type in ['photo', 'timelapse']:
try:
urlretrieve(settings.url, path_file)
except HTTPError as err:
logger.error(err)
except Exception as err:
logger.exception(err)

if any((settings.hflip, settings.vflip, settings.rotation)):
img_orig = cv2.imread(path_file)

if settings.hflip and settings.vflip:
img_edited = cv2.flip(img_orig, -1)
elif settings.hflip:
img_edited = cv2.flip(img_orig, 1)
elif settings.vflip:
img_edited = cv2.flip(img_orig, 0)

if settings.rotation:
img_edited = imutils.rotate_bound(img_orig, settings.rotation)

cv2.imwrite(path_file, img_edited)

elif record_type == 'video':
pass # No video (yet)

try:
set_user_grp(path_file, 'mycodo', 'mycodo')
except Exception as e:
Expand Down
3 changes: 3 additions & 0 deletions mycodo/mycodo_flask/forms/forms_camera.py
Expand Up @@ -106,3 +106,6 @@ class Camera(FlaskForm):
picamera_exposure_mode = StringField(lazy_gettext('Exposure Mode'))
picamera_meter_mode = StringField(lazy_gettext('Meter Mode'))
picamera_image_effect = StringField(lazy_gettext('Image Effect'))

# HTTP Address
url = StringField(lazy_gettext('HTTP Address'))
8 changes: 6 additions & 2 deletions mycodo/mycodo_flask/templates/pages/camera.html
Expand Up @@ -49,7 +49,7 @@
{{form_camera.capture_still(class_='form-control btn btn-primary')}}
</div>

{% if each_camera.library in ['opencv', 'picamera'] and
{% if camera_info[each_camera.library]['capable_stream'] and
not each_camera.timelapse_started %}
<div class="col-12 col-sm-3 col-lg-2">
{% if each_camera.stream_started -%}
Expand Down Expand Up @@ -188,12 +188,14 @@
{{form_camera.path_timelapse(class_='form-control', value=each_camera.path_timelapse, **{'title':_('Path to save timelapse image files. Leave blank to use default location.')})}}
</div>
</div>
{% if camera_info[each_camera.library]['capable_stream'] %}
<div class="col-auto">
{{form_camera.path_video.label(class_='control-label')}}
<div>
{{form_camera.path_video(class_='form-control', value=each_camera.path_video, **{'title':_('Path to save video files. Leave blank to use default location.')})}}
</div>
</div>
{% endif %}
<div class="col-auto">
{{form_camera.hflip.label(class_='control-label')}}
<div class="input-group-text">
Expand Down Expand Up @@ -225,6 +227,8 @@
{% include 'pages/camera_options/opencv.html' %}
{% elif each_camera.library == 'fswebcam' %}
{% include 'pages/camera_options/fswebcam.html' %}
{% elif each_camera.library == 'http_address' %}
{% include 'pages/camera_options/http_address.html' %}
{% endif %}

</div>
Expand All @@ -234,7 +238,7 @@

<div class="row small-gutters">

{%- if each_camera.library in ['opencv', 'picamera'] and
{%- if camera_info[each_camera.library]['capable_stream'] and
each_camera.stream_started -%}
<div>
{{_('Video Stream')}}:
Expand Down
@@ -0,0 +1,6 @@
<div class="col-auto">
{{form_camera.url.label(class_='control-label')}}
<div>
{{form_camera.url(class_='form-control', value=each_camera.url)}}
</div>
</div>
4 changes: 4 additions & 0 deletions mycodo/mycodo_flask/utils/utils_camera.py
Expand Up @@ -56,6 +56,8 @@ def camera_add(form_camera):
new_camera.hue = -1.0
new_camera.saturation = 0.1
new_camera.white_balance = 0.0
elif form_camera.library.data == 'http_address':
new_camera.url = 'http://s.w-x.co/staticmaps/wu/wu/wxtype1200_cur/uscsg/current.png'
if not error:
try:
new_camera.save()
Expand Down Expand Up @@ -131,6 +133,8 @@ def camera_mod(form_camera):
mod_camera.hue = form_camera.hue.data
mod_camera.saturation = form_camera.saturation.data
mod_camera.white_balance = form_camera.white_balance.data
elif mod_camera.library == 'http_address':
mod_camera.url = form_camera.url.data
else:
error.append("Unknown camera library")

Expand Down

0 comments on commit 231d452

Please sign in to comment.