75 lines
1.7 KiB
Go
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()
|
|
}
|