Skip to content

Commit

Permalink
Fix #7 - JPEG API must be enabled to create camera entity
Browse files Browse the repository at this point in the history
  • Loading branch information
elad-bar committed Jun 11, 2021
1 parent 477119c commit caa6bcc
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 53 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

## 1.1.5

- Fix motion binary sensor is now relying on detector_pam settings
- Fix motion binary sensor is now relying on detector_pam settings [#10](https://github.com/elad-bar/ha-shinobi/issues/10)
- JPEG API must be enabled to create camera entity [#7](https://github.com/elad-bar/ha-shinobi/issues/7), in addition, will present warning log message:

`JPEG API is not enabled for {camera.name}, Camera will not be created`

## 1.1.4

Expand Down
13 changes: 8 additions & 5 deletions custom_components/shinobi/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,22 +117,25 @@ async def async_camera_image(self):
try:
url = self._still_image_url.async_render()
except TemplateError as err:
_LOGGER.error("Error parsing template %s: %s", self._still_image_url, err)
_LOGGER.error(f"Error parsing template {self._still_image_url}, Error: {err}")
return self._last_image

if url == self._last_url and self._limit_refetch:
return self._last_image

try:
websession = async_get_clientsession(self.hass, verify_ssl=self.verify_ssl)
ws = async_get_clientsession(self.hass, verify_ssl=self.verify_ssl)
with async_timeout.timeout(10):
response = await websession.get(url, auth=self._auth)
response = await ws.get(url, auth=self._auth)

self._last_image = await response.read()

except asyncio.TimeoutError:
_LOGGER.error("Timeout getting camera image from %s", self.name)
_LOGGER.error(f"Timeout getting camera image from {self.name}")
return self._last_image

except aiohttp.ClientError as err:
_LOGGER.error("Error getting new camera image from %s: %s", self.name, err)
_LOGGER.error(f"Error getting new camera image from {self.name}, Error: {err}")
return self._last_image

self._last_url = url
Expand Down
98 changes: 52 additions & 46 deletions custom_components/shinobi/managers/entity_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ def generate_camera_binary_sensors(self, camera: CameraData):
for sensor_type_name in supported_sensors:
entity = self.get_camera_entity(camera, sensor_type_name)

entities.append(entity)
if entity is not None:
entities.append(entity)

except Exception as ex:
self.log_exception(ex, f"Failed to generate binary sensors for {camera}")
Expand All @@ -305,64 +306,69 @@ def get_camera_component(self, camera: CameraData) -> EntityData:
device_name = self.device_manager.get_camera_device_name(camera)

entity_name = f"{self.integration_title} {camera.name}"
username = self.config_data.username
password = self.config_data.password_clear_text
base_url = self.api.base_url

unique_id = f"{DOMAIN}-{DOMAIN_CAMERA}-{entity_name}"
if camera.jpeg_api_enabled:
username = self.config_data.username
password = self.config_data.password_clear_text
base_url = self.api.base_url

snapshot = f"{base_url}{camera.snapshot}"
still_image_url_template = cv.template(snapshot)
unique_id = f"{DOMAIN}-{DOMAIN_CAMERA}-{entity_name}"

support_stream = DOMAIN_STREAM in self.hass.data
snapshot = f"{base_url}{camera.snapshot}"
still_image_url_template = cv.template(snapshot)

stream_source = ""
support_stream = DOMAIN_STREAM in self.hass.data

for stream in camera.streams:
stream_source = f"{base_url}{stream}"
stream_source = ""

break
for stream in camera.streams:
stream_source = f"{base_url}{stream}"

camera_details = {
CONF_NAME: f"{entity_name}",
CONF_STILL_IMAGE_URL: still_image_url_template,
CONF_STREAM_SOURCE: stream_source,
CONF_LIMIT_REFETCH_TO_URL_CHANGE: False,
CONF_FRAMERATE: camera.fps,
CONF_CONTENT_TYPE: DEFAULT_CONTENT_TYPE,
CONF_VERIFY_SSL: False,
CONF_USERNAME: username,
CONF_PASSWORD: password,
CONF_AUTHENTICATION: AUTHENTICATION_BASIC,
CONF_SUPPORT_STREAM: support_stream,
}
break

attributes = {
ATTR_FRIENDLY_NAME: entity_name,
CONF_STREAM_SOURCE: stream_source,
CONF_STILL_IMAGE_URL: snapshot
}
camera_details = {
CONF_NAME: f"{entity_name}",
CONF_STILL_IMAGE_URL: still_image_url_template,
CONF_STREAM_SOURCE: stream_source,
CONF_LIMIT_REFETCH_TO_URL_CHANGE: False,
CONF_FRAMERATE: camera.fps,
CONF_CONTENT_TYPE: DEFAULT_CONTENT_TYPE,
CONF_VERIFY_SSL: False,
CONF_USERNAME: username,
CONF_PASSWORD: password,
CONF_AUTHENTICATION: AUTHENTICATION_BASIC,
CONF_SUPPORT_STREAM: support_stream,
}

for key in CAMERA_ATTRIBUTES:
key_name = CAMERA_ATTRIBUTES[key]
attributes[key_name] = camera.details.get(key, "N/A")
attributes = {
ATTR_FRIENDLY_NAME: entity_name,
CONF_STREAM_SOURCE: stream_source,
CONF_STILL_IMAGE_URL: snapshot
}

monitor_details = camera.details.get("details", {})
for key in CAMERA_ATTRIBUTES:
key_name = CAMERA_ATTRIBUTES[key]
attributes[key_name] = camera.details.get(key, "N/A")

for key in CAMERA_DETAILS_ATTRIBUTES:
key_name = CAMERA_DETAILS_ATTRIBUTES[key]
attributes[key_name] = monitor_details.get(key, "N/A")
monitor_details = camera.details.get("details", {})

entity = EntityData()
for key in CAMERA_DETAILS_ATTRIBUTES:
key_name = CAMERA_DETAILS_ATTRIBUTES[key]
attributes[key_name] = monitor_details.get(key, "N/A")

entity.id = camera.monitorId
entity.unique_id = unique_id
entity.name = entity_name
entity.attributes = attributes
entity.icon = DEFAULT_ICON
entity.device_name = device_name
entity.details = camera_details
entity.state = camera.status
entity = EntityData()

entity.id = camera.monitorId
entity.unique_id = unique_id
entity.name = entity_name
entity.attributes = attributes
entity.icon = DEFAULT_ICON
entity.device_name = device_name
entity.details = camera_details
entity.state = camera.status

else:
_LOGGER.warning(f"JPEG API is not enabled for {camera.name}, Camera will not be created")

except Exception as ex:
self.log_exception(ex, f"Failed to get camera for {camera}")
Expand Down
3 changes: 2 additions & 1 deletion custom_components/shinobi/models/camera_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class CameraData:
has_audio_detector: bool
has_motion_detector: bool
fps: int
jpeg_api_enabled: bool

def __init__(self, camera):
self.monitorId = camera.get(ATTR_CAMERA_MONITOR_ID)
Expand All @@ -19,6 +20,7 @@ def __init__(self, camera):
self.snapshot = camera.get(ATTR_CAMERA_SNAPSHOT)
self.streams = camera.get(ATTR_CAMERA_STREAMS)
self.details = camera
self.jpeg_api_enabled = self.snapshot is not None and self.snapshot != ""

monitor_details = camera.get("details", {})

Expand All @@ -44,7 +46,6 @@ def __repr__(self):
SOUND_DETECTION: self.has_audio_detector,
TRIGGER_PLUG_DB: self.has_audio,
ATTR_FPS: self.fps

}

to_string = f"{obj}"
Expand Down

0 comments on commit caa6bcc

Please sign in to comment.