protocol

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 1, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultSlaveAddr = 0x01

	FuncReadHoldingRegisters = 0x03
)

The batteries speak Modbus RTU framed over BLE GATT writes. A request is a standard Modbus read-holding-registers frame written to the write characteristic; the response arrives as a single notification on the notify characteristic. Frames with an invalid CRC are silently ignored by the BMS.

View Source
const (
	RegVoltage      = 0  // pack voltage, 0.01 V
	RegCurrent      = 1  // pack current, int16, 0.1 A, positive=charging (observed +2.7 A under charge; discharge sign inferred)
	RegCellBase     = 2  // cell voltages, 1 mV, 16 slots (regs 2-17)
	RegTempBase     = 18 // temperature sensors, int16 °C, 3 slots (regs 18-20)
	RegSOC          = 21 // state of charge, % (regs 21/24 track together; 21 assumed SOC)
	RegSOH          = 22 // state of health, % (regs 22/23 track together; 22 assumed SOH)
	RegCellCount    = 36 // number of cells in series
	RegFullCapacity = 37 // full capacity, 0.1 Ah

	// StatusRegisterCount is the number of registers the Voltgo app requests
	// for a status poll (read 0x29 registers from address 0).
	StatusRegisterCount = 41

	// DeviceInfoStart/Count cover the ASCII device-info block (model,
	// hardware version, manufacture date as NUL-padded strings).
	DeviceInfoStart = 105
	DeviceInfoCount = 32
)

Register map for the status block (holding registers 0-40). Derived from live reads of ZT-25.6V100Ah batteries; entries marked "unverified" have not been observed at a non-trivial value yet.

Variables

View Source
var (
	ErrShortFrame    = fmt.Errorf("frame too short")
	ErrCRCMismatch   = fmt.Errorf("CRC mismatch")
	ErrWrongSlave    = fmt.Errorf("unexpected slave address")
	ErrWrongFunction = fmt.Errorf("unexpected function code")
)

Functions

func AppendCRC

func AppendCRC(frame []byte) []byte

AppendCRC returns frame with its CRC-16/MODBUS appended (low byte first, per Modbus RTU convention).

func CRC16

func CRC16(data []byte) uint16

CRC16 computes the CRC-16/MODBUS checksum (poly 0xA001, init 0xFFFF).

func NewExceptionResponse

func NewExceptionResponse(slaveAddr, function, code byte) []byte

NewExceptionResponse builds a Modbus exception response frame for the given function and exception code, for device emulators.

func NewReadRequest

func NewReadRequest(slaveAddr byte, startReg, count uint16) []byte

NewReadRequest builds a read-holding-registers request frame. Register addresses and counts are big-endian per Modbus RTU.

func NewReadResponse

func NewReadResponse(slaveAddr byte, regs []uint16) []byte

NewReadResponse builds a read-holding-registers response frame carrying the given register values. This is the encoder counterpart of ParseReadResponse, for device emulators and round-trip tests.

func ParseBMSInfo

func ParseBMSInfo(regs []uint16) (*battery.BMSInfo, error)

ParseBMSInfo parses the status register block (registers 0-40).

func ParseDeviceInfo

func ParseDeviceInfo(regs []uint16) *battery.DeviceIdentity

ParseDeviceInfo extracts printable ASCII fields from the device-info register block (registers 105+).

func ParseReadResponse

func ParseReadResponse(frame []byte, slaveAddr byte) ([]uint16, error)

ParseReadResponse validates a read-holding-registers response frame and returns the register values.

func VerifyCRC

func VerifyCRC(frame []byte) bool

VerifyCRC reports whether the trailing two bytes of frame are a valid CRC-16/MODBUS of the preceding bytes.

Types

type ModbusError

type ModbusError struct {
	Function byte
	Code     byte
}

ModbusError is a Modbus exception response from the device.

func (*ModbusError) Error

func (e *ModbusError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL