Fork sync

This commit is contained in:
SBado
2020-10-26 09:09:25 +01:00
26 changed files with 792 additions and 468 deletions

View File

@@ -3,39 +3,50 @@ import logging
from .mod_view import setup_view
from .connection import setup_connection
from .service import setup_service
from .const import DOMAIN, DATA_DEVICES, DATA_ALIASES, DATA_ADDERS, CONFIG_DEVICES, DATA_CONFIG
from .const import (
DOMAIN,
DATA_DEVICES,
DATA_ALIASES,
DATA_ADDERS,
CONFIG_DEVICES,
DATA_CONFIG,
DATA_SETUP_COMPLETE,
)
_LOGGER = logging.getLogger(__name__)
async def async_setup(hass, config):
await setup_connection(hass, config)
setup_view(hass)
async def async_setup(hass, config):
aliases = {}
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: {},
DATA_ALIASES: aliases,
DATA_ADDERS: {},
DATA_CONFIG: config[DOMAIN],
DATA_SETUP_COMPLETE: False,
}
await hass.helpers.discovery.async_load_platform("media_player", DOMAIN, {}, config)
await hass.helpers.discovery.async_load_platform("sensor", DOMAIN, {}, config)
await hass.helpers.discovery.async_load_platform("binary_sensor", DOMAIN, {}, config)
await hass.helpers.discovery.async_load_platform("light", DOMAIN, {}, config)
await hass.helpers.discovery.async_load_platform("camera", DOMAIN, {}, config)
await setup_connection(hass, config)
setup_view(hass)
async_load_platform = hass.helpers.discovery.async_load_platform
await async_load_platform("media_player", DOMAIN, {}, config)
await async_load_platform("sensor", DOMAIN, {}, config)
await async_load_platform("binary_sensor", DOMAIN, {}, config)
await async_load_platform("light", DOMAIN, {}, config)
await async_load_platform("camera", DOMAIN, {}, config)
await setup_service(hass)
hass.data[DOMAIN][DATA_SETUP_COMPLETE] = True
for device in hass.data[DOMAIN][DATA_DEVICES].values():
device.trigger_update()
return True

File diff suppressed because one or more lines are too long

View File

@@ -21,7 +21,8 @@ class BrowserModCamera(Camera, BrowserModEntity):
self.last_seen = None
def updated(self):
self.last_seen = datetime.now()
if self.last_seen is None or (datetime.now() - self.last_seen).seconds > 15:
self.last_seen = datetime.now()
self.schedule_update_ha_state()
def camera_image(self):

View File

@@ -1,14 +1,19 @@
import logging
import voluptuous as vol
from homeassistant.components.websocket_api import websocket_command, result_message, event_message, async_register_command
from homeassistant.helpers.entity import Entity, async_generate_entity_id
from homeassistant.components.websocket_api import (
websocket_command,
result_message,
event_message,
async_register_command
)
from .const import DOMAIN, WS_CONNECT, WS_UPDATE, WS_CAMERA
from .helpers import get_devices, create_entity, get_config
from .const import WS_CONNECT, WS_UPDATE
from .helpers import get_devices, create_entity, get_config, is_setup_complete
_LOGGER = logging.getLogger(__name__)
async def setup_connection(hass, config):
@websocket_command({
@@ -18,7 +23,8 @@ async def setup_connection(hass, config):
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
@@ -29,7 +35,7 @@ async def setup_connection(hass, config):
vol.Required("deviceID"): str,
vol.Optional("data"): dict,
})
def handle_update( hass, connection, msg):
def handle_update(hass, connection, msg):
devices = get_devices(hass)
deviceID = msg["deviceID"]
if deviceID in devices:
@@ -38,6 +44,7 @@ async def setup_connection(hass, config):
async_register_command(hass, handle_connect)
async_register_command(hass, handle_update)
class BrowserModConnection:
def __init__(self, hass, deviceID):
self.hass = hass
@@ -52,7 +59,7 @@ class BrowserModConnection:
def connect(self, connection, cid):
self.connection.append((connection, cid))
self.send("update", **get_config(self.hass, self.deviceID))
self.trigger_update()
def disconnect():
self.connection.remove((connection, cid))
@@ -67,6 +74,10 @@ class BrowserModConnection:
**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'):
self.sensor = self.sensor or create_entity(
@@ -112,4 +123,3 @@ class BrowserModConnection:
self)
if self.camera:
self.camera.data = data.get('camera')

View File

@@ -8,6 +8,7 @@ DATA_DEVICES = "devices"
DATA_ALIASES = "aliases"
DATA_ADDERS = "adders"
DATA_CONFIG = "config"
DATA_SETUP_COMPLETE = "setup_complete"
CONFIG_DEVICES = "devices"
CONFIG_PREFIX = "prefix"

View File

@@ -2,35 +2,53 @@ import logging
from homeassistant.helpers.entity import Entity, async_generate_entity_id
from .const import DOMAIN, DATA_DEVICES, DATA_ALIASES, DATA_ADDERS, CONFIG_DEVICES, DATA_CONFIG, CONFIG_PREFIX, CONFIG_DISABLE, CONFIG_DISABLE_ALL
from .const import (
DOMAIN,
DATA_DEVICES,
DATA_ALIASES,
DATA_ADDERS,
CONFIG_DEVICES,
DATA_CONFIG,
CONFIG_PREFIX,
CONFIG_DISABLE,
CONFIG_DISABLE_ALL,
DATA_SETUP_COMPLETE,
)
_LOGGER = logging.getLogger(__name__)
def get_devices(hass):
return hass.data[DOMAIN][DATA_DEVICES]
def get_alias(hass, deviceID):
for k,v in hass.data[DOMAIN][DATA_ALIASES].items():
for k, v in hass.data[DOMAIN][DATA_ALIASES].items():
if v == deviceID:
return k
return None
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, [])):
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))
return entity
def setup_platform(hass, config, async_add_devices, platform, cls):
def adder(hass, deviceID, connection, alias=None):
entity = cls(hass, connection, deviceID, alias)
@@ -39,6 +57,11 @@ def setup_platform(hass, config, async_add_devices, platform, cls):
hass.data[DOMAIN][DATA_ADDERS][platform] = adder
return True
def is_setup_complete(hass):
return hass.data[DOMAIN][DATA_SETUP_COMPLETE]
class BrowserModEntity(Entity):
def __init__(self, hass, connection, deviceID, alias=None):
@@ -47,7 +70,11 @@ class BrowserModEntity(Entity):
self.deviceID = deviceID
self._data = {}
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.entity_id = async_generate_entity_id(
self.domain+".{}",
alias or f"{prefix}{deviceID}",
hass=hass
)
def updated(self):
pass
@@ -55,6 +82,7 @@ class BrowserModEntity(Entity):
@property
def data(self):
return self._data
@data.setter
def data(self, data):
self._data = data

View File

@@ -48,6 +48,10 @@ class BrowserModLight(LightEntity, BrowserModEntity):
return SUPPORT_BRIGHTNESS
return 0
@property
def brightness(self):
return self.data.get('brightness', None)
def turn_on(self, **kwargs):
self.connection.send("no-blackout", **kwargs)

View File

@@ -1,9 +1,85 @@
command:
description: Send a command to a browser
description: 'Send a command to a browser.'
fields:
command:
description: Command to send
description: 'Command to send'
example: 'navigate'
deviceID:
description: List of receiving browsers
description: '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.'
set_theme:
description: 'On all browsers, change the theme.'
fields:
theme:
description: 'Theme to change to'
example: '{theme: "clear_light"}'
navigate:
description: 'Navigate to a path on a browser.'
fields:
navigation_path:
description: 'Path to navigate to'
example: '/lovelace/1'
deviceID:
description: 'List of receiving browsers'
example: '["99980b13-dabc9563", "office_computer"]'
more_info:
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'
deviceID:
description: 'List of receiving browsers'
example: '["99980b13-dabc9563", "office_computer"]'
large:
description: '(optional) Set to true to make wider'
example: 'true'
toast:
description: 'Show a toast message in the bottom left on all browsers.'
fields:
message:
description: 'Message to show'
example: 'Short message'
duration:
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.'
fields:
title:
description: 'Name to show in popup bar'
example: 'Popup example'
card:
description: 'YAML config for card to show'
deviceID:
description: 'List of receiving browsers'
example: '["99980b13-dabc9563", "office_computer"]'
large:
description: '(optional) Set to true to make wider'
example: 'true'
hide_header:
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'
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'
close_popup:
description: 'Close all popups on all browsers.'
blackout:
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'
no_blackout:
description: 'Remove a blackout from a browser.'
fields:
brightness:
description: '(optional) On a Fully Kiosk Browser Plus set the screen brightness from 0 - 255.'
lovelace_reload:
description: 'Refresh the lovelace configuration.'