Skip to content
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b5b509d
Initial working commit
oblogic7 Feb 16, 2019
9107f4c
Create const file. Load camera from component.
oblogic7 Feb 16, 2019
04427a9
Handle failed authentication. Bump library version.
oblogic7 Feb 16, 2019
74b39c4
Remove line break
oblogic7 Feb 16, 2019
37cd298
Camera attributes and recording services
oblogic7 Feb 16, 2019
e88efcc
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
oblogic7 Jan 25, 2020
d2fe4f6
Add services, manifest, constant update, and exclude_channels. Prefi…
oblogic7 Jan 26, 2020
af19a6e
Update codeowners
oblogic7 Jan 26, 2020
3e52766
Update coveragerc
oblogic7 Jan 26, 2020
c70fc28
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
oblogic7 Jan 26, 2020
a003f5c
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
oblogic7 Jan 26, 2020
f30e36a
Remove codeowners line
oblogic7 Jan 26, 2020
d8bc8dc
Update codeowners again from python3 -m script.hassfest
oblogic7 Jan 26, 2020
79e2b44
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
oblogic7 Jan 31, 2020
0202d8a
Update homeassistant/components/qvrpro/__init__.py
oblogic7 Feb 3, 2020
99d067c
Requested changes
oblogic7 Feb 3, 2020
15e278c
Merge branch 'qvrpro' of https://github.com/oblogic7/home-assistant i…
oblogic7 Feb 3, 2020
d337632
Fix typo
oblogic7 Feb 4, 2020
1bbd804
Update to use exception. Bump library version.
oblogic7 Feb 7, 2020
d5bc4e8
Support stream component
oblogic7 Feb 7, 2020
f2e26ed
Merge branch 'qvrpro' of https://github.com/oblogic7/home-assistant i…
oblogic7 Feb 8, 2020
ede446b
Update module header
oblogic7 Feb 8, 2020
bdb7b94
Missing property wrapper
oblogic7 Feb 8, 2020
4accc26
Partial requested changes
oblogic7 Feb 19, 2020
3b3f65b
Update coveragerc and codeowners
oblogic7 Feb 19, 2020
c1da03b
Move constants to const file. Add SHORT_NAME
oblogic7 Feb 19, 2020
366f535
Add conf variable
oblogic7 Feb 19, 2020
90a27e9
Use camera domain
oblogic7 Feb 19, 2020
bb63e68
More requested changes
oblogic7 Feb 19, 2020
6f887ca
Requested changes
oblogic7 Feb 20, 2020
a0f1d29
Requested changes
oblogic7 Feb 20, 2020
33bb74d
Merge remote-tracking branch 'upstream/dev' into qvrpro
oblogic7 Feb 20, 2020
0d476b1
Update prefix
oblogic7 Feb 20, 2020
afe1929
Handle error condition when camera is not configured to support live …
oblogic7 Feb 20, 2020
31e5fc2
Move method to camera setup. Disable stream component support.
oblogic7 Feb 21, 2020
e072e6d
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
oblogic7 Feb 21, 2020
e7ee71e
Move auth string to library to prevent private member access
oblogic7 Feb 21, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ omit =
homeassistant/components/qnap/sensor.py
homeassistant/components/qrcode/image_processing.py
homeassistant/components/quantum_gateway/device_tracker.py
homeassistant/components/qvr_pro/*
homeassistant/components/qwikswitch/*
homeassistant/components/rachio/*
homeassistant/components/radarr/sensor.py
Expand Down
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ homeassistant/components/pvoutput/* @fabaff
homeassistant/components/qld_bushfire/* @exxamalte
homeassistant/components/qnap/* @colinodell
homeassistant/components/quantum_gateway/* @cisasteelersfan
homeassistant/components/qvr_pro/* @oblogic7
homeassistant/components/qwikswitch/* @kellerza
homeassistant/components/rainbird/* @konikvranik
homeassistant/components/raincloud/* @vanstinator
Expand Down
91 changes: 91 additions & 0 deletions homeassistant/components/qvr_pro/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"""Support for QVR Pro NVR software by QNAP."""

import logging

from pyqvrpro import Client
from pyqvrpro.client import AuthenticationError, InsufficientPermissionsError
import voluptuous as vol

from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.discovery import load_platform

from .const import CONF_EXCLUDE_CHANNELS, DOMAIN, SHORT_NAME, START_RECORD, STOP_RECORD

_LOGGER = logging.getLogger(__name__)

CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_EXCLUDE_CHANNELS, default=[]): vol.All(
cv.ensure_list_csv, [cv.positive_int]
),
}
)
},
extra=vol.ALLOW_EXTRA,
)


def setup(hass, config):
"""Set up the QVR Pro component."""
conf = config[DOMAIN]
user = conf[CONF_USERNAME]
password = conf[CONF_PASSWORD]
host = conf[CONF_HOST]
excluded_channels = conf[CONF_EXCLUDE_CHANNELS]

try:
qvrpro = Client(user, password, host)

channel_resp = qvrpro.get_channel_list()

except InsufficientPermissionsError:
_LOGGER.error("User must have Surveillance Management permission")
return False
except AuthenticationError:
_LOGGER.error("Authentication failed")
return False

channels = []

for channel in channel_resp["channels"]:
if channel["channel_index"] + 1 in excluded_channels:
continue

channels.append(QVRChannel(**channel))

hass.data[DOMAIN] = {"channels": channels, "client": qvrpro}

load_platform(hass, CAMERA_DOMAIN, DOMAIN, {}, config)

# Register services
def handle_start_record(call):
guid = call.data.get("guid")
qvrpro.start_recording(guid)

def handle_stop_record(call):
guid = call.data.get("guid")
qvrpro.stop_recording(guid)

hass.services.register(DOMAIN, START_RECORD, handle_start_record)
hass.services.register(DOMAIN, STOP_RECORD, handle_stop_record)
Comment thread
oblogic7 marked this conversation as resolved.
Outdated

return True


class QVRChannel:
Comment thread
oblogic7 marked this conversation as resolved.
Outdated
"""Representation of a QVR channel."""

def __init__(self, name, model, brand, channel_index, guid):
"""Initialize QVRChannel."""
self.name = f"{SHORT_NAME} {name}"
self.model = model
self.brand = brand
self.index = channel_index
self.guid = guid
66 changes: 66 additions & 0 deletions homeassistant/components/qvr_pro/camera.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""Support for QVR Pro streams."""

from homeassistant.components.camera import SUPPORT_STREAM, Camera

from .const import DOMAIN


def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the QVR Pro camera platform."""
client = hass.data[DOMAIN]["client"]
Comment thread
oblogic7 marked this conversation as resolved.

entities = []

for channel in hass.data[DOMAIN]["channels"]:
entities.append(QVRProCamera(channel, client))

add_entities(entities)


class QVRProCamera(Camera):
"""Representation of a QVR Pro camera."""

def __init__(self, channel, client):
"""Init QVR Pro camera."""

self._channel = channel
self._client = client

super().__init__()

@property
def name(self):
"""Get the name of the camera."""
return self._channel.name

@property
def model(self):
"""Get the model of the camera."""
return self._channel.model

@property
def brand(self):
"""Get the brand of the camera."""
return self._channel.brand

@property
def state_attributes(self):
Comment thread
oblogic7 marked this conversation as resolved.
Outdated
"""Get the state attributes."""
attrs = super().state_attributes
Comment thread
oblogic7 marked this conversation as resolved.
Outdated

attrs["qvr_guid"] = self._channel.guid

return attrs

def camera_image(self):
"""Get image bytes from camera."""
return self._client.get_snapshot(self._channel.guid)

def stream_source(self):
"""Get stream source."""
return self._client.get_channel_live_stream(self._channel.guid)

@property
def supported_features(self):
"""Get supported features."""
return SUPPORT_STREAM
9 changes: 9 additions & 0 deletions homeassistant/components/qvr_pro/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Constants for QVR Pro component."""

DOMAIN = "qvr_pro"
SHORT_NAME = "QVR"

CONF_EXCLUDE_CHANNELS = "exclude_channels"

STOP_RECORD = "stop_record"
START_RECORD = "start_record"
Comment thread
oblogic7 marked this conversation as resolved.
Outdated
8 changes: 8 additions & 0 deletions homeassistant/components/qvr_pro/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"domain": "qvr_pro",
"name": "QVR Pro",
"documentation": "https://www.home-assistant.io/integrations/qvr_pro",
"requirements": ["pyqvrpro==0.49"],
"dependencies": [],
"codeowners": ["@oblogic7"]
}
13 changes: 13 additions & 0 deletions homeassistant/components/qvr_pro/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
start_record:
description: Start QVR Pro recording on specified channel.
fields:
guid:
description: GUID of the channel to start recording.
example: '245EBE933C0A597EBE865C0A245E0002'

stop_record:
description: Stop QVR Pro recording on specified channel.
fields:
guid:
description: GUID of the channel to stop recording.
example: '245EBE933C0A597EBE865C0A245E0002'
3 changes: 3 additions & 0 deletions requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1454,6 +1454,9 @@ pypoint==1.1.2
# homeassistant.components.ps4
pyps4-2ndscreen==1.0.6

# homeassistant.components.qvr_pro
pyqvrpro==0.49

# homeassistant.components.qwikswitch
pyqwikswitch==0.93

Expand Down