Skip to content

Commit

Permalink
add files
Browse files Browse the repository at this point in the history
  • Loading branch information
MadOne committed Jul 28, 2024
1 parent 2f65681 commit c9ed384
Show file tree
Hide file tree
Showing 18 changed files with 1,709 additions and 1 deletion.
1 change: 0 additions & 1 deletion custom_components/weishaupt_modbus
Submodule weishaupt_modbus deleted from 870804
34 changes: 34 additions & 0 deletions custom_components/weishaupt_modbus/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Weishaupt Modbus Integration."""

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant

from .const import DOMAIN

PLATFORMS: list[str] = ["number", "select", "sensor"]


# Return boolean to indicate that initialization was successful.
# return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Hello World from a config entry."""
# Store an instance of the "connecting" class that does the work of speaking
# with your actual devices.
# hass.data.setdefault(DOMAIN, {})[entry.entry_id] = hub.Hub(hass, entry.data["host"])

# This creates each HA object for each platform your device requires.
# It's done by calling the `async_setup_entry` function in each platform module.
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."""
# This is called when an entry/configured device is to be removed. The class
# needs to unload itself, and remove callbacks. See the classes for further
# details
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)

return unload_ok
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
95 changes: 95 additions & 0 deletions custom_components/weishaupt_modbus/config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
"""Weishaupt Modbus Integration."""

from typing import Any

import voluptuous as vol

from homeassistant import config_entries, exceptions
from homeassistant.const import CONF_HOST, CONF_PORT
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv

# from . import wp
from .const import DOMAIN

# DATA_SCHEMA = vol.Schema({("host"): str, ("port"): cv.port})
DATA_SCHEMA = vol.Schema(
{vol.Required(CONF_HOST): str, vol.Optional(CONF_PORT, default="502"): cv.port}
)


async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]:
"""Validate the user input allows us to connect.
Data has the keys from DATA_SCHEMA with values provided by the user.
"""
# Validate the data can be used to set up a connection.

# This is a simple example to show an error in the UI for a short hostname
# The exceptions are defined at the end of this file, and are used in the
# `async_step_user` method below.
if len(data["host"]) < 3:
raise InvalidHost

# whp = wp.heat_pump("10.10.1.225", 502)
# if not whp:
# raise ConnectionFailed

# If your PyPI package is not built with async, pass your methods
# to the executor:
# await hass.async_add_executor_job(
# your_validate_func, data["username"], data["password"]
# )

# If you cannot connect:
# throw CannotConnect
# If the authentication is wrong:
# InvalidAuth

# Return info that you want to store in the config entry.
# "Title" is what is displayed to the user for this hub device
# It is stored internally in HA as part of the device config.
# See `async_step_user` below for how this is used
return {"title": data["host"]}


class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Hello World."""

VERSION = 1
# Pick one of the available connection classes in homeassistant/config_entries.py
# This tells HA if it should be asking for updates, or it'll be notified of updates
# automatically. This example uses PUSH, as the dummy hub will notify HA of
# changes.
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_PUSH

async def async_step_user(self, user_input=None):
"""Handle the initial step."""
# This goes through the steps to take the user through the setup process.
# Using this it is possible to update the UI and prompt for additional
# information. This example provides a single form (built from `DATA_SCHEMA`),
# and when that has some validated input, it calls `async_create_entry` to
# actually create the HA config entry. Note the "title" value is returned by
# `validate_input` above.
errors = {}
if user_input is not None:
try:
info = await validate_input(self.hass, user_input)

return self.async_create_entry(title=info["title"], data=user_input)

except Exception:
errors["base"] = "unknown"

# If there is no user input or there were errors, show the form again, including any errors that were found with the input.
return self.async_show_form(
step_id="user", data_schema=DATA_SCHEMA, errors=errors
)


class InvalidHost(exceptions.HomeAssistantError):
"""Error to indicate there is an invalid hostname."""


class ConnectionFailed(exceptions.HomeAssistantError):
"""Error to indicate there is an invalid hostname."""
8 changes: 8 additions & 0 deletions custom_components/weishaupt_modbus/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Constants."""

from datetime import timedelta

DOMAIN = "weishaupt_modbus"
SCAN_INTERVAL = timedelta(minutes=1)
UNIQUE_ID = "unique_id"
APPID = 100
11 changes: 11 additions & 0 deletions custom_components/weishaupt_modbus/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"domain": "weishaupt_modbus",
"name": "Weishaupt Modbus Integration",
"codeowners": ["@MadOne"],
"config_flow": true,
"documentation": "https://www.not_yet.com",
"iot_class": "local_polling",
"requirements": [],
"version": "0.0.1"
}

78 changes: 78 additions & 0 deletions custom_components/weishaupt_modbus/number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"""Number platform for wemportal component."""

from homeassistant.components.number import NumberEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PORT, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType

from . import wp
from .const import DOMAIN


async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the wemportal component."""
hass.data.setdefault(DOMAIN, {})
return True


