From 613656a96477b8d9d633891c2db838d110a61628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Tue, 1 Oct 2019 21:40:20 +0200 Subject: [PATCH] Update readme and allow popups from popups --- README.md | 62 +++-- custom_components/browser_mod/browser_mod.js | 259 ++++--------------- js/main.js | 1 + 3 files changed, 83 insertions(+), 239 deletions(-) diff --git a/README.md b/README.md index 2df2ecc..fec2e62 100644 --- a/README.md +++ b/README.md @@ -129,32 +129,30 @@ Be aware that keeping the camera on may make your device run hot and drain your The `binary_sensor` will only be available for Fully Kiosk Browser PRO *devices*. It's state will be the state of the camera motion detector of the *device* (5 second cooldown). -## `browser_mod.command` service +## Services -Call the `browser_mod.command` service to control your *device* in various ways. +`browser_mod` registers a number of services. -All service calls have two parameters in common, `command` which is the command to execute, and `deviceID` which is a list of *devices* to execute the command on. If `deviceID` is omitted, the command will be executed on **all** currently connected *devices*. `deviceID` may also contain aliases. +All service calls have one parameter in common; `deviceID` which is a list of *devices* to execute the comand on. If `deviceID` is omitted, the command will be executed on **all** currenctly connected *devices*. `deviceID` may also contain aliases. -There is a special function that will replace the special alias `this` with the current deviceID in the list `deviceID` for any service call from the frontend. In the examples below it will be shown used for the `browser_mod.command` service, but it also works e.g for calling scripts from the frontend. +If a service is called from the frontend (e.g. by using the `call-service` tap action), a value of `this` in the `deviceID` list will be replaced with the ID of the *device* the call was made from. +Alternatively, `deviceID: this` will also work. All examples below are given in the syntax used for calling them from lovelace via e.g. an entity-button card with `tap_action:` set to `call-service`. If you call the service from a script or an automation, the syntax will be slightly different. ### debug ``` -service: browser_mod.command -service_data: - command: debug +service: browser_mod.debug ``` Display a popup with the deviceID *and* a javascript alert with the deviceID on all connected *devices*. -### set-theme +### set_theme ``` -service: browser_mod.command +service: browser_mod.set_theme service_data: - command: set-theme theme: clear_light ``` @@ -162,9 +160,8 @@ will set the current theme to `clear_light` on all devices. ### navigate ``` -service: browser_mod.command +service: browser_mod.navigate service_data: - command: navigate navigation_path: /lovelace/1 deviceID: - ded3b4dc-abedd098 @@ -174,11 +171,10 @@ will open your second lovelace view on just the *device* `ded3b4dc-abedd098`. Note: `navigation_path` does not have to be a lovelace path. All paths in Home Assistant works. (E.g. `/states`, `/dev-info`, `/map`) -### more-info +### more_info ``` -service: browser_mod.command +service: browser_mod.more_info service_data: - command: more-info entity_id: camera.front_door deviceID: - ded3b4dc-abedd098 @@ -191,9 +187,8 @@ The optional parameter `large: true` will make the popup wider. ### popup ``` -service: browser_mod.command +service: browser_mod.popup service_data: - command: popup title: Popup example card: type: entities @@ -203,9 +198,10 @@ service_data: - light.ceiling_lights deviceID: - this + - dashboard ``` -will display the specified `entities` card as a popup on the current device. +will display the specified `entities` card as a popup on the current device and on `dashboard` ![popup-example](https://user-images.githubusercontent.com/1299821/60288984-a7cb6b00-9915-11e9-9322-324323a9ec6e.png) @@ -224,44 +220,38 @@ Ex: Note: Sometimes this doesn't work if the *device* is not currently displaying a lovelace path. I'm looking into that... -### close-popup +### close_popup ``` -service: browser_mod.command -service_data: - command: close-popup +service: browser_mod.close_popup ``` will close all more-info dialogs and popups that are open on all connected *devices*. ### blackout ``` -service: browser_mod.command +service: browser_mod.blackout service_data: - command: blackout + deviceID: this ``` -Will cover the entire window (or screen if in full screen mode) with black. +Will cover the entire window (or screen if in full screen mode) with black on the current device. Moving the mouse, touching the screen or pressing any key will restore the view. The optional parameter `time:` will make the blackout turn on automatically after the specified number of seconds. It works kind of like a screensaver and will keep turning on until `blackout` is called again with `time: -1`. Note: This will *not* turn off your screen backlight. Most screens will still emit light in a dark room. -### no-blackout +### no_blackout ``` -service: browser_mod.command -service_data: - command: no-blackout +service: browser_mod.no_blackout ``` Remove a blackout. The optional parameter `brightness` will set the screen brightness of a device running Fully Kiosk Browser to a value between 0 and 255. -### lovelace-reload +### lovelace_reload ``` -service: browser_mod.command -service_data: - command: lovelace-reload +service: browser_mod.lovelace_reload ``` Refreshes the lovelace config. Same as clicking "Refresh" in the top right menu in lovelace. @@ -284,6 +274,8 @@ The player card also displays the `entityID`. Click it to select, so you can cop # Fully Kiosk Browser If you are using a device running [Fully Kiosk Browser](https://www.ozerov.de/fully-kiosk-browser/) (PLUS version only) you will have access to a few more functions. +For this to work you need to activate `Settings->Advanced Web Settings->Javascript Interface (PLUS)` and `Settings->Motion Detection (PLUS)->Enable Visual Motion Detection`. + First of all the commands `blackout` and `no-blackout` will control the devices screen directly. `no-blackout` also has an optional parameter `brightness` that can set the screen brightness between 0 and 255. @@ -331,5 +323,9 @@ Some of [my lovelace plugins](https://github.com/thomasloven/hass-config/wiki/My `/dev-service` requires json-formatted service data. There's an explanation on the differences between yaml and json [here](http://thomasloven.com/blog/2018/08/YAML-For-Nonprogrammers/). +### How do I run commands from a script/automation? + +Basically, just replace `service_data` with `data` or `data_template`, whichever fits your needs. + --- Buy Me A Coffee diff --git a/custom_components/browser_mod/browser_mod.js b/custom_components/browser_mod/browser_mod.js index 7d9f2e0..90b0c66 100644 --- a/custom_components/browser_mod/browser_mod.js +++ b/custom_components/browser_mod/browser_mod.js @@ -1,209 +1,56 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = "./js/main.js"); -/******/ }) -/************************************************************************/ -/******/ ({ +!function(e){var t={};function i(s){if(t[s])return t[s].exports;var o=t[s]={i:s,l:!1,exports:{}};return e[s].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=e,i.c=t,i.d=function(e,t,s){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(i.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)i.d(s,o,function(t){return e[t]}.bind(null,o));return s},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=0)}([function(e,t,i){"use strict";i.r(t);let s=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${e()}${e()}-${e()}${e()}`}return localStorage["lovelace-player-device-id"]}();function o(){return document.querySelector("home-assistant").hass}function n(e){return document.querySelector("home-assistant").provideHass(e)}function a(){if(customElements.get("hui-view"))return!0;const e=document.createElement("partial-panel-resolver");e.hass=o(),e.route={path:"/lovelace/"};try{document.querySelector("home-assistant").appendChild(e).catch(e=>{})}catch(t){document.querySelector("home-assistant").removeChild(e)}return!!customElements.get("hui-view")}function r(e,t,i=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},i)i.dispatchEvent(e);else{var s=document.querySelector("home-assistant");(s=(s=(s=(s=(s=(s=(s=(s=(s=(s=(s=s&&s.shadowRoot)&&s.querySelector("home-assistant-main"))&&s.shadowRoot)&&s.querySelector("app-drawer-layout partial-panel-resolver"))&&s.shadowRoot||s)&&s.querySelector("ha-panel-lovelace"))&&s.shadowRoot)&&s.querySelector("hui-root"))&&s.shadowRoot)&&s.querySelector("ha-app-layout #view"))&&s.firstElementChild)&&s.dispatchEvent(e)}}const l="custom:";function c(e,t){const i=document.createElement("hui-error-card");return i.setConfig({type:"error",error:e,config:t}),i}function d(e,t){if(!t||"object"!=typeof t||!t.type)return c(`No ${e} type configured`,t);let i=t.type;if(i=i.startsWith(l)?i.substr(l.length):`hui-${i}-${e}`,customElements.get(i))return function(e,t){const i=document.createElement(e);try{i.setConfig(t)}catch(e){return c(e,t)}return i}(i,t);const s=c(`Custom element doesn't exist: ${i}.`,t);s.style.display="None";const o=setTimeout(()=>{s.style.display=""},2e3);return customElements.whenDefined(i).then(()=>{clearTimeout(o),r("ll-rebuild",{},s)}),s}function u(e,t=!1){r("hass-more-info",{entityId:e},document.querySelector("home-assistant"));const i=document.querySelector("home-assistant")._moreInfoEl;return i.large=t,i}const h=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),p=h.prototype.html,m=h.prototype.css;class y extends h{static get properties(){return{hass:{},config:{}}}setConfig(e){this._config=e,this.el?this.el.setConfig(e):this.el=this.create(e),this._hass&&(this.el.hass=this._hass),this.noHass&&n(this)}set config(e){this.setConfig(e)}set hass(e){this._hass=e,this.el&&(this.el.hass=e)}createRenderRoot(){return this}render(){return p`${this.el}`}}if(!customElements.get("card-maker")){class e extends y{create(e){return function(e){return d("card",e)}(e)}}customElements.define("card-maker",e)}if(!customElements.get("element-maker")){class e extends y{create(e){return function(e){return d("element",e)}(e)}}customElements.define("element-maker",e)}if(!customElements.get("entity-row-maker")){class e extends y{create(e){return function(e){const t=new Set(["call-service","divider","section","weblink"]);if(!e)return c("Invalid configuration given.",e);if("string"==typeof e&&(e={entity:e}),"object"!=typeof e||!e.entity&&!e.type)return c("Invalid configuration given.",e);const i=e.type||"default";if(t.has(i)||i.startsWith(l))return d("row",e);const s=e.entity.split(".",1)[0];return Object.assign(e,{type:{alert:"toggle",automation:"toggle",climate:"climate",cover:"cover",fan:"toggle",group:"group",input_boolean:"toggle",input_number:"input-number",input_select:"input-select",input_text:"input-text",light:"toggle",lock:"lock",media_player:"media-player",remote:"toggle",scene:"scene",script:"script",sensor:"sensor",timer:"timer",switch:"toggle",vacuum:"toggle",water_heater:"climate",input_datetime:"input-datetime"}[s]||"text"}),d("entity-row",e)}(e)}}customElements.define("entity-row-maker",e)}function v(e,t,i=!1,s=null,n=!1){u(Object.keys(o().states)[0]);const a=document.createElement("card-maker");a.noHass=!0,a.config=t;const r=document.createElement("div");r.innerHTML="\n \n ";const l=document.createElement("app-toolbar");l.innerHTML=`\n \n
\n ${e}\n
\n `;const c=document.createElement("div");c.classList.add("scrollable"),c.appendChild(a),n||r.appendChild(l),r.appendChild(c);const d=document.querySelector("home-assistant")._moreInfoEl;d._closer&&d._closer(),d.sizingTarget=c,d.large=i,d._page="none",d.shadowRoot.appendChild(r);let h={};if(s)for(var p in s)h[p]=d.style[p],d.style.setProperty(p,s[p]);return d._closer=function(){for(var e in r.parentNode.removeChild(r),h)h[e]?d.style.setProperty(e,h[e]):d.style.removeProperty(e);d._closer=null},setTimeout(()=>{let e=setInterval(()=>{d.getAttribute("aria-hidden")&&(clearInterval(e),d._closer&&d._closer())},100)},1e3),d}customElements.define("browser-player",class extends h{static get properties(){return{hass:{}}}setConfig(e){this._config=e}handleMute(e){window.browser_mod.mute({})}handleVolumeChange(e){const t=parseFloat(e.target.value);window.browser_mod.set_volume({volume_level:t})}handleMoreInfo(e){u(window.browser_mod.entity_id)}handlePlayPause(e){window.browser_mod.player.paused?window.browser_mod.play({}):window.browser_mod.pause({})}render(){const e=window.browser_mod.player;return p` + +
+ + -/***/ "../../../card-tools/card-maker.js": -/*!*********************************!*\ - !*** /card-tools/card-maker.js ***! - \*********************************/ -/*! no exports provided */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + ${"stopped"===window.browser_mod.player_state?p`
`:p` + + `} + +
-"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _lit_element_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lit-element.js */ \"../../../card-tools/lit-element.js\");\n/* harmony import */ var _lovelace_element_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lovelace-element.js */ \"../../../card-tools/lovelace-element.js\");\n/* harmony import */ var _hass_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./hass.js */ \"../../../card-tools/hass.js\");\n\n\n\n\nclass ThingMaker extends _lit_element_js__WEBPACK_IMPORTED_MODULE_0__[\"LitElement\"] {\n static get properties() {\n return {\n 'hass': {},\n 'config': {},\n };\n }\n setConfig(config) {\n this._config = config;\n if(!this.el)\n this.el = this.create(config);\n else\n this.el.setConfig(config);\n if(this._hass) this.el.hass = this._hass;\n if(this.noHass) Object(_hass_js__WEBPACK_IMPORTED_MODULE_2__[\"provideHass\"])(this);\n }\n set config(config) {\n this.setConfig(config);\n }\n set hass(hass) {\n this._hass = hass;\n if(this.el) this.el.hass = hass;\n }\n\n createRenderRoot() {\n return this;\n }\n render() {\n return _lit_element_js__WEBPACK_IMPORTED_MODULE_0__[\"html\"]`${this.el}`;\n }\n}\n\nif(!customElements.get(\"card-maker\")) {\n class CardMaker extends ThingMaker {\n create(config) {\n return Object(_lovelace_element_js__WEBPACK_IMPORTED_MODULE_1__[\"createCard\"])(config);\n }\n }\n customElements.define(\"card-maker\", CardMaker);\n}\n\nif(!customElements.get(\"element-maker\")) {\n class ElementMaker extends ThingMaker {\n create(config) {\n return Object(_lovelace_element_js__WEBPACK_IMPORTED_MODULE_1__[\"createElement\"])(config);\n }\n }\n customElements.define(\"element-maker\", ElementMaker);\n}\n\nif(!customElements.get(\"entity-row-maker\")) {\n class EntityRowMaker extends ThingMaker {\n create(config) {\n return Object(_lovelace_element_js__WEBPACK_IMPORTED_MODULE_1__[\"createEntityRow\"])(config);\n }\n }\n customElements.define(\"entity-row-maker\", EntityRowMaker);\n}\n\n\n//# sourceURL=webpack:////card-tools/card-maker.js?"); +
+ ${s} +
-/***/ }), - -/***/ "../../../card-tools/deviceId.js": -/*!*******************************!*\ - !*** /card-tools/deviceId.js ***! - \*******************************/ -/*! exports provided: deviceID */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"deviceID\", function() { return deviceID; });\nfunction _deviceID() {\n const ID_STORAGE_KEY = 'lovelace-player-device-id';\n if(window['fully'] && typeof fully.getDeviceId === \"function\")\n return fully.getDeviceId();\n if(!localStorage[ID_STORAGE_KEY])\n {\n const s4 = () => {\n return Math.floor((1+Math.random())*100000).toString(16).substring(1);\n }\n localStorage[ID_STORAGE_KEY] = `${s4()}${s4()}-${s4()}${s4()}`;\n }\n return localStorage[ID_STORAGE_KEY];\n};\n\nlet deviceID = _deviceID();\n\n\n//# sourceURL=webpack:////card-tools/deviceId.js?"); - -/***/ }), - -/***/ "../../../card-tools/event.js": -/*!****************************!*\ - !*** /card-tools/event.js ***! - \****************************/ -/*! exports provided: fireEvent */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"fireEvent\", function() { return fireEvent; });\nfunction fireEvent(ev, detail, entity=null) {\n ev = new Event(ev, {\n bubbles: true,\n cancelable: false,\n composed: true,\n });\n ev.detail = detail || {};\n if(entity) {\n entity.dispatchEvent(ev);\n } else {\n var root = document.querySelector(\"home-assistant\");\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"home-assistant-main\");\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"app-drawer-layout partial-panel-resolver\");\n root = root && root.shadowRoot || root;\n root = root && root.querySelector(\"ha-panel-lovelace\");\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"hui-root\");\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"ha-app-layout #view\");\n root = root && root.firstElementChild;\n if (root) root.dispatchEvent(ev);\n }\n}\n\n\n//# sourceURL=webpack:////card-tools/event.js?"); - -/***/ }), - -/***/ "../../../card-tools/hass.js": -/*!***************************!*\ - !*** /card-tools/hass.js ***! - \***************************/ -/*! exports provided: hass, provideHass, lovelace, lovelace_view, load_lovelace */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"hass\", function() { return hass; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"provideHass\", function() { return provideHass; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"lovelace\", function() { return lovelace; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"lovelace_view\", function() { return lovelace_view; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"load_lovelace\", function() { return load_lovelace; });\nfunction hass() {\n return document.querySelector('home-assistant').hass\n};\n\nfunction provideHass(element) {\n return document.querySelector(\"home-assistant\").provideHass(element);\n}\n\nfunction lovelace() {\n var root = document.querySelector(\"home-assistant\");\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"home-assistant-main\");\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"app-drawer-layout partial-panel-resolver\");\n root = root && root.shadowRoot || root;\n root = root && root.querySelector(\"ha-panel-lovelace\")\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"hui-root\")\n if (root) {\n var ll = root.lovelace\n ll.current_view = root.___curView;\n return ll;\n }\n return null;\n}\n\nfunction lovelace_view() {\n var root = document.querySelector(\"home-assistant\");\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"home-assistant-main\");\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"app-drawer-layout partial-panel-resolver\");\n root = root && root.shadowRoot || root;\n root = root && root.querySelector(\"ha-panel-lovelace\");\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"hui-root\");\n root = root && root.shadowRoot;\n root = root && root.querySelector(\"ha-app-layout #view\");\n root = root && root.firstElementChild;\n return root;\n}\n\nfunction load_lovelace() {\n if(customElements.get(\"hui-view\")) return true;\n\n const res = document.createElement(\"partial-panel-resolver\");\n res.hass = hass();\n res.route = {path: \"/lovelace/\"};\n // res._updateRoutes();\n try {\n document.querySelector(\"home-assistant\").appendChild(res).catch((error) => {});\n } catch (error) {\n document.querySelector(\"home-assistant\").removeChild(res);\n }\n if(customElements.get(\"hui-view\")) return true;\n return false;\n\n}\n\n\n//# sourceURL=webpack:////card-tools/hass.js?"); - -/***/ }), - -/***/ "../../../card-tools/lit-element.js": -/*!**********************************!*\ - !*** /card-tools/lit-element.js ***! - \**********************************/ -/*! exports provided: LitElement, html, css */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"LitElement\", function() { return LitElement; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"html\", function() { return html; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"css\", function() { return css; });\nconst LitElement = customElements.get('home-assistant-main') ? Object.getPrototypeOf(customElements.get('home-assistant-main')) : Object.getPrototypeOf(customElements.get('hui-view'));\n\nconst html = LitElement.prototype.html;\n\nconst css = LitElement.prototype.css;\n\n\n//# sourceURL=webpack:////card-tools/lit-element.js?"); - -/***/ }), - -/***/ "../../../card-tools/lovelace-element.js": -/*!***************************************!*\ - !*** /card-tools/lovelace-element.js ***! - \***************************************/ -/*! exports provided: CUSTOM_TYPE_PREFIX, DOMAINS_HIDE_MORE_INFO, createCard, createElement, createEntityRow */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"CUSTOM_TYPE_PREFIX\", function() { return CUSTOM_TYPE_PREFIX; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"DOMAINS_HIDE_MORE_INFO\", function() { return DOMAINS_HIDE_MORE_INFO; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createCard\", function() { return createCard; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createElement\", function() { return createElement; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"createEntityRow\", function() { return createEntityRow; });\n/* harmony import */ var _event_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./event.js */ \"../../../card-tools/event.js\");\n\n\nconst CUSTOM_TYPE_PREFIX = \"custom:\";\n\nconst DOMAINS_HIDE_MORE_INFO = [\n \"input_number\",\n \"input_select\",\n \"input_text\",\n \"scene\",\n \"weblink\",\n];\n\nfunction errorElement(error, config) {\n const el = document.createElement(\"hui-error-card\");\n el.setConfig({\n type: \"error\",\n error,\n config,\n });\n return el;\n}\n\nfunction _createElement(tag, config) {\n const el = document.createElement(tag);\n try {\n el.setConfig(config);\n } catch (err) {\n return errorElement(err, config);\n }\n return el;\n}\n\nfunction createLovelaceElement(thing, config) {\n if(!config || typeof config !== \"object\" || !config.type)\n return errorElement(`No ${thing} type configured`, config);\n\n let tag = config.type;\n if(tag.startsWith(CUSTOM_TYPE_PREFIX))\n tag = tag.substr(CUSTOM_TYPE_PREFIX.length);\n else\n tag = `hui-${tag}-${thing}`;\n\n if(customElements.get(tag))\n return _createElement(tag, config);\n\n const el = errorElement(`Custom element doesn't exist: ${tag}.`, config);\n el.style.display = \"None\";\n\n const timer = setTimeout(() => {\n el.style.display = \"\";\n }, 2000);\n\n customElements.whenDefined(tag).then(() => {\n clearTimeout(timer);\n Object(_event_js__WEBPACK_IMPORTED_MODULE_0__[\"fireEvent\"])(\"ll-rebuild\", {}, el);\n });\n\n return el;\n}\n\nfunction createCard(config) {\n return createLovelaceElement('card', config);\n}\nfunction createElement(config) {\n return createLovelaceElement('element', config);\n}\nfunction createEntityRow(config) {\n const SPECIAL_TYPES = new Set([\n \"call-service\",\n \"divider\",\n \"section\",\n \"weblink\",\n ]);\n const DEFAULT_ROWS = {\n alert: \"toggle\",\n automation: \"toggle\",\n climate: \"climate\",\n cover: \"cover\",\n fan: \"toggle\",\n group: \"group\",\n input_boolean: \"toggle\",\n input_number: \"input-number\",\n input_select: \"input-select\",\n input_text: \"input-text\",\n light: \"toggle\",\n lock: \"lock\",\n media_player: \"media-player\",\n remote: \"toggle\",\n scene: \"scene\",\n script: \"script\",\n sensor: \"sensor\",\n timer: \"timer\",\n switch: \"toggle\",\n vacuum: \"toggle\",\n water_heater: \"climate\",\n input_datetime: \"input-datetime\",\n };\n\n if(!config)\n return errorElement(\"Invalid configuration given.\", config);\n if(typeof config === \"string\")\n config = {entity: config};\n if(typeof config !== \"object\" || (!config.entity && !config.type))\n return errorElement(\"Invalid configuration given.\", config);\n\n const type = config.type || \"default\";\n if(SPECIAL_TYPES.has(type) || type.startsWith(CUSTOM_TYPE_PREFIX))\n return createLovelaceElement('row', config);\n\n const domain = config.entity.split(\".\", 1)[0];\n Object.assign(config, {type: DEFAULT_ROWS[domain] || \"text\"});\n\n return createLovelaceElement('entity-row', config);\n}\n\n\n//# sourceURL=webpack:////card-tools/lovelace-element.js?"); - -/***/ }), - -/***/ "../../../card-tools/more-info.js": -/*!********************************!*\ - !*** /card-tools/more-info.js ***! - \********************************/ -/*! exports provided: moreInfo */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"moreInfo\", function() { return moreInfo; });\n/* harmony import */ var _event_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./event.js */ \"../../../card-tools/event.js\");\n\n\nfunction moreInfo(entity, large=false) {\n Object(_event_js__WEBPACK_IMPORTED_MODULE_0__[\"fireEvent\"])(\"hass-more-info\", {entityId: entity}, document.querySelector(\"home-assistant\"));\n const el = document.querySelector(\"home-assistant\")._moreInfoEl;\n el.large = large;\n return el;\n}\n\n\n//# sourceURL=webpack:////card-tools/more-info.js?"); - -/***/ }), - -/***/ "../../../card-tools/popup.js": -/*!****************************!*\ - !*** /card-tools/popup.js ***! - \****************************/ -/*! exports provided: closePopUp, popUp */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"closePopUp\", function() { return closePopUp; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"popUp\", function() { return popUp; });\n/* harmony import */ var _hass_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./hass.js */ \"../../../card-tools/hass.js\");\n/* harmony import */ var _event_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./event.js */ \"../../../card-tools/event.js\");\n/* harmony import */ var _lovelace_element_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lovelace-element.js */ \"../../../card-tools/lovelace-element.js\");\n/* harmony import */ var _more_info_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./more-info.js */ \"../../../card-tools/more-info.js\");\n/* harmony import */ var _card_maker_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./card-maker.js */ \"../../../card-tools/card-maker.js\");\n\n\n\n\n\n\nfunction closePopUp() {\n const moreInfoEl = document.querySelector(\"home-assistant\")._moreInfoEl;\n if(moreInfoEl)\n moreInfoEl.close();\n}\n\nfunction popUp(title, card, large=false, style=null, fullscreen=false) {\n\n const dummy_entity = Object.keys(Object(_hass_js__WEBPACK_IMPORTED_MODULE_0__[\"hass\"])().states)[0];\n Object(_more_info_js__WEBPACK_IMPORTED_MODULE_3__[\"moreInfo\"])(dummy_entity);\n\n const content = document.createElement(\"card-maker\")\n content.noHass = true;\n content.config = card;\n\n const wrapper = document.createElement(\"div\");\n wrapper.innerHTML = `\n \n `;\n\n const header = document.createElement(\"app-toolbar\");\n header.innerHTML = `\n \n
\n ${title}\n
\n `;\n\n const scroll = document.createElement(\"div\");\n scroll.classList.add('scrollable');\n scroll.appendChild(content);\n\n if(!fullscreen) {\n wrapper.appendChild(header);\n }\n wrapper.appendChild(scroll);\n\n const moreInfoEl = document.querySelector(\"home-assistant\")._moreInfoEl;\n moreInfoEl.sizingTarget = scroll;\n moreInfoEl.large = large;\n moreInfoEl._page = \"none\";\n moreInfoEl.shadowRoot.appendChild(wrapper);\n\n let oldStyle = {};\n if(style) {\n for (var k in style) {\n oldStyle[k] = moreInfoEl.style[k];\n moreInfoEl.style.setProperty(k, style[k]);\n }\n }\n\n setTimeout(() => {\n let interval = setInterval(() => {\n if (moreInfoEl.getAttribute(\"aria-hidden\")) {\n clearInterval(interval);\n wrapper.parentNode.removeChild(wrapper);\n for (var k in oldStyle)\n if (oldStyle[k])\n moreInfoEl.style.setProperty(k, oldStyle[k]);\n else\n moreInfoEl.style.removeProperty(k);\n }\n }, 100);\n }, 1000);\n return moreInfoEl;\n}\n\n\n//# sourceURL=webpack:////card-tools/popup.js?"); - -/***/ }), - -/***/ "./js/browser-player.js": -/*!******************************!*\ - !*** ./js/browser-player.js ***! - \******************************/ -/*! no exports provided */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _card_tools_lit_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! /card-tools/lit-element */ \"../../../card-tools/lit-element.js\");\n/* harmony import */ var _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! /card-tools/deviceId */ \"../../../card-tools/deviceId.js\");\n/* harmony import */ var _card_tools_more_info__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! /card-tools/more-info */ \"../../../card-tools/more-info.js\");\n\n\n\n\nclass BrowserPlayer extends _card_tools_lit_element__WEBPACK_IMPORTED_MODULE_0__[\"LitElement\"] {\n\n static get properties() {\n return {\n hass: {},\n };\n }\n\n setConfig(config) {\n this._config = config;\n }\n handleMute(ev) {\n window.browser_mod.mute({});\n }\n handleVolumeChange(ev) {\n const vol = parseFloat(ev.target.value);\n window.browser_mod.set_volume({volume_level: vol});\n }\n handleMoreInfo(ev) {\n Object(_card_tools_more_info__WEBPACK_IMPORTED_MODULE_2__[\"moreInfo\"])(window.browser_mod.entity_id);\n }\n handlePlayPause(ev) {\n if (window.browser_mod.player.paused)\n window.browser_mod.play({});\n else\n window.browser_mod.pause({});\n }\n\n render() {\n const player = window.browser_mod.player;\n return _card_tools_lit_element__WEBPACK_IMPORTED_MODULE_0__[\"html\"]`\n \n
\n \n \n\n ${window.browser_mod.player_state === \"stopped\"\n ? _card_tools_lit_element__WEBPACK_IMPORTED_MODULE_0__[\"html\"]`
`\n : _card_tools_lit_element__WEBPACK_IMPORTED_MODULE_0__[\"html\"]`\n \n `}\n \n
\n\n
\n ${_card_tools_deviceId__WEBPACK_IMPORTED_MODULE_1__[\"deviceID\"]}\n
\n\n
\n `;\n }\n\n static get styles() {\n return _card_tools_lit_element__WEBPACK_IMPORTED_MODULE_0__[\"css\"]`\n paper-icon-button[highlight] {\n color: var(--accent-color);\n }\n .card-content {\n display: flex;\n justify-content: center;\n }\n .placeholder {\n width: 24px;\n padding: 8px;\n }\n .device-id {\n opacity: 0.7;\n font-size: xx-small;\n margin-top: -10px;\n user-select: all;\n -webkit-user-select: all;\n -moz-user-select: all;\n -ms-user-select: all;\n }\n `\n }\n\n}\n\ncustomElements.define(\"browser-player\", BrowserPlayer);\n\n\n//# sourceURL=webpack:///./js/browser-player.js?"); - -/***/ }), - -/***/ "./js/main.js": -/*!********************!*\ - !*** ./js/main.js ***! - \********************/ -/*! no exports provided */ -/***/ (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 const index = serviceData.deviceID.indexOf('this');\n if(index !== -1)\n serviceData.deviceID[index] = _card_tools_deviceId__WEBPACK_IMPORTED_MODULE_0__[\"deviceID\"];\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 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 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 if(msg.auto_close && msg.time) {\n msg.time = parseInt(msg.time)\n if(msg.time == -1) {\n clearTimeout(this._screenSaverTimer);\n this._screenSaverTime = 0;\n return;\n }\n this._screenSaverTime = msg.time * 1000;\n this._screenSaver = fn;\n this._screenSaverTimer = setTimeout(this._screenSaver, this._screenSaverTime)\n } else {\n fn();\n }\n }\n close_popup(msg){\n this.autoclose_popup_active = false;\n Object(_card_tools_popup__WEBPACK_IMPORTED_MODULE_2__[\"closePopUp\"])();\n if(this._screenSaverTime) {\n this._screenSaverTimer = setTimeout(this._screenSaver, this._screenSaverTime)\n }\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 msg.time = parseInt(msg.time)\n if(msg.time == -1) {\n clearTimeout(this._screenSaverTimer);\n this._screenSaverTime = 0;\n return;\n }\n this._screenSaverTime = msg.time * 1000;\n this._screenSaver = fn;\n this._screenSaverTimer = setTimeout(this._screenSaver, this._screenSaverTime)\n } else {\n fn();\n }\n }\n no_blackout(msg){\n\n clearTimeout(this._screenSaverTimer);\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 if(this._screenSaverTime) {\n this._screenSaverTimer = setTimeout(this._screenSaver, this._screenSaverTime)\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?"); - -/***/ }) - -/******/ }); \ No newline at end of file +
+ `}static get styles(){return m` + paper-icon-button[highlight] { + color: var(--accent-color); + } + .card-content { + display: flex; + justify-content: center; + } + .placeholder { + width: 24px; + padding: 8px; + } + .device-id { + opacity: 0.7; + font-size: xx-small; + margin-top: -10px; + user-select: all; + -webkit-user-select: all; + -moz-user-select: all; + -ms-user-select: all; + } + `}});window.browser_mod=new class{set hass(e){if(!e)return;if(this._hass=e,this.hassPatched)return;const t=e.callService;e.callService=(e,i,o)=>{if(o&&o.deviceID)if(Array.isArray(o.deviceID)){const e=o.deviceID.indexOf("this");-1!==e&&(o.deviceID[e]=s)}else"this"===o.deviceID&&(o.deviceID=s);return t(e,i,o)},this.hassPatched=!0,document.querySelector("home-assistant").hassChanged(e,e)}playOnce(e){this._video&&this._video.play(),window.browser_mod.playedOnce||(window.browser_mod.player.play(),window.browser_mod.playedOnce=!0)}constructor(){window.setTimeout(a,500),window.hassConnection.then(e=>this.connect(e.conn)),this.player=new Audio,this.playedOnce=!1,this.autoclose_popup_active=!1;const e=this.update.bind(this);this.player.addEventListener("ended",e),this.player.addEventListener("play",e),this.player.addEventListener("pause",e),this.player.addEventListener("volumechange",e),document.addEventListener("visibilitychange",e),window.addEventListener("location-changed",e),window.addEventListener("click",this.playOnce),window.addEventListener("mousemove",this.no_blackout.bind(this)),window.addEventListener("mousedown",this.no_blackout.bind(this)),window.addEventListener("keydown",this.no_blackout.bind(this)),window.addEventListener("touchstart",this.no_blackout.bind(this)),n(this),window.fully&&(this._fullyMotion=!1,this._motionTimeout=void 0,fully.bind("screenOn","browser_mod.update();"),fully.bind("screenOff","browser_mod.update();"),fully.bind("pluggedAC","browser_mod.update();"),fully.bind("pluggedUSB","browser_mod.update();"),fully.bind("onBatteryLevelChanged","browser_mod.update();"),fully.bind("unplugged","browser_mod.update();"),fully.bind("networkReconnect","browser_mod.update();"),fully.bind("onMotion","browser_mod.fullyMotion();")),this._screenSaver=void 0,this._screenSaverTimer=void 0,this._screenSaverTime=0,this._blackout=document.createElement("div"),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 ",document.body.appendChild(this._blackout)}connect(e){this.conn=e,e.subscribeMessage(e=>this.callback(e),{type:"browser_mod/connect",deviceID:s})}callback(e){switch(e.command){case"update":this.update(e);break;case"debug":this.debug(e);break;case"play":this.play(e);break;case"pause":this.pause(e);break;case"stop":this.stop(e);break;case"set_volume":this.set_volume(e);break;case"mute":this.mute(e);break;case"popup":this.popup(e);break;case"close-popup":this.close_popup(e);break;case"navigate":this.navigate(e);break;case"more-info":this.more_info(e);break;case"set-theme":this.set_theme(e);break;case"lovelace-reload":this.lovelace_reload(e);break;case"blackout":this.blackout(e);break;case"no-blackout":this.no_blackout(e)}}get player_state(){return this.player.src?this.player.ended?"stopped":this.player.paused?"paused":"playing":"stopped"}debug(e){v("deviceID",{type:"markdown",content:`# ${s}`}),alert(s)}_set_screensaver(e,t){if(clearTimeout(this._screenSaverTimer),e){if(-1==(t=parseInt(t)))return clearTimeout(this._screenSaverTimer),void(this._screenSaverTime=0);this._screenSaverTime=1e3*t,this._screenSaver=e,this._screenSaverTimer=setTimeout(this._screenSaver,this._screenSaverTime)}else this._screenSaverTime&&(this._screenSaverTimer=setTimeout(this._screenSaver,this._screenSaverTime))}play(e){const t=e.media_content_id;t&&(this.player.src=t),this.player.play()}pause(e){this.player.pause()}stop(e){this.player.pause(),this.player.src=null}set_volume(e){void 0!==e.volume_level&&(this.player.volume=e.volume_level)}mute(e){void 0===e.mute&&(e.mute=!this.player.muted),this.player.muted=Boolean(e.mute)}popup(e){if(!e.title&&!e.auto_close)return;if(!e.card)return;const t=()=>{v(e.title,e.card,e.large,e.style,e.auto_close),e.auto_close&&(this.autoclose_popup_active=!0)};e.auto_close&&e.time?this._set_screensaver(t,e.time):t()}close_popup(e){this._set_screensaver(),this.autoclose_popup_active=!1,function(){const e=document.querySelector("home-assistant")._moreInfoEl;e&&e.close()}()}navigate(e){e.navigation_path&&(history.pushState(null,"",e.navigation_path),r("location-changed",{},document.querySelector("home-assistant")))}more_info(e){e.entity_id&&u(e.entity_id,e.large)}set_theme(e){e.theme||(e.theme="default"),r("settheme",e.theme,document.querySelector("home-assistant"))}lovelace_reload(e){const t=i=(i=(i=(i=(i=(i=(i=(i=(i=(i=(i=(i=document.querySelector("home-assistant"))&&i.shadowRoot)&&i.querySelector("home-assistant-main"))&&i.shadowRoot)&&i.querySelector("app-drawer-layout partial-panel-resolver"))&&i.shadowRoot||i)&&i.querySelector("ha-panel-lovelace"))&&i.shadowRoot)&&i.querySelector("hui-root"))&&i.shadowRoot)&&i.querySelector("ha-app-layout #view"))&&i.firstElementChild;var i;t&&r("config-refresh",{},t)}blackout(e){const t=()=>{window.fully?fully.turnScreenOff():this._blackout.style.visibility="visible",this.update()};e.time?this._set_screensaver(t,e.time):t()}no_blackout(e){if(this._set_screensaver(),this.autoclose_popup_active)return this.close_popup();window.fully?(fully.getScreenOn()||fully.turnScreenOn(),e.brightness&&fully.setScreenBrightness(e.brightness),this.update()):"hidden"!==this._blackout.style.visibility&&(this._blackout.style.visibility="hidden",this.update())}is_blackout(){return window.fully?!fully.getScreenOn():Boolean("visible"===this._blackout.style.visibility)}fullyMotion(){this._fullyMotion=!0,clearTimeout(this._motionTimeout),this._motionTimeout=setTimeout(()=>{this._fullyMotion=!1,this.update()},5e3),this.update()}start_camera(){this._video||(this._video=document.createElement("video"),this._video.autoplay=!0,this._video.playsInline=!0,this._video.style.cssText="\n visibility: hidden;\n width: 0;\n height: 0;\n ",this._canvas=document.createElement("canvas"),this._canvas.style.cssText="\n visibility: hidden;\n width: 0;\n height: 0;\n ",document.body.appendChild(this._canvas),document.body.appendChild(this._video),navigator.mediaDevices.getUserMedia({video:!0,audio:!1}).then(e=>{this._video.srcObject=e,this._video.play(),this.send_cam()}))}send_cam(e){this._canvas.getContext("2d").drawImage(this._video,0,0,this._canvas.width,this._canvas.height),this.conn.sendMessage({type:"browser_mod/update",deviceID:s,data:{camera:this._canvas.toDataURL("image/png")}}),setTimeout(this.send_cam.bind(this),5e3)}update(e=null){this.conn&&(e&&(e.entity_id&&(this.entity_id=e.entity_id),e.camera&&this.start_camera()),this.conn.sendMessage({type:"browser_mod/update",deviceID:s,data:{browser:{path:window.location.pathname,visibility:document.visibilityState,userAgent:navigator.userAgent,currentUser:this._hass&&this._hass.user&&this._hass.user.name,fullyKiosk:!!window.fully||void 0,width:window.innerWidth,height:window.innerHeight},player:{volume:this.player.volume,muted:this.player.muted,src:this.player.src,state:this.player_state},screen:{blackout:this.is_blackout(),brightness:window.fully?fully.getScreenBrightness():void 0},fully:window.fully?{battery:window.fully?fully.getBatteryLevel():void 0,charging:window.fully?fully.isPlugged():void 0,motion:window.fully?this._fullyMotion:void 0}:void 0}}))}}}]); \ No newline at end of file diff --git a/js/main.js b/js/main.js index 96a7dfa..e04dd48 100644 --- a/js/main.js +++ b/js/main.js @@ -221,6 +221,7 @@ class BrowserMod { if(msg.auto_close && msg.time) { this._set_screensaver(fn, msg.time); } else { + // closePopUp(); fn(); } }