Skip to content

Commit

Permalink
refactor: After merges
Browse files Browse the repository at this point in the history
  • Loading branch information
davidrapan committed Jul 19, 2024
1 parent 591baab commit 559c978
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 53 deletions.
8 changes: 6 additions & 2 deletions custom_components/solarman/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@
REQUEST_START = "start"
REQUEST_END = "end"

SERVICES_PARAM_DEVICE = "device"
SERVICES_PARAM_REGISTER = "register"
SERVICES_PARAM_COUNT = "count"
SERVICES_PARAM_VALUE = "value"
SERVICES_PARAM_VALUES = "values"

SERVICE_WRITE_REGISTER = "write_holding_register"
SERVICE_WRITE_MULTIPLE_REGISTERS = "write_multiple_holding_registers"
SERVICE_READ_HOLDING_REGISTER = "read_holding_register"
SERVICE_READ_MULTIPLE_HOLDING_REGISTERS = "read_multiple_holding_registers"
SERVICE_WRITE_HOLDING_REGISTER = "write_holding_register"
SERVICE_WRITE_MULTIPLE_HOLDING_REGISTERS = "write_multiple_holding_registers"
67 changes: 28 additions & 39 deletions custom_components/solarman/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,36 @@

_LOGGER = logging.getLogger(__name__)

SERVICE_READ_HOLDING_REGISTER = 'read_holding_register'
SERVICE_READ_MULTIPLE_HOLDING_REGISTERS = 'read_multiple_holding_registers'
SERVICE_WRITE_HOLDING_REGISTER = 'write_holding_register'
SERVICE_WRITE_MULTIPLE_HOLDING_REGISTERS = 'write_multiple_holding_registers'
PARAM_DEVICE = 'device'
PARAM_REGISTER = 'register'
PARAM_COUNT = 'count'
PARAM_VALUE = 'value'
PARAM_VALUES = 'values'

# Register the services one can invoke on the inverter.
# Apart from this, it also need to be defined in the file
# services.yaml for the Home Assistant UI in "Developer Tools"


SERVICE_READ_REGISTER_SCHEMA = vol.Schema(
{
vol.Required(PARAM_DEVICE): vol.All(vol.Coerce(str)),
vol.Required(PARAM_REGISTER): vol.All(vol.Coerce(int), vol.Range(min = 0, max = 65535))
vol.Required(SERVICES_PARAM_DEVICE): vol.All(vol.Coerce(str)),
vol.Required(SERVICES_PARAM_REGISTER): vol.All(vol.Coerce(int), vol.Range(min = 0, max = 65535))
}
)

SERVICE_READ_MULTIPLE_REGISTERS_SCHEMA = vol.Schema(
{
vol.Required(PARAM_DEVICE): vol.All(vol.Coerce(str)),
vol.Required(PARAM_REGISTER): vol.All(vol.Coerce(int), vol.Range(min = 0, max = 65535)),
vol.Required(PARAM_COUNT): vol.All(vol.Coerce(int), vol.Range(min = 0, max = 65535))
vol.Required(SERVICES_PARAM_DEVICE): vol.All(vol.Coerce(str)),
vol.Required(SERVICES_PARAM_REGISTER): vol.All(vol.Coerce(int), vol.Range(min = 0, max = 65535)),
vol.Required(SERVICES_PARAM_COUNT): vol.All(vol.Coerce(int), vol.Range(min = 0, max = 65535))
}
)

