Allow "slave" parameter in modbus service calls (#66874)

* Allow "slave" parameter in modbus service calls.
This commit is contained in:
jan iversen 2022-02-24 13:35:45 +01:00 committed by GitHub
parent a12870081e
commit 9131fb39fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 14 deletions

View File

@ -69,6 +69,7 @@ UDP = "udp"
ATTR_ADDRESS = "address" ATTR_ADDRESS = "address"
ATTR_HUB = "hub" ATTR_HUB = "hub"
ATTR_UNIT = "unit" ATTR_UNIT = "unit"
ATTR_SLAVE = "slave"
ATTR_VALUE = "value" ATTR_VALUE = "value"
ATTR_STATE = "state" ATTR_STATE = "state"
ATTR_TEMPERATURE = "temperature" ATTR_TEMPERATURE = "temperature"

View File

@ -39,6 +39,7 @@ from homeassistant.helpers.typing import ConfigType
from .const import ( from .const import (
ATTR_ADDRESS, ATTR_ADDRESS,
ATTR_HUB, ATTR_HUB,
ATTR_SLAVE,
ATTR_STATE, ATTR_STATE,
ATTR_UNIT, ATTR_UNIT,
ATTR_VALUE, ATTR_VALUE,
@ -156,7 +157,11 @@ async def async_modbus_setup(
async def async_write_register(service: ServiceCall) -> None: async def async_write_register(service: ServiceCall) -> None:
"""Write Modbus registers.""" """Write Modbus registers."""
unit = int(float(service.data[ATTR_UNIT])) unit = 0
if ATTR_UNIT in service.data:
unit = int(float(service.data[ATTR_UNIT]))
if ATTR_SLAVE in service.data:
unit = int(float(service.data[ATTR_SLAVE]))
address = int(float(service.data[ATTR_ADDRESS])) address = int(float(service.data[ATTR_ADDRESS]))
value = service.data[ATTR_VALUE] value = service.data[ATTR_VALUE]
hub = hub_collect[ hub = hub_collect[
@ -173,7 +178,11 @@ async def async_modbus_setup(
async def async_write_coil(service: ServiceCall) -> None: async def async_write_coil(service: ServiceCall) -> None:
"""Write Modbus coil.""" """Write Modbus coil."""
unit = service.data[ATTR_UNIT] unit = 0
if ATTR_UNIT in service.data:
unit = int(float(service.data[ATTR_UNIT]))
if ATTR_SLAVE in service.data:
unit = int(float(service.data[ATTR_SLAVE]))
address = service.data[ATTR_ADDRESS] address = service.data[ATTR_ADDRESS]
state = service.data[ATTR_STATE] state = service.data[ATTR_STATE]
hub = hub_collect[ hub = hub_collect[
@ -195,7 +204,8 @@ async def async_modbus_setup(
schema=vol.Schema( schema=vol.Schema(
{ {
vol.Optional(ATTR_HUB, default=DEFAULT_HUB): cv.string, vol.Optional(ATTR_HUB, default=DEFAULT_HUB): cv.string,
vol.Required(ATTR_UNIT): cv.positive_int, vol.Exclusive(ATTR_SLAVE, "unit"): cv.positive_int,
vol.Exclusive(ATTR_UNIT, "unit"): cv.positive_int,
vol.Required(ATTR_ADDRESS): cv.positive_int, vol.Required(ATTR_ADDRESS): cv.positive_int,
vol.Required(x_write[2]): vol.Any( vol.Required(x_write[2]): vol.Any(
cv.positive_int, vol.All(cv.ensure_list, [x_write[3]]) cv.positive_int, vol.All(cv.ensure_list, [x_write[3]])

View File

@ -14,13 +14,13 @@ write_coil:
name: State name: State
description: State to write. description: State to write.
required: true required: true
example: false example: "0 or [1,0]"
selector: selector:
object: object:
unit: slave:
name: Unit name: Slave
description: Address of the modbus unit. description: Address of the modbus unit/slave.
required: true required: false
selector: selector:
number: number:
min: 1 min: 1
@ -44,10 +44,10 @@ write_register:
number: number:
min: 0 min: 0
max: 65535 max: 65535
unit: slave:
name: Unit name: Slave
description: Address of the modbus unit. description: Address of the modbus unit/slave.
required: true required: false
selector: selector:
number: number:
min: 1 min: 1

View File

@ -25,6 +25,7 @@ from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAI
from homeassistant.components.modbus.const import ( from homeassistant.components.modbus.const import (
ATTR_ADDRESS, ATTR_ADDRESS,
ATTR_HUB, ATTR_HUB,
ATTR_SLAVE,
ATTR_STATE, ATTR_STATE,
ATTR_UNIT, ATTR_UNIT,
ATTR_VALUE, ATTR_VALUE,
@ -484,8 +485,15 @@ SERVICE = "service"
{VALUE: ModbusException("fail write_"), DATA: "Pymodbus:"}, {VALUE: ModbusException("fail write_"), DATA: "Pymodbus:"},
], ],
) )
@pytest.mark.parametrize(
"do_unit",
[
ATTR_UNIT,
ATTR_SLAVE,
],
)
async def test_pb_service_write( async def test_pb_service_write(
hass, do_write, do_return, caplog, mock_modbus_with_pymodbus hass, do_write, do_return, do_unit, caplog, mock_modbus_with_pymodbus
): ):
"""Run test for service write_register.""" """Run test for service write_register."""
@ -498,7 +506,7 @@ async def test_pb_service_write(
data = { data = {
ATTR_HUB: TEST_MODBUS_NAME, ATTR_HUB: TEST_MODBUS_NAME,
ATTR_UNIT: 17, do_unit: 17,
ATTR_ADDRESS: 16, ATTR_ADDRESS: 16,
do_write[DATA]: do_write[VALUE], do_write[DATA]: do_write[VALUE],
} }