Skip to content
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
2 changes: 1 addition & 1 deletion CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ homeassistant/components/min_max/* @fabaff
homeassistant/components/minecraft_server/* @elmurato
homeassistant/components/minio/* @tkislan
homeassistant/components/mobile_app/* @robbiet480
homeassistant/components/modbus/* @adamchengtkc @janiversen
homeassistant/components/modbus/* @adamchengtkc @janiversen @vzahradnik
homeassistant/components/monoprice/* @etsinko @OnFreund
homeassistant/components/moon/* @fabaff
homeassistant/components/mpd/* @fabaff
Expand Down
75 changes: 67 additions & 8 deletions homeassistant/components/modbus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,84 @@
from pymodbus.transaction import ModbusRtuFramer
import voluptuous as vol

from homeassistant.components.cover import (
DEVICE_CLASSES_SCHEMA as COVER_DEVICE_CLASSES_SCHEMA,
)
from homeassistant.const import (
ATTR_STATE,
CONF_COVERS,
CONF_DELAY,
CONF_DEVICE_CLASS,
CONF_HOST,
CONF_METHOD,
CONF_NAME,
CONF_PORT,
CONF_SCAN_INTERVAL,
CONF_SLAVE,
CONF_TIMEOUT,
CONF_TYPE,
EVENT_HOMEASSISTANT_STOP,
)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.discovery import load_platform

from .const import (
ATTR_ADDRESS,
ATTR_HUB,
ATTR_UNIT,
ATTR_VALUE,
CALL_TYPE_COIL,
CALL_TYPE_REGISTER_HOLDING,
CALL_TYPE_REGISTER_INPUT,
CONF_BAUDRATE,
CONF_BYTESIZE,
CONF_INPUT_TYPE,
CONF_PARITY,
CONF_REGISTER,
CONF_STATE_CLOSED,
CONF_STATE_CLOSING,
CONF_STATE_OPEN,
CONF_STATE_OPENING,
CONF_STATUS_REGISTER,
CONF_STATUS_REGISTER_TYPE,
CONF_STOPBITS,
DEFAULT_HUB,
DEFAULT_SCAN_INTERVAL,
DEFAULT_SLAVE,
MODBUS_DOMAIN as DOMAIN,
SERVICE_WRITE_COIL,
SERVICE_WRITE_REGISTER,
)

_LOGGER = logging.getLogger(__name__)


BASE_SCHEMA = vol.Schema({vol.Optional(CONF_NAME, default=DEFAULT_HUB): cv.string})

COVERS_SCHEMA = vol.All(
cv.has_at_least_one_key(CALL_TYPE_COIL, CONF_REGISTER),
vol.Schema(
{
vol.Required(CONF_NAME): cv.string,
vol.Optional(CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL): vol.All(
cv.time_period, lambda value: value.total_seconds()
),
vol.Optional(CONF_DEVICE_CLASS): COVER_DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_SLAVE, default=DEFAULT_SLAVE): cv.positive_int,
vol.Optional(CONF_STATE_CLOSED, default=0): cv.positive_int,
vol.Optional(CONF_STATE_CLOSING, default=3): cv.positive_int,
vol.Optional(CONF_STATE_OPEN, default=1): cv.positive_int,
vol.Optional(CONF_STATE_OPENING, default=2): cv.positive_int,
vol.Optional(CONF_STATUS_REGISTER): cv.positive_int,
vol.Optional(
CONF_STATUS_REGISTER_TYPE,
default=CALL_TYPE_REGISTER_HOLDING,
): vol.In([CALL_TYPE_REGISTER_HOLDING, CALL_TYPE_REGISTER_INPUT]),
vol.Exclusive(CALL_TYPE_COIL, CONF_INPUT_TYPE): cv.positive_int,
vol.Exclusive(CONF_REGISTER, CONF_INPUT_TYPE): cv.positive_int,
}
),
)

SERIAL_SCHEMA = BASE_SCHEMA.extend(
{
vol.Required(CONF_BAUDRATE): cv.positive_int,
Expand All @@ -49,6 +94,7 @@
vol.Required(CONF_STOPBITS): vol.Any(1, 2),
vol.Required(CONF_TYPE): "serial",
vol.Optional(CONF_TIMEOUT, default=3): cv.socket_timeout,
vol.Optional(CONF_COVERS): vol.All(cv.ensure_list, [COVERS_SCHEMA]),
}
)

Expand All @@ -59,14 +105,10 @@
vol.Required(CONF_TYPE): vol.Any("tcp", "udp", "rtuovertcp"),
vol.Optional(CONF_TIMEOUT, default=3): cv.socket_timeout,
vol.Optional(CONF_DELAY, default=0): cv.positive_int,
vol.Optional(CONF_COVERS): vol.All(cv.ensure_list, [COVERS_SCHEMA]),
}
)

CONFIG_SCHEMA = vol.Schema(
{DOMAIN: vol.All(cv.ensure_list, [vol.Any(SERIAL_SCHEMA, ETHERNET_SCHEMA)])},
extra=vol.ALLOW_EXTRA,
)

SERVICE_WRITE_REGISTER_SCHEMA = vol.Schema(
{
vol.Optional(ATTR_HUB, default=DEFAULT_HUB): cv.string,
Expand All @@ -87,13 +129,30 @@
}
)

CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.All(
cv.ensure_list,
[
vol.Any(SERIAL_SCHEMA, ETHERNET_SCHEMA),
],
),
},
extra=vol.ALLOW_EXTRA,
)


def setup(hass, config):
"""Set up Modbus component."""
hass.data[DOMAIN] = hub_collect = {}

for client_config in config[DOMAIN]:
hub_collect[client_config[CONF_NAME]] = ModbusHub(client_config)
for conf_hub in config[DOMAIN]:
hub_collect[conf_hub[CONF_NAME]] = ModbusHub(conf_hub)

# load platforms
for component, conf_key in (("cover", CONF_COVERS),):
if conf_key in conf_hub:
load_platform(hass, component, DOMAIN, conf_hub, config)

def stop_modbus(event):
"""Stop Modbus service."""
Expand Down
10 changes: 10 additions & 0 deletions homeassistant/components/modbus/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
ATTR_VALUE = "value"
SERVICE_WRITE_COIL = "write_coil"
SERVICE_WRITE_REGISTER = "write_register"
DEFAULT_SCAN_INTERVAL = 15 # seconds

# binary_sensor.py
CONF_INPUTS = "inputs"
Expand All @@ -71,3 +72,12 @@
CONF_MAX_TEMP = "max_temp"
CONF_MIN_TEMP = "min_temp"
CONF_STEP = "temp_step"

# cover.py
CONF_STATE_OPEN = "state_open"
CONF_STATE_CLOSED = "state_closed"
CONF_STATE_OPENING = "state_opening"
CONF_STATE_CLOSING = "state_closing"
CONF_STATUS_REGISTER = "status_register"
CONF_STATUS_REGISTER_TYPE = "status_register_type"
DEFAULT_SLAVE = 1
Loading