- ${Object.keys(window.browser_mod.devices).map((d) => $ `
+ ${Object.keys(window.browser_mod.browsers).map((d) => $ `
${d}
Last connected:
diff --git a/custom_components/browser_mod/camera.py b/custom_components/browser_mod/camera.py
index 3a24f6e..d9dfabd 100644
--- a/custom_components/browser_mod/camera.py
+++ b/custom_components/browser_mod/camera.py
@@ -21,13 +21,13 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class BrowserModCamera(BrowserModEntity, Camera):
- def __init__(self, coordinator, deviceID):
- BrowserModEntity.__init__(self, coordinator, deviceID, None)
+ def __init__(self, coordinator, browserID):
+ BrowserModEntity.__init__(self, coordinator, browserID, None)
Camera.__init__(self)
@property
def unique_id(self):
- return f"{self.deviceID}-camera"
+ return f"{self.browserID}-camera"
@property
def entity_registry_visible_default(self):
diff --git a/custom_components/browser_mod/connection.py b/custom_components/browser_mod/connection.py
index fa3df1f..f447fd4 100644
--- a/custom_components/browser_mod/connection.py
+++ b/custom_components/browser_mod/connection.py
@@ -18,7 +18,7 @@ from .const import (
DOMAIN,
)
-from .device import getDevice, deleteDevice
+from .browser import getBrowser, deleteBrowser
_LOGGER = logging.getLogger(__name__)
@@ -27,12 +27,12 @@ async def async_setup_connection(hass):
@websocket_api.websocket_command(
{
vol.Required("type"): WS_CONNECT,
- vol.Required("deviceID"): str,
+ vol.Required("browserID"): str,
}
)
@websocket_api.async_response
async def handle_connect(hass, connection, msg):
- deviceID = msg["deviceID"]
+ browserID = msg["browserID"]
store = hass.data[DOMAIN]["store"]
def listener(data):
@@ -41,93 +41,93 @@ async def async_setup_connection(hass):
connection.subscriptions[msg["id"]] = store.add_listener(listener)
connection.send_result(msg["id"])
- if store.get_device(deviceID).enabled:
- dev = getDevice(hass, deviceID)
- dev.update_settings(hass, store.get_device(deviceID).asdict())
+ if store.get_browser(browserID).enabled:
+ dev = getBrowser(hass, browserID)
+ dev.update_settings(hass, store.get_browser(browserID).asdict())
dev.connection = (connection, msg["id"])
- await store.set_device(
- deviceID, last_seen=datetime.now(tz=timezone.utc).isoformat()
+ await store.set_browser(
+ browserID, last_seen=datetime.now(tz=timezone.utc).isoformat()
)
listener(store.asdict())
@websocket_api.websocket_command(
{
vol.Required("type"): WS_REGISTER,
- vol.Required("deviceID"): str,
+ vol.Required("browserID"): str,
}
)
@websocket_api.async_response
async def handle_register(hass, connection, msg):
- deviceID = msg["deviceID"]
+ browserID = msg["browserID"]
store = hass.data[DOMAIN]["store"]
- await store.set_device(deviceID, enabled=True)
+ await store.set_browser(browserID, enabled=True)
connection.send_result(msg["id"])
@websocket_api.websocket_command(
{
vol.Required("type"): WS_UNREGISTER,
- vol.Required("deviceID"): str,
+ vol.Required("browserID"): str,
}
)
@websocket_api.async_response
async def handle_unregister(hass, connection, msg):
- deviceID = msg["deviceID"]
+ browserID = msg["browserID"]
store = hass.data[DOMAIN]["store"]
- deleteDevice(hass, deviceID)
- await store.delete_device(deviceID)
+ deleteBrowser(hass, browserID)
+ await store.delete_browser(browserID)
connection.send_result(msg["id"])
@websocket_api.websocket_command(
{
vol.Required("type"): WS_REREGISTER,
- vol.Required("deviceID"): str,
+ vol.Required("browserID"): str,
vol.Required("data"): dict,
}
)
@websocket_api.async_response
async def handle_reregister(hass, connection, msg):
- deviceID = msg["deviceID"]
+ browserID = msg["browserID"]
store = hass.data[DOMAIN]["store"]
data = msg["data"]
del data["last_seen"]
- deviceSettings = {}
+ browserSettings = {}
- if "deviceID" in data:
- newDeviceID = data["deviceID"]
- del data["deviceID"]
+ if "browserID" in data:
+ newBrowserID = data["browserID"]
+ del data["browserID"]
- oldDeviceSettings = store.get_device(deviceID)
- if oldDeviceSettings:
- deviceSettings = oldDeviceSettings.asdict()
- await store.delete_device(deviceID)
+ oldBrowserSetting = store.get_browser(browserID)
+ if oldBrowserSetting:
+ browserSettings = oldBrowserSetting.asdict()
+ await store.delete_browser(browserID)
- deleteDevice(hass, deviceID)
+ deleteBrowser(hass, browserID)
- deviceID = newDeviceID
+ browserID = newBrowserID
- if (dev := getDevice(hass, deviceID, create=False)) is not None:
+ if (dev := getBrowser(hass, browserID, create=False)) is not None:
dev.update_settings(hass, data)
- deviceSettings.update(data)
- await store.set_device(deviceID, **deviceSettings)
+ browserSettings.update(data)
+ await store.set_browser(browserID, **browserSettings)
@websocket_api.websocket_command(
{
vol.Required("type"): WS_UPDATE,
- vol.Required("deviceID"): str,
+ vol.Required("browserID"): str,
vol.Optional("data"): dict,
}
)
@websocket_api.async_response
async def handle_update(hass, connection, msg):
- deviceID = msg["deviceID"]
+ browserID = msg["browserID"]
store = hass.data[DOMAIN]["store"]
- if store.get_device(deviceID).enabled:
- dev = getDevice(hass, deviceID)
+ if store.get_browser(browserID).enabled:
+ dev = getBrowser(hass, browserID)
dev.update(hass, msg.get("data", {}))
async_register_command(hass, handle_connect)
diff --git a/custom_components/browser_mod/const.py b/custom_components/browser_mod/const.py
index c083a44..6130de7 100644
--- a/custom_components/browser_mod/const.py
+++ b/custom_components/browser_mod/const.py
@@ -3,7 +3,7 @@ DOMAIN = "browser_mod"
FRONTEND_SCRIPT_URL = "/browser_mod.js"
SETTINGS_PANEL_URL = "/browser_mod_panel.js"
-DATA_DEVICES = "devices"
+DATA_BROWSERS = "browsers"
DATA_ADDERS = "adders"
DATA_STORE = "store"
DATA_ALIASES = "aliases"
diff --git a/custom_components/browser_mod/coordinator.py b/custom_components/browser_mod/coordinator.py
index 3f3f135..6803563 100644
--- a/custom_components/browser_mod/coordinator.py
+++ b/custom_components/browser_mod/coordinator.py
@@ -8,10 +8,10 @@ _LOGGER = logging.getLogger(__name__)
class Coordinator(DataUpdateCoordinator):
- def __init__(self, hass, deviceID):
+ def __init__(self, hass, browserID):
super().__init__(
hass,
_LOGGER,
name="Browser Mod Coordinator",
)
- self.deviceID = deviceID
+ self.browserID = browserID
diff --git a/custom_components/browser_mod/helpers.py b/custom_components/browser_mod/helpers.py
index 579125e..eece033 100644
--- a/custom_components/browser_mod/helpers.py
+++ b/custom_components/browser_mod/helpers.py
@@ -11,9 +11,9 @@ _LOGGER = logging.getLogger(__name__)
class BrowserModEntity(CoordinatorEntity):
- def __init__(self, coordinator, deviceID, name):
+ def __init__(self, coordinator, browserID, name):
super().__init__(coordinator)
- self.deviceID = deviceID
+ self.browserID = browserID
self._name = name
@property
@@ -26,8 +26,8 @@ class BrowserModEntity(CoordinatorEntity):
if ip := self._data.get("browser", {}).get("ip_address"):
config_url = {"configuration_url": f"http://{ip}:2323"}
return {
- "identifiers": {(DOMAIN, self.deviceID)},
- "name": self.deviceID,
+ "identifiers": {(DOMAIN, self.browserID)},
+ "name": self.browserID,
"manufacturer": "Browser Mod",
**config_url,
}
@@ -36,7 +36,7 @@ class BrowserModEntity(CoordinatorEntity):
def extra_state_attributes(self):
return {
"type": "browser_mod",
- "deviceID": self.deviceID,
+ "browserID": self.browserID,
}
@property
@@ -53,4 +53,4 @@ class BrowserModEntity(CoordinatorEntity):
@property
def unique_id(self):
- return f"{self.deviceID}-{self._name.replace(' ','_')}"
+ return f"{self.browserID}-{self._name.replace(' ','_')}"
diff --git a/custom_components/browser_mod/light.py b/custom_components/browser_mod/light.py
index 6c5f4e4..faa7149 100644
--- a/custom_components/browser_mod/light.py
+++ b/custom_components/browser_mod/light.py
@@ -15,10 +15,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class BrowserModLight(BrowserModEntity, LightEntity):
- def __init__(self, coordinator, deviceID, device):
- BrowserModEntity.__init__(self, coordinator, deviceID, "Screen")
+ def __init__(self, coordinator, browserID, browser):
+ BrowserModEntity.__init__(self, coordinator, browserID, "Screen")
LightEntity.__init__(self)
- self.device = device
+ self.browser = browser
@property
def entity_registry_visible_default(self):
@@ -41,7 +41,7 @@ class BrowserModLight(BrowserModEntity, LightEntity):
return self._data.get("screen_brightness", 1)
def turn_on(self, **kwargs):
- self.device.send("screen_on", **kwargs)
+ self.browser.send("screen_on", **kwargs)
def turn_off(self, **kwargs):
- self.device.send("screen_off")
+ self.browser.send("screen_off")
diff --git a/custom_components/browser_mod/media_player.py b/custom_components/browser_mod/media_player.py
index 6fa26db..888bb74 100644
--- a/custom_components/browser_mod/media_player.py
+++ b/custom_components/browser_mod/media_player.py
@@ -39,14 +39,14 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class BrowserModPlayer(BrowserModEntity, MediaPlayerEntity):
- def __init__(self, coordinator, deviceID, device):
- BrowserModEntity.__init__(self, coordinator, deviceID, None)
+ def __init__(self, coordinator, browserID, browser):
+ BrowserModEntity.__init__(self, coordinator, browserID, None)
MediaPlayerEntity.__init__(self)
- self.device = device
+ self.browser = browser
@property
def unique_id(self):
- return f"{self.deviceID}-player"
+ return f"{self.browserID}-player"
@property
def entity_registry_visible_default(self):
@@ -83,10 +83,10 @@ class BrowserModPlayer(BrowserModEntity, MediaPlayerEntity):
return self._data.get("player", {}).get("muted", False)
def set_volume_level(self, volume):
- self.device.send("player-set-volume", volume_level=volume)
+ self.browser.send("player-set-volume", volume_level=volume)
def mute_volume(self, mute):
- self.device.send("player-mute", mute=mute)
+ self.browser.send("player-mute", mute=mute)
async def async_play_media(self, media_type, media_id, **kwargs):
if media_source.is_media_source_id(media_id):
@@ -97,7 +97,7 @@ class BrowserModPlayer(BrowserModEntity, MediaPlayerEntity):
media_id = play_item.url
if media_type in (MEDIA_TYPE_URL, MEDIA_TYPE_MUSIC):
media_id = async_process_play_media_url(self.hass, media_id)
- self.device.send("player-play", media_content_id=media_id)
+ self.browser.send("player-play", media_content_id=media_id)
async def async_browse_media(self, media_content_type=None, media_content_id=None):
"""Implement the websocket media browsing helper."""
@@ -108,10 +108,10 @@ class BrowserModPlayer(BrowserModEntity, MediaPlayerEntity):
)
def media_play(self):
- self.device.send("player-play")
+ self.browser.send("player-play")
def media_pause(self):
- self.device.send("player-pause")
+ self.browser.send("player-pause")
def media_stop(self):
- self.device.send("player-stop")
+ self.browser.send("player-stop")
diff --git a/custom_components/browser_mod/sensor.py b/custom_components/browser_mod/sensor.py
index 21f6012..f64ed2c 100644
--- a/custom_components/browser_mod/sensor.py
+++ b/custom_components/browser_mod/sensor.py
@@ -18,13 +18,13 @@ class BrowserSensor(BrowserModEntity, SensorEntity):
def __init__(
self,
coordinator,
- deviceID,
+ browserID,
parameter,
name,
unit_of_measurement=None,
device_class=None,
):
- super().__init__(coordinator, deviceID, name)
+ super().__init__(coordinator, browserID, name)
self.parameter = parameter
self._device_class = device_class
self._unit_of_measurement = unit_of_measurement
diff --git a/custom_components/browser_mod/service.py b/custom_components/browser_mod/service.py
index 7b79dea..b8841f0 100644
--- a/custom_components/browser_mod/service.py
+++ b/custom_components/browser_mod/service.py
@@ -1,17 +1,10 @@
import logging
-from homeassistant.helpers.entity_registry import (
- async_entries_for_config_entry,
- async_entries_for_device,
-)
-from homeassistant.const import STATE_UNAVAILABLE
-from homeassistant.helpers import device_registry, area_registry
+from homeassistant.helpers import device_registry
from .const import (
DOMAIN,
- DATA_DEVICES,
- DATA_ALIASES,
- USER_COMMANDS,
+ DATA_BROWSERS,
)
_LOGGER = logging.getLogger(__name__)
@@ -20,29 +13,31 @@ _LOGGER = logging.getLogger(__name__)
async def async_setup_services(hass):
def call_service(service, targets, data):
- devices = hass.data[DOMAIN][DATA_DEVICES]
+ browsers = hass.data[DOMAIN][DATA_BROWSERS]
if isinstance(targets, str):
targets = [targets]
+ # If no targets were specified, send to all browsers
+ if len(targets) == 0:
+ targets = browsers.keys()
+
for target in targets:
- if target not in devices:
+ if target not in browsers:
continue
- device = devices[target]
- device.send(service, **data)
+ browser = browsers[target]
+ browser.send(service, **data)
def handle_service(call):
service = call.service
data = {**call.data}
- device_ids = set(data.get("device_id", []))
- data.pop("device_id", None)
- area_ids = set(data.get("area_id", []))
- data.pop("area_id", None)
- targets = data.get("target", [])
- if isinstance(targets, str):
- targets = [targets]
- targets = set(targets)
- data.pop("target", None)
+
+ browsers = data.pop("browser_id", [])
+ if isinstance(browsers, str):
+ browsers = [browsers]
+ browsers = set(browsers)
+ device_ids = set(data.pop("device_id", []))
+ area_ids = set(data.pop("area_id", []))
dr = device_registry.async_get(hass)
@@ -53,53 +48,16 @@ async def async_setup_services(hass):
browserID = list(dev.identifiers)[0][1]
if browserID is None:
continue
- targets.add(browserID)
+ browsers.add(browserID)
for area in area_ids:
for dev in device_registry.async_entries_for_area(dr, area):
browserID = list(dev.identifiers)[0][1]
if browserID is None:
continue
- targets.add(browserID)
+ browsers.add(browserID)
- _LOGGER.error(service)
- _LOGGER.error(targets)
- _LOGGER.error(data)
-
- call_service(service, targets, data)
+ call_service(service, browsers, data)
hass.services.async_register(DOMAIN, "test", handle_service)
hass.services.async_register(DOMAIN, "popup", handle_service)
-
-
-async def setup_service(hass):
- def handle_command(call):
- command = call.data.get("command", None)
- if not command:
- return
-
- targets = call.data.get("deviceID", None)
- if isinstance(targets, str):
- targets = [targets]
- devices = hass.data[DOMAIN][DATA_DEVICES]
- aliases = hass.data[DOMAIN][DATA_ALIASES]
- if not targets:
- targets = devices.keys()
- targets = [aliases.get(t, t) for t in targets]
-
- data = dict(call.data)
- del data["command"]
-
- for t in targets:
- if t in devices:
- devices[t].send(command, **data)
-
- def command_wrapper(call):
- command = call.service.replace("_", "-")
- call.data = dict(call.data)
- call.data["command"] = command
- handle_command(call)
-
- hass.services.async_register(DOMAIN, "command", handle_command)
- for cmd in USER_COMMANDS:
- hass.services.async_register(DOMAIN, cmd.replace("-", "_"), command_wrapper)
diff --git a/custom_components/browser_mod/store.py b/custom_components/browser_mod/store.py
index 721419f..20a5c45 100644
--- a/custom_components/browser_mod/store.py
+++ b/custom_components/browser_mod/store.py
@@ -10,7 +10,7 @@ _LOGGER = logging.getLogger(__name__)
@attr.s
-class DeviceStoreData:
+class BrowserStoreData:
last_seen = attr.ib(type=int, default=0)
enabled = attr.ib(type=bool, default=False)
camera = attr.ib(type=bool, default=False)
@@ -26,17 +26,19 @@ class DeviceStoreData:
@attr.s
class ConfigStoreData:
- devices = attr.ib(type=dict[str:DeviceStoreData], factory=dict)
+ browsers = attr.ib(type=dict[str:BrowserStoreData], factory=dict)
version = attr.ib(type=str, default="2.0")
@classmethod
def from_dict(cls, data={}):
- devices = {k: DeviceStoreData.from_dict(v) for k, v in data["devices"].items()}
+ browsers = {
+ k: BrowserStoreData.from_dict(v) for k, v in data["browsers"].items()
+ }
return cls(
**(
data
| {
- "devices": devices,
+ "browsers": browsers,
}
)
)
@@ -83,15 +85,15 @@ class BrowserModStore:
return remove_listener
- def get_device(self, deviceID):
- return self.data.devices.get(deviceID, DeviceStoreData())
+ def get_browser(self, browserID):
+ return self.data.browsers.get(browserID, BrowserStoreData())
- async def set_device(self, deviceID, **data):
- device = self.data.devices.get(deviceID, DeviceStoreData())
- device.__dict__.update(data)
- self.data.devices[deviceID] = device
+ async def set_browser(self, browserID, **data):
+ browser = self.data.browsers.get(browserID, BrowserStoreData())
+ browser.__dict__.update(data)
+ self.data.browsers[browserID] = browser
await self.updated()
- async def delete_device(self, deviceID):
- del self.data.devices[deviceID]
+ async def delete_browser(self, browserID):
+ del self.data.browsers[browserID]
await self.updated()
diff --git a/js/config_panel/main.ts b/js/config_panel/main.ts
index 640dfd6..20be064 100644
--- a/js/config_panel/main.ts
+++ b/js/config_panel/main.ts
@@ -14,32 +14,32 @@ loadDevTools().then(() => {
if (!window.browser_mod?.connected) return;
window.browser_mod.registered = !window.browser_mod.registered;
}
- changeDeviceID(ev) {
- window.browser_mod.deviceID = ev.target.value;
+ changeBrowserID(ev) {
+ window.browser_mod.browserID = ev.target.value;
}
toggleCameraEnabled() {
window.browser_mod.cameraEnabled = !window.browser_mod.cameraEnabled;
}
- unregister_device(ev) {
- const deviceID = ev.currentTarget.deviceID;
+ unregister_browser(ev) {
+ const browserID = ev.currentTarget.browserID;
const unregisterCallback = () => {
- console.log(deviceID, window.browser_mod.deviceID);
- if (deviceID === window.browser_mod.deviceID) {
+ console.log(browserID, window.browser_mod.browserID);
+ if (browserID === window.browser_mod.browserID) {
console.log("Unregister self");
window.browser_mod.registered = false;
} else {
window.browser_mod.connection.sendMessage({
type: "browser_mod/unregister",
- deviceID,
+ browserID,
});
}
};
window.browser_mod.showPopup(
- "Unregister device",
- `Are you sure you want to unregister device ${deviceID}?`,
+ "Unregister browser",
+ `Are you sure you want to unregister browser ${browserID}?`,
{
primary_action: "Yes",
secondary_action: "No",
@@ -109,21 +109,21 @@ loadDevTools().then(() => {
- DeviceID
+ BrowserID
A unique identifier for this browser-device
combination.
Enable camera
Get camera input from this device (hardware
+ >Get camera input from this browser (hardware
dependent)
{
-