Code linting
This commit is contained in:
parent
c1a000abb3
commit
862b93a175
161
README.md
161
README.md
@ -1,5 +1,4 @@
|
||||
browser\_mod
|
||||
============
|
||||
# browser_mod
|
||||
|
||||
[](https://github.com/custom-components/hacs)
|
||||
|
||||
@ -34,29 +33,31 @@ browser_mod:
|
||||
> - url: /browser_mod.js
|
||||
> type: module
|
||||
> ```
|
||||
>
|
||||
> to your `ui_lovelace.yaml`.
|
||||
> Don't worry about where to put browser_mod.js, the integration will handle that automatically, and please note that it's **not** `/local/browser_mod.js`.
|
||||
|
||||
|
||||
# Usage
|
||||
|
||||
Here's a fantastic video summary of all `browser_mod` functions by Pinkywafer: [Youtube link](https://www.youtube.com/watch?v=atpIP2RYldA).
|
||||
|
||||
## Devices
|
||||
The most important concept of `browser_mod` is the *device*.
|
||||
|
||||
A *device* is a machine-browser combination identified by a unique `deviceID`. The `deviceID` is randomly generated and may look like `ded3b4dc-abedd098`.
|
||||
The most important concept of `browser_mod` is the _device_.
|
||||
|
||||
- Chrome on your desktop and Chrome on your laptop are two different *devices*.
|
||||
- Chrome on your laptop and Safari on your laptop are two different *devices*.
|
||||
- Two tabs in Firefox on the same computer is one *device*.
|
||||
- Two windows in Edge on the same computer is one *device*.
|
||||
A _device_ is a machine-browser combination identified by a unique `deviceID`. The `deviceID` is randomly generated and may look like `ded3b4dc-abedd098`.
|
||||
|
||||
In the two latter cases, the last loaded tab/window will be the *active* one.
|
||||
- Chrome on your desktop and Chrome on your laptop are two different _devices_.
|
||||
- Chrome on your laptop and Safari on your laptop are two different _devices_.
|
||||
- Two tabs in Firefox on the same computer is one _device_.
|
||||
- Two windows in Edge on the same computer is one _device_.
|
||||
|
||||
Note: Incognito mode will generate a new `deviceID` and thus a new *device* every time it's started.
|
||||
In the two latter cases, the last loaded tab/window will be the _active_ one.
|
||||
|
||||
Note: Incognito mode will generate a new `deviceID` and thus a new _device_ every time it's started.
|
||||
|
||||
### Aliases
|
||||
|
||||
Since the deviceID can be a bit hard to remember for devices you use often, you can specify an alias in `configuration.yaml`
|
||||
|
||||
```yaml
|
||||
@ -67,12 +68,13 @@ browser_mod:
|
||||
d2fc860c-16379d23:
|
||||
name: dashboard
|
||||
```
|
||||
This binds the *aliases* `arrakis` to `99980b13-dabc9563` and `dashboard` to `d2fc860c-16379d23`.
|
||||
|
||||
This binds the _aliases_ `arrakis` to `99980b13-dabc9563` and `dashboard` to `d2fc860c-16379d23`.
|
||||
|
||||
Note: Aliases must be unique.
|
||||
|
||||
|
||||
#### Changing deviceID
|
||||
|
||||
You can change the deviceID of your device by adding a `browser-player` card to your lovelace interface and clicking the deviceID at the bottom of the card. Set it to `clear` to generate a new random one.
|
||||
|
||||
You can also set a deviceID by adding `?deviceID=mydeviceID` to the end of the URL you're using to access Home Assistant. Be careful - I have no idea what could happen if several devices were to have the same ID.
|
||||
@ -81,19 +83,23 @@ Use `?deviceID=clear` to generate a new random one.
|
||||
**Take care to avoid deviceID collissions. There's no telling what could happen if more devices share the same ID.**
|
||||
|
||||
### 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.
|
||||
|
||||
### Disabling entities
|
||||
`browser_mod` creates a number of entities, which is explained below. In some cases, you may not want to do that. If so, add a list of entity types you do *not* want to add to a `disable` section, either for each device, or globally to ignore for all unknown devices:
|
||||
|
||||
E.g. to disable the `light` and `media_player` for the device aliased to `arrakis`, AND disable *all* entities for all devices which *don't* have an alias:
|
||||
`browser_mod` creates a number of entities, which is explained below. In some cases, you may not want to do that. If so, add a list of entity types you do _not_ want to add to a `disable` section, either for each device, or globally to ignore for all unknown devices:
|
||||
|
||||
E.g. to disable the `light` and `media_player` for the device aliased to `arrakis`, AND disable _all_ entities for all devices which _don't_ have an alias:
|
||||
|
||||
```yaml
|
||||
browser_mod:
|
||||
@ -105,11 +111,11 @@ browser_mod:
|
||||
- media_player
|
||||
disable:
|
||||
- all
|
||||
````
|
||||
|
||||
```
|
||||
|
||||
## Entities
|
||||
Once `browser_mod` is installed, loading up your Home Assistant frontend on a new *device* will create three to five new devices.
|
||||
|
||||
Once `browser_mod` is installed, loading up your Home Assistant frontend on a new _device_ will create three to five new devices.
|
||||
|
||||
- `sensor.<device>`
|
||||
- `media_player.<device>`
|
||||
@ -117,7 +123,7 @@ Once `browser_mod` is installed, loading up your Home Assistant frontend on a ne
|
||||
- If you've enabled it: `camera.<device>`
|
||||
- If you're using Fully Kiosk Browser: `binary_sensor.<device>`
|
||||
|
||||
`<device>` here will be the `deviceID` of the *device* but with the dash (`-`) replaced by an underscore (`_`). If you've defined an alias, it will be that instead.
|
||||
`<device>` here will be the `deviceID` of the _device_ but with the dash (`-`) replaced by an underscore (`_`). If you've defined an alias, it will be that instead.
|
||||
|
||||
E.g:
|
||||
Connecting your phone with `deviceID: ded3b4dc-abedd098` will create the entities `sensor.ded3b4dc_abedd098`, `media_player.ded3b4dc_abedd098` and `light.ded3b4dc_abedd098`.
|
||||
@ -129,24 +135,24 @@ The `sensor` will display the number of connected views (tabs/windows) of the de
|
||||
|
||||
The sensor also has the following attributes:
|
||||
|
||||
| attribute | content |
|
||||
| --- | --- |
|
||||
| `type` | `browser_mod` |
|
||||
| `last_seen` | The time when the *device* was last seen |
|
||||
| `deviceID` | The deviceID of the *device*. |
|
||||
| `path` | The currently displayed path on the *device*. |
|
||||
| `visibility` | Whether the frontend is currently visible on the *device*. |
|
||||
| `userAgent` | The User Agent of the associated browser. |
|
||||
| `currentUser` | The user currently logged in on the *device*. |
|
||||
| `fullyKiosk` | True if the *device* is a Fully Kiosk browser. Undefined otherwise. |
|
||||
| `width` | The current width of the browser window in pixels. |
|
||||
| `height` | The current height of the browser window in pixels. |
|
||||
| `battery_level` | The current battery level of your device - if supported |
|
||||
| `charging` | The current charging state of your device - if supported |
|
||||
| attribute | content |
|
||||
| --------------- | ------------------------------------------------------------------- |
|
||||
| `type` | `browser_mod` |
|
||||
| `last_seen` | The time when the _device_ was last seen |
|
||||
| `deviceID` | The deviceID of the _device_. |
|
||||
| `path` | The currently displayed path on the _device_. |
|
||||
| `visibility` | Whether the frontend is currently visible on the _device_. |
|
||||
| `userAgent` | The User Agent of the associated browser. |
|
||||
| `currentUser` | The user currently logged in on the _device_. |
|
||||
| `fullyKiosk` | True if the _device_ is a Fully Kiosk browser. Undefined otherwise. |
|
||||
| `width` | The current width of the browser window in pixels. |
|
||||
| `height` | The current height of the browser window in pixels. |
|
||||
| `battery_level` | The current battery level of your device - if supported |
|
||||
| `charging` | The current charging state of your device - if supported |
|
||||
|
||||
### media\_player
|
||||
### media_player
|
||||
|
||||
The `media_player` can be used to play sounds on the *device*.
|
||||
The `media_player` can be used to play sounds on the _device_.
|
||||
|
||||
**NOTE: Because Apple is Apple; on iOS you need to touch the screen once after loading the frontend before any playback will work.**
|
||||
|
||||
@ -161,6 +167,7 @@ For other browsers, the interface will just be covered with black (the screen is
|
||||
For security and UX reasons, the camera must be enabled manually on a device by device basis.
|
||||
|
||||
Enabling the camera is done by adding `camera: true` to the devices configuration in `configuration.yaml`:
|
||||
|
||||
```yaml
|
||||
browser_mod:
|
||||
devices:
|
||||
@ -170,35 +177,33 @@ browser_mod:
|
||||
d2fc860c-16379d23:
|
||||
name: dashboard
|
||||
```
|
||||
|
||||
After restarting Home Assistant (and [clearing cache](https://github.com/thomasloven/hass-config/wiki/Lovelace-Plugins#clearing-cache)), the next time you load your interface your browser will ask you if you want Home Assistant to be able to access your camera. Some browsers (e.g. mobile Safari) will ask every time you make a hard refresh.
|
||||
|
||||
Be aware that keeping the camera on may make your device run hot and drain your battery.
|
||||
|
||||
The camera does not work well with Fully Kiosk Browser. If you're using FKB, use the built-in camera functionality instead. It's better in every way.
|
||||
|
||||
### binary\_sensor
|
||||
### binary_sensor
|
||||
|
||||
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).
|
||||
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).
|
||||
|
||||
## Services
|
||||
|
||||
`browser_mod` registers a number of services.
|
||||
|
||||
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** 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** currently connected _devices_. `deviceID` may also contain aliases.
|
||||
|
||||
You can also activate any service from the frontend by using the `fire-dom-event` `tap_action`.
|
||||
|
||||
|
||||
|
||||
|
||||
### - debug
|
||||
|
||||
```yaml
|
||||
service: browser_mod.debug
|
||||
```
|
||||
|
||||
Display a popup with the deviceID *and* a javascript alert with the deviceID on all connected *devices*.
|
||||
Display a popup with the deviceID _and_ a javascript alert with the deviceID on all connected _devices_.
|
||||
|
||||
### - set_theme
|
||||
|
||||
@ -211,6 +216,7 @@ data:
|
||||
will set the current theme to `clear_light` on all devices.
|
||||
|
||||
### - navigate
|
||||
|
||||
```yaml
|
||||
service: browser_mod.navigate
|
||||
data:
|
||||
@ -219,11 +225,12 @@ data:
|
||||
- ded3b4dc-abedd098
|
||||
```
|
||||
|
||||
will open your second lovelace view on just the *device* `ded3b4dc-abedd098`.
|
||||
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
|
||||
|
||||
```yaml
|
||||
service: browser_mod.more_info
|
||||
data:
|
||||
@ -233,11 +240,12 @@ data:
|
||||
- dashboard
|
||||
```
|
||||
|
||||
will show the more-info dialog of `camera.front_door` on the *devices* `ded3b4dc-abedd098` and `dashboard`.
|
||||
will show the more-info dialog of `camera.front_door` on the _devices_ `ded3b4dc-abedd098` and `dashboard`.
|
||||
|
||||
The optional parameter `large: true` will make the popup wider.
|
||||
|
||||
### - toast
|
||||
|
||||
```yaml
|
||||
service: browser_mod.toast
|
||||
data:
|
||||
@ -248,6 +256,7 @@ 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
|
||||
|
||||
```yaml
|
||||
service: browser_mod.popup
|
||||
data:
|
||||
@ -275,13 +284,15 @@ The optional parameter `time:` (only useable if `auto_close: true` is also set)
|
||||
If [card-mod](https://github.com/thomasloven/lovelace-card-mod) is installed, the popup can be styled by the optional `style` parameter, or by the `card-mod-more-info[-yaml]` theme variable.
|
||||
|
||||
### - close_popup
|
||||
|
||||
```yaml
|
||||
service: browser_mod.close_popup
|
||||
```
|
||||
|
||||
will close all more-info dialogs and popups that are open on all connected *devices*.
|
||||
will close all more-info dialogs and popups that are open on all connected _devices_.
|
||||
|
||||
### - blackout
|
||||
|
||||
```yaml
|
||||
service: browser_mod.blackout
|
||||
data:
|
||||
@ -293,9 +304,10 @@ 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.
|
||||
Note: This will _not_ turn off your screen backlight. Most screens will still emit light in a dark room.
|
||||
|
||||
### - no_blackout
|
||||
|
||||
```yaml
|
||||
service: browser_mod.no_blackout
|
||||
```
|
||||
@ -304,6 +316,7 @@ 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
|
||||
|
||||
```yaml
|
||||
service: browser_mod.lovelace_reload
|
||||
```
|
||||
@ -311,6 +324,7 @@ service: browser_mod.lovelace_reload
|
||||
Refreshes the lovelace config. Same as clicking "Refresh" in the top right menu in lovelace.
|
||||
|
||||
### - window_reload
|
||||
|
||||
```yaml
|
||||
service: browser_mod.window_reload
|
||||
```
|
||||
@ -318,6 +332,7 @@ service: browser_mod.window_reload
|
||||
Forces the browser to reload the page. Same as clicking your browsers refresh button.
|
||||
|
||||
### - command
|
||||
|
||||
```yaml
|
||||
service: browser_mod.command
|
||||
data:
|
||||
@ -325,7 +340,7 @@ data:
|
||||
<data>
|
||||
```
|
||||
|
||||
This can be used to send any command to a *device* by setting `command:` to the service name and appending any other options.
|
||||
This can be used to send any command to a _device_ by setting `command:` to the service name and appending any other options.
|
||||
E.g. the following two service calls will perform the same function:
|
||||
|
||||
```yaml
|
||||
@ -338,7 +353,9 @@ service: browser_mod.toast
|
||||
data:
|
||||
message: Hello World!
|
||||
```
|
||||
|
||||
### - commands
|
||||
|
||||
```yaml
|
||||
service: browser_mod.commands
|
||||
data:
|
||||
@ -348,9 +365,11 @@ data:
|
||||
- command: <command>
|
||||
<data>
|
||||
```
|
||||
|
||||
This service can be used to call several services listed in the `commands:` parameter consecutively.
|
||||
|
||||
### - delay
|
||||
|
||||
```yaml
|
||||
service: browser_mod.delay
|
||||
data:
|
||||
@ -360,6 +379,7 @@ data:
|
||||
Do nothing for `<seconds>` seconds.
|
||||
|
||||
## Run a command from the frontend
|
||||
|
||||
To run a command from the frontend, you can use the tap_action `fire-dom-event` with a `browser_mod` parameter.
|
||||
E.g:
|
||||
|
||||
@ -374,20 +394,26 @@ tap_action:
|
||||
```
|
||||
|
||||
There's also a special command which is only useful from the frontend:
|
||||
|
||||
### - call_service
|
||||
|
||||
```yaml
|
||||
command: call-service:
|
||||
service: <service>
|
||||
service_data:
|
||||
<service_data>
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
This works exactly like a `call_service` tap_action, but if `service_data` contains the parameter `deviceID` and that contains the word `this`, that will be replaced with the current device's deviceID.
|
||||
This may be useful for e.g. calling scripts if you want to know from where it was triggered.
|
||||
=======
|
||||
|
||||
This works exactly like a `call_service` tap_action, but if `service_data` contains the parameter `deviceID` and that contains the word `this`, that will be replaced with the current deviced deviceID.
|
||||
>>>>>>> Code linting
|
||||
This may be useful for e.g. calling scripts if you want to know from where it was triggered.
|
||||
|
||||
# `browser-player` card
|
||||
|
||||
To control the playback in the current *device*, `browser_mod` includes a custom lovelace card. Just add
|
||||
To control the playback in the current _device_, `browser_mod` includes a custom lovelace card. Just add
|
||||
|
||||
```yaml
|
||||
type: custom:browser-player
|
||||
@ -399,8 +425,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`.
|
||||
@ -410,21 +436,22 @@ First of all the commands `blackout` and `no-blackout` will control the devices
|
||||
|
||||
Second, there are a few more attributes available
|
||||
|
||||
| attribute | content |
|
||||
| --- | --- |
|
||||
| `fullyKiosk` | True. |
|
||||
| `brightness` | The current screen brightness. |
|
||||
| `battery_level` | The current charge percentage of the devices battery. |
|
||||
| `charging` | Whether the battery is currently charging. |
|
||||
| `motion` | Whether the devices camera has detected any motion in the last five seconds. |
|
||||
|
||||
| attribute | content |
|
||||
| --------------- | ---------------------------------------------------------------------------- |
|
||||
| `fullyKiosk` | True. |
|
||||
| `brightness` | The current screen brightness. |
|
||||
| `battery_level` | The current charge percentage of the devices battery. |
|
||||
| `charging` | Whether the battery is currently charging. |
|
||||
| `motion` | Whether the devices camera has detected any motion in the last five seconds. |
|
||||
|
||||
# Replacing more-info dialogs
|
||||
|
||||
With browser_mod, you can replace any more-info dialog with any lovelace card you choose yourself. This can be done either per lovelace view, or globally (even outside of lovelace).
|
||||
|
||||
The replacement is included in your lovelace or lovelace view configuration, and the syntax is exactly like the `popup` service, except you can't use `auto_close` or `time`.
|
||||
|
||||
Ex:
|
||||
|
||||
```yaml
|
||||
views:
|
||||
- title: Home view
|
||||
@ -460,14 +487,13 @@ popup_cards:
|
||||
type: gauge
|
||||
entity: sensor.sensor2
|
||||
```
|
||||
This would replace the more-info dialogs of `sensor.sensor1` and `sensor.sensor2` anywhere in your interface. Even outside of lovelace - be careful about that.
|
||||
|
||||
This would replace the more-info dialogs of `sensor.sensor1` and `sensor.sensor2` anywhere in your interface. Even outside of lovelace - be careful about that.
|
||||
|
||||
# Support
|
||||
|
||||
[Home Assistant community forum thread](https://community.home-assistant.io/t/browser-mod-turn-your-browser-into-a-controllable-device-and-a-media-player/123806)
|
||||
|
||||
|
||||
# FAQ
|
||||
|
||||
### Where can I find my deviceID?
|
||||
@ -479,28 +505,30 @@ But you can also find the device id on the `browser-player` card, if you added o
|
||||
An alternative way is to type `localStorage["lovelace-player-device-id"]` into your browsers console.
|
||||
|
||||
### Does this replace lovelace-player and lovelace-browser-commander
|
||||
|
||||
Yes.
|
||||
|
||||
Some improvements
|
||||
|
||||
- With the backend support `browser_mod` does the same things as both of those, but better.
|
||||
- Since `browser_mod` uses a service for executing commands rather than events, the commands can be easily triggered by any lovelace element which has a `tap_action` setting.
|
||||
This actually means it pretty much replaces `popup-card` as well.
|
||||
- `browser_mod` uses websockets to get immediate feedback from the *device* to the backend and much better tracking of disconnects.
|
||||
- *Aliases*. 'nuff said.
|
||||
This actually means it pretty much replaces `popup-card` as well.
|
||||
- `browser_mod` uses websockets to get immediate feedback from the _device_ to the backend and much better tracking of disconnects.
|
||||
- _Aliases_. 'nuff said.
|
||||
- `browser_mod` works outside of `/lovelace`.
|
||||
- This works even if the currently logged in user is not in the admin group.
|
||||
|
||||
### Does this replace lovelace-fullykiosk
|
||||
|
||||
Yes. You need the paid version, btw.
|
||||
|
||||
### Can the deviceID be used to track me across the internet
|
||||
|
||||
No\*. The device is stored in your browsers localStorage - a data store which is sandboxed only to Home Assistant. That means only Home Assistant can access it. Furthermore, different Home Assistant installations cannot acces each others localStorage.
|
||||
|
||||
Some of [my lovelace plugins](https://github.com/thomasloven/hass-config/wiki/My-Lovelace-Plugins) use the device to do different things for different *devices*.
|
||||
Some of [my lovelace plugins](https://github.com/thomasloven/hass-config/wiki/My-Lovelace-Plugins) use the device to do different things for different _devices_.
|
||||
|
||||
> *\*There is one exception. If you are using [Fully Kiosk Browser](https://www.ozerov.de/fully-kiosk-browser/), the deviceID is taken from the browser instead of being randomly generated. This deviceID will be the same for each website that asks for it.*
|
||||
> _\*There is one exception. If you are using [Fully Kiosk Browser](https://www.ozerov.de/fully-kiosk-browser/), the deviceID is taken from the browser instead of being randomly generated. This deviceID will be the same for each website that asks for it._
|
||||
|
||||
### My Fully Kiosk Browser device goes unavailable after the screen has been turned off for five minutes
|
||||
|
||||
@ -517,4 +545,5 @@ browser_mod:
|
||||
That will make the screen turn on and off again for a second regularly to stop the five minute timer from running out.
|
||||
|
||||
---
|
||||
|
||||
<a href="https://www.buymeacoffee.com/uqD6KHCdJ" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/white_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>
|
||||
|
@ -31,11 +31,7 @@ async def async_setup(hass, config):
|
||||
if not hass.config_entries.async_entries(DOMAIN):
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={
|
||||
"source": config_entries.SOURCE_IMPORT
|
||||
},
|
||||
data={}
|
||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data={}
|
||||
)
|
||||
)
|
||||
|
||||
@ -43,7 +39,7 @@ async def async_setup(hass, config):
|
||||
for d in config[DOMAIN].get(CONFIG_DEVICES, {}):
|
||||
name = config[DOMAIN][CONFIG_DEVICES][d].get("name", None)
|
||||
if name:
|
||||
aliases[name] = d.replace('_', '-')
|
||||
aliases[name] = d.replace("_", "-")
|
||||
|
||||
hass.data[DOMAIN] = {
|
||||
DATA_DEVICES: {},
|
||||
@ -51,19 +47,14 @@ async def async_setup(hass, config):
|
||||
DATA_ADDERS: {},
|
||||
DATA_CONFIG: config[DOMAIN],
|
||||
DATA_SETUP_COMPLETE: False,
|
||||
}
|
||||
}
|
||||
|
||||
await setup_connection(hass, config)
|
||||
setup_view(hass)
|
||||
|
||||
for component in COMPONENTS:
|
||||
hass.async_create_task(
|
||||
hass.helpers.discovery.async_load_platform(
|
||||
component,
|
||||
DOMAIN,
|
||||
{},
|
||||
config
|
||||
)
|
||||
hass.helpers.discovery.async_load_platform(component, DOMAIN, {}, config)
|
||||
)
|
||||
|
||||
await setup_service(hass)
|
||||
@ -79,9 +70,6 @@ async def async_setup(hass, config):
|
||||
async def async_setup_entry(hass, config_entry):
|
||||
for component in COMPONENTS:
|
||||
hass.async_create_task(
|
||||
hass.config_entries.async_forward_entry_setup(
|
||||
config_entry,
|
||||
component
|
||||
)
|
||||
hass.config_entries.async_forward_entry_setup(config_entry, component)
|
||||
)
|
||||
return True
|
||||
|
@ -1,12 +1,18 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from homeassistant.const import STATE_UNAVAILABLE, ATTR_BATTERY_CHARGING, ATTR_BATTERY_LEVEL, STATE_ON, STATE_OFF
|
||||
from homeassistant.const import (
|
||||
STATE_UNAVAILABLE,
|
||||
ATTR_BATTERY_CHARGING,
|
||||
ATTR_BATTERY_LEVEL,
|
||||
STATE_ON,
|
||||
STATE_OFF,
|
||||
)
|
||||
from homeassistant.components.binary_sensor import DEVICE_CLASS_MOTION
|
||||
|
||||
from .helpers import setup_platform, BrowserModEntity
|
||||
|
||||
PLATFORM = 'binary_sensor'
|
||||
PLATFORM = "binary_sensor"
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
return setup_platform(hass, config, async_add_devices, PLATFORM, BrowserModSensor)
|
||||
@ -31,14 +37,13 @@ class BrowserModSensor(BrowserModEntity):
|
||||
def state(self):
|
||||
if not self.connection.connection:
|
||||
return STATE_UNAVAILABLE
|
||||
if self.data.get('motion', False):
|
||||
if self.data.get("motion", False):
|
||||
return STATE_ON
|
||||
return STATE_OFF
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
return not self.data.get('motion', False)
|
||||
|
||||
return not self.data.get("motion", False)
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
@ -47,9 +52,9 @@ class BrowserModSensor(BrowserModEntity):
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
return {
|
||||
"type": "browser_mod",
|
||||
"last_seen": self.last_seen,
|
||||
ATTR_BATTERY_LEVEL: self.data.get('battery', None),
|
||||
ATTR_BATTERY_CHARGING: self.data.get('charging', None),
|
||||
**self.data
|
||||
}
|
||||
"type": "browser_mod",
|
||||
"last_seen": self.last_seen,
|
||||
ATTR_BATTERY_LEVEL: self.data.get("battery", None),
|
||||
ATTR_BATTERY_CHARGING: self.data.get("charging", None),
|
||||
**self.data,
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
import base64
|
||||
|
||||
from homeassistant.const import STATE_UNAVAILABLE, STATE_ON, STATE_OFF, STATE_IDLE
|
||||
from homeassistant.components.camera import Camera
|
||||
|
||||
from .helpers import setup_platform, BrowserModEntity
|
||||
|
||||
PLATFORM = 'camera'
|
||||
PLATFORM = "camera"
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
return setup_platform(hass, config, async_add_devices, PLATFORM, BrowserModCamera)
|
||||
@ -31,12 +30,12 @@ class BrowserModCamera(Camera, BrowserModEntity):
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
def camera_image(self):
|
||||
return base64.b64decode(self.data.split(',')[1])
|
||||
return base64.b64decode(self.data.split(",")[1])
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
return {
|
||||
"type": "browser_mod",
|
||||
"deviceID": self.deviceID,
|
||||
"last_seen": self.last_seen,
|
||||
}
|
||||
"type": "browser_mod",
|
||||
"deviceID": self.deviceID,
|
||||
"last_seen": self.last_seen,
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ from homeassistant import config_entries
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
|
||||
class BrowserModConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
|
||||
VERSION = 1
|
||||
|
@ -5,7 +5,7 @@ from homeassistant.components.websocket_api import (
|
||||
websocket_command,
|
||||
result_message,
|
||||
event_message,
|
||||
async_register_command
|
||||
async_register_command,
|
||||
)
|
||||
|
||||
from .const import WS_CONNECT, WS_UPDATE
|
||||
@ -15,26 +15,28 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def setup_connection(hass, config):
|
||||
|
||||
@websocket_command({
|
||||
vol.Required("type"): WS_CONNECT,
|
||||
vol.Required("deviceID"): str,
|
||||
})
|
||||
@websocket_command(
|
||||
{
|
||||
vol.Required("type"): WS_CONNECT,
|
||||
vol.Required("deviceID"): str,
|
||||
}
|
||||
)
|
||||
def handle_connect(hass, connection, msg):
|
||||
deviceID = msg["deviceID"]
|
||||
|
||||
device = get_devices(hass).get(deviceID,
|
||||
BrowserModConnection(hass, deviceID))
|
||||
device = get_devices(hass).get(deviceID, BrowserModConnection(hass, deviceID))
|
||||
device.connect(connection, msg["id"])
|
||||
get_devices(hass)[deviceID] = device
|
||||
|
||||
connection.send_message(result_message(msg["id"]))
|
||||
|
||||
@websocket_command({
|
||||
vol.Required("type"): WS_UPDATE,
|
||||
vol.Required("deviceID"): str,
|
||||
vol.Optional("data"): dict,
|
||||
})
|
||||
@websocket_command(
|
||||
{
|
||||
vol.Required("type"): WS_UPDATE,
|
||||
vol.Required("deviceID"): str,
|
||||
vol.Optional("data"): dict,
|
||||
}
|
||||
)
|
||||
def handle_update(hass, connection, msg):
|
||||
devices = get_devices(hass)
|
||||
deviceID = msg["deviceID"]
|
||||
@ -69,57 +71,52 @@ class BrowserModConnection:
|
||||
def send(self, command, **kwargs):
|
||||
if self.connection:
|
||||
connection, cid = self.connection[-1]
|
||||
connection.send_message(event_message(cid, {
|
||||
"command": command,
|
||||
**kwargs,
|
||||
}))
|
||||
connection.send_message(
|
||||
event_message(
|
||||
cid,
|
||||
{
|
||||
"command": command,
|
||||
**kwargs,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
def trigger_update(self):
|
||||
if is_setup_complete(self.hass):
|
||||
self.send("update", **get_config(self.hass, self.deviceID))
|
||||
|
||||
def update(self, data):
|
||||
if data.get('browser'):
|
||||
if data.get("browser"):
|
||||
self.sensor = self.sensor or create_entity(
|
||||
self.hass,
|
||||
'sensor',
|
||||
self.deviceID,
|
||||
self)
|
||||
self.hass, "sensor", self.deviceID, self
|
||||
)
|
||||
if self.sensor:
|
||||
self.sensor.data = data.get('browser')
|
||||
self.sensor.data = data.get("browser")
|
||||
|
||||
if data.get('player'):
|
||||
if data.get("player"):
|
||||
self.media_player = self.media_player or create_entity(
|
||||
self.hass,
|
||||
'media_player',
|
||||
self.deviceID,
|
||||
self)
|
||||
self.hass, "media_player", self.deviceID, self
|
||||
)
|
||||
if self.media_player:
|
||||
self.media_player.data = data.get('player')
|
||||
self.media_player.data = data.get("player")
|
||||
|
||||
if data.get('screen'):
|
||||
if data.get("screen"):
|
||||
self.screen = self.screen or create_entity(
|
||||
self.hass,
|
||||
'light',
|
||||
self.deviceID,
|
||||
self)
|
||||
self.hass, "light", self.deviceID, self
|
||||
)
|
||||
if self.screen:
|
||||
self.screen.data = data.get('screen')
|
||||
self.screen.data = data.get("screen")
|
||||
|
||||
if data.get('fully'):
|
||||
if data.get("fully"):
|
||||
self.fully = self.fully or create_entity(
|
||||
self.hass,
|
||||
'binary_sensor',
|
||||
self.deviceID,
|
||||
self)
|
||||
self.hass, "binary_sensor", self.deviceID, self
|
||||
)
|
||||
if self.fully:
|
||||
self.fully.data = data.get('fully')
|
||||
self.fully.data = data.get("fully")
|
||||
|
||||
if data.get('camera'):
|
||||
if data.get("camera"):
|
||||
self.camera = self.camera or create_entity(
|
||||
self.hass,
|
||||
'camera',
|
||||
self.deviceID,
|
||||
self)
|
||||
self.hass, "camera", self.deviceID, self
|
||||
)
|
||||
if self.camera:
|
||||
self.camera.data = data.get('camera')
|
||||
self.camera.data = data.get("camera")
|
||||
|
@ -2,7 +2,7 @@ DOMAIN = "browser_mod"
|
||||
|
||||
FRONTEND_SCRIPT_URL = "/browser_mod.js"
|
||||
|
||||
DATA_EXTRA_MODULE_URL = 'frontend_extra_module_url'
|
||||
DATA_EXTRA_MODULE_URL = "frontend_extra_module_url"
|
||||
|
||||
DATA_DEVICES = "devices"
|
||||
DATA_ALIASES = "aliases"
|
||||
@ -21,18 +21,18 @@ WS_UPDATE = "{}/update".format(WS_ROOT)
|
||||
WS_CAMERA = "{}/camera".format(WS_ROOT)
|
||||
|
||||
USER_COMMANDS = [
|
||||
"debug",
|
||||
"popup",
|
||||
"close-popup",
|
||||
"navigate",
|
||||
"more-info",
|
||||
"set-theme",
|
||||
"lovelace-reload",
|
||||
"window-reload",
|
||||
"blackout",
|
||||
"no-blackout",
|
||||
"toast",
|
||||
"commands",
|
||||
"call_service",
|
||||
"delay",
|
||||
]
|
||||
"debug",
|
||||
"popup",
|
||||
"close-popup",
|
||||
"navigate",
|
||||
"more-info",
|
||||
"set-theme",
|
||||
"lovelace-reload",
|
||||
"window-reload",
|
||||
"blackout",
|
||||
"no-blackout",
|
||||
"toast",
|
||||
"commands",
|
||||
"call_service",
|
||||
"delay",
|
||||
]
|
||||
|
@ -31,18 +31,20 @@ def get_alias(hass, deviceID):
|
||||
|
||||
def get_config(hass, deviceID):
|
||||
config = hass.data[DOMAIN][DATA_CONFIG].get(CONFIG_DEVICES, {})
|
||||
return config.get(deviceID, config.get(deviceID.replace('-', '_'), {}))
|
||||
return config.get(deviceID, config.get(deviceID.replace("-", "_"), {}))
|
||||
|
||||
|
||||
def create_entity(hass, platform, deviceID, connection):
|
||||
conf = get_config(hass, deviceID)
|
||||
if conf and (platform in conf.get(CONFIG_DISABLE, [])
|
||||
or CONFIG_DISABLE_ALL in conf.get(CONFIG_DISABLE, [])):
|
||||
if conf and (
|
||||
platform in conf.get(CONFIG_DISABLE, [])
|
||||
or CONFIG_DISABLE_ALL in conf.get(CONFIG_DISABLE, [])
|
||||
):
|
||||
return None
|
||||
if not conf and \
|
||||
(platform in hass.data[DOMAIN][DATA_CONFIG].get(CONFIG_DISABLE, [])
|
||||
or CONFIG_DISABLE_ALL in
|
||||
hass.data[DOMAIN][DATA_CONFIG].get(CONFIG_DISABLE, [])):
|
||||
if not conf and (
|
||||
platform in hass.data[DOMAIN][DATA_CONFIG].get(CONFIG_DISABLE, [])
|
||||
or CONFIG_DISABLE_ALL in hass.data[DOMAIN][DATA_CONFIG].get(CONFIG_DISABLE, [])
|
||||
):
|
||||
return None
|
||||
adder = hass.data[DOMAIN][DATA_ADDERS][platform]
|
||||
entity = adder(hass, deviceID, connection, get_alias(hass, deviceID))
|
||||
@ -57,6 +59,7 @@ def setup_platform(hass, config, async_add_devices, platform, cls):
|
||||
entity = cls(hass, connection, deviceID, alias)
|
||||
async_add_devices([entity])
|
||||
return entity
|
||||
|
||||
hass.data[DOMAIN][DATA_ADDERS][platform] = adder
|
||||
return True
|
||||
|
||||
@ -66,19 +69,16 @@ def is_setup_complete(hass):
|
||||
|
||||
|
||||
class BrowserModEntity(Entity):
|
||||
|
||||
def __init__(self, hass, connection, deviceID, alias=None):
|
||||
self.hass = hass
|
||||
self.connection = connection
|
||||
self.deviceID = deviceID
|
||||
self._data = {}
|
||||
self._alias = alias
|
||||
prefix = hass.data[DOMAIN][DATA_CONFIG].get(CONFIG_PREFIX, '')
|
||||
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
|
||||
)
|
||||
self.domain + ".{}", alias or f"{prefix}{deviceID}", hass=hass
|
||||
)
|
||||
|
||||
def updated(self):
|
||||
pass
|
||||
@ -86,10 +86,8 @@ class BrowserModEntity(Entity):
|
||||
@property
|
||||
def device_info(self):
|
||||
return {
|
||||
"identifiers": {
|
||||
(DOMAIN, self.deviceID)
|
||||
},
|
||||
"name": self._alias or self.deviceID
|
||||
"identifiers": {(DOMAIN, self.deviceID)},
|
||||
"name": self._alias or self.deviceID,
|
||||
}
|
||||
|
||||
@property
|
||||
|
@ -1,4 +1,3 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from homeassistant.const import STATE_UNAVAILABLE, STATE_ON, STATE_OFF
|
||||
@ -6,7 +5,8 @@ from homeassistant.components.light import LightEntity, SUPPORT_BRIGHTNESS
|
||||
|
||||
from .helpers import setup_platform, BrowserModEntity
|
||||
|
||||
PLATFORM = 'light'
|
||||
PLATFORM = "light"
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
return setup_platform(hass, config, async_add_devices, PLATFORM, BrowserModLight)
|
||||
@ -31,31 +31,31 @@ class BrowserModLight(LightEntity, BrowserModEntity):
|
||||
def state(self):
|
||||
if not self.connection.connection:
|
||||
return STATE_UNAVAILABLE
|
||||
if self.data.get('blackout', False):
|
||||
if self.data.get("blackout", False):
|
||||
return STATE_OFF
|
||||
return STATE_ON
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
return not self.data.get('blackout', False)
|
||||
return not self.data.get("blackout", False)
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
return {
|
||||
"type": "browser_mod",
|
||||
"deviceID": self.deviceID,
|
||||
"last_seen": self.last_seen,
|
||||
}
|
||||
"type": "browser_mod",
|
||||
"deviceID": self.deviceID,
|
||||
"last_seen": self.last_seen,
|
||||
}
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
if self.data.get('brightness', False):
|
||||
if self.data.get("brightness", False):
|
||||
return SUPPORT_BRIGHTNESS
|
||||
return 0
|
||||
|
||||
@property
|
||||
def brightness(self):
|
||||
return self.data.get('brightness', None)
|
||||
return self.data.get("brightness", None)
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
self.connection.send("no-blackout", **kwargs)
|
||||
|
@ -1,23 +1,27 @@
|
||||
import logging
|
||||
from homeassistant.components.media_player import (
|
||||
SUPPORT_PLAY, SUPPORT_PLAY_MEDIA,
|
||||
SUPPORT_PAUSE, SUPPORT_STOP,
|
||||
SUPPORT_VOLUME_SET, SUPPORT_VOLUME_MUTE,
|
||||
MediaPlayerEntity,
|
||||
)
|
||||
SUPPORT_PLAY,
|
||||
SUPPORT_PLAY_MEDIA,
|
||||
SUPPORT_PAUSE,
|
||||
SUPPORT_STOP,
|
||||
SUPPORT_VOLUME_SET,
|
||||
SUPPORT_VOLUME_MUTE,
|
||||
MediaPlayerEntity,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_PAUSED,
|
||||
STATE_PLAYING,
|
||||
STATE_IDLE,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_PAUSED,
|
||||
STATE_PLAYING,
|
||||
STATE_IDLE,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
|
||||
from .helpers import setup_platform, BrowserModEntity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PLATFORM = 'media_player'
|
||||
PLATFORM = "media_player"
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
return setup_platform(hass, config, async_add_devices, PLATFORM, BrowserModPlayer)
|
||||
@ -40,9 +44,9 @@ class BrowserModPlayer(MediaPlayerEntity, BrowserModEntity):
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
return {
|
||||
"type": "browser_mod",
|
||||
"deviceID": self.deviceID,
|
||||
}
|
||||
"type": "browser_mod",
|
||||
"deviceID": self.deviceID,
|
||||
}
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
@ -50,37 +54,48 @@ class BrowserModPlayer(MediaPlayerEntity, BrowserModEntity):
|
||||
return STATE_UNAVAILABLE
|
||||
state = self.data.get("state", "unknown")
|
||||
return {
|
||||
"playing": STATE_PLAYING,
|
||||
"paused": STATE_PAUSED,
|
||||
"stopped": STATE_IDLE,
|
||||
}.get(state, STATE_UNKNOWN)
|
||||
"playing": STATE_PLAYING,
|
||||
"paused": STATE_PAUSED,
|
||||
"stopped": STATE_IDLE,
|
||||
}.get(state, STATE_UNKNOWN)
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
return (
|
||||
SUPPORT_PLAY | SUPPORT_PLAY_MEDIA |
|
||||
SUPPORT_PAUSE | SUPPORT_STOP |
|
||||
SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE
|
||||
)
|
||||
SUPPORT_PLAY
|
||||
| SUPPORT_PLAY_MEDIA
|
||||
| SUPPORT_PAUSE
|
||||
| SUPPORT_STOP
|
||||
| SUPPORT_VOLUME_SET
|
||||
| SUPPORT_VOLUME_MUTE
|
||||
)
|
||||
|
||||
@property
|
||||
def volume_level(self):
|
||||
return self.data.get("volume", 0)
|
||||
|
||||
@property
|
||||
def is_volume_muted(self):
|
||||
return self.data.get("muted", False)
|
||||
|
||||
@property
|
||||
def media_content_id(self):
|
||||
return self.data.get("src", "")
|
||||
|
||||
def set_volume_level(self, volume):
|
||||
self.connection.send("set_volume", volume_level=volume)
|
||||
|
||||
def mute_volume(self, mute):
|
||||
self.connection.send("mute", mute=mute)
|
||||
|
||||
def play_media(self, media_type, media_id, **kwargs):
|
||||
self.connection.send("play", media_content_id=media_id)
|
||||
|
||||
def media_play(self):
|
||||
self.connection.send("play")
|
||||
|
||||
def media_pause(self):
|
||||
self.connection.send("pause")
|
||||
|
||||
def media_stop(self):
|
||||
self.connection.send("stop")
|
||||
|
@ -12,6 +12,7 @@ def setup_view(hass):
|
||||
|
||||
hass.http.register_view(ModView(hass, FRONTEND_SCRIPT_URL))
|
||||
|
||||
|
||||
class ModView(HomeAssistantView):
|
||||
|
||||
name = "browser_mod_script"
|
||||
@ -33,4 +34,6 @@ class ModView(HomeAssistantView):
|
||||
except Exception as exception:
|
||||
pass
|
||||
|
||||
return web.Response(body=filecontent, content_type="text/javascript", charset="utf-8")
|
||||
return web.Response(
|
||||
body=filecontent, content_type="text/javascript", charset="utf-8"
|
||||
)
|
||||
|
@ -5,7 +5,8 @@ from homeassistant.const import STATE_UNAVAILABLE
|
||||
|
||||
from .helpers import setup_platform, BrowserModEntity
|
||||
|
||||
PLATFORM = 'sensor'
|
||||
PLATFORM = "sensor"
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
return setup_platform(hass, config, async_add_devices, PLATFORM, BrowserModSensor)
|
||||
@ -35,8 +36,8 @@ class BrowserModSensor(BrowserModEntity):
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
return {
|
||||
"type": "browser_mod",
|
||||
"last_seen": self.last_seen,
|
||||
"deviceID": self.deviceID,
|
||||
**self.data
|
||||
}
|
||||
"type": "browser_mod",
|
||||
"last_seen": self.last_seen,
|
||||
"deviceID": self.deviceID,
|
||||
**self.data,
|
||||
}
|
||||
|
@ -2,20 +2,23 @@ import logging
|
||||
|
||||
from homeassistant.helpers.entity_registry import (
|
||||
async_entries_for_config_entry,
|
||||
async_entries_for_device
|
||||
async_entries_for_device,
|
||||
)
|
||||
from homeassistant.const import STATE_UNAVAILABLE
|
||||
|
||||
from .const import (
|
||||
DOMAIN, DATA_DEVICES, DATA_ALIASES,
|
||||
USER_COMMANDS, DATA_CONFIG, CONFIG_DEVICES
|
||||
DOMAIN,
|
||||
DATA_DEVICES,
|
||||
DATA_ALIASES,
|
||||
USER_COMMANDS,
|
||||
DATA_CONFIG,
|
||||
CONFIG_DEVICES,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def setup_service(hass):
|
||||
|
||||
def handle_command(call):
|
||||
command = call.data.get("command", None)
|
||||
if not command:
|
||||
@ -38,23 +41,19 @@ async def setup_service(hass):
|
||||
devices[t].send(command, **data)
|
||||
|
||||
def command_wrapper(call):
|
||||
command = call.service.replace('_', '-')
|
||||
command = call.service.replace("_", "-")
|
||||
call.data = dict(call.data)
|
||||
call.data['command'] = command
|
||||
call.data["command"] = command
|
||||
handle_command(call)
|
||||
|
||||
hass.services.async_register(DOMAIN, 'command', handle_command)
|
||||
hass.services.async_register(DOMAIN, "command", handle_command)
|
||||
for cmd in USER_COMMANDS:
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
cmd.replace('-', '_'),
|
||||
command_wrapper
|
||||
)
|
||||
hass.services.async_register(DOMAIN, cmd.replace("-", "_"), command_wrapper)
|
||||
|
||||
async def call_service(service_call):
|
||||
await async_clean_devices(hass, service_call.data)
|
||||
|
||||
hass.services.async_register(DOMAIN, 'clean_devices', call_service)
|
||||
hass.services.async_register(DOMAIN, "clean_devices", call_service)
|
||||
|
||||
|
||||
async def async_clean_devices(hass, data):
|
||||
@ -63,14 +62,12 @@ async def async_clean_devices(hass, data):
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
device_registry = await hass.helpers.device_registry.async_get_registry()
|
||||
entity_entries = async_entries_for_config_entry(
|
||||
entity_registry,
|
||||
config_entry.entry_id
|
||||
entity_registry, config_entry.entry_id
|
||||
)
|
||||
|
||||
device_entries = [
|
||||
entry
|
||||
for entry
|
||||
in device_registry.devices.values()
|
||||
for entry in device_registry.devices.values()
|
||||
if config_entry.entry_id in entry.config_entries
|
||||
]
|
||||
|
||||
@ -103,7 +100,4 @@ async def async_clean_devices(hass, data):
|
||||
|
||||
devices = hass.data[DOMAIN][DATA_DEVICES]
|
||||
for rec in devices:
|
||||
devices[rec].send(
|
||||
'toast',
|
||||
message=f"Removed devices: {removed}"
|
||||
)
|
||||
devices[rec].send("toast", message=f"Removed devices: {removed}")
|
||||
|
@ -1,128 +1,128 @@
|
||||
command:
|
||||
description: 'Send a command to a browser.'
|
||||
description: "Send a command to a browser."
|
||||
fields:
|
||||
command:
|
||||
description: 'Command to send'
|
||||
example: 'navigate'
|
||||
description: "Command to send"
|
||||
example: "navigate"
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
commands:
|
||||
description: 'Send several commands to a browser'
|
||||
description: "Send several commands to a browser"
|
||||
fields:
|
||||
commands:
|
||||
description: "List of commands to send"
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
debug:
|
||||
description: 'On all browsers, show a popup, and a javascript alert with the current device ID.'
|
||||
description: "On all browsers, show a popup, and a javascript alert with the current device ID."
|
||||
fields:
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
set_theme:
|
||||
description: 'On all browsers, change the theme.'
|
||||
description: "On all browsers, change the theme."
|
||||
fields:
|
||||
theme:
|
||||
description: 'Theme to change to'
|
||||
description: "Theme to change to"
|
||||
example: '{theme: "clear_light"}'
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
navigate:
|
||||
description: 'Navigate to a path on a browser.'
|
||||
description: "Navigate to a path on a browser."
|
||||
fields:
|
||||
navigation_path:
|
||||
description: 'Path to navigate to'
|
||||
example: '/lovelace/1'
|
||||
description: "Path to navigate to"
|
||||
example: "/lovelace/1"
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
more_info:
|
||||
description: 'Open the more info dialog of an entity on a browser.'
|
||||
description: "Open the more info dialog of an entity on a browser."
|
||||
fields:
|
||||
entity_id:
|
||||
description: 'Entity to show more info for'
|
||||
example: 'camera.front_door'
|
||||
description: "Entity to show more info for"
|
||||
example: "camera.front_door"
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
large:
|
||||
description: '(optional) Set to true to make wider'
|
||||
example: 'true'
|
||||
description: "(optional) Set to true to make wider"
|
||||
example: "true"
|
||||
toast:
|
||||
description: 'Show a toast message in the bottom left on all browsers.'
|
||||
description: "Show a toast message in the bottom left on all browsers."
|
||||
fields:
|
||||
message:
|
||||
description: 'Message to show'
|
||||
example: 'Short message'
|
||||
description: "Message to show"
|
||||
example: "Short message"
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
duration:
|
||||
description: '(optional) Time in milliseconds to show message for. Set to 0 for persistent display.'
|
||||
example: '10000'
|
||||
description: "(optional) Time in milliseconds to show message for. Set to 0 for persistent display."
|
||||
example: "10000"
|
||||
popup:
|
||||
description: 'Pop up a card on a browser.'
|
||||
description: "Pop up a card on a browser."
|
||||
fields:
|
||||
title:
|
||||
description: 'Name to show in popup bar'
|
||||
example: 'Popup example'
|
||||
description: "Name to show in popup bar"
|
||||
example: "Popup example"
|
||||
card:
|
||||
description: 'YAML config for card to show'
|
||||
description: "YAML config for card to show"
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
large:
|
||||
description: '(optional) Set to true to make wider'
|
||||
example: 'true'
|
||||
description: "(optional) Set to true to make wider"
|
||||
example: "true"
|
||||
hide_header:
|
||||
description: '(optional) Hide header title and close button'
|
||||
example: 'true'
|
||||
description: "(optional) Hide header title and close button"
|
||||
example: "true"
|
||||
auto_close:
|
||||
description: '(optional) Close popup when mouse is moved or key is pressed. Also hides header'
|
||||
example: 'true'
|
||||
description: "(optional) Close popup when mouse is moved or key is pressed. Also hides header"
|
||||
example: "true"
|
||||
time:
|
||||
description: "(optional) When mouse isn't moved or keys aren't pressed for this amount of seconds, reopen. Only usable with auto_close. See blackout"
|
||||
example: '20'
|
||||
example: "20"
|
||||
close_popup:
|
||||
description: 'Close all popups on all browsers.'
|
||||
description: "Close all popups on all browsers."
|
||||
fields:
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
blackout:
|
||||
description: 'Cover screen in black until the mouse is moved or a key is pressed.'
|
||||
description: "Cover screen in black until the mouse is moved or a key is pressed."
|
||||
fields:
|
||||
time:
|
||||
description: '(optional) The blackout will 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.'
|
||||
example: '20'
|
||||
description: "(optional) The blackout will 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."
|
||||
example: "20"
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
no_blackout:
|
||||
description: 'Remove a blackout from a browser.'
|
||||
description: "Remove a blackout from a browser."
|
||||
fields:
|
||||
brightness:
|
||||
description: '(optional) On a Fully Kiosk Browser Plus set the screen brightness from 0 - 255.'
|
||||
description: "(optional) On a Fully Kiosk Browser Plus set the screen brightness from 0 - 255."
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
lovelace_reload:
|
||||
description: 'Refresh the lovelace configuration.'
|
||||
description: "Refresh the lovelace configuration."
|
||||
fields:
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
delay:
|
||||
description: 'Do nothing for a while'
|
||||
description: "Do nothing for a while"
|
||||
fields:
|
||||
seconds:
|
||||
description: 'Number of seconds to delay'
|
||||
example: '5'
|
||||
description: "Number of seconds to delay"
|
||||
example: "5"
|
||||
deviceID:
|
||||
description: '(optional) List of receiving browsers'
|
||||
description: "(optional) List of receiving browsers"
|
||||
example: '["99980b13-dabc9563", "office_computer"]'
|
||||
call_service:
|
||||
description: ""
|
||||
|
Loading…
x
Reference in New Issue
Block a user