|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
pb "FRMS/internal/pkg/grpc"
|
|
|
|
"FRMS/internal/pkg/logging"
|
|
|
|
"FRMS/internal/pkg/sensor"
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
_ "log"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
)
|
|
|
|
|
|
|
|
// this package will implement a reactor manager and associated go routines
|
|
|
|
|
|
|
|
type ReactorManager struct {
|
|
|
|
*Manager
|
|
|
|
// StatusMon *StatusMonitor putting on pause
|
|
|
|
*ReactorDevices
|
|
|
|
Config *viper.Viper // config to update
|
|
|
|
}
|
|
|
|
|
|
|
|
type ReactorDevices struct {
|
|
|
|
// device struct
|
|
|
|
Devices map[int]DeviceManager
|
|
|
|
sync.RWMutex
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewReactorManager(err chan error) *ReactorManager {
|
|
|
|
r := &ReactorManager{}
|
|
|
|
// sub managers
|
|
|
|
dm := make(map[int]DeviceManager)
|
|
|
|
r.ReactorDevices = &ReactorDevices{Devices: dm}
|
|
|
|
// core manager
|
|
|
|
r.Manager = NewManager(err)
|
|
|
|
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ReactorManager) Start() error {
|
|
|
|
return r.Manager.Start()
|
|
|
|
//go r.StatusMon.Send(&DeviceInfo{Id: r.Id, Type: "Reactor", Status: "[green]ONLINE[white]"}, "Reactor")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ReactorManager) Exit() {
|
|
|
|
r.Manager.Exit()
|
|
|
|
logging.Debug(logging.DExit, "RMA %v exiting", r.Id)
|
|
|
|
//go r.StatusMon.Send(&DeviceInfo{Id: r.Id, Type: "Reactor", Status: "[red]OFFLINE[white]", Data: fmt.Sprintf("Last Seen %v", time.Now().Format("Mon at 03:04:05pm MST"))}, "Reactor")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ReactorManager) ReactorStatusHandler(ctx context.Context, req *pb.ReactorStatusPing) (*pb.ReactorStatusResponse, error) {
|
|
|
|
// function client will call to update reactor information
|
|
|
|
//go r.PingReset()
|
|
|
|
fmt.Printf("Recieved ping from %v!\n", req.GetId())
|
|
|
|
// update devices/sensors
|
|
|
|
go r.UpdateDevices(req.GetDevices())
|
|
|
|
|
|
|
|
return &pb.ReactorStatusResponse{Id: int32(r.Id)}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// device stuff
|
|
|
|
|
|
|
|
type DeviceManager interface {
|
|
|
|
SetName(string) error // change name
|
|
|
|
GetParameter(string) (string, error) // key ret val
|
|
|
|
SetParameter(string, string) error // key, val
|
|
|
|
Update(*pb.Device, *viper.Viper) error // write updates
|
|
|
|
String() string // printing
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewDeviceManager(device *pb.Device) (DeviceManager, error) {
|
|
|
|
// returns a manager struct
|
|
|
|
return sensor.NewDeviceManager(device)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ReactorManager) UpdateDevices(devs []*pb.Device) {
|
|
|
|
// pass updates to correct manager
|
|
|
|
r.ReactorDevices.RLock() // read lock only
|
|
|
|
defer r.ReactorDevices.RUnlock()
|
|
|
|
|
|
|
|
for _, dev := range devs {
|
|
|
|
// looping over devs
|
|
|
|
if dm, ok := r.ReactorDevices.Devices[int(dev.GetAddr())]; ok {
|
|
|
|
// device manager found
|
|
|
|
go dm.Update(dev, r.Config) // update dm
|
|
|
|
fmt.Println(dm)
|
|
|
|
} else {
|
|
|
|
// not found
|
|
|
|
go r.AddDevice(dev, r.Err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ReactorDevices) AddDevice(dev *pb.Device, errCh chan error) {
|
|
|
|
r.Lock() // write lock
|
|
|
|
defer r.Unlock()
|
|
|
|
dm, err := NewDeviceManager(dev)
|
|
|
|
if err != nil {
|
|
|
|
errCh <- err
|
|
|
|
}
|
|
|
|
r.Devices[int(dev.GetAddr())] = dm
|
|
|
|
}
|