Files
bj_power/bj_power_mes/internal/plc/manager.go
T

75 lines
1.7 KiB
Go

package plc
import (
"context"
"log/slog"
"time"
goplc "bjhardman.cn/bjhardman/goplc"
"bjhardman.cn/bjhardman/goplc/s7"
"bj_power_mes/internal/eventbus"
)
type Manager struct {
client goplc.Client
bus eventbus.Bus
}
func Build(conf PlcConf, bus eventbus.Bus) *Manager {
m := &Manager{bus: bus}
client := s7.NewClient(conf.Host,
s7.WithMaxRetries(-1),
s7.WithConnectionType(s7.ConnectionType(conf.ConnectType)),
s7.WithOnConnected(func() {
slog.Info("PLC connected", "host", conf.Host)
m.publishConnectionEvent(true)
}),
s7.WithOnDisconnected(func(err error) {
if err != nil {
slog.Error("PLC disconnected with error", "host", conf.Host, "error", err)
} else {
slog.Warn("PLC disconnected", "host", conf.Host)
}
m.publishConnectionEvent(false)
}),
s7.WithOnReconnecting(func(attempt int) {
slog.Info("PLC reconnecting", "host", conf.Host, "attempt", attempt)
}),
)
m.client = client
go func() {
_ = client.Connect()
}()
return m
}
func (m *Manager) publishConnectionEvent(connected bool) {
if m.bus == nil {
return
}
_ = m.bus.Publish(context.Background(), eventbus.Event{
ID: "conn-" + time.Now().Format("20060102150405.000"),
Type: eventbus.EventConnectionStatusUpdated,
Source: "plc-manager",
Timestamp: time.Now(),
Payload: map[string]any{
"plcConnected": connected,
},
})
}
// NewManager creates a Manager with a pre-built PLC client.
func NewManager(client goplc.Client) *Manager {
return &Manager{client: client}
}
func (m *Manager) GetPlc() (rc goplc.Client) {
return m.client
}
func (m *Manager) IsConnected() bool {
return m.client != nil && m.client.IsConnected()
}