Skip to content

Commit

Permalink
add basic cover virtual entity (#64)
Browse files Browse the repository at this point in the history
This entity only supports cover_open and cover_closed services (therefore, only STATE_CLOSED is considered)
  • Loading branch information
anarubioruiz authored Nov 9, 2023
1 parent 26c94df commit 0eacb77
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 2 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Virtual components for testing Home Assistant systems.
### **Breaking Changes**

I've added persistent support to `binary_sensor`, `fan`, `light`, `lock`,
`sensor`, `switch` and `device_tracker`. The persistent saving of state is
`sensor`, `switch`, `cover` and `device_tracker`. The persistent saving of state is
turned *on* by default. If you do not want this set `persistent: False` in the
entity configuration.

Expand Down Expand Up @@ -227,6 +227,22 @@ Only `name` is required. 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 _(in development)_

To add a virtual cover use the following:

```yaml
cover:
- platform: virtual
name: Window cover
initial_value: 'closed'
initial_availability: true
persistent: false
```

`name` is required. By the moment, only `open` (default `initial_value`)
and `closed` states are supported and, therefore, only `cover.cover_open`
and `cover.cover_close` services are available.

### Device Tracking

Expand Down Expand Up @@ -264,4 +280,3 @@ device_tracker:
- virtual_user1
- virtual_user2
```

75 changes: 75 additions & 0 deletions custom_components/virtual/cover.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""
This component provides support for a virtual cover.
"""

import logging
import voluptuous as vol
from typing import Any

import homeassistant.helpers.config_validation as cv
from homeassistant.components.cover import CoverEntity, DOMAIN
from homeassistant.helpers.config_validation import (PLATFORM_SCHEMA)
from homeassistant.const import (
ATTR_DEVICE_CLASS,
STATE_CLOSED,
)

from .const import (
COMPONENT_DOMAIN,
CONF_INITIAL_VALUE,
CONF_CLASS,
)
from .entity import VirtualEntity, virtual_schema

_LOGGER = logging.getLogger(__name__)

DEFAULT_INITIAL_VALUE = "open"
DEPENDENCIES = [COMPONENT_DOMAIN]

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(virtual_schema(DEFAULT_INITIAL_VALUE, {
vol.Optional(CONF_CLASS): cv.string,
}))


async def async_setup_platform(_hass, config, async_add_entities, _discovery_info=None):
covers = [VirtualCover(config)]
async_add_entities(covers, True)


class VirtualCover(VirtualEntity, CoverEntity):
"""Representation of a Virtual cover."""

def __init__(self, config):
"""Initialize the Virtual cover device."""
super().__init__(config, DOMAIN)

self._attr_device_class = config.get(CONF_CLASS)

_LOGGER.info('VirtualCover: {} created'.format(self.name))

def _create_state(self, config):
super()._create_state(config)

self._attr_is_closed = config.get(CONF_INITIAL_VALUE).lower() == STATE_CLOSED

def _restore_state(self, state, config):
super()._restore_state(state, config)

self._attr_is_closed = state.state.lower() == STATE_CLOSED

def _update_attributes(self):
super()._update_attributes();
self._attr_extra_state_attributes.update({
name: value for name, value in (
(ATTR_DEVICE_CLASS, self._attr_device_class),
) if value is not None
})

def open_cover(self, **kwargs: Any) -> None:
_LOGGER.info(f'opening {self.name}')
self._attr_is_closed = False

def close_cover(self, **kwargs: Any) -> None:
_LOGGER.info(f'closing {self.name}')
self._attr_is_closed = True

0 comments on commit 0eacb77

Please sign in to comment.