Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
aneisch committed Apr 10, 2024
1 parent c39fc6d commit 4b60550
Show file tree
Hide file tree
Showing 22 changed files with 327 additions and 378 deletions.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
[![Build Status](https://github.com/aneisch/home-assistant-config/actions/workflows/check-ha-release-compatibility.yml/badge.svg)](https://github.com/aneisch/home-assistant-config/actions)
[![GitHub last commit](https://img.shields.io/github/last-commit/aneisch/home-assistant-config)](https://github.com/aneisch/home-assistant-config/commits/master)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/y/aneisch/home-assistant-config)](https://github.com/aneisch/home-assistant-config/graphs/commit-activity)
[![HA Version](https://img.shields.io/badge/Running%20Home%20Assistant-2024.4.1%20(Latest)-brightgreen)](https://github.com/home-assistant/home-assistant/releases/latest)
[![HA Version](https://img.shields.io/badge/Running%20Home%20Assistant-2024.4.2%20(Latest)-brightgreen)](https://github.com/home-assistant/home-assistant/releases/latest)
<br><a href="https://www.buymeacoffee.com/aneisch" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-black.png" width="150px" height="35px" alt="Buy Me A Coffee" style="height: 35px !important;width: 150px !important;" ></a>


Expand Down Expand Up @@ -64,15 +64,14 @@ Z-Wave devices in [`zwave_js`](https://www.home-assistant.io/integrations/zwave_

Description | value
-- | --
Entities in the [`automation`](https://www.home-assistant.io/components/automation) domain | 121
Entities in the [`automation`](https://www.home-assistant.io/components/automation) domain | 119
Entities in the [`binary_sensor`](https://www.home-assistant.io/components/binary_sensor) domain | 145
Entities in the [`button`](https://www.home-assistant.io/components/button) domain | 17
Entities in the [`camera`](https://www.home-assistant.io/components/camera) domain | 14
Entities in the [`climate`](https://www.home-assistant.io/components/climate) domain | 1
Entities in the [`counter`](https://www.home-assistant.io/components/counter) domain | 1
Entities in the [`cover`](https://www.home-assistant.io/components/cover) domain | 13
Entities in the [`device_tracker`](https://www.home-assistant.io/components/device_tracker) domain | 4
Entities in the [`event`](https://www.home-assistant.io/components/event) domain | 50
Entities in the [`fan`](https://www.home-assistant.io/components/fan) domain | 3
Entities in the [`group`](https://www.home-assistant.io/components/group) domain | 17
Entities in the [`image`](https://www.home-assistant.io/components/image) domain | 8
Expand All @@ -90,17 +89,17 @@ Entities in the [`plant`](https://www.home-assistant.io/components/plant) domain
Entities in the [`remote`](https://www.home-assistant.io/components/remote) domain | 1
Entities in the [`script`](https://www.home-assistant.io/components/script) domain | 56
Entities in the [`select`](https://www.home-assistant.io/components/select) domain | 3
Entities in the [`sensor`](https://www.home-assistant.io/components/sensor) domain | 443
Entities in the [`sensor`](https://www.home-assistant.io/components/sensor) domain | 444
Entities in the [`siren`](https://www.home-assistant.io/components/siren) domain | 1
Entities in the [`sun`](https://www.home-assistant.io/components/sun) domain | 1
Entities in the [`switch`](https://www.home-assistant.io/components/switch) domain | 166
Entities in the [`switch`](https://www.home-assistant.io/components/switch) domain | 168
Entities in the [`timer`](https://www.home-assistant.io/components/timer) domain | 6
Entities in the [`tts`](https://www.home-assistant.io/components/tts) domain | 1
Entities in the [`update`](https://www.home-assistant.io/components/update) domain | 35
Entities in the [`vacuum`](https://www.home-assistant.io/components/vacuum) domain | 1
Entities in the [`weather`](https://www.home-assistant.io/components/weather) domain | 1
Entities in the [`zone`](https://www.home-assistant.io/components/zone) domain | 6
**Total state objects** | **1287**
**Total state objects** | **1238**
## The HACS integrations/plugins that I use:
**Appdaemon**:<br>
[aneisch/follow_me_appdaemon](https://github.com/aneisch/follow_me_appdaemon)<br>
Expand Down
6 changes: 3 additions & 3 deletions automations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@
allowed_methods:
- POST
action:
- service: notify.signal_homeassistant
- service: notify.signal_self
data:
message: '{{ trigger.json.notifications[0].message }}: {{ trigger.json.run_url
}}'
Expand Down Expand Up @@ -766,7 +766,7 @@
- platform: homeassistant
event: start
action:
- service: notify.signal_homeassistant
- service: notify.signal_self
data:
message: 'Home Assistant v{{ states(''sensor.ha_version'')}} has started!
Expand Down Expand Up @@ -924,7 +924,7 @@
condition:
- condition: state
entity_id: lock.all_doors
state: open
state: unlocked
action:
- if: '{{ trigger.id == ''alert'' }}'
then:
Expand Down
39 changes: 21 additions & 18 deletions custom_components/webrtc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
import time
import uuid
from pathlib import Path
from typing import Union, cast
from typing import Union
from urllib.parse import urlencode, urljoin

import homeassistant.helpers.config_validation as cv
import voluptuous as vol
from aiohttp import web
from aiohttp.web_exceptions import HTTPUnauthorized, HTTPGone, HTTPNotFound
from homeassistant.components.image import ImageEntity
from homeassistant.components.camera import async_get_image as camera_get_image
from homeassistant.components.image import _async_get_image as image_get_image
from homeassistant.components.camera import async_get_image
from homeassistant.components.hassio.ingress import _websocket_forward
from homeassistant.components.http import HomeAssistantView
from homeassistant.config_entries import ConfigEntry
Expand Down Expand Up @@ -47,8 +45,9 @@
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
vol.Exclusive("url", "url"): cv.string,
vol.Exclusive("entity", "url"): cv.entity_id,
vol.Optional("force", default=False): bool,
vol.Optional("extra"): dict,
vol.Optional("force", default=False): bool,
vol.Optional("hass_url"): str,
},
required=True,
)
Expand All @@ -65,15 +64,14 @@ async def async_setup(hass: HomeAssistantType, config: ConfigType):
# 1. Serve lovelace card
path = Path(__file__).parent / "www"
for name in ("video-rtc.js", "webrtc-camera.js", "digital-ptz.js"):
utils.register_static_path(hass.http.app, "/webrtc/" + name, path / name)
hass.http.register_static_path("/webrtc/" + name, str(path / name))

# 2. Add card to resources
version = getattr(hass.data["integrations"][DOMAIN], "version", 0)
await utils.init_resource(hass, "/webrtc/webrtc-camera.js", str(version))

# 3. Serve html page
path = Path(__file__).parent / "www/embed.html"
utils.register_static_path(hass.http.app, "/webrtc/embed", path)
hass.http.register_static_path("/webrtc/embed", str(path / "embed.html"))

# 4. Serve WebSocket API
hass.http.register_view(WebSocketView)
Expand All @@ -96,21 +94,25 @@ async def create_link(call: ServiceCallType):
async def dash_cast(call: ServiceCallType):
link_id = uuid.uuid4().hex
LINKS[link_id] = {
"url": call.data.get("url"),
"entity": call.data.get("entity"),
"url": call.data.get("url"), # camera URL (rtsp...)
"entity": call.data.get("entity"), # camera entity id
"limit": 1, # 1 attempt
"ts": time.time() + 30, # for 30 seconds
}

hass_url = call.data.get("hass_url") or get_url(hass)
query = call.data.get("extra", {})
query["url"] = link_id
cast_url = hass_url + "/webrtc/embed?" + urlencode(query)

_LOGGER.debug(f"dash_cast: {cast_url}")

await hass.async_add_executor_job(
utils.dash_cast,
hass,
call.data[ATTR_ENTITY_ID],
f"{get_url(hass)}/webrtc/embed?" + urlencode(query),
call.data.get("force"),
cast_url,
call.data.get("force", False),
)

hass.services.async_register(DOMAIN, "create_link", create_link, CREATE_LINK_SCHEMA)
Expand Down Expand Up @@ -175,16 +177,17 @@ async def ws_connect(hass: HomeAssistantType, params: dict) -> str:
raise Exception("Missing url or entity")

return urljoin("ws" + server[4:], "api/ws") + "?" + urlencode(query)

def _get_image_from_entity_id(hass: HomeAssistantType, entity_id: str) -> ImageEntity:


def _get_image_from_entity_id(hass: HomeAssistantType, entity_id: str):
"""Get camera component from entity_id."""
if (component := hass.data.get("image")) is None:
raise Exception("Image integration not set up")

if (image := component.get_entity(entity_id)) is None:
raise Exception("Image not found")

return cast(ImageEntity, image)
return image


async def ws_poster(hass: HomeAssistantType, params: dict) -> web.Response:
Expand All @@ -196,12 +199,12 @@ async def ws_poster(hass: HomeAssistantType, params: dict) -> web.Response:

if poster.startswith("camera."):
# support entity_id as poster
image = await camera_get_image(hass, poster)
image = await async_get_image(hass, poster)
return web.Response(body=image.content, content_type=image.content_type)

if poster.startswith("image."):
# support entity_id as poster
image_entity = _get_image_from_entity_id(hass, poster)
image_entity = _get_image_from_entity_id(hass, poster)
image = await image_entity.async_image()
_LOGGER.debug(f"webrtc image_entity: {image_entity} - {len(image)}")
return web.Response(body=image, content_type="image/jpeg")
Expand Down
2 changes: 1 addition & 1 deletion custom_components/webrtc/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
"iot_class": "calculated",
"issue_tracker": "https://github.com/AlexxIT/WebRTC/issues",
"requirements": [],
"version": "v3.5.1"
"version": "v3.5.2"
}
44 changes: 10 additions & 34 deletions custom_components/webrtc/services.yaml
Original file line number Diff line number Diff line change
@@ -1,45 +1,27 @@
create_link:
name: Create Link
description: Create a temporary or permanent link to a stream (enter "url" or "entity")
fields:
link_id:
name: Link ID
description: Create a random or permanent ID for your link
example: fd0a53ca-e9ab-4e7a-86a2-441642b16ae1
required: true
selector:
text:

url:
name: URL
description: Link to RTSP-stream
example: rtsp://rtsp:[email protected]:554/av_stream/ch0
selector:
text:

entity:
name: Entity ID
description: Camera entity
example: camera.generic_stream
selector:
entity:
domain: camera

open_limit:
name: Open limit
description: How many times a link can be opened (0 - unlimit)
example: 1
default: 1
selector:
number:
min: 0
max: 100
unit_of_measurement: times

time_to_live:
name: Time to live
description: How many seconds will the link live (0 - unlimit)
example: 60
default: 60
selector:
number:
Expand All @@ -48,36 +30,30 @@ create_link:
unit_of_measurement: seconds

dash_cast:
name: DashCast
description: Cast stream to Chromecast device via DashCast application
fields:
entity_id:
name: Entity ID
description: Media player entity
example: media_player.mibox4
required: true
selector:
entity:
integration: cast
domain: media_player

url:
name: URL
description: Link to RTSP-stream
example: rtsp://rtsp:[email protected]:554/av_stream/ch0
selector:
text:

force:
name: Force
description: Force restart DashCast application
selector:
boolean:

entity:
name: Entity ID
description: Camera entity
example: camera.generic_stream
selector:
entity:
domain: camera
extra:
selector:
object:
force:
selector:
boolean:
hass_url:
example: http://192.168.1.123:8123
selector:
text:
58 changes: 58 additions & 0 deletions custom_components/webrtc/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,63 @@
}
}
}
},
"services": {
"create_link": {
"name": "Create Link",
"description": "Create a temporary or permanent link to a stream (enter `url` or `entity`)",
"fields": {
"link_id": {
"name": "Link ID",
"description": "Create a random or permanent ID for your link"
},
"url": {
"name": "URL",
"description": "Link to RTSP-stream"
},
"entity": {
"name": "Entity",
"description": "Camera entity_id"
},
"open_limit": {
"name": "Open limit",
"description": "How many times a link can be opened (0 - unlimit)"
},
"time_to_live": {
"name": "Time to live",
"description": "How many seconds will the link live (0 - unlimit)"
}
}
},
"dash_cast": {
"name": "DashCast",
"description": "Cast stream to Chromecast device via DashCast application",
"fields": {
"entity_id": {
"name": "Media Entity",
"description": "Media player entity_id"
},
"url": {
"name": "URL",
"description": "Link to RTSP-stream"
},
"entity": {
"name": "Entity",
"description": "Camera entity_id"
},
"extra": {
"name": "Extra",
"description": "Additional card params"
},
"force": {
"name": "Force",
"description": "Force restart DashCast application"
},
"hass_url": {
"name": "Hass URL",
"description": "Manual base URL to Hass server"
}
}
}
}
}
Loading

0 comments on commit 4b60550

Please sign in to comment.