pac3100-exporter/scraper/scraper.go

309 lines
7.0 KiB
Go

package scraper
import (
"encoding/binary"
"fmt"
"github.com/goburrow/serial"
"github.com/rs/zerolog"
"github.com/things-go/go-modbus"
"math"
)
type Scraper struct {
modbus modbus.Client
logger zerolog.Logger
}
type Measurements struct {
VoltageAN float32
VoltageBN float32
VoltageCN float32
VoltageAB float32
VoltageBC float32
VoltageCA float32
CurrentA float32
CurrentB float32
CurrentC float32
ApparantPowerA float32
ApparantPowerB float32
ApparantPowerC float32
ActivePowerA float32
ActivePowerB float32
ActivePowerC float32
Frequency float32
TotalPowerFactor float32
}
func New(address string, logger zerolog.Logger) (*Scraper, error) {
p := modbus.NewRTUClientProvider(
modbus.WithSerialConfig(serial.Config{
Address: address,
BaudRate: 19200,
DataBits: 8,
StopBits: 2,
Parity: "N",
Timeout: modbus.SerialDefaultTimeout,
}),
)
client := modbus.NewClient(p)
err := client.Connect()
if err != nil {
return nil, fmt.Errorf("connecting modbus client: %w", err)
}
scraper := &Scraper{modbus: client, logger: logger}
return scraper, nil
}
func (s *Scraper) GetMeasurments() (Measurements, error) {
var err error
measurement := Measurements{}
measurement.VoltageAN, err = s.GetVoltageAN()
if err != nil {
s.logger.Err(err)
}
measurement.VoltageBN, err = s.GetVoltageBN()
if err != nil {
s.logger.Err(err)
}
measurement.VoltageCN, err = s.GetVoltageCN()
if err != nil {
s.logger.Err(err)
}
measurement.VoltageAB, err = s.GetVoltageAB()
if err != nil {
s.logger.Err(err)
}
measurement.VoltageBC, err = s.GetVoltageBC()
if err != nil {
s.logger.Err(err)
}
measurement.VoltageCA, err = s.GetVoltageCA()
if err != nil {
s.logger.Err(err)
}
measurement.CurrentA, err = s.GetCurrentA()
if err != nil {
s.logger.Err(err)
}
measurement.CurrentB, err = s.GetCurrentB()
if err != nil {
s.logger.Err(err)
}
measurement.CurrentC, err = s.GetCurrentC()
if err != nil {
s.logger.Err(err)
}
measurement.ApparantPowerA, err = s.GetApparentPowerA()
if err != nil {
s.logger.Err(err)
}
measurement.ApparantPowerB, err = s.GetApparentPowerB()
if err != nil {
s.logger.Err(err)
}
measurement.ApparantPowerC, err = s.GetApparentPowerC()
if err != nil {
s.logger.Err(err)
}
measurement.ActivePowerA, err = s.GetActivePowerA()
if err != nil {
s.logger.Err(err)
}
measurement.ActivePowerB, err = s.GetActivePowerB()
if err != nil {
s.logger.Err(err)
}
measurement.ActivePowerC, err = s.GetActivePowerC()
if err != nil {
s.logger.Err(err)
}
measurement.Frequency, err = s.GetFrequency()
if err != nil {
s.logger.Err(err)
}
measurement.TotalPowerFactor, err = s.GetTotalPowerFactor()
if err != nil {
s.logger.Err(err)
}
return measurement, nil
}
//Unit: V
func (s *Scraper) GetVoltageAN() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 1, 2)
if err != nil {
return 0, fmt.Errorf("reading Voltage A-N: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: V
func (s *Scraper) GetVoltageBN() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 3, 2)
if err != nil {
return 0, fmt.Errorf("reading Voltage B-N: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: V
func (s *Scraper) GetVoltageCN() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 5, 2)
if err != nil {
return 0, fmt.Errorf("reading Voltage C-N: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: V
func (s *Scraper) GetVoltageAB() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 7, 2)
if err != nil {
return 0, fmt.Errorf("reading Voltage A-B: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: V
func (s *Scraper) GetVoltageBC() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 9, 2)
if err != nil {
return 0, fmt.Errorf("reading Voltage B-C: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: V
func (s *Scraper) GetVoltageCA() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 11, 2)
if err != nil {
return 0, fmt.Errorf("reading Voltage A-C: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: A
func (s *Scraper) GetCurrentA() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 13, 2)
if err != nil {
return 0, fmt.Errorf("reading Current A: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: A
func (s *Scraper) GetCurrentB() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 15, 2)
if err != nil {
return 0, fmt.Errorf("reading Current B: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: A
func (s *Scraper) GetCurrentC() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 17, 2)
if err != nil {
return 0, fmt.Errorf("reading Current C: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: VA
func (s *Scraper) GetApparentPowerA() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 19, 2)
if err != nil {
return 0, fmt.Errorf("reading Apparent Power A: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: VA
func (s *Scraper) GetApparentPowerB() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 21, 2)
if err != nil {
return 0, fmt.Errorf("reading Apparent Power B: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: VA
func (s *Scraper) GetApparentPowerC() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 23, 2)
if err != nil {
return 0, fmt.Errorf("reading Apparent Power C: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: VA
func (s *Scraper) GetActivePowerA() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 25, 2)
if err != nil {
return 0, fmt.Errorf("reading Active Power A: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: VA
func (s *Scraper) GetActivePowerB() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 27, 2)
if err != nil {
return 0, fmt.Errorf("reading Active Power B: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: VA
func (s *Scraper) GetActivePowerC() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 25, 2)
if err != nil {
return 0, fmt.Errorf("reading Active Power C: %w", err)
}
return Float32fromBytes(results), nil
}
//Unit: Hz
func (s *Scraper) GetFrequency() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 39, 2)
if err != nil {
return 0, fmt.Errorf("reading Freaquency: %w", err)
}
return Float32fromBytes(results), nil
}
// no Unit
func (s *Scraper) GetTotalPowerFactor() (float32, error) {
results, err := s.modbus.ReadInputRegistersBytes(126, 53, 2)
if err != nil {
return 0, fmt.Errorf("reading Total Power Factor: %w", err)
}
return Float32fromBytes(results), nil
}
func Float32fromBytes(bytes []byte) float32 {
bits := binary.BigEndian.Uint32(bytes)
float := math.Float32frombits(bits)
return float
}