Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support both mechanisms #123

Merged
merged 4 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 46 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,28 @@ _Virtual_ is a component that provides virtual entities for _Home Assistant_.

![icon](images/virtual-icon.png)


# !!!BREAKING CHANGES!!!

Version 0.9 supports adding virtual devices using _config flow_. By default it
will move your existing devices into a single file `virtual.yaml`. If you
**DO NOT** want this behaviour add this to your `virtual` configuration.

```yaml
virtual:
yaml_config: True
```


# Table Of Contents

<!-- TOC -->
* [**Virtual devices for Home Assistant**](#virtual-devices-for-home-assistant)
* [!!!BREAKING CHANGES!!!](#breaking-changes)
* [Table Of Contents](#table-of-contents)
* [Introduction](#introduction)
* [Notes](#notes)
* [Version 0.8?](#version-08)
* [Version 0.8 Documentation](#version-08-documentation)
* [New Features in 0.9.0](#new-features-in-090)
* [Config Flow](#config-flow)
* [What pieces are done](#what-pieces-are-done)
Expand All @@ -22,9 +36,10 @@ _Virtual_ is a component that provides virtual entities for _Home Assistant_.
* [Installation](#installation)
* [HACS](#hacs)
* [Component Configuration](#component-configuration)
* [Availability](#availability)
* [Persistence](#persistence)
* [Platforms](#platforms)
* [Entity Configuration](#entity-configuration)
* [Common Attributes](#common-attributes)
* [Availability](#availability)
* [Persistence](#persistence)
* [Switches](#switches)
* [Binary Sensors](#binary-sensors)
* [Sensors](#sensors)
Expand All @@ -34,9 +49,11 @@ _Virtual_ is a component that provides virtual entities for _Home Assistant_.
* [Covers](#covers)
* [Valves](#valves)
* [Device Tracking](#device-tracking)
* [Old Style Entity Configuration](#old-style-entity-configuration)
* [Services](#services)
<!-- TOC -->


# Introduction

Virtual provides virtual components for testing Home Assistant systems.
Expand All @@ -46,7 +63,7 @@ Wherever you see `/config` in this README it refers to your home-assistant
configuration directory. For me, for example, it's `/home/steve/ha` that is
mapped to `/config` inside my docker container.

## Version 0.8?
## Version 0.8 Documentation

**This documentation is for the 0.9.x version, you can find the
0.8.x version** [here](https://github.com/twrecked/hass-virtual/tree/version-0.8.x#readme).
Expand Down Expand Up @@ -141,6 +158,19 @@ development branches this is the easiest way to install.

# Component Configuration

- `yaml_config`; set to `True` to enable backwards compatability, set to `False`
to disable it. The default is `False`.

For example, this enable backwards compatability.

```yaml
virtual:
yaml_config: True
```


# Entity Configuration

All component configuration is done through a _yaml_ file. There is a single
file per integration instance. The default file, created on upgrade, is
`/config/virtual.yaml`. An empty file looks like this:
Expand Down Expand Up @@ -227,7 +257,9 @@ Living Room Multi Sensor:
class: temperature
```

## Availability
## Common Attributes

### Availability

By default, all devices are market as available. As shown below in each domain,
adding `initial_availability: false` to configuration can override default and
Expand All @@ -236,8 +268,7 @@ the `virtual.set_available` with value `true` or `false`.

This is fully optional and `initial_availability` is not required to be set.


## Persistence
### Persistence
By default, all device states are persistent. You can change this behaviour with
the `persistent` configuration option.

Expand All @@ -252,8 +283,6 @@ Test Switch:
initial_value: on
```

# Platforms

## Switches

To add a virtual switch use the following:
Expand All @@ -263,7 +292,6 @@ Test Switch:
- platform: switch
```


## Binary Sensors
To add a virtual binary_sensor use the following. It supports all standard
classes.
Expand All @@ -278,7 +306,6 @@ Test Binary Sensor:
Use the `virtual.turn_on`, `virtual.turn_off` and `virtual.toggle` services to
manipulate the binary sensors.


## Sensors

To add a virtual sensor use the following:
Expand Down Expand Up @@ -323,7 +350,6 @@ Only `name` is required.

_Note; *white_value is deprecated and will be removed in future releases._


## Locks

To add a virtual lock use the following:
Expand All @@ -346,7 +372,6 @@ Test Lock:
- `jamming_test`: optional, default `0` tries; any positive value will result in a
jamming failure approximately once per `jamming_test` tries


## Fans

To add a virtual fan use the following:
Expand All @@ -367,7 +392,6 @@ You only need one of `speed` or `speed_count`.
- `direction`; if `True` then fan can run in 2 directions
- `oscillate`; if `True` then fan can be set to oscillate


## Covers

To add a virtual cover use the following:
Expand All @@ -385,7 +409,6 @@ the cover is emulated with timed events, and the timing can be controlled with
- `open_close_duration`: The time it take to go from fully open to fully closed, or back
- `open_close_tick`: The update interval when opening and closing


## Valves

To add a virtual valve use the following:
Expand All @@ -403,7 +426,6 @@ the valve is emulated with timed events, and the timing can be controlled with
- `open_close_duration`: The time it take to go from fully open to fully closed, or back
- `open_close_tick`: The update interval when opening and closing


## Device Tracking

To add a virtual device tracker use the following:
Expand All @@ -421,6 +443,12 @@ Test Device_Tracker:

Use the `virtual.move` service to change device locations.


# Old Style Entity Configuration

For now; look at [the 0.8](https://github.com/twrecked/hass-virtual/tree/version-0.8.x?tab=readme-ov-file#component-configuration) documentation.


# Services

The component provides the following services:
Expand Down Expand Up @@ -469,3 +497,4 @@ This service will turn off a binary sensor.
- `gps`; GPS coordinates

Move a device tracker. You use one of the parameters.

2 changes: 2 additions & 0 deletions changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
0.9.0b14:
Restore previous YAML config support.
0.9.0b13:
Refactored cover to provide valve support.
Made `version and device` optional in the yaml config
Expand Down
103 changes: 67 additions & 36 deletions custom_components/virtual/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,17 @@
from .cfg import BlendedCfg, UpgradeCfg


__version__ = '0.9.0b13'
__version__ = '0.9.0b14'

_LOGGER = logging.getLogger(__name__)

# Purely to quieten down the checks.
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({})
CONFIG_SCHEMA = vol.Schema({
COMPONENT_DOMAIN: vol.Schema({
vol.Optional(CONF_YAML_CONFIG, default=False): cv.boolean,
}),
},
extra=vol.ALLOW_EXTRA,
)

SERVICE_AVAILABILE = 'set_available'
SERVICE_SCHEMA = vol.Schema({
Expand All @@ -55,43 +60,68 @@
Platform.VALVE
]

async def async_setup(hass, config):
"""Set up a virtual components.

async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up a virtual component.
This uses the old mechanism and has to be enabled with 'yaml_config: True'
"""

hass.data[COMPONENT_DOMAIN] = {}
hass.data[COMPONENT_SERVICES] = {}

# See if we have already imported the data. If we haven't then do it now.
config_entry = _async_find_matching_config_entry(hass)
if not config_entry:
_LOGGER.debug('importing a YAML setup')
hass.async_create_task(
hass.config_entries.flow.async_init(
COMPONENT_DOMAIN,
context={CONF_SOURCE: SOURCE_IMPORT},
data=config
# Set up hass data if necessary
if COMPONENT_DOMAIN not in hass.data:
hass.data[COMPONENT_DOMAIN] = {}
hass.data[COMPONENT_SERVICES] = {}
hass.data[COMPONENT_CONFIG] = {}

# See if yaml support was enabled.
if not config.get(COMPONENT_DOMAIN, {}).get(CONF_YAML_CONFIG, False):

# New style. We import old config if needed.
_LOGGER.debug("setting up new virtual components")
hass.data[COMPONENT_CONFIG][CONF_YAML_CONFIG] = False

# See if we have already imported the data. If we haven't then do it now.
config_entry = _async_find_matching_config_entry(hass)
if not config_entry:
_LOGGER.debug('importing a YAML setup')
hass.async_create_task(
hass.config_entries.flow.async_init(
COMPONENT_DOMAIN,
context={CONF_SOURCE: SOURCE_IMPORT},
data=config
)
)

async_create_issue(
hass,
HOMEASSISTANT_DOMAIN,
f"deprecated_yaml_{COMPONENT_DOMAIN}",
is_fixable=False,
issue_domain=COMPONENT_DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml",
translation_placeholders={
"domain": COMPONENT_DOMAIN,
"integration_title": "Virtual",
},
)
)

async_create_issue(
hass,
HOMEASSISTANT_DOMAIN,
f"deprecated_yaml_{COMPONENT_DOMAIN}",
is_fixable=False,
issue_domain=COMPONENT_DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml",
translation_placeholders={
"domain": COMPONENT_DOMAIN,
"integration_title": "Virtual",
},
)

return True

_LOGGER.debug('ignoring a YAML setup')

else:
_LOGGER.debug('ignoring a YAML setup')

else:

# Original style. We just use the entities as now.
_LOGGER.debug("setting up old virtual components")
hass.data[COMPONENT_CONFIG][CONF_YAML_CONFIG] = True

@verify_domain_control(hass, COMPONENT_DOMAIN)
async def async_virtual_service_set_available(call) -> None:
"""Call virtual service handler."""
_LOGGER.info("{} service called".format(call.service))
await async_virtual_set_availability_service(hass, call)

hass.services.async_register(COMPONENT_DOMAIN, SERVICE_AVAILABILE, async_virtual_service_set_available)

return True


Expand All @@ -111,6 +141,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
if COMPONENT_DOMAIN not in hass.data:
hass.data[COMPONENT_DOMAIN] = {}
hass.data[COMPONENT_SERVICES] = {}
hass.data[COMPONENT_CONFIG] = {}

# Get the config.
_LOGGER.debug(f"creating new cfg")
Expand Down
Loading
Loading