Dane Sabo 3299181c70 Auto sync: 2025-09-02 22:47:53 (10335 files changed)
M  lazy-lock.json

M  lua/custom/configs/lspconfig.lua

M  lua/custom/init.lua

A  lua/custom/journal.lua

A  nvim_venv/bin/Activate.ps1

A  nvim_venv/bin/activate

A  nvim_venv/bin/activate.csh

A  nvim_venv/bin/activate.fish
2025-09-02 22:47:53 -04:00

130 lines
4.3 KiB
Python

"""Remote datastore."""
from pymodbus.datastore import ModbusBaseSlaveContext
from pymodbus.exceptions import NotImplementedException
from pymodbus.logging import Log
# ---------------------------------------------------------------------------#
# Context
# ---------------------------------------------------------------------------#
class RemoteSlaveContext(ModbusBaseSlaveContext):
"""TODO.
This creates a modbus data model that connects to
a remote device (depending on the client used)
"""
def __init__(self, client, slave=None):
"""Initialize the datastores.
:param client: The client to retrieve values with
:param slave: Unit ID of the remote slave
"""
self._client = client
self.slave = slave
self.result = None
self.__build_mapping()
if not self.__set_callbacks:
Log.error("Init went wrong.")
def reset(self):
"""Reset all the datastores to their default values."""
raise NotImplementedException()
def validate(self, _fc_as_hex, _address, _count):
"""Validate the request to make sure it is in range.
:returns: True
"""
return True
def getValues(self, fc_as_hex, _address, _count=1):
"""Get values from real call in validate."""
if fc_as_hex in self._write_fc:
return [0]
group_fx = self.decode(fc_as_hex)
func_fc = self.__get_callbacks[group_fx]
self.result = func_fc(_address, _count)
return self.__extract_result(self.decode(fc_as_hex), self.result)
def setValues(self, fc_as_hex, address, values):
"""Set the datastore with the supplied values."""
group_fx = self.decode(fc_as_hex)
if fc_as_hex not in self._write_fc:
raise ValueError(f"setValues() called with an non-write function code {fc_as_hex}")
func_fc = self.__set_callbacks[f"{group_fx}{fc_as_hex}"]
if fc_as_hex in {0x0F, 0x10}: # Write Multiple Coils, Write Multiple Registers
self.result = func_fc(address, values)
else:
self.result = func_fc(address, values[0])
# if self.result.isError():
# return self.result
def __str__(self):
"""Return a string representation of the context.
:returns: A string representation of the context
"""
return f"Remote Slave Context({self._client})"
def __build_mapping(self):
"""Build the function code mapper."""
params = {}
if self.slave:
params["slave"] = self.slave
self.__get_callbacks = {
"d": lambda a, c: self._client.read_discrete_inputs(
a, count=c, **params
),
"c": lambda a, c: self._client.read_coils(
a, count=c, **params
),
"h": lambda a, c: self._client.read_holding_registers(
a, count=c, **params
),
"i": lambda a, c: self._client.read_input_registers(
a, count=c, **params
),
}
self.__set_callbacks = {
"d5": lambda a, v: self._client.write_coil(
a, v, **params
),
"d15": lambda a, v: self._client.write_coils(
a, v, **params
),
"c5": lambda a, v: self._client.write_coil(
a, v, **params
),
"c15": lambda a, v: self._client.write_coils(
a, v, **params
),
"h6": lambda a, v: self._client.write_register(
a, v, **params
),
"h16": lambda a, v: self._client.write_registers(
a, v, **params
),
"i6": lambda a, v: self._client.write_register(
a, v, **params
),
"i16": lambda a, v: self._client.write_registers(
a, v, **params
),
}
self._write_fc = (0x05, 0x06, 0x0F, 0x10)
def __extract_result(self, fc_as_hex, result):
"""Extract the values out of a response.
TODO make this consistent (values?)
"""
if not result.isError():
if fc_as_hex in {"d", "c"}:
return result.bits
if fc_as_hex in {"h", "i"}:
return result.registers
else:
return result
return None