sundog - SunSpec in Trio¶
Resources¶
Introduction¶
sundog provides asynchronous access to SunSpec devices using the Trio library. The SunSpec organization has developed a device interface standard for the distributed energy industry. The communication side of the standard is built as a layer on top of Modbus. SunSpec provides libraries including pysunspec2 for loading the interface definition files and communicating with devices. sundog uses pysunspec2 for the data handling and pymodbus for the communications.
Installation¶
This application is not yet published to PyPI nor built into directly runnable packages. It is installable via either cloning and installing or directly via the Git repository. When installing the Python package itself, it is recommended to work in a virtual environment. For a quick introduction, see Python Virtual Environments in Five Minutes.
$ myvenv/bin/pip install git+https://github.com/altendky/sundog
$ myvenv/scripts/pip install git+https://github.com/altendky/sundog
The Name¶
Sun dogs are a pair of bright spots to either side of the sun created by the refraction of sunlight through ice crystals in the atmosphere. The usage of dog in this case is that of a verb meaning to hunt, track, or follow. The two false suns will follow, or dog, the true sun through the sky. With the two false suns following the one true sun we have a trio of suns. Thus, here we are with the sundog library implementing SunSpec using Trio.
SunSpec¶
Client¶
-
async with
sundog.client.
open_client
(host, port)[source]¶ Open a SunSpec Modbus TCP connection to the passed host and port.
- Parameters
- Yields
The SunSpec client.
- Return type
-
class
sundog.client.
Client
(modbus_client, protocol, sunspec_device)[source]¶ Bases:
object
A SunSpec Modbus TCP client using
trio
support inpymodbus
for communication and pysunspec2 for loading models and holding the local cache of the data. The existing communication abilities of the pysunspec2 objects are left intact but should not be used.-
__getitem__
(item)[source]¶ SunSpec models are accessible by indexing the client using either the model number or model name.
model_1 = client[1] model_common = client["common"] assert model_1 is model_common
- Return type
SunSpecModbusClientModel
- Returns
The requested model.
-
modbus_client
: pymodbus.client.asynchronous.trio.TrioModbusTcpClient¶ The Modbus TCP client used for communication.
-
protocol
: pymodbus.client.common.ModbusClientMixin¶ The Modbus client protocol.
-
sunspec_device
: sunspec2.modbus.client.SunSpecModbusClientDevice¶ The SunSpec device object that holds the local data cache and model structures.
-
await
scan
()[source]¶ Scan the device to identify the base address, if not already set, and collect the model list. This also populates all the data.
- Return type
-
await
read_registers
(address, count)[source]¶ Read from the specified sequential register range in the device. Based on the 16-bit Modbus register size, the data in the returned bytes is in 2-byte chunks with each having a big-endian byte order. The local data is not updated.
- Parameters
- Return type
- Returns
The raw bytes read from the device.
- Raises
sundog.ModbusError – When a Modbus exception response is received.
-
await
read_point
(point)[source]¶ Read the passed point from the device and update the local data.
- Parameters
point (
SunSpecModbusClientPoint
) – The SunSpec point object to read.- Return type
- Returns
The new computed value of the point.
- Raises
sundog.ModbusError – When a Modbus exception response is received.
-
point_address
(point)[source]¶ Calculate the start address of a given SunSpec point.
- Parameters
point (
SunSpecModbusClientPoint
) – The SunSpec point object to read.- Return type
- Returns
The address of the first register of the point.
-
await
write_registers
(address, values)[source]¶ Write to the specified sequential register range in the device. Based on the 16-bit Modbus register size, the data in the passed bytes should in 2-byte chunks with each having a big-endian byte order. The local data is not updated.
- Parameters
address (
int
) – The first register to write.count – The total number of sequential registers to write.
- Return type
- Returns
The raw bytes to be written to the device.
- Raises
sundog.ModbusError – When a Modbus exception response is received.
-
await
write_point
(point)[source]¶ Write the passed point from the local data to the device.
- Parameters
point (
SunSpecModbusClientPoint
) – The SunSpec point object to write.- Raises
sundog.ModbusError – When a Modbus exception response is received.
- Return type
-
Server¶
-
class
sundog.server.
Server
(slave_context, server_context, identity)[source]¶ Bases:
object
A SunSpec Modbus TCP server using
trio
support inpymodbus
for communication and pysunspec2 for loading models and holding the local cache of the data. The actual TCP server can be launched usingServer.tcp_server()
.await nursery.start( functools.partial( trio.serve_tcp, server.tcp_server, host="127.0.0.1", port=0, ), )
-
__getitem__
(item)[source]¶ SunSpec models are accessible by indexing the client using either the model number or model name.
model_1 = server[1] model_common = server["common"] assert model_1 is model_common
-
slave_context
: sundog.server.SunSpecModbusSlaveContext¶ The single slave context to be served by this server. This is backed by the SunSpec device object.
-
server_context
: pymodbus.datastore.context.ModbusServerContext¶ The datastore for this pymodbus server. Presently only a single slave context is supported.
-
identity
: pymodbus.device.ModbusDeviceIdentification¶ The identity information for this Modbus server.
-
classmethod
build
(model_summaries)[source]¶ Build the server instance based on the passed model summaries. Any per-point or bulk data update must be done separately.
- Parameters
model_summaries (
Sequence
[ModelSummary
]) – The models which you want the server to provide.- Return type
- Returns
The instance of the server datastore pieces.
-
await
tcp_server
(server_stream)[source]¶ Handle serving over a stream. See
Server
for an example.- Parameters
server_stream (
SocketStream
) – The stream to communicate over.- Return type
-
-
class
sundog.server.
ModelSummary
(id, length)[source]¶ Bases:
object
A model can be summarized by its ID and length. While models of fixed length would not need the length provided, those with repeatable blocks need a length to indicate the number of repetitions of the repeating block.
-
class
sundog.server.
SunSpecModbusSlaveContext
(sunspec_device)[source]¶ Bases:
pymodbus.interfaces.IModbusSlaveContext
A
pymodbus
slave context that is backed by thepysunspec2
device object.-
sunspec_device
: sunspec2.modbus.client.SunSpecModbusClientDevice¶ The
pysunspec2
device object use for local storage of the SunSpec data.
-
getValues
(fx, address, count=1)[source]¶ See
pymodbus.interfaces.IModbusSlaveContext.getValues()
.- Return type
-
setValues
(fx, address, values)[source]¶ See
pymodbus.interfaces.IModbusSlaveContext.setValues()
.- Return type
-
validate
(fx, address, count=1)[source]¶ See
pymodbus.interfaces.IModbusSlaveContext.validate()
.- Return type
-
-
class
sundog.server.
PreparedRequest
(data, slice, offset_address, bytes_offset_address)[source]¶ Bases:
object
Holds some common bits used in serving a request.
-
data
: bytearray¶ The entire block of registers. Each register is a 2-byte chunk stored in big-endian byte order. The first element is the high byte of the server’s register located at the base address.
-
Exceptions¶
-
class
sundog.
SundogError
¶ Bases:
Exception
The base for all sundog errors. Not to be raised directly, but could be used if you want to catch any except this program may explicitly raise.
-
class
sundog.
BaseAddressNotFoundError
(addresses)¶ Bases:
sundog.SundogError
Raised if no address matched the expected SunSpec sentinel value.
-
class
sundog.
InternalError
¶ Bases:
sundog.SundogError
Raised when things that should not happen do, and they aren’t the user’s fault.
-
class
sundog.
InvalidBaseAddressError
(address, value)¶ Bases:
sundog.SundogError
Raised if the specified base address does not match the expected SunSpec sentinel value.
-
class
sundog.
ModbusError
(exception)¶ Bases:
sundog.SundogError
Raised when a Modbus action results in a Modbus exception.