solaxx1rs485

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2022 License: MIT Imports: 5 Imported by: 0

README

Solax X1 Air RS485 communication client in Go

GND: 1 orange/white A: 4 blue B: 5 blue/wite

Documentation

Index

Constants

View Source
const (
	ControlCodeRegister byte = 0x10
	ControlCodeRead     byte = 0x11
	ControlCodeWrite    byte = 0x12
	ControlCodeExecute  byte = 0x13

	StatusACK   byte = 0x06
	StatusNOACK byte = 0x15
)

Variables

View Source
var (
	ErrIncompleteRead  = errors.New("Failed to read read body")
	ErrIncompleteWrite = errors.New("Failed to write full body")
	ErrNoInverter      = errors.New("No inverter responded to call")
)
View Source
var (
	ErrMaxDataSizeExceeded    = errors.New("Exceeded max data length is 255 bytes")
	ErrInvalidBody            = errors.New("Could not parse body into valid packet")
	ErrUnexpectedControlCode  = errors.New("Unexpected Control Code")
	ErrUnexpectedFunctionCode = errors.New("Unexpected Function Code")
)

Functions

func ParseRegisterInverterResponse

func ParseRegisterInverterResponse(body []byte) error

0x81

func ParseUnregisterInverterResponse

func ParseUnregisterInverterResponse(body []byte) error

0x82

Types

type Client

type Client struct {
	Conn         Connection
	LastResponse []byte
}

func NewClient

func NewClient(device string) (*Client, error)

func NewClientWithConnection

func NewClientWithConnection(conn Connection) (*Client, error)

func (*Client) FindUnregisteredInverter

func (c *Client) FindUnregisteredInverter() (*Inverter, error)

FindUnregisteredInverter returns the first unregistered inverter (address 0x00) Use RegisterInverter afterwards to set an address for the inverter

func (*Client) GetInfo

func (c *Client) GetInfo(inverter *Inverter) (*NormalInfoResponse, error)

func (*Client) GetInverterInfo

func (c *Client) GetInverterInfo(inverter *Inverter) (*InverterInfoResponse, error)

func (*Client) Read

func (c *Client) Read() ([]byte, error)

func (*Client) RegisterInverter

func (c *Client) RegisterInverter(inverter *Inverter, address byte) error

RegisterInverter Sets the bus address for an unregistered inverter

func (*Client) Send

func (c *Client) Send(req []byte) error

func (*Client) UnregisterInverter

func (c *Client) UnregisterInverter(inverter *Inverter) error

UnregisterInverter resets the inverter address (becomes 0x00)

type Connection

type Connection interface {
	io.ReadWriteCloser
	Flush() error
}

type Inverter

type Inverter struct {
	Serial  []byte
	Address byte
}

type InverterInfoResponse

type InverterInfoResponse struct {
	Phase           byte
	RatedPower      string
	FirmwareVersion string
	ModuleName      string
	FactoryName     string
	SerialNumber    string
	RatedBusVoltage string
}

func InverterInfoResponseFromData

func InverterInfoResponseFromData(data []byte) (InverterInfoResponse, error)

func ParseInverterInfoResponse

func ParseInverterInfoResponse(body []byte) (InverterInfoResponse, error)

0x83

type NormalInfoResponse