SERVICE_WRITE_REGISTER_SCHEMA = vol.Schema(
SERVICE_WRITE_HOLDING_REGISTER_SCHEMA = vol.Schema(
{
vol.Required(PARAM_DEVICE): vol.All(vol.Coerce(str)),
vol.Required(SERVICES_PARAM_DEVICE): vol.All(vol.Coerce(str)),
vol.Required(SERVICES_PARAM_REGISTER): vol.All(vol.Coerce(int), vol.Range(min = 0, max = 65535)),
vol.Required(SERVICES_PARAM_VALUE): vol.All(vol.Coerce(int), vol.Range(min = 0, max = 65535)),
}
)

SERVICE_WRITE_MULTIPLE_REGISTERS_SCHEMA = vol.Schema(
SERVICE_WRITE_MULTIPLE_HOLDING_REGISTERS_SCHEMA = vol.Schema(
{
vol.Required(PARAM_DEVICE): vol.All(vol.Coerce(str)),
vol.Required(SERVICES_PARAM_DEVICE): vol.All(vol.Coerce(str)),
vol.Required(SERVICES_PARAM_REGISTER): vol.All(vol.Coerce(int), vol.Range(min = 0, max = 65535)),
vol.Required(SERVICES_PARAM_VALUES): vol.All(cv.ensure_list, [vol.All(vol.Coerce(int), vol.Range(min = 0, max = 65535))]),
}
Expand All @@ -72,45 +61,45 @@ def getInverter(device_id):
domain = entity_id.partition(".")[0]
entity_comp = hass.data.get("entity_components", {}).get(domain)
if entity_comp is None:
_LOGGER.info(f'read_holding_register: Component for {entity_id} not loaded')
_LOGGER.info(f"read_holding_register: Component for {entity_id} not loaded")
continue

if (entity_obj := entity_comp.get_entity(entity_id)) is None:
_LOGGER.info(f'read_holding_register: Entity {entity_id} not found')
_LOGGER.info(f"read_holding_register: Entity {entity_id} not found")
continue

if (inverter := entity_obj.inverter) is None:
_LOGGER.info(f'read_holding_register: Entity {entity_id} has no inverter')
_LOGGER.info(f"read_holding_register: Entity {entity_id} has no inverter")
continue

break

return inverter

async def read_holding_register(call: ServiceCall) -> int:
_LOGGER.debug(f'read_holding_register: {call}')
if (inverter := getInverter(call.data.get(PARAM_DEVICE))) is None:
_LOGGER.debug(f"read_holding_register: {call}")
if (inverter := getInverter(call.data.get(SERVICES_PARAM_DEVICE))) is None:
raise ServiceValidationError(
"No communication interface for device found",
translation_domain = DOMAIN,
translation_key = "no_interface_found"
)

try:
response = inverter.service_read_holding_register(register = call.data.get(PARAM_REGISTER))
response = inverter.service_read_holding_register(register = call.data.get(SERVICES_PARAM_REGISTER))
except Exception as e:
raise ServiceValidationError(
e,
translation_domain = DOMAIN,
translation_key = "call_failed"
)

result = { call.data.get(PARAM_REGISTER): response[0] }
result = { call.data.get(SERVICES_PARAM_REGISTER): response[0] }
return result

async def read_multiple_holding_registers(call: ServiceCall) -> int:
_LOGGER.debug(f'read_multiple_holding_registers: {call}')
if (inverter := getInverter(call.data.get(PARAM_DEVICE))) is None:
_LOGGER.debug(f"read_multiple_holding_registers: {call}")
if (inverter := getInverter(call.data.get(SERVICES_PARAM_DEVICE))) is None:
raise ServiceValidationError(
"No communication interface for device found",
translation_domain = DOMAIN,
Expand All @@ -119,8 +108,8 @@ async def read_multiple_holding_registers(call: ServiceCall) -> int:

try:
response = inverter.service_read_multiple_holding_registers(
register = call.data.get(PARAM_REGISTER),
count = call.data.get(PARAM_COUNT))
register = call.data.get(SERVICES_PARAM_REGISTER),
count = call.data.get(SERVICES_PARAM_COUNT))
except Exception as e:
raise ServiceValidationError(
e,
Expand All @@ -129,14 +118,14 @@ async def read_multiple_holding_registers(call: ServiceCall) -> int:
)

result = {}
register = call.data.get(PARAM_REGISTER)
for i in range(0,call.data.get(PARAM_COUNT)):
register = call.data.get(SERVICES_PARAM_REGISTER)
for i in range(0,call.data.get(SERVICES_PARAM_COUNT)):
result[register + i] = response[i]
return result

async def write_holding_register(call: ServiceCall) -> None:
_LOGGER.debug(f'write_holding_register: {call}')
if (inverter := getInverter(call.data.get(PARAM_DEVICE))) is None:
_LOGGER.debug(f"write_holding_register: {call}")
if (inverter := getInverter(call.data.get(SERVICES_PARAM_DEVICE))) is None:
raise ServiceValidationError(
"No communication interface for device found",
translation_domain = DOMAIN,
Expand All @@ -156,8 +145,8 @@ async def write_holding_register(call: ServiceCall) -> None:
return

async def write_multiple_holding_registers(call: ServiceCall) -> None:
_LOGGER.debug(f'write_multiple_holding_registers: {call}')
if (inverter := getInverter(call.data.get(PARAM_DEVICE))) is None:
_LOGGER.debug(f"write_multiple_holding_registers: {call}")
if (inverter := getInverter(call.data.get(SERVICES_PARAM_DEVICE))) is None:
raise ServiceValidationError(
"No communication interface for device found",
translation_domain = DOMAIN,
Expand Down Expand Up @@ -185,11 +174,11 @@ async def write_multiple_holding_registers(call: ServiceCall) -> None:
)

hass.services.async_register(
DOMAIN, SERVICE_WRITE_HOLDING_REGISTER, write_holding_register, schema = SERVICE_WRITE_REGISTER_SCHEMA
DOMAIN, SERVICE_WRITE_HOLDING_REGISTER, write_holding_register, schema = SERVICE_WRITE_HOLDING_REGISTER_SCHEMA
)

hass.services.async_register(
DOMAIN, SERVICE_WRITE_MULTIPLE_HOLDING_REGISTERS, write_multiple_holding_registers, schema = SERVICE_WRITE_MULTIPLE_REGISTERS_SCHEMA
DOMAIN, SERVICE_WRITE_MULTIPLE_HOLDING_REGISTERS, write_multiple_holding_registers, schema = SERVICE_WRITE_MULTIPLE_HOLDING_REGISTERS_SCHEMA
)
return

Expand Down
19 changes: 7 additions & 12 deletions custom_components/solarman/services.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
read_holding_register:
name: Read Holding Register (Modbus Function Code 3)
description: Read a single register value

fields:
device:
name: Device
description: The Device
example: "inverter_roof"
example: "Inverter"
required: true
selector:
device:
Expand All @@ -26,12 +25,11 @@ read_holding_register:
read_multiple_holding_registers:
name: Read Multiple Holding Registers (Modbus Function Code 3)
description: Read values from multiple consecutive registers at once.

fields:
device:
name: Device
description: The Device
example: "inverter_roof"
example: "Inverter"
required: true
selector:
device:
Expand Down Expand Up @@ -61,12 +59,11 @@ read_multiple_holding_registers:
write_holding_register:
name: Write Holding Register (Modbus Function Code 6)
description: NOTE USE WITH CARE! (Some devices might not accept Code 6 in this case try to use 'Write Multiple Holding Registers')

fields:
device:
name: Device
description: The Device
example: "inverter_roof"
example: "Inverter"
required: true
selector:
device:
Expand All @@ -83,23 +80,24 @@ write_holding_register:
max: 65535
mode: box
value:
name: Values
name: Value
description: Value to write
example: "1"
required: true
selector:
number:
min: 0
max: 65535
mode: box

write_multiple_holding_registers:
name: Write Multiple Holding Registers (Modbus Function Code 16)
description: NOTE USE WITH CARE! (Some devices might not accept Code 16 in this case try to use 'Write Holding Register')

fields:
device:
name: Device
description: The Device
example: "inverter_roof"
example: "Inverter"
required: true
selector:
device:
Expand Down Expand Up @@ -128,6 +126,3 @@ write_multiple_holding_registers:
min: 0
max: 65535
mode: box
object:


0 comments on commit 559c978

Please sign in to comment.