From 88694c978b50c1e2dbb2e2a3cd2a0c11909d3685 Mon Sep 17 00:00:00 2001 From: Paul Madden Date: Tue, 9 Apr 2019 03:56:04 -0600 Subject: [PATCH] Camera component for BOM integration (#22816) * Work on PR comments * Work on PR comments * Update imports * Work on schema validation * Fix package * Add bomradarcam to .coveragerc * Improve error message for location * Delinting * Correct module name in .coveragerc * Add manifest.json * Update requirements_all.txt * Merge bomradarcam into existing bom integration --- .coveragerc | 1 + homeassistant/components/bom/camera.py | 80 ++++++++++++++++++++++ homeassistant/components/bom/manifest.json | 4 +- requirements_all.txt | 3 + 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/bom/camera.py diff --git a/.coveragerc b/.coveragerc index a87b4d7f8f4..9f2a31f3d14 100644 --- a/.coveragerc +++ b/.coveragerc @@ -64,6 +64,7 @@ omit = homeassistant/components/bme280/sensor.py homeassistant/components/bme680/sensor.py homeassistant/components/bmw_connected_drive/* + homeassistant/components/bom/camera.py homeassistant/components/bom/sensor.py homeassistant/components/bom/weather.py homeassistant/components/braviatv/media_player.py diff --git a/homeassistant/components/bom/camera.py b/homeassistant/components/bom/camera.py new file mode 100644 index 00000000000..d3e78034015 --- /dev/null +++ b/homeassistant/components/bom/camera.py @@ -0,0 +1,80 @@ +"""Provide animated GIF loops of BOM radar imagery.""" +import voluptuous as vol + +from homeassistant.components.camera import PLATFORM_SCHEMA, Camera +from homeassistant.const import CONF_ID, CONF_NAME +from homeassistant.helpers import config_validation as cv + +REQUIREMENTS = ['bomradarloop==0.1.2'] + +CONF_DELTA = 'delta' +CONF_FRAMES = 'frames' +CONF_LOCATION = 'location' +CONF_OUTFILE = 'filename' + +LOCATIONS = [ + 'Adelaide', 'Albany', 'AliceSprings', 'Bairnsdale', 'Bowen', 'Brisbane', + 'Broome', 'Cairns', 'Canberra', 'Carnarvon', 'Ceduna', 'Dampier', 'Darwin', + 'Emerald', 'Esperance', 'Geraldton', 'Giles', 'Gladstone', 'Gove', + 'Grafton', 'Gympie', 'HallsCreek', 'Hobart', 'Kalgoorlie', 'Katherine', + 'Learmonth', 'Longreach', 'Mackay', 'Marburg', 'Melbourne', 'Mildura', + 'Moree', 'MorningtonIs', 'MountIsa', 'MtGambier', 'Namoi', 'Newcastle', + 'Newdegate', 'NorfolkIs', 'NWTasmania', 'Perth', 'PortHedland', + 'SellicksHill', 'SouthDoodlakine', 'Sydney', 'Townsville', 'WaggaWagga', + 'Warrego', 'Warruwi', 'Watheroo', 'Weipa', 'WillisIs', 'Wollongong', + 'Woomera', 'Wyndham', 'Yarrawonga', +] + + +def _validate_schema(config): + if config.get(CONF_LOCATION) is None: + if not all(config.get(x) for x in (CONF_ID, CONF_DELTA, CONF_FRAMES)): + raise vol.Invalid( + "Specify '{}', '{}' and '{}' when '{}' is unspecified".format( + CONF_ID, CONF_DELTA, CONF_FRAMES, CONF_LOCATION)) + return config + + +LOCATIONS_MSG = "Set '{}' to one of: {}".format( + CONF_LOCATION, ', '.join(sorted(LOCATIONS))) +XOR_MSG = "Specify exactly one of '{}' or '{}'".format(CONF_ID, CONF_LOCATION) + +PLATFORM_SCHEMA = vol.All( + PLATFORM_SCHEMA.extend({ + vol.Exclusive(CONF_ID, 'xor', msg=XOR_MSG): cv.string, + vol.Exclusive(CONF_LOCATION, 'xor', msg=XOR_MSG): vol.In( + LOCATIONS, msg=LOCATIONS_MSG), + vol.Optional(CONF_DELTA): cv.positive_int, + vol.Optional(CONF_FRAMES): cv.positive_int, + vol.Optional(CONF_NAME): cv.string, + vol.Optional(CONF_OUTFILE): cv.string, + }), _validate_schema) + + +def setup_platform(hass, config, add_entities, discovery_info=None): + """Set up BOM radar-loop camera component.""" + location = config.get(CONF_LOCATION) or "ID {}".format(config.get(CONF_ID)) + name = config.get(CONF_NAME) or "BOM Radar Loop - {}".format(location) + args = [config.get(x) for x in (CONF_LOCATION, CONF_ID, CONF_DELTA, + CONF_FRAMES, CONF_OUTFILE)] + add_entities([BOMRadarCam(name, *args)]) + + +class BOMRadarCam(Camera): + """A camera component producing animated BOM radar-imagery GIFs.""" + + def __init__(self, name, location, radar_id, delta, frames, outfile): + """Initialize the component.""" + from bomradarloop import BOMRadarLoop + super().__init__() + self._name = name + self._cam = BOMRadarLoop(location, radar_id, delta, frames, outfile) + + def camera_image(self): + """Return the current BOM radar-loop image.""" + return self._cam.current + + @property + def name(self): + """Return the component name.""" + return self._name diff --git a/homeassistant/components/bom/manifest.json b/homeassistant/components/bom/manifest.json index e4744d4cfd2..cb7ce4383b0 100644 --- a/homeassistant/components/bom/manifest.json +++ b/homeassistant/components/bom/manifest.json @@ -2,7 +2,9 @@ "domain": "bom", "name": "Bom", "documentation": "https://www.home-assistant.io/components/bom", - "requirements": [], + "requirements": [ + "bomradarloop==0.1.2" + ], "dependencies": [], "codeowners": [] } diff --git a/requirements_all.txt b/requirements_all.txt index 26668571462..4d2cfcf8034 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -235,6 +235,9 @@ blockchain==1.4.4 # homeassistant.components.bme680 # bme680==1.0.5 +# homeassistant.components.bom +bomradarloop==0.1.2 + # homeassistant.components.amazon_polly # homeassistant.components.aws_lambda # homeassistant.components.aws_sns