type NormalInfoResponse struct {
	Temperature uint16 // Celsius
	EnergyToday uint16 // 0.1kWh
	Vpv1        uint16 // 0.1V
	Vpv2        uint16 // 0.1V
	Apv1        uint16 // 0.1A
	Apv2        uint16 // 0.1A
	Iac         uint16 // 0.1A
	Vac         uint16 // 0.1V
	Frequency   uint16 // 0.01Hz
	Power       uint16 // 1W

	EnergyTotal      uint32 // 0.1kWh
	TimeTotal        uint32 // hours
	Mode             uint16 // Inverter mode (0: Wait, 1: Check, 2: Normal, 3: Fault, 4: Permanent Fault, 5: Update, 6: Selftest)
	GridVoltFault    uint16 // 0.1V Grid voltage fault value
	GridFreqFault    uint16 // 0.01Hz Grid frequency fault value
	DCIFault         uint16 // mA, DJ injection fault value
	TemperatureFault uint16 // Temperature fault value
	PV1Fault         uint16 // 0.1V PV1 voltage fault value
	PV2Fault         uint16 // 0.1V PV2 voltage fault value
	GFCFault         uint16 // mA, GFC fault value
	ErrMessage       uint32 // Error message code
	// contains filtered or unexported fields
}

func NormalInfoResponseFromData

func NormalInfoResponseFromData(data []byte) (NormalInfoResponse, error)

func ParseNormalInfoResponse

func ParseNormalInfoResponse(body []byte) (NormalInfoResponse, error)

0x82

type NormalizedNormalInfoResponse

type NormalizedNormalInfoResponse struct {
	Temperature uint16  // Celsius
	EnergyToday float64 // 0.1kWh -> kWh
	Vpv1        float64 // 0.1V -> V
	Vpv2        float64 // 0.1V -> V
	Apv1        float64 // 0.1A -> A
	Apv2        float64 // 0.1A -> A
	Iac         float64 // 0.1A -> A
	Vac         float64 // 0.1V -> V
	Frequency   float64 // 0.01Hz -> Hz
	Power       uint16  // 1W

	EnergyTotal      float64  // 0.1kWh
	TimeTotal        uint32   // hours
	Mode             string   // Inverter mode (0: Wait, 1: Check, 2: Normal, 3: Fault, 4: Permanent Fault, 5: Update, 6: Selftest)
	GridVoltFault    float64  // 0.1V Grid voltage fault value -> V
	GridFreqFault    float64  // 0.01Hz Grid frequency fault value -> Hz
	DCIFault         float64  // mA, DJ injection fault value -> A
	TemperatureFault float64  // Temperature fault value
	PV1Fault         float64  // 0.1V PV1 voltage fault value -> V
	PV2Fault         float64  // 0.1V PV2 voltage fault value -> V
	GFCFault         float64  // mA, GFC fault value -> A
	ErrMessage       []string // Error message code
	// contains filtered or unexported fields
}

type Packet

type Packet struct {
	Header       uint16
	Source       uint16
	Destination  uint16
	ControlCode  byte
	FunctionCode byte
	Data         []byte
}

Default packet format for Solax X1 air. It uses an RS485 protocol that with some resemblance to modbus

## Packet format: Header 2 0xAA55 // Always same value Source Address 2 0xXX00 // Typically 0x0000 Destination Address 2 0x00XX // As set, default 0x0000 Control code 1 0xXX // Depends on command Function code 1 0xXX // Depends on command Data lenght 1 0xXX // Data length, can be 0 Data0..N N Checksum 2 sum of bytes above

func DefaultPacket

func DefaultPacket() *Packet

func InverterInfoRequest

func InverterInfoRequest(address byte) *Packet

0x03

func NormalInfoRequest

func NormalInfoRequest(address byte) *Packet

0x02

func ParsePacket

func ParsePacket(res []byte) (*Packet, error)

func RegisterInverterRequest

func RegisterInverterRequest(serial []byte, address byte) *Packet

0x01

func UnregisterInverterRequest

func UnregisterInverterRequest(serial []byte, address byte) *Packet

0x02

func UnregisteredInverterRequest

func UnregisteredInverterRequest() *Packet

0x00

func (*Packet) Bytes

func (p *Packet) Bytes() ([]byte, error)

type UnregisteredInverterResponse

type UnregisteredInverterResponse struct {
	Serial []byte
}

func ParseUnregisteredInverterResponse

func ParseUnregisteredInverterResponse(body []byte) (UnregisteredInverterResponse, error)

0x80

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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