Renamed Device to Browser throughout
This commit is contained in:
parent
3bf2481e5b
commit
acc4a15e02
@ -3,7 +3,7 @@ import logging
|
||||
from .store import BrowserModStore
|
||||
from .mod_view import async_setup_view
|
||||
from .connection import async_setup_connection
|
||||
from .const import DOMAIN, DATA_DEVICES, DATA_ADDERS, DATA_STORE
|
||||
from .const import DOMAIN, DATA_BROWSERS, DATA_ADDERS, DATA_STORE
|
||||
from .service import async_setup_services
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -15,7 +15,7 @@ async def async_setup(hass, config):
|
||||
await store.load()
|
||||
|
||||
hass.data[DOMAIN] = {
|
||||
DATA_DEVICES: {},
|
||||
DATA_BROWSERS: {},
|
||||
DATA_ADDERS: {},
|
||||
DATA_STORE: store,
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import logging
|
||||
from homeassistant.components.websocket_api import event_message
|
||||
from homeassistant.helpers import device_registry, entity_registry
|
||||
|
||||
from .const import DOMAIN, DATA_ADDERS
|
||||
from .const import DATA_BROWSERS, DOMAIN, DATA_ADDERS
|
||||
from .coordinator import Coordinator
|
||||
from .sensor import BrowserSensor
|
||||
from .light import BrowserModLight
|
||||
@ -14,13 +14,13 @@ from .camera import BrowserModCamera
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BrowserModDevice:
|
||||
"""A Browser_mod device."""
|
||||
class BrowserModBrowser:
|
||||
"""A Browser_mod browser."""
|
||||
|
||||
def __init__(self, hass, deviceID):
|
||||
def __init__(self, hass, browserID):
|
||||
""" """
|
||||
self.deviceID = deviceID
|
||||
self.coordinator = Coordinator(hass, deviceID)
|
||||
self.browserID = browserID
|
||||
self.coordinator = Coordinator(hass, browserID)
|
||||
self.entities = {}
|
||||
self.data = {}
|
||||
self.settings = {}
|
||||
@ -38,17 +38,17 @@ class BrowserModDevice:
|
||||
self.update_entities(hass)
|
||||
|
||||
def update_entities(self, hass):
|
||||
"""Create all entities associated with the device."""
|
||||
"""Create all entities associated with the browser."""
|
||||
|
||||
coordinator = self.coordinator
|
||||
deviceID = self.deviceID
|
||||
browserID = self.browserID
|
||||
|
||||
def _assert_browser_sensor(type, name, *properties):
|
||||
if name in self.entities:
|
||||
return
|
||||
adder = hass.data[DOMAIN][DATA_ADDERS][type]
|
||||
cls = {"sensor": BrowserSensor, "binary_sensor": BrowserBinarySensor}[type]
|
||||
new = cls(coordinator, deviceID, name, *properties)
|
||||
new = cls(coordinator, browserID, name, *properties)
|
||||
adder([new])
|
||||
self.entities[name] = new
|
||||
|
||||
@ -70,19 +70,19 @@ class BrowserModDevice:
|
||||
|
||||
if "screen" not in self.entities:
|
||||
adder = hass.data[DOMAIN][DATA_ADDERS]["light"]
|
||||
new = BrowserModLight(coordinator, deviceID, self)
|
||||
new = BrowserModLight(coordinator, browserID, self)
|
||||
adder([new])
|
||||
self.entities["screen"] = new
|
||||
|
||||
if "player" not in self.entities:
|
||||
adder = hass.data[DOMAIN][DATA_ADDERS]["media_player"]
|
||||
new = BrowserModPlayer(coordinator, deviceID, self)
|
||||
new = BrowserModPlayer(coordinator, browserID, self)
|
||||
adder([new])
|
||||
self.entities["player"] = new
|
||||
|
||||
if "camera" not in self.entities and self.settings.get("camera"):
|
||||
adder = hass.data[DOMAIN][DATA_ADDERS]["camera"]
|
||||
new = BrowserModCamera(coordinator, deviceID)
|
||||
new = BrowserModCamera(coordinator, browserID)
|
||||
adder([new])
|
||||
self.entities["camera"] = new
|
||||
if "camera" in self.entities and not self.settings.get("camera"):
|
||||
@ -95,7 +95,7 @@ class BrowserModDevice:
|
||||
)
|
||||
|
||||
def send(self, command, **kwargs):
|
||||
"""Send a command to this device."""
|
||||
"""Send a command to this browser."""
|
||||
if self.connection is None:
|
||||
return
|
||||
|
||||
@ -112,7 +112,7 @@ class BrowserModDevice:
|
||||
)
|
||||
|
||||
def delete(self, hass):
|
||||
"""Delete device and associated entities."""
|
||||
"""Delete browser and associated entities."""
|
||||
dr = device_registry.async_get(hass)
|
||||
er = entity_registry.async_get(hass)
|
||||
|
||||
@ -121,25 +121,25 @@ class BrowserModDevice:
|
||||
|
||||
self.entities = {}
|
||||
|
||||
device = dr.async_get_device({(DOMAIN, self.deviceID)})
|
||||
device = dr.async_get_device({(DOMAIN, self.browserID)})
|
||||
dr.async_remove_device(device.id)
|
||||
|
||||
|
||||
def getDevice(hass, deviceID, *, create=True):
|
||||
"""Get or create device by deviceID."""
|
||||
devices = hass.data[DOMAIN]["devices"]
|
||||
if deviceID in devices:
|
||||
return devices[deviceID]
|
||||
def getBrowser(hass, browserID, *, create=True):
|
||||
"""Get or create browser by browserID."""
|
||||
browsers = hass.data[DOMAIN][DATA_BROWSERS]
|
||||
if browserID in browsers:
|
||||
return browsers[browserID]
|
||||
|
||||
if not create:
|
||||
return None
|
||||
|
||||
devices[deviceID] = BrowserModDevice(hass, deviceID)
|
||||
return devices[deviceID]
|
||||
browsers[browserID] = BrowserModBrowser(hass, browserID)
|
||||
return browsers[browserID]
|
||||
|
||||
|
||||
def deleteDevice(hass, deviceID):
|
||||
devices = hass.data[DOMAIN]["devices"]
|
||||
if deviceID in devices:
|
||||
devices[deviceID].delete(hass)
|
||||
del devices[deviceID]
|
||||
def deleteBrowser(hass, browserID):
|
||||
browsers = hass.data[DOMAIN][DATA_BROWSERS]
|
||||
if browserID in browsers:
|
||||
browsers[browserID].delete(hass)
|
||||
del browsers[browserID]
|
@ -129,7 +129,7 @@ class BrowserPlayer extends s {
|
||||
composed: true,
|
||||
cancelable: false,
|
||||
detail: {
|
||||
entityId: (_a = window.browser_mod.deviceEntities) === null || _a === void 0 ? void 0 : _a.player,
|
||||
entityId: (_a = window.browser_mod.browserEntities) === null || _a === void 0 ? void 0 : _a.player,
|
||||
},
|
||||
}));
|
||||
}
|
||||
@ -179,7 +179,7 @@ class BrowserPlayer extends s {
|
||||
</ha-icon-button>
|
||||
</div>
|
||||
|
||||
<div class="device-id">${window.browser_mod.deviceID}</div>
|
||||
<div class="browser-id">${window.browser_mod.browserID}</div>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
@ -196,7 +196,7 @@ class BrowserPlayer extends s {
|
||||
width: 24px;
|
||||
padding: 8px;
|
||||
}
|
||||
.device-id {
|
||||
.browser-id {
|
||||
opacity: 0.7;
|
||||
font-size: xx-small;
|
||||
margin-top: -10px;
|
||||
@ -260,7 +260,7 @@ const loadLoadCardHelpers = async () => {
|
||||
await ((_c = (_b = (_a = routes === null || routes === void 0 ? void 0 : routes.routes) === null || _a === void 0 ? void 0 : _a.a) === null || _b === void 0 ? void 0 : _b.load) === null || _c === void 0 ? void 0 : _c.call(_b));
|
||||
};
|
||||
|
||||
const ID_STORAGE_KEY = "browser_mod-device-id";
|
||||
const ID_STORAGE_KEY = "browser_mod-browser-id";
|
||||
const ConnectionMixin = (SuperClass) => {
|
||||
class BrowserModConnection extends SuperClass {
|
||||
constructor() {
|
||||
@ -269,7 +269,7 @@ const ConnectionMixin = (SuperClass) => {
|
||||
this.connectionPromise = new Promise((resolve) => {
|
||||
this._connectionResolve = resolve;
|
||||
});
|
||||
this.deviceEntities = {};
|
||||
this.browserEntities = {};
|
||||
}
|
||||
LOG(...args) {
|
||||
const dt = new Date();
|
||||
@ -284,8 +284,8 @@ const ConnectionMixin = (SuperClass) => {
|
||||
this.LOG("Command:", msg);
|
||||
this.fireEvent(`command-${msg.command}`, msg);
|
||||
}
|
||||
else if (msg.deviceEntities) {
|
||||
this.deviceEntities = msg.deviceEntities;
|
||||
else if (msg.browserEntities) {
|
||||
this.browserEntities = msg.browserEntities;
|
||||
}
|
||||
else if (msg.result) {
|
||||
this.update_config(msg.result);
|
||||
@ -296,7 +296,7 @@ const ConnectionMixin = (SuperClass) => {
|
||||
var _a;
|
||||
this.LOG("Receive:", cfg);
|
||||
let update = false;
|
||||
if (!this.registered && ((_a = cfg.devices) === null || _a === void 0 ? void 0 : _a[this.deviceID])) {
|
||||
if (!this.registered && ((_a = cfg.browsers) === null || _a === void 0 ? void 0 : _a[this.browserID])) {
|
||||
update = true;
|
||||
}
|
||||
this._data = cfg;
|
||||
@ -314,7 +314,7 @@ const ConnectionMixin = (SuperClass) => {
|
||||
// Subscribe to configuration updates
|
||||
conn.subscribeMessage((msg) => this.incoming_message(msg), {
|
||||
type: "browser_mod/connect",
|
||||
deviceID: this.deviceID,
|
||||
browserID: this.browserID,
|
||||
});
|
||||
// Keep connection status up to date
|
||||
conn.addEventListener("disconnected", () => {
|
||||
@ -332,13 +332,13 @@ const ConnectionMixin = (SuperClass) => {
|
||||
var _a, _b;
|
||||
return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.config) !== null && _b !== void 0 ? _b : {};
|
||||
}
|
||||
get devices() {
|
||||
get browsers() {
|
||||
var _a, _b;
|
||||
return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.devices) !== null && _b !== void 0 ? _b : [];
|
||||
return (_b = (_a = this._data) === null || _a === void 0 ? void 0 : _a.browsers) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
get registered() {
|
||||
var _a;
|
||||
return ((_a = this.devices) === null || _a === void 0 ? void 0 : _a[this.deviceID]) !== undefined;
|
||||
return ((_a = this.browsers) === null || _a === void 0 ? void 0 : _a[this.browserID]) !== undefined;
|
||||
}
|
||||
set registered(reg) {
|
||||
(async () => {
|
||||
@ -347,7 +347,7 @@ const ConnectionMixin = (SuperClass) => {
|
||||
return;
|
||||
await this.connection.sendMessage({
|
||||
type: "browser_mod/register",
|
||||
deviceID: this.deviceID,
|
||||
browserID: this.browserID,
|
||||
});
|
||||
}
|
||||
else {
|
||||
@ -355,7 +355,7 @@ const ConnectionMixin = (SuperClass) => {
|
||||
return;
|
||||
await this.connection.sendMessage({
|
||||
type: "browser_mod/unregister",
|
||||
deviceID: this.deviceID,
|
||||
browserID: this.browserID,
|
||||
});
|
||||
}
|
||||
})();
|
||||
@ -363,14 +363,14 @@ const ConnectionMixin = (SuperClass) => {
|
||||
async _reregister(newData = {}) {
|
||||
await this.connection.sendMessage({
|
||||
type: "browser_mod/reregister",
|
||||
deviceID: this.deviceID,
|
||||
data: Object.assign(Object.assign({}, this.devices[this.deviceID]), newData),
|
||||
browserID: this.browserID,
|
||||
data: Object.assign(Object.assign({}, this.browsers[this.browserID]), newData),
|
||||
});
|
||||
}
|
||||
get meta() {
|
||||
if (!this.registered)
|
||||
return null;
|
||||
return this.devices[this.deviceID].meta;
|
||||
return this.browsers[this.browserID].meta;
|
||||
}
|
||||
set meta(value) {
|
||||
this._reregister({ meta: value });
|
||||
@ -378,7 +378,7 @@ const ConnectionMixin = (SuperClass) => {
|
||||
get cameraEnabled() {
|
||||
if (!this.registered)
|
||||
return null;
|
||||
return this.devices[this.deviceID].camera;
|
||||
return this.browsers[this.browserID].camera;
|
||||
}
|
||||
set cameraEnabled(value) {
|
||||
this._reregister({ camera: value });
|
||||
@ -389,19 +389,19 @@ const ConnectionMixin = (SuperClass) => {
|
||||
this.LOG("Send:", data);
|
||||
this.connection.sendMessage({
|
||||
type: "browser_mod/update",
|
||||
deviceID: this.deviceID,
|
||||
browserID: this.browserID,
|
||||
data,
|
||||
});
|
||||
}
|
||||
get deviceID() {
|
||||
get browserID() {
|
||||
if (localStorage[ID_STORAGE_KEY])
|
||||
return localStorage[ID_STORAGE_KEY];
|
||||
this.deviceID = "";
|
||||
return this.deviceID;
|
||||
this.browserID = "";
|
||||
return this.browserID;
|
||||
}
|
||||
set deviceID(id) {
|
||||
set browserID(id) {
|
||||
var _a, _b;
|
||||
function _createDeviceID() {
|
||||
function _createBrowserID() {
|
||||
var _a, _b;
|
||||
const s4 = () => {
|
||||
return Math.floor((1 + Math.random()) * 100000)
|
||||
@ -411,21 +411,20 @@ const ConnectionMixin = (SuperClass) => {
|
||||
return (_b = (_a = window.fully) === null || _a === void 0 ? void 0 : _a.getDeviceId()) !== null && _b !== void 0 ? _b : `${s4()}${s4()}-${s4()}${s4()}`;
|
||||
}
|
||||
if (id === "")
|
||||
id = _createDeviceID();
|
||||
id = _createBrowserID();
|
||||
const oldID = localStorage[ID_STORAGE_KEY];
|
||||
localStorage[ID_STORAGE_KEY] = id;
|
||||
this.fireEvent("browser-mod-config-update");
|
||||
if (((_a = this.devices) === null || _a === void 0 ? void 0 : _a[oldID]) !== undefined &&
|
||||
((_b = this.devices) === null || _b === void 0 ? void 0 : _b[this.deviceID]) === undefined) {
|
||||
if (((_a = this.browsers) === null || _a === void 0 ? void 0 : _a[oldID]) !== undefined &&
|
||||
((_b = this.browsers) === null || _b === void 0 ? void 0 : _b[this.browserID]) === undefined) {
|
||||
(async () => {
|
||||
await this.connection.sendMessage({
|
||||
type: "browser_mod/reregister",
|
||||
deviceID: oldID,
|
||||
data: Object.assign(Object.assign({}, this.devices[oldID]), { deviceID: this.deviceID }),
|
||||
browserID: oldID,
|
||||
data: Object.assign(Object.assign({}, this.browsers[oldID]), { browserID: this.browserID }),
|
||||
});
|
||||
})();
|
||||
}
|
||||
// TODO: Send update to backend to update device
|
||||
}
|
||||
}
|
||||
return BrowserModConnection;
|
||||
@ -1256,8 +1255,8 @@ var pjson = {
|
||||
/*
|
||||
TODO:
|
||||
- Fix nomenclature
|
||||
- Command -> Service
|
||||
- Device -> Browser
|
||||
x Command -> Service
|
||||
x Device -> Browser
|
||||
- Popups
|
||||
X Basic popups
|
||||
- Card-mod integration
|
||||
@ -1306,13 +1305,10 @@ class BrowserMod extends ServicesMixin(PopupMixin(BrowserStateMixin(CameraMixin(
|
||||
// }
|
||||
// });
|
||||
console.info(`%cBROWSER_MOD ${pjson.version} IS INSTALLED
|
||||
%cDeviceID: ${this.deviceID}`, "color: green; font-weight: bold", "");
|
||||
%cBrowserID: ${this.browserID}`, "color: green; font-weight: bold", "");
|
||||
}
|
||||
}
|
||||
// (async () => {
|
||||
// await hass_loaded();
|
||||
if (!window.browser_mod)
|
||||
window.browser_mod = new BrowserMod();
|
||||
// })();
|
||||
window.browser_mod = new BrowserMod();
|
||||
|
||||
export { BrowserMod };
|
||||
|
@ -90,28 +90,28 @@ loadDevTools().then(() => {
|
||||
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}?`, {
|
||||
window.browser_mod.showPopup("Unregister browser", `Are you sure you want to unregister browser ${browserID}?`, {
|
||||
primary_action: "Yes",
|
||||
secondary_action: "No",
|
||||
callbacks: {
|
||||
@ -176,21 +176,21 @@ loadDevTools().then(() => {
|
||||
</ha-settings-row>
|
||||
|
||||
<ha-settings-row>
|
||||
<span slot="heading">DeviceID</span>
|
||||
<span slot="heading">BrowserID</span>
|
||||
<span slot="description"
|
||||
>A unique identifier for this browser-device
|
||||
combination.</span
|
||||
>
|
||||
<ha-textfield
|
||||
.value=${(_c = window.browser_mod) === null || _c === void 0 ? void 0 : _c.deviceID}
|
||||
@change=${this.changeDeviceID}
|
||||
.value=${(_c = window.browser_mod) === null || _c === void 0 ? void 0 : _c.browserID}
|
||||
@change=${this.changeBrowserID}
|
||||
></ha-textfield>
|
||||
</ha-settings-row>
|
||||
|
||||
<ha-settings-row>
|
||||
<span slot="heading">Enable camera</span>
|
||||
<span slot="description"
|
||||
>Get camera input from this device (hardware
|
||||
>Get camera input from this browser (hardware
|
||||
dependent)</span
|
||||
>
|
||||
<ha-switch
|
||||
@ -201,20 +201,20 @@ loadDevTools().then(() => {
|
||||
</div>
|
||||
</ha-card>
|
||||
|
||||
<ha-card header="Registered devices" outlined>
|
||||
<ha-card header="Registered browsers" outlined>
|
||||
<div class="card-content">
|
||||
${Object.keys(window.browser_mod.devices).map((d) => $ ` <ha-settings-row>
|
||||
${Object.keys(window.browser_mod.browsers).map((d) => $ ` <ha-settings-row>
|
||||
<span slot="heading"> ${d} </span>
|
||||
<span slot="description">
|
||||
Last connected:
|
||||
<ha-relative-time
|
||||
.hass=${this.hass}
|
||||
.datetime=${window.browser_mod.devices[d].last_seen}
|
||||
.datetime=${window.browser_mod.browsers[d].last_seen}
|
||||
></ha-relative-time>
|
||||
</span>
|
||||
<ha-icon-button
|
||||
.deviceID=${d}
|
||||
@click=${this.unregister_device}
|
||||
.browserID=${d}
|
||||
@click=${this.unregister_browser}
|
||||
>
|
||||
<ha-icon .icon=${"mdi:delete"}></ha-icon>
|
||||
</ha-icon-button>
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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(' ','_')}"
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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(() => {
|
||||
</ha-settings-row>
|
||||
|
||||
<ha-settings-row>
|
||||
<span slot="heading">DeviceID</span>
|
||||
<span slot="heading">BrowserID</span>
|
||||
<span slot="description"
|
||||
>A unique identifier for this browser-device
|
||||
combination.</span
|
||||
>
|
||||
<ha-textfield
|
||||
.value=${window.browser_mod?.deviceID}
|
||||
@change=${this.changeDeviceID}
|
||||
.value=${window.browser_mod?.browserID}
|
||||
@change=${this.changeBrowserID}
|
||||
></ha-textfield>
|
||||
</ha-settings-row>
|
||||
|
||||
<ha-settings-row>
|
||||
<span slot="heading">Enable camera</span>
|
||||
<span slot="description"
|
||||
>Get camera input from this device (hardware
|
||||
>Get camera input from this browser (hardware
|
||||
dependent)</span
|
||||
>
|
||||
<ha-switch
|
||||
@ -134,21 +134,21 @@ loadDevTools().then(() => {
|
||||
</div>
|
||||
</ha-card>
|
||||
|
||||
<ha-card header="Registered devices" outlined>
|
||||
<ha-card header="Registered browsers" outlined>
|
||||
<div class="card-content">
|
||||
${Object.keys(window.browser_mod.devices).map(
|
||||
${Object.keys(window.browser_mod.browsers).map(
|
||||
(d) => html` <ha-settings-row>
|
||||
<span slot="heading"> ${d} </span>
|
||||
<span slot="description">
|
||||
Last connected:
|
||||
<ha-relative-time
|
||||
.hass=${this.hass}
|
||||
.datetime=${window.browser_mod.devices[d].last_seen}
|
||||
.datetime=${window.browser_mod.browsers[d].last_seen}
|
||||
></ha-relative-time>
|
||||
</span>
|
||||
<ha-icon-button
|
||||
.deviceID=${d}
|
||||
@click=${this.unregister_device}
|
||||
.browserID=${d}
|
||||
@click=${this.unregister_browser}
|
||||
>
|
||||
<ha-icon .icon=${"mdi:delete"}></ha-icon>
|
||||
</ha-icon-button>
|
||||
|
@ -47,7 +47,7 @@ class BrowserPlayer extends LitElement {
|
||||
composed: true,
|
||||
cancelable: false,
|
||||
detail: {
|
||||
entityId: window.browser_mod.deviceEntities?.player,
|
||||
entityId: window.browser_mod.browserEntities?.player,
|
||||
},
|
||||
})
|
||||
);
|
||||
@ -98,7 +98,7 @@ class BrowserPlayer extends LitElement {
|
||||
</ha-icon-button>
|
||||
</div>
|
||||
|
||||
<div class="device-id">${window.browser_mod.deviceID}</div>
|
||||
<div class="browser-id">${window.browser_mod.browserID}</div>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
@ -116,7 +116,7 @@ class BrowserPlayer extends LitElement {
|
||||
width: 24px;
|
||||
padding: 8px;
|
||||
}
|
||||
.device-id {
|
||||
.browser-id {
|
||||
opacity: 0.7;
|
||||
font-size: xx-small;
|
||||
margin-top: -10px;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { hass, provideHass } from "../helpers";
|
||||
|
||||
const ID_STORAGE_KEY = "browser_mod-device-id";
|
||||
const ID_STORAGE_KEY = "browser_mod-browser-id";
|
||||
|
||||
export const ConnectionMixin = (SuperClass) => {
|
||||
class BrowserModConnection extends SuperClass {
|
||||
@ -12,7 +12,7 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
public connectionPromise = new Promise((resolve) => {
|
||||
this._connectionResolve = resolve;
|
||||
});
|
||||
public deviceEntities = {};
|
||||
public browserEntities = {};
|
||||
|
||||
LOG(...args) {
|
||||
const dt = new Date();
|
||||
@ -27,8 +27,8 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
if (msg.command) {
|
||||
this.LOG("Command:", msg);
|
||||
this.fireEvent(`command-${msg.command}`, msg);
|
||||
} else if (msg.deviceEntities) {
|
||||
this.deviceEntities = msg.deviceEntities;
|
||||
} else if (msg.browserEntities) {
|
||||
this.browserEntities = msg.browserEntities;
|
||||
} else if (msg.result) {
|
||||
this.update_config(msg.result);
|
||||
}
|
||||
@ -39,7 +39,7 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
this.LOG("Receive:", cfg);
|
||||
|
||||
let update = false;
|
||||
if (!this.registered && cfg.devices?.[this.deviceID]) {
|
||||
if (!this.registered && cfg.browsers?.[this.browserID]) {
|
||||
update = true;
|
||||
}
|
||||
this._data = cfg;
|
||||
@ -61,7 +61,7 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
// Subscribe to configuration updates
|
||||
conn.subscribeMessage((msg) => this.incoming_message(msg), {
|
||||
type: "browser_mod/connect",
|
||||
deviceID: this.deviceID,
|
||||
browserID: this.browserID,
|
||||
});
|
||||
|
||||
// Keep connection status up to date
|
||||
@ -82,12 +82,12 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
return this._data?.config ?? {};
|
||||
}
|
||||
|
||||
get devices() {
|
||||
return this._data?.devices ?? [];
|
||||
get browsers() {
|
||||
return this._data?.browsers ?? [];
|
||||
}
|
||||
|
||||
get registered() {
|
||||
return this.devices?.[this.deviceID] !== undefined;
|
||||
return this.browsers?.[this.browserID] !== undefined;
|
||||
}
|
||||
|
||||
set registered(reg) {
|
||||
@ -96,13 +96,13 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
if (this.registered) return;
|
||||
await this.connection.sendMessage({
|
||||
type: "browser_mod/register",
|
||||
deviceID: this.deviceID,
|
||||
browserID: this.browserID,
|
||||
});
|
||||
} else {
|
||||
if (!this.registered) return;
|
||||
await this.connection.sendMessage({
|
||||
type: "browser_mod/unregister",
|
||||
deviceID: this.deviceID,
|
||||
browserID: this.browserID,
|
||||
});
|
||||
}
|
||||
})();
|
||||
@ -111,9 +111,9 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
private async _reregister(newData = {}) {
|
||||
await this.connection.sendMessage({
|
||||
type: "browser_mod/reregister",
|
||||
deviceID: this.deviceID,
|
||||
browserID: this.browserID,
|
||||
data: {
|
||||
...this.devices[this.deviceID],
|
||||
...this.browsers[this.browserID],
|
||||
...newData,
|
||||
},
|
||||
});
|
||||
@ -121,7 +121,7 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
|
||||
get meta() {
|
||||
if (!this.registered) return null;
|
||||
return this.devices[this.deviceID].meta;
|
||||
return this.browsers[this.browserID].meta;
|
||||
}
|
||||
set meta(value) {
|
||||
this._reregister({ meta: value });
|
||||
@ -129,7 +129,7 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
|
||||
get cameraEnabled() {
|
||||
if (!this.registered) return null;
|
||||
return this.devices[this.deviceID].camera;
|
||||
return this.browsers[this.browserID].camera;
|
||||
}
|
||||
set cameraEnabled(value) {
|
||||
this._reregister({ camera: value });
|
||||
@ -143,18 +143,18 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
|
||||
this.connection.sendMessage({
|
||||
type: "browser_mod/update",
|
||||
deviceID: this.deviceID,
|
||||
browserID: this.browserID,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
get deviceID() {
|
||||
get browserID() {
|
||||
if (localStorage[ID_STORAGE_KEY]) return localStorage[ID_STORAGE_KEY];
|
||||
this.deviceID = "";
|
||||
return this.deviceID;
|
||||
this.browserID = "";
|
||||
return this.browserID;
|
||||
}
|
||||
set deviceID(id) {
|
||||
function _createDeviceID() {
|
||||
set browserID(id) {
|
||||
function _createBrowserID() {
|
||||
const s4 = () => {
|
||||
return Math.floor((1 + Math.random()) * 100000)
|
||||
.toString(16)
|
||||
@ -163,29 +163,27 @@ export const ConnectionMixin = (SuperClass) => {
|
||||
return window.fully?.getDeviceId() ?? `${s4()}${s4()}-${s4()}${s4()}`;
|
||||
}
|
||||
|
||||
if (id === "") id = _createDeviceID();
|
||||
if (id === "") id = _createBrowserID();
|
||||
const oldID = localStorage[ID_STORAGE_KEY];
|
||||
localStorage[ID_STORAGE_KEY] = id;
|
||||
|
||||
this.fireEvent("browser-mod-config-update");
|
||||
|
||||
if (
|
||||
this.devices?.[oldID] !== undefined &&
|
||||
this.devices?.[this.deviceID] === undefined
|
||||
this.browsers?.[oldID] !== undefined &&
|
||||
this.browsers?.[this.browserID] === undefined
|
||||
) {
|
||||
(async () => {
|
||||
await this.connection.sendMessage({
|
||||
type: "browser_mod/reregister",
|
||||
deviceID: oldID,
|
||||
browserID: oldID,
|
||||
data: {
|
||||
...this.devices[oldID],
|
||||
deviceID: this.deviceID,
|
||||
...this.browsers[oldID],
|
||||
browserID: this.browserID,
|
||||
},
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
||||
// TODO: Send update to backend to update device
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,8 @@ import pjson from "../../package.json";
|
||||
/*
|
||||
TODO:
|
||||
- Fix nomenclature
|
||||
- Command -> Service
|
||||
- Device -> Browser
|
||||
x Command -> Service
|
||||
x Device -> Browser
|
||||
- Popups
|
||||
X Basic popups
|
||||
- Card-mod integration
|
||||
@ -81,107 +81,11 @@ export class BrowserMod extends ServicesMixin(
|
||||
|
||||
console.info(
|
||||
`%cBROWSER_MOD ${pjson.version} IS INSTALLED
|
||||
%cDeviceID: ${this.deviceID}`,
|
||||
%cBrowserID: ${this.browserID}`,
|
||||
"color: green; font-weight: bold",
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
// async msg_callback(msg) {
|
||||
// const handlers = {
|
||||
// update: (msg) => this.update(msg),
|
||||
// debug: (msg) => this.debug(msg),
|
||||
|
||||
// play: (msg) => this.player_play(msg.media_content_id),
|
||||
// pause: (msg) => this.player_pause(),
|
||||
// stop: (msg) => this.player_stop(),
|
||||
// "set-volume": (msg) => this.player_set_volume(msg.volume_level),
|
||||
// mute: (msg) => this.player_mute(msg.mute),
|
||||
|
||||
// toast: (msg) => this.do_toast(msg.message, msg.duration),
|
||||
// popup: (msg) => this.do_popup(msg),
|
||||
// "close-popup": (msg) => this.do_close_popup(),
|
||||
// "more-info": (msg) => this.do_more_info(msg.entity_id, msg.large),
|
||||
|
||||
// navigate: (msg) => this.do_navigate(msg.navigation_path),
|
||||
// "set-theme": (msg) => this.set_theme(msg),
|
||||
// "lovelace-reload": (msg) => this.lovelace_reload(msg),
|
||||
// "window-reload": () => window.location.reload(),
|
||||
|
||||
// blackout: (msg) =>
|
||||
// this.do_blackout(msg.time ? parseInt(msg.time) : undefined),
|
||||
// "no-blackout": (msg) => {
|
||||
// if (msg.brightness && this.isFully) {
|
||||
// (window as any).fully.setScreenBrightness(msg.brightness);
|
||||
// }
|
||||
// this.no_blackout();
|
||||
// },
|
||||
|
||||
// "call-service": (msg) => this.call_service(msg),
|
||||
// commands: async (msg) => {
|
||||
// for (const m of msg.commands) {
|
||||
// await this.msg_callback(m);
|
||||
// }
|
||||
// },
|
||||
// delay: async (msg) =>
|
||||
// await new Promise((resolve) => {
|
||||
// window.setTimeout(resolve, msg.seconds * 1000);
|
||||
// }),
|
||||
// };
|
||||
|
||||
// await handlers[msg.command.replace("_", "-")](msg);
|
||||
// }
|
||||
|
||||
// debug(msg) {
|
||||
// popUp(`deviceID`, { type: "markdown", content: `# ${deviceID}` });
|
||||
// alert(deviceID);
|
||||
// }
|
||||
|
||||
// set_theme(msg) {
|
||||
// if (!msg.theme) msg.theme = "default";
|
||||
// fireEvent("settheme", { theme: msg.theme }, ha_element());
|
||||
// }
|
||||
|
||||
// lovelace_reload(msg) {
|
||||
// const ll = lovelace_view();
|
||||
// if (ll) fireEvent("config-refresh", {}, ll);
|
||||
// }
|
||||
|
||||
// call_service(msg) {
|
||||
// const _replaceThis = (data) => {
|
||||
// if (data === "this") return deviceID;
|
||||
// if (Array.isArray(data)) return data.map(_replaceThis);
|
||||
// if (data.constructor == Object) {
|
||||
// for (const key in data) data[key] = _replaceThis(data[key]);
|
||||
// }
|
||||
// return data;
|
||||
// };
|
||||
// const [domain, service] = msg.service.split(".", 2);
|
||||
// let service_data = _replaceThis(
|
||||
// JSON.parse(JSON.stringify(msg.service_data))
|
||||
// );
|
||||
// this.hass.callService(domain, service, service_data);
|
||||
// }
|
||||
|
||||
// // update(msg = null) {
|
||||
// // if (msg) {
|
||||
// // if (msg.name) {
|
||||
// // this.entity_id = msg.name.toLowerCase();
|
||||
// // }
|
||||
// // if (msg.camera && !this.isFully) {
|
||||
// // this.setup_camera();
|
||||
// // }
|
||||
// // this.config = { ...this.config, ...msg };
|
||||
// // }
|
||||
// // this.player_update();
|
||||
// // this.fully_update();
|
||||
// // this.screen_update();
|
||||
// // this.sensor_update();
|
||||
// // }
|
||||
}
|
||||
|
||||
// (async () => {
|
||||
// await hass_loaded();
|
||||
|
||||
if (!window.browser_mod) window.browser_mod = new BrowserMod();
|
||||
// })();
|
||||
|
Loading…
x
Reference in New Issue
Block a user