async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
discovery_info=None,
) -> None:
"""Set up Numbers."""
hass.data.setdefault(DOMAIN, {})
# hub = hass.data[DOMAIN][config_entry.entry_id]
host = config_entry.data[CONF_HOST]
port = config_entry.data[CONF_PORT]
# port = config_entry.data.get[CONF_PORT]
# host = "10.10.1.225"
# port = "502"
async_add_entities([Number(host, port)], update_before_add=True)


class Number(NumberEntity):
"""Representation of a WEM Portal number."""

_attr_name = "WW Soll Temp"
_attr_unique_id = DOMAIN + _attr_name
_attr_native_value = 0
_attr_should_poll = True
_attr_native_min_value = 40
_attr_native_max_value = 60
_attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS

def __init__(self, host, port) -> None:
"""Init."""
self._host = host
self._port = port
whp = wp.heat_pump(host, port)
whp.connect()
self._attr_native_value = whp.WW_Soll
# self.async_write_ha_state()

async def async_set_native_value(self, value: float) -> None:
"""Update the current value."""
whp = wp.heat_pump(self._host, self._port)
whp.connect()
whp.WW_Soll = int(value)

self._attr_native_value = whp.WW_Soll
self.async_write_ha_state()

async def async_update(self) -> None:
"""Update Entity Only used by the generic entity update service."""
whp = wp.heat_pump(self._host, self._port)
whp.connect()
self._attr_native_value = whp.WW_Soll

@property
def device_info(self) -> DeviceInfo:
"""Information about this entity/device."""
return {
"identifiers": {(DOMAIN, "Warmwasser")},
}
108 changes: 108 additions & 0 deletions custom_components/weishaupt_modbus/select.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
"""Select platform for wemportal component."""

from homeassistant.components.select import SelectEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PORT
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import wp
from .const import DOMAIN


async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Select entry setup."""
host = config_entry.data[CONF_HOST]
port = config_entry.data[CONF_PORT]
async_add_entities(
[
Sys_Betriebsart(host, port),
HK_Konfiguration(host, port),
],
update_before_add=True,
)


class Sys_Betriebsart(SelectEntity):
"""Representation of a WEM Portal Sensor."""

_attr_name = "Systembetriebsart"
_attr_unique_id = DOMAIN + _attr_name
_attr_should_poll = True
options = ["AUTOMATIK", "HEIZEN", "KÜHLEN", "SOMMER", "STANDBY", "2.WEZ", "FEHLER"]
_attr_current_option = "FEHLER"

def __init__(self, host, port) -> None:
"""Init."""
self._host = host
self.async_internal_will_remove_from_hass_port = port

async def async_select_option(self, option: str) -> None:
"""Call the API to change the parameter value."""

self._attr_current_option = option

self.async_write_ha_state()

async def async_update(self) -> None:
"""Update Entity Only used by the generic entity update service."""
# await self.coordinator.async_request_refresh()
whp = wp.heat_pump("10.10.1.225", 502)
whp.connect()
self._attr_current_option = whp.Sys_Betriebsart

@property
def device_info(self) -> DeviceInfo:
"""Information about this entity/device."""
return {
"identifiers": {(DOMAIN, "System")},
}


class HK_Konfiguration(SelectEntity):
"""Representation of a WEM Portal Sensor."""

_attr_name = "Konfiguration"
_attr_unique_id = DOMAIN + _attr_name
_attr_should_poll = True
options = [
"AUS",
"PUMPENKREIS",
"MISCHKREIS",
"SOLLWERT (PUMPE M1)",
"FEHLER",
]
_attr_current_option = "FEHLER"

def __init__(self, host, port) -> None:
"""Init."""
self._host = host
self._port = port

async def async_select_option(self, option: str) -> None:
"""Call the API to change the parameter value."""

self._attr_current_option = option

self.async_write_ha_state()

async def async_update(
self,
) -> None:
"""Update Entity Only used by the generic entity update service."""
# await self.coordinator.async_request_refresh()
whp = wp.heat_pump(self._host, self._port)
whp.connect()
self._attr_current_option = whp.HK_Konfiguration

@property
def device_info(self) -> DeviceInfo:
"""Information about this entity/device."""
return {
"identifiers": {(DOMAIN, "Heizkreis")},
}
Loading

0 comments on commit c9ed384

Please sign in to comment.