diff --git a/README.md b/README.md index fec2e62..ebacb5c 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,16 @@ This binds the *aliases* `arrakis` to `99980b13-dabc9563` and `dashboard` to `d2 Note: Aliases must be unique. +### Prefix +You can add a custom prefix to all entity ids in `configuration.yaml`: + +E.g. to give entities default names like `media_player.browser_99980b13_dabc9563` add: +```yaml +browser_mod: + prefix: "browser_" +``` +This does not apply to devices with an alias. + ## Entities Once `browser_mod` is installed, loading up your Home Assistant frontend on a new *device* will create three to five new devices. @@ -185,6 +195,16 @@ will show the more-info dialog of `camera.front_door` on the *devices* `ded3b4dc The optional parameter `large: true` will make the popup wider. +### toast +``` +service: browser_mod.toast +service_data: + message: Short message +``` + +Display a toast notification on all devices. +The optional parameter `duration:` determines the time (in ms) that the toast is shown. Set to 0 for persistent display. Default is 3000. + ### popup ``` service: browser_mod.popup diff --git a/custom_components/browser_mod/__init__.py b/custom_components/browser_mod/__init__.py index 9b62ed0..b15ed59 100644 --- a/custom_components/browser_mod/__init__.py +++ b/custom_components/browser_mod/__init__.py @@ -22,7 +22,7 @@ async def async_setup(hass, config): DATA_DEVICES: {}, DATA_ALIASES: aliases, DATA_ADDERS: {}, - DATA_CONFIG: config[DOMAIN].get(CONFIG_DEVICES, {}), + DATA_CONFIG: config[DOMAIN], } await hass.helpers.discovery.async_load_platform("media_player", DOMAIN, {}, config) diff --git a/custom_components/browser_mod/browser_mod.js b/custom_components/browser_mod/browser_mod.js index 2722e5c..1c3c3f0 100644 --- a/custom_components/browser_mod/browser_mod.js +++ b/custom_components/browser_mod/browser_mod.js @@ -202,7 +202,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _car /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! /card-tools/deviceId */ \"../../../card-tools/deviceId.js\");\n/* harmony import */ var _card_tools_hass__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! /card-tools/hass */ \"../../../card-tools/hass.js\");\n/* harmony import */ var _card_tools_popup__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! /card-tools/popup */ \"../../../card-tools/popup.js\");\n/* harmony import */ var _card_tools_event__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! /card-tools/event */ \"../../../card-tools/event.js\");\n/* harmony import */ var _card_tools_more_info_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! /card-tools/more-info.js */ \"../../../card-tools/more-info.js\");\n/* harmony import */ var _browser_player__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./browser-player */ \"./js/browser-player.js\");\n\n\n\n\n\n\n\nclass BrowserMod {\n\n set hass(hass) {\n if(!hass) return;\n this._hass = hass;\n if(this.hassPatched) return;\n const callService = hass.callService;\n const newCallService = (domain, service, serviceData) => {\n if(serviceData && serviceData.deviceID) {\n if(Array.isArray(serviceData.deviceID)) {\n const index = serviceData.deviceID.indexOf('this');\n if(index !== -1)\n serviceData.deviceID[index] = _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"];\n } else if(serviceData.deviceID === \"this\") {\n serviceData.deviceID = _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"];\n }\n }\n return callService(domain, service, serviceData);\n };\n hass.callService = newCallService;\n\n this.hassPatched = true;\n document.querySelector(\"home-assistant\").hassChanged(hass, hass);\n }\n\n playOnce(ev) {\n if(this._video) this._video.play();\n if(window.browser_mod.playedOnce) return;\n window.browser_mod.player.play();\n window.browser_mod.playedOnce = true;\n }\n\n constructor() {\n window.setTimeout(_card_tools_hass__WEBPACK_IMPORTED_MODULE_1__[\"load_lovelace\"], 500);\n window.hassConnection.then((conn) => this.connect(conn.conn));\n this.player = new Audio();\n this.playedOnce = false;\n\n this.autoclose_popup_active = false;\n\n const updater = this.update.bind(this);\n this.player.addEventListener(\"ended\", updater);\n this.player.addEventListener(\"play\", updater);\n this.player.addEventListener(\"pause\", updater);\n this.player.addEventListener(\"volumechange\", updater);\n document.addEventListener(\"visibilitychange\", updater);\n window.addEventListener(\"location-changed\", updater);\n window.addEventListener(\"click\", this.playOnce);\n window.addEventListener(\"mousemove\", this.no_blackout.bind(this));\n window.addEventListener(\"mousedown\", this.no_blackout.bind(this));\n window.addEventListener(\"keydown\", this.no_blackout.bind(this));\n window.addEventListener(\"touchstart\", this.no_blackout.bind(this));\n Object(_card_tools_hass__WEBPACK_IMPORTED_MODULE_1__[\"provideHass\"])(this);\n\n if(window.fully)\n {\n this._fullyMotion = false;\n this._motionTimeout = undefined;\n fully.bind('screenOn', 'browser_mod.update();');\n fully.bind('screenOff', 'browser_mod.update();');\n fully.bind('pluggedAC', 'browser_mod.update();');\n fully.bind('pluggedUSB', 'browser_mod.update();');\n fully.bind('onBatteryLevelChanged', 'browser_mod.update();');\n fully.bind('unplugged', 'browser_mod.update();');\n fully.bind('networkReconnect', 'browser_mod.update();');\n\n fully.bind('onMotion', 'browser_mod.fullyMotion();');\n }\n\n this._screenSaver = undefined;\n this._screenSaverTimer = undefined;\n this._screenSaverTime = 0;\n this._blackout = document.createElement(\"div\");\n this._blackout.style.cssText = `\n position: fixed;\n left: 0;\n top: 0;\n padding: 0;\n margin: 0;\n width: 100%;\n height: 100%;\n background: black;\n visibility: hidden;\n `;\n document.body.appendChild(this._blackout);\n }\n\n connect(conn) {\n this.conn = conn\n conn.subscribeMessage((msg) => this.callback(msg), {\n type: 'browser_mod/connect',\n deviceID: _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"],\n });\n }\n\n callback(msg) {\n switch (msg.command) {\n case \"update\":\n this.update(msg);\n break;\n\n case \"debug\":\n this.debug(msg);\n break;\n\n case \"play\":\n this.play(msg);\n break;\n case \"pause\":\n this.pause(msg);\n break;\n case \"stop\":\n this.stop(msg);\n break;\n case \"set_volume\":\n this.set_volume(msg);\n break;\n case \"mute\":\n this.mute(msg);\n break;\n\n case \"popup\":\n this.popup(msg);\n break;\n case \"close-popup\":\n this.close_popup(msg);\n break;\n case \"navigate\":\n this.navigate(msg);\n break;\n case \"more-info\":\n this.more_info(msg);\n break;\n case \"set-theme\":\n this.set_theme(msg);\n break;\n\n case \"lovelace-reload\":\n this.lovelace_reload(msg);\n break;\n\n case \"blackout\":\n this.blackout(msg);\n break;\n case \"no-blackout\":\n this.no_blackout(msg);\n break;\n }\n }\n\n get player_state() {\n if (!this.player.src) return \"stopped\";\n if (this.player.ended) return \"stopped\";\n if (this.player.paused) return \"paused\";\n return \"playing\";\n }\n\n debug(msg) {\n Object(_card_tools_popup__WEBPACK_IMPORTED_MODULE_2__[\"popUp\"])(`deviceID`, {type: \"markdown\", content: `# ${_card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"]}`})\n alert(_card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"]);\n }\n\n _set_screensaver(fn, time) {\n clearTimeout(this._screenSaverTimer);\n if(!fn) {\n if(this._screenSaverTime)\n this._screenSaverTimer = setTimeout(this._screenSaver, this._screenSaverTime)\n } else {\n time = parseInt(time)\n if(time == -1) {\n clearTimeout(this._screenSaverTimer);\n this._screenSaverTime = 0;\n return;\n }\n this._screenSaverTime = time * 1000;\n this._screenSaver = fn;\n this._screenSaverTimer = setTimeout(this._screenSaver, this._screenSaverTime)\n }\n }\n\n play(msg) {\n const src = msg.media_content_id;\n if(src)\n this.player.src = src;\n this.player.play();\n }\n pause(msg) {\n this.player.pause();\n }\n stop(msg) {\n this.player.pause();\n this.player.src = null;\n }\n set_volume(msg) {\n if (msg.volume_level === undefined) return;\n this.player.volume = msg.volume_level;\n }\n mute(msg) {\n if (msg.mute === undefined)\n msg.mute = !this.player.muted;\n this.player.muted = Boolean(msg.mute)\n }\n\n popup(msg){\n if(!msg.title && !msg.auto_close) return;\n if(!msg.card) return;\n\n const fn = () => {\n Object(_card_tools_popup__WEBPACK_IMPORTED_MODULE_2__[\"popUp\"])(msg.title, msg.card, msg.large, msg.style, msg.auto_close);\n if(msg.auto_close)\n this.autoclose_popup_active = true;\n };\n\n if(msg.auto_close && msg.time) {\n this._set_screensaver(fn, msg.time);\n } else {\n // closePopUp();\n fn();\n }\n }\n close_popup(msg){\n this._set_screensaver();\n this.autoclose_popup_active = false;\n Object(_card_tools_popup__WEBPACK_IMPORTED_MODULE_2__[\"closePopUp\"])();\n }\n navigate(msg){\n if(!msg.navigation_path) return;\n history.pushState(null, \"\", msg.navigation_path);\n Object(_card_tools_event__WEBPACK_IMPORTED_MODULE_3__[\"fireEvent\"])(\"location-changed\", {}, document.querySelector(\"home-assistant\"));\n }\n more_info(msg){\n if(!msg.entity_id) return;\n Object(_card_tools_more_info_js__WEBPACK_IMPORTED_MODULE_4__[\"moreInfo\"])(msg.entity_id, msg.large);\n }\n set_theme(msg){\n if(!msg.theme) msg.theme = \"default\";\n Object(_card_tools_event__WEBPACK_IMPORTED_MODULE_3__[\"fireEvent\"])(\"settheme\", msg.theme, document.querySelector(\"home-assistant\"));\n }\n\n lovelace_reload(msg) {\n const ll = Object(_card_tools_hass__WEBPACK_IMPORTED_MODULE_1__[\"lovelace_view\"])();\n if (ll)\n Object(_card_tools_event__WEBPACK_IMPORTED_MODULE_3__[\"fireEvent\"])(\"config-refresh\", {}, ll);\n }\n\n blackout(msg){\n const fn = () => {\n if (window.fully)\n {\n fully.turnScreenOff();\n } else {\n this._blackout.style.visibility = \"visible\";\n }\n this.update();\n };\n if(msg.time) {\n this._set_screensaver(fn, msg.time)\n } else {\n fn();\n }\n }\n no_blackout(msg){\n this._set_screensaver();\n if(this.autoclose_popup_active)\n return this.close_popup();\n if (window.fully)\n {\n if (!fully.getScreenOn())\n fully.turnScreenOn();\n if (msg.brightness)\n fully.setScreenBrightness(msg.brightness);\n this.update();\n } else {\n if(this._blackout.style.visibility !== \"hidden\") {\n this._blackout.style.visibility = \"hidden\";\n this.update();\n }\n }\n }\n is_blackout(){\n if (window.fully)\n return !fully.getScreenOn();\n return Boolean(this._blackout.style.visibility === \"visible\")\n }\n\n fullyMotion() {\n this._fullyMotion = true;\n clearTimeout(this._motionTimeout);\n this._motionTimeout = setTimeout(() => {\n this._fullyMotion = false;\n this.update();\n }, 5000);\n this.update();\n }\n\n\n start_camera() {\n if(this._video) return;\n this._video = document.createElement(\"video\");\n this._video.autoplay = true;\n this._video.playsInline = true;\n this._video.style.cssText = `\n visibility: hidden;\n width: 0;\n height: 0;\n `;\n this._canvas = document.createElement(\"canvas\");\n this._canvas.style.cssText = `\n visibility: hidden;\n width: 0;\n height: 0;\n `;\n document.body.appendChild(this._canvas);\n document.body.appendChild(this._video);\n navigator.mediaDevices.getUserMedia({video: true, audio: false}).then((stream) => {\n this._video.srcObject = stream;\n this._video.play();\n this.send_cam();\n });\n }\n\n send_cam(data) {\n const context = this._canvas.getContext('2d');\n context.drawImage(this._video, 0, 0, this._canvas.width, this._canvas.height);\n this.conn.sendMessage({\n type: 'browser_mod/update',\n deviceID: _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"],\n data: {\n camera: this._canvas.toDataURL('image/png'),\n },\n });\n setTimeout(this.send_cam.bind(this), 5000);\n }\n\n\n update(msg=null) {\n if(!this.conn) return;\n\n if(msg) {\n if(msg.entity_id) {\n this.entity_id = msg.entity_id;\n }\n if(msg.camera) {\n this.start_camera();\n }\n }\n\n\n this.conn.sendMessage({\n type: 'browser_mod/update',\n deviceID: _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"],\n data: {\n browser: {\n path: window.location.pathname,\n visibility: document.visibilityState,\n userAgent: navigator.userAgent,\n currentUser: this._hass && this._hass.user && this._hass.user.name,\n fullyKiosk: window.fully ? true : undefined,\n width: window.innerWidth,\n height: window.innerHeight,\n },\n player: {\n volume: this.player.volume,\n muted: this.player.muted,\n src: this.player.src,\n state: this.player_state,\n },\n screen: {\n blackout: this.is_blackout(),\n brightness: window.fully ? fully.getScreenBrightness() : undefined,\n },\n fully: window.fully ? {\n battery: window.fully ? fully.getBatteryLevel() : undefined,\n charging: window.fully ? fully.isPlugged(): undefined,\n motion: window.fully ? this._fullyMotion : undefined,\n } : undefined,\n },\n });\n\n }\n\n}\n\nwindow.browser_mod = new BrowserMod();\n\n\n//# sourceURL=webpack:///./js/main.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! /card-tools/deviceId */ \"../../../card-tools/deviceId.js\");\n/* harmony import */ var _card_tools_hass__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! /card-tools/hass */ \"../../../card-tools/hass.js\");\n/* harmony import */ var _card_tools_popup__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! /card-tools/popup */ \"../../../card-tools/popup.js\");\n/* harmony import */ var _card_tools_event__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! /card-tools/event */ \"../../../card-tools/event.js\");\n/* harmony import */ var _card_tools_more_info_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! /card-tools/more-info.js */ \"../../../card-tools/more-info.js\");\n/* harmony import */ var _browser_player__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./browser-player */ \"./js/browser-player.js\");\n\n\n\n\n\n\n\nclass BrowserMod {\n\n set hass(hass) {\n if(!hass) return;\n this._hass = hass;\n if(this.hassPatched) return;\n const callService = hass.callService;\n const newCallService = (domain, service, serviceData) => {\n if(serviceData && serviceData.deviceID) {\n if(Array.isArray(serviceData.deviceID)) {\n const index = serviceData.deviceID.indexOf('this');\n if(index !== -1)\n serviceData.deviceID[index] = _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"];\n } else if(serviceData.deviceID === \"this\") {\n serviceData.deviceID = _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"];\n }\n }\n return callService(domain, service, serviceData);\n };\n hass.callService = newCallService;\n\n this.hassPatched = true;\n document.querySelector(\"home-assistant\").hassChanged(hass, hass);\n }\n\n playOnce(ev) {\n if(this._video) this._video.play();\n if(window.browser_mod.playedOnce) return;\n window.browser_mod.player.play();\n window.browser_mod.playedOnce = true;\n }\n\n constructor() {\n window.setTimeout(_card_tools_hass__WEBPACK_IMPORTED_MODULE_1__[\"load_lovelace\"], 500);\n window.hassConnection.then((conn) => this.connect(conn.conn));\n this.player = new Audio();\n this.playedOnce = false;\n\n this.autoclose_popup_active = false;\n\n const updater = this.update.bind(this);\n this.player.addEventListener(\"ended\", updater);\n this.player.addEventListener(\"play\", updater);\n this.player.addEventListener(\"pause\", updater);\n this.player.addEventListener(\"volumechange\", updater);\n document.addEventListener(\"visibilitychange\", updater);\n window.addEventListener(\"location-changed\", updater);\n window.addEventListener(\"click\", this.playOnce);\n window.addEventListener(\"mousemove\", this.no_blackout.bind(this));\n window.addEventListener(\"mousedown\", this.no_blackout.bind(this));\n window.addEventListener(\"keydown\", this.no_blackout.bind(this));\n window.addEventListener(\"touchstart\", this.no_blackout.bind(this));\n Object(_card_tools_hass__WEBPACK_IMPORTED_MODULE_1__[\"provideHass\"])(this);\n\n if(window.fully)\n {\n this._fullyMotion = false;\n this._motionTimeout = undefined;\n fully.bind('screenOn', 'browser_mod.update();');\n fully.bind('screenOff', 'browser_mod.update();');\n fully.bind('pluggedAC', 'browser_mod.update();');\n fully.bind('pluggedUSB', 'browser_mod.update();');\n fully.bind('onBatteryLevelChanged', 'browser_mod.update();');\n fully.bind('unplugged', 'browser_mod.update();');\n fully.bind('networkReconnect', 'browser_mod.update();');\n\n fully.bind('onMotion', 'browser_mod.fullyMotion();');\n }\n\n this._screenSaver = undefined;\n this._screenSaverTimer = undefined;\n this._screenSaverTime = 0;\n this._blackout = document.createElement(\"div\");\n this._blackout.style.cssText = `\n position: fixed;\n left: 0;\n top: 0;\n padding: 0;\n margin: 0;\n width: 100%;\n height: 100%;\n background: black;\n visibility: hidden;\n `;\n document.body.appendChild(this._blackout);\n }\n\n connect(conn) {\n this.conn = conn\n conn.subscribeMessage((msg) => this.callback(msg), {\n type: 'browser_mod/connect',\n deviceID: _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"],\n });\n }\n\n callback(msg) {\n switch (msg.command) {\n case \"update\":\n this.update(msg);\n break;\n\n case \"debug\":\n this.debug(msg);\n break;\n\n case \"play\":\n this.play(msg);\n break;\n case \"pause\":\n this.pause(msg);\n break;\n case \"stop\":\n this.stop(msg);\n break;\n case \"set_volume\":\n this.set_volume(msg);\n break;\n case \"mute\":\n this.mute(msg);\n break;\n\n case \"toast\":\n this.toast(msg);\n break;\n case \"popup\":\n this.popup(msg);\n break;\n case \"close-popup\":\n this.close_popup(msg);\n break;\n case \"navigate\":\n this.navigate(msg);\n break;\n case \"more-info\":\n this.more_info(msg);\n break;\n case \"set-theme\":\n this.set_theme(msg);\n break;\n\n case \"lovelace-reload\":\n this.lovelace_reload(msg);\n break;\n\n case \"blackout\":\n this.blackout(msg);\n break;\n case \"no-blackout\":\n this.no_blackout(msg);\n break;\n }\n }\n\n get player_state() {\n if (!this.player.src) return \"stopped\";\n if (this.player.ended) return \"stopped\";\n if (this.player.paused) return \"paused\";\n return \"playing\";\n }\n\n debug(msg) {\n Object(_card_tools_popup__WEBPACK_IMPORTED_MODULE_2__[\"popUp\"])(`deviceID`, {type: \"markdown\", content: `# ${_card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"]}`})\n alert(_card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"]);\n }\n\n _set_screensaver(fn, time) {\n clearTimeout(this._screenSaverTimer);\n if(!fn) {\n if(this._screenSaverTime)\n this._screenSaverTimer = setTimeout(this._screenSaver, this._screenSaverTime)\n } else {\n time = parseInt(time)\n if(time == -1) {\n clearTimeout(this._screenSaverTimer);\n this._screenSaverTime = 0;\n return;\n }\n this._screenSaverTime = time * 1000;\n this._screenSaver = fn;\n this._screenSaverTimer = setTimeout(this._screenSaver, this._screenSaverTime)\n }\n }\n\n play(msg) {\n const src = msg.media_content_id;\n if(src)\n this.player.src = src;\n this.player.play();\n }\n pause(msg) {\n this.player.pause();\n }\n stop(msg) {\n this.player.pause();\n this.player.src = null;\n }\n set_volume(msg) {\n if (msg.volume_level === undefined) return;\n this.player.volume = msg.volume_level;\n }\n mute(msg) {\n if (msg.mute === undefined)\n msg.mute = !this.player.muted;\n this.player.muted = Boolean(msg.mute)\n }\n\n toast(msg) {\n if(!msg.message) return;\n\n Object(_card_tools_event__WEBPACK_IMPORTED_MODULE_3__[\"fireEvent\"])(\"hass-notification\", {\n message: msg.message,\n duration: msg.duration !== undefined ? parseInt(msg.duration) : undefined\n }, document.querySelector(\"home-assistant\"));\n }\n\n popup(msg){\n if(!msg.title && !msg.auto_close) return;\n if(!msg.card) return;\n\n const fn = () => {\n Object(_card_tools_popup__WEBPACK_IMPORTED_MODULE_2__[\"popUp\"])(msg.title, msg.card, msg.large, msg.style, msg.auto_close);\n if(msg.auto_close)\n this.autoclose_popup_active = true;\n };\n\n if(msg.auto_close && msg.time) {\n this._set_screensaver(fn, msg.time);\n } else {\n // closePopUp();\n fn();\n }\n }\n close_popup(msg){\n this._set_screensaver();\n this.autoclose_popup_active = false;\n Object(_card_tools_popup__WEBPACK_IMPORTED_MODULE_2__[\"closePopUp\"])();\n }\n navigate(msg){\n if(!msg.navigation_path) return;\n history.pushState(null, \"\", msg.navigation_path);\n Object(_card_tools_event__WEBPACK_IMPORTED_MODULE_3__[\"fireEvent\"])(\"location-changed\", {}, document.querySelector(\"home-assistant\"));\n }\n more_info(msg){\n if(!msg.entity_id) return;\n Object(_card_tools_more_info_js__WEBPACK_IMPORTED_MODULE_4__[\"moreInfo\"])(msg.entity_id, msg.large);\n }\n set_theme(msg){\n if(!msg.theme) msg.theme = \"default\";\n Object(_card_tools_event__WEBPACK_IMPORTED_MODULE_3__[\"fireEvent\"])(\"settheme\", msg.theme, document.querySelector(\"home-assistant\"));\n }\n\n lovelace_reload(msg) {\n const ll = Object(_card_tools_hass__WEBPACK_IMPORTED_MODULE_1__[\"lovelace_view\"])();\n if (ll)\n Object(_card_tools_event__WEBPACK_IMPORTED_MODULE_3__[\"fireEvent\"])(\"config-refresh\", {}, ll);\n }\n\n blackout(msg){\n const fn = () => {\n if (window.fully)\n {\n fully.turnScreenOff();\n } else {\n this._blackout.style.visibility = \"visible\";\n }\n this.update();\n };\n if(msg.time) {\n this._set_screensaver(fn, msg.time)\n } else {\n fn();\n }\n }\n no_blackout(msg){\n this._set_screensaver();\n if(this.autoclose_popup_active)\n return this.close_popup();\n if (window.fully)\n {\n if (!fully.getScreenOn())\n fully.turnScreenOn();\n if (msg.brightness)\n fully.setScreenBrightness(msg.brightness);\n this.update();\n } else {\n if(this._blackout.style.visibility !== \"hidden\") {\n this._blackout.style.visibility = \"hidden\";\n this.update();\n }\n }\n }\n is_blackout(){\n if (window.fully)\n return !fully.getScreenOn();\n return Boolean(this._blackout.style.visibility === \"visible\")\n }\n\n fullyMotion() {\n this._fullyMotion = true;\n clearTimeout(this._motionTimeout);\n this._motionTimeout = setTimeout(() => {\n this._fullyMotion = false;\n this.update();\n }, 5000);\n this.update();\n }\n\n\n start_camera() {\n if(this._video) return;\n this._video = document.createElement(\"video\");\n this._video.autoplay = true;\n this._video.playsInline = true;\n this._video.style.cssText = `\n visibility: hidden;\n width: 0;\n height: 0;\n `;\n this._canvas = document.createElement(\"canvas\");\n this._canvas.style.cssText = `\n visibility: hidden;\n width: 0;\n height: 0;\n `;\n document.body.appendChild(this._canvas);\n document.body.appendChild(this._video);\n navigator.mediaDevices.getUserMedia({video: true, audio: false}).then((stream) => {\n this._video.srcObject = stream;\n this._video.play();\n this.send_cam();\n });\n }\n\n send_cam(data) {\n const context = this._canvas.getContext('2d');\n context.drawImage(this._video, 0, 0, this._canvas.width, this._canvas.height);\n this.conn.sendMessage({\n type: 'browser_mod/update',\n deviceID: _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"],\n data: {\n camera: this._canvas.toDataURL('image/png'),\n },\n });\n setTimeout(this.send_cam.bind(this), 5000);\n }\n\n\n update(msg=null) {\n if(!this.conn) return;\n\n if(msg) {\n if(msg.entity_id) {\n this.entity_id = msg.entity_id;\n }\n if(msg.camera) {\n this.start_camera();\n }\n }\n\n\n this.conn.sendMessage({\n type: 'browser_mod/update',\n deviceID: _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"],\n data: {\n browser: {\n path: window.location.pathname,\n visibility: document.visibilityState,\n userAgent: navigator.userAgent,\n currentUser: this._hass && this._hass.user && this._hass.user.name,\n fullyKiosk: window.fully ? true : undefined,\n width: window.innerWidth,\n height: window.innerHeight,\n },\n player: {\n volume: this.player.volume,\n muted: this.player.muted,\n src: this.player.src,\n state: this.player_state,\n },\n screen: {\n blackout: this.is_blackout(),\n brightness: window.fully ? fully.getScreenBrightness() : undefined,\n },\n fully: window.fully ? {\n battery: window.fully ? fully.getBatteryLevel() : undefined,\n charging: window.fully ? fully.isPlugged(): undefined,\n motion: window.fully ? this._fullyMotion : undefined,\n } : undefined,\n },\n });\n\n }\n\n}\n\nwindow.browser_mod = new BrowserMod();\n\n\n//# sourceURL=webpack:///./js/main.js?"); /***/ }) diff --git a/custom_components/browser_mod/const.py b/custom_components/browser_mod/const.py index 2655fcf..95c0897 100644 --- a/custom_components/browser_mod/const.py +++ b/custom_components/browser_mod/const.py @@ -10,6 +10,7 @@ DATA_ADDERS = "adders" DATA_CONFIG = "config" CONFIG_DEVICES = "devices" +CONFIG_PREFIX = "prefix" WS_ROOT = DOMAIN WS_CONNECT = "{}/connect".format(WS_ROOT) @@ -26,4 +27,5 @@ USER_COMMANDS = [ "lovelace-reload", "blackout", "no-blackout", + "toast", ] diff --git a/custom_components/browser_mod/helpers.py b/custom_components/browser_mod/helpers.py index 3bda4e6..5c30a2e 100644 --- a/custom_components/browser_mod/helpers.py +++ b/custom_components/browser_mod/helpers.py @@ -2,7 +2,7 @@ import logging from homeassistant.helpers.entity import Entity, async_generate_entity_id -from .const import DOMAIN, DATA_DEVICES, DATA_ALIASES, DATA_ADDERS, CONFIG_DEVICES, DATA_CONFIG +from .const import DOMAIN, DATA_DEVICES, DATA_ALIASES, DATA_ADDERS, CONFIG_DEVICES, DATA_CONFIG, CONFIG_PREFIX _LOGGER = logging.getLogger(__name__) @@ -16,7 +16,7 @@ def get_alias(hass, deviceID): return None def get_config(hass, deviceID): - config = hass.data[DOMAIN][DATA_CONFIG] + config = hass.data[DOMAIN][DATA_CONFIG].get(CONFIG_DEVICES, {}) return config.get(deviceID, config.get(deviceID.replace('-','_'), {})) def create_entity(hass, platform, deviceID, connection): @@ -39,7 +39,8 @@ class BrowserModEntity(Entity): self.connection = connection self.deviceID = deviceID self._data = {} - self.entity_id = async_generate_entity_id(self.domain+".{}", alias or deviceID, hass=hass) + prefix = hass.data[DOMAIN][DATA_CONFIG].get(CONFIG_PREFIX, '') + self.entity_id = async_generate_entity_id(self.domain+".{}", alias or f"{prefix}{deviceID}", hass=hass) def updated(self): pass diff --git a/js/main.js b/js/main.js index e04dd48..06e3185 100644 --- a/js/main.js +++ b/js/main.js @@ -126,6 +126,9 @@ class BrowserMod { this.mute(msg); break; + case "toast": + this.toast(msg); + break; case "popup": this.popup(msg); break; @@ -208,6 +211,15 @@ class BrowserMod { this.player.muted = Boolean(msg.mute) } + toast(msg) { + if(!msg.message) return; + + fireEvent("hass-notification", { + message: msg.message, + duration: msg.duration !== undefined ? parseInt(msg.duration) : undefined + }, document.querySelector("home-assistant")); + } + popup(msg){ if(!msg.title && !msg.auto_close) return; if(!msg.card) return;