308 lines
7 KiB
Go
308 lines
7 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
|
|
}
|