|
|
|
@ -3,10 +3,13 @@ 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
|
|
|
|
@ -14,21 +17,33 @@ import (
|
|
|
|
|
type ReactorManager struct {
|
|
|
|
|
*Manager
|
|
|
|
|
// StatusMon *StatusMonitor putting on pause
|
|
|
|
|
*devstatus
|
|
|
|
|
*ReactorSensors
|
|
|
|
|
*ReactorDevices
|
|
|
|
|
Config *viper.Viper // config to update
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ReactorSensors struct {
|
|
|
|
|
// sensor struct
|
|
|
|
|
Sensors map[int]SensorManager
|
|
|
|
|
sync.RWMutex
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type devstatus struct {
|
|
|
|
|
// keeping this around but not using it to create status for status mon
|
|
|
|
|
sync.Mutex
|
|
|
|
|
Devs map[int]*DeviceInfo
|
|
|
|
|
type ReactorDevices struct {
|
|
|
|
|
// device struct
|
|
|
|
|
Devices map[int]DeviceManager
|
|
|
|
|
sync.RWMutex
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewReactorManager(err chan error) *ReactorManager {
|
|
|
|
|
r := &ReactorManager{}
|
|
|
|
|
di := make(map[int]*DeviceInfo)
|
|
|
|
|
r.devstatus = &devstatus{Devs: di}
|
|
|
|
|
// sub managers
|
|
|
|
|
dm := make(map[int]DeviceManager)
|
|
|
|
|
sm := make(map[int]SensorManager)
|
|
|
|
|
r.ReactorDevices = &ReactorDevices{Devices: dm}
|
|
|
|
|
r.ReactorSensors = &ReactorSensors{Sensors: sm}
|
|
|
|
|
// core manager
|
|
|
|
|
r.Manager = NewManager(err)
|
|
|
|
|
//r.StatusMon = NewStatusMonitor("Reactor", c.Id, sys)
|
|
|
|
|
|
|
|
|
|
return r
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -41,38 +56,94 @@ 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")
|
|
|
|
|
r.devstatus.Lock()
|
|
|
|
|
defer r.devstatus.Unlock()
|
|
|
|
|
// keeping this because it **COULD** be useful, maybe
|
|
|
|
|
for _, d := range r.Devs {
|
|
|
|
|
newd := d
|
|
|
|
|
newd.Status = "UNKOWN"
|
|
|
|
|
r.Devs[newd.Id] = newd
|
|
|
|
|
//go r.StatusMon.Send(newd, "Device")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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())
|
|
|
|
|
for _, dev := range req.GetDevices() {
|
|
|
|
|
d := &DeviceInfo{Id: int(dev.GetAddr()), Type: dev.GetName(), Status: dev.GetStatus().String(), Data: dev.GetData()}
|
|
|
|
|
go r.UpdateDevice(d)
|
|
|
|
|
}
|
|
|
|
|
// update devices/sensors
|
|
|
|
|
go r.UpdateSensors(req.GetSensors())
|
|
|
|
|
go r.UpdateDevices(req.GetDevices())
|
|
|
|
|
|
|
|
|
|
return &pb.ReactorStatusResponse{Id: int32(r.Id)}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *ReactorManager) UpdateDevice(d *DeviceInfo) {
|
|
|
|
|
r.devstatus.Lock()
|
|
|
|
|
defer r.devstatus.Unlock()
|
|
|
|
|
if olddev, ok := r.Devs[d.Id]; !ok {
|
|
|
|
|
// new device
|
|
|
|
|
r.Devs[d.Id] = d
|
|
|
|
|
//go r.StatusMon.Send(d, "Device")
|
|
|
|
|
} else if olddev.Status != d.Status || olddev.Data != d.Data {
|
|
|
|
|
// dev status or data has changed
|
|
|
|
|
r.Devs[d.Id] = d
|
|
|
|
|
//go r.StatusMon.Send(d, "Device")
|
|
|
|
|
// sensor/device stuff
|
|
|
|
|
|
|
|
|
|
type SensorManager interface {
|
|
|
|
|
SetName(string) error // change name
|
|
|
|
|
SetSampleRate(int) error // change sample rate
|
|
|
|
|
Update(*pb.Sensor, *viper.Viper) error // write updates
|
|
|
|
|
String() string // printing
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type DeviceManager interface {
|
|
|
|
|
SetName(string) error // change name
|
|
|
|
|
SetParameter(string, string) error // key, val
|
|
|
|
|
Update(*pb.Device, *viper.Viper) error // write updates
|
|
|
|
|
String() string // printing
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewSensorManager(sens *pb.Sensor) (SensorManager, error) {
|
|
|
|
|
// returns a manager struct
|
|
|
|
|
return sensor.NewSensorManager(sens)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
} 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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *ReactorManager) UpdateSensors(sensors []*pb.Sensor) {
|
|
|
|
|
// pass updates to correct manager
|
|
|
|
|
r.ReactorSensors.RLock() // read lock
|
|
|
|
|
defer r.ReactorSensors.RUnlock()
|
|
|
|
|
for _, sens := range sensors {
|
|
|
|
|
// looping over sensors
|
|
|
|
|
if sm, ok := r.ReactorSensors.Sensors[int(sens.GetAddr())]; ok {
|
|
|
|
|
// sensor manager found
|
|
|
|
|
go sm.Update(sens, r.Config) // update sm
|
|
|
|
|
} else {
|
|
|
|
|
// not found
|
|
|
|
|
go r.AddSensor(sens, r.Err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *ReactorSensors) AddSensor(sensor *pb.Sensor, errCh chan error) {
|
|
|
|
|
r.Lock() // write lock
|
|
|
|
|
defer r.Unlock()
|
|
|
|
|
sm, err := NewSensorManager(sensor)
|
|
|
|
|
if err != nil {
|
|
|
|
|
errCh <- err
|
|
|
|
|
}
|
|
|
|
|
r.Sensors[int(sensor.GetAddr())] = sm
|
|
|
|
|
}
|
|
|
|
|