Skip to content

Commit

Permalink
Add initial Home Assistant integration boilerplate
Browse files Browse the repository at this point in the history
  • Loading branch information
Jalle19 committed Sep 6, 2024
1 parent ee79c84 commit 1fd8532
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 0 deletions.
32 changes: 32 additions & 0 deletions custom_components/vinx/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from __future__ import annotations

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady

from custom_components.vinx.lw3 import LW3

PLATFORMS: list[Platform] = [Platform.MEDIA_PLAYER]


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up from a config entry."""
# Verify we can connect
try:
device = LW3(entry.data["host"], entry.data["port"])
await device.connect()
except ConnectionError as e:
raise ConfigEntryNotReady("Unable to connect") from e

# Store the device as runtime data in teh entry
entry.runtime_data = device

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

return True


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
40 changes: 40 additions & 0 deletions custom_components/vinx/config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from typing import Any

import voluptuous as vol

from homeassistant.config_entries import ConfigFlow, ConfigFlowResult

from .const import CONF_HOST, CONF_PORT, DOMAIN
from .lw3 import LW3

STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST): str,
vol.Required(CONF_PORT, default=6107): int,
}
)


class VinxConfigFlow(ConfigFlow, domain=DOMAIN):
VERSION = 1

async def async_step_user(self, user_input: dict[str, Any] | None = None) -> ConfigFlowResult:
"""Handle user initiated configuration"""
errors: dict[str, str] = {}
if user_input is not None:
try:
# Try to connect to the device
lw3_device = LW3(user_input["host"], user_input["port"])
await lw3_device.connect()

# Make a title for the entry
title = str(await lw3_device.get_property("/.ProductName"))

# Disconnect, this was just for validation
await lw3_device.disconnect()
except (ConnectionError, OSError):
errors["base"] = "cannot_connect"
else:
return self.async_create_entry(title=title, data=user_input)

return self.async_show_form(step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors)
6 changes: 6 additions & 0 deletions custom_components/vinx/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
DOMAIN = "vinx"

CONF_HOST = "host"
CONF_PORT = "port"
CONF_PASSWORD = "password"
CONF_DEVICE_TYPE = "device_type"
4 changes: 4 additions & 0 deletions custom_components/vinx/lw3.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ async def _read_until(self, phrase: str) -> str | None:
async def connect(self):
self._reader, self._writer = await asyncio.open_connection(self._hostname, self._port)

async def disconnect(self):
self._writer.close()
await self._writer.wait_closed()

@staticmethod
def _is_error_response(response: str) -> bool:
return response[1] == "E"
Expand Down
17 changes: 17 additions & 0 deletions custom_components/vinx/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"domain": "vinx",
"name": "VINX",
"version": "0.0.1",
"codeowners": [
"@Jalle19"
],
"config_flow": true,
"integration_type": "device",
"dependencies": [],
"documentation": "https://www.home-assistant.io/integrations/vinx",
"homekit": {},
"iot_class": "local_polling",
"requirements": [],
"ssdp": [],
"zeroconf": []
}
21 changes: 21 additions & 0 deletions custom_components/vinx/media_player.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import logging

from homeassistant.components.media_player import MediaPlayerEntity

from custom_components.vinx import LW3

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(hass, entry, async_add_entities):
# Extract stored runtime data
lw3_device: LW3 = entry.runtime_data
_LOGGER.info(lw3_device)


class VinxEncoder(MediaPlayerEntity):
pass


class VinxDecoder(MediaPlayerEntity):
pass
19 changes: 19 additions & 0 deletions custom_components/vinx/strings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"config": {
"step": {
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]",
"port": "[%key:common::config_flow::data::port%]"
}
}
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}
}
}
19 changes: 19 additions & 0 deletions custom_components/vinx/translations/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"config": {
"abort": {
"already_configured": "Device is already configured"
},
"error": {
"cannot_connect": "Failed to connect",
"unknown": "Unexpected error"
},
"step": {
"user": {
"data": {
"host": "Host",
"port": "Port"
}
}
}
}
}

0 comments on commit 1fd8532

Please sign in to comment.