expanded the sensor/device manager stuff to prep for fully fledged managers
parent
63811505eb
commit
e64efad3fc
@ -1,79 +1,72 @@
|
|||||||
package I2C
|
package I2C
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type I2CDevice struct {
|
type I2CDevice struct {
|
||||||
*I2CBus // embeds bus
|
*I2CBus // embeds bus
|
||||||
bool // stores whether dev is currently connected
|
bool // stores whether dev is currently connected
|
||||||
int // addr
|
int // addr
|
||||||
Data *data
|
Data *data
|
||||||
}
|
}
|
||||||
|
|
||||||
type data struct {
|
type data struct {
|
||||||
string
|
string
|
||||||
bool
|
bool
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d I2CDevice) String() string {
|
func (d I2CDevice) String() string {
|
||||||
t := map[int]string{97:"DO Sensor",99:"pH Sensor",102:"Temperature Sensor",64:"DHT11 Sensor"}
|
t := map[int]string{97: "DO Sensor", 99: "pH Sensor", 102: "Temperature Sensor", 64: "DHT11 Sensor"}
|
||||||
return t[d.int]
|
return t[d.int]
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDevice(addr int,bus *I2CBus) *I2CDevice {
|
func NewDevice(addr int, bus *I2CBus) *I2CDevice {
|
||||||
d := &I2CDevice{}
|
d := &I2CDevice{}
|
||||||
d.I2CBus = bus
|
d.I2CBus = bus
|
||||||
d.int = addr
|
d.int = addr
|
||||||
d.Data = &data{}
|
d.Data = &data{}
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *I2CDevice) GetAddr() int {
|
func (d *I2CDevice) GetAddr() int {
|
||||||
return d.int
|
return d.int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *I2CDevice) GetStatus() string {
|
func (d *I2CDevice) GetStatus() bool {
|
||||||
// TODO
|
// TODO
|
||||||
s := d.I2CBus.GetStatus(d.int)
|
return d.I2CBus.GetStatus(d.int)
|
||||||
if s {
|
|
||||||
d.Data.Active()
|
|
||||||
return "[green]ACTIVE[white]"
|
|
||||||
} else {
|
|
||||||
d.Data.Killed()
|
|
||||||
return "[red]KILLED[white]"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *I2CDevice) GetType() string {
|
func (d *I2CDevice) GetType() string {
|
||||||
// TODO
|
// TODO
|
||||||
return fmt.Sprint(d)
|
return fmt.Sprint(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *I2CDevice) GetData() string {
|
func (d *I2CDevice) GetData() string {
|
||||||
d.Data.Lock()
|
d.Data.Lock()
|
||||||
defer d.Data.Unlock()
|
defer d.Data.Unlock()
|
||||||
d.Data.string = d.I2CBus.GetData(d.int)
|
d.Data.string = d.I2CBus.GetData(d.int)
|
||||||
return d.Data.string
|
return d.Data.string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *data) Active() {
|
func (d *data) Active() {
|
||||||
d.Lock()
|
d.Lock()
|
||||||
defer d.Unlock()
|
defer d.Unlock()
|
||||||
if !d.bool {
|
if !d.bool {
|
||||||
d.string = ""
|
d.string = ""
|
||||||
d.bool = true
|
d.bool = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *data) Killed() {
|
func (d *data) Killed() {
|
||||||
d.Lock()
|
d.Lock()
|
||||||
defer d.Unlock()
|
defer d.Unlock()
|
||||||
if d.bool {
|
if d.bool {
|
||||||
d.string = time.Now().Format("Mon at 03:04:05pm MST")
|
d.string = time.Now().Format("Mon at 03:04:05pm MST")
|
||||||
d.bool = false
|
d.bool = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,97 +1,102 @@
|
|||||||
package I2C
|
package I2C
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
_ "fmt"
|
||||||
_ "fmt"
|
"sync"
|
||||||
"sync"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
i2c monitor implements a long running monitor responsible for sending active devices to the rlc
|
i2c monitor implements a long running monitor responsible for sending active devices to the rlc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type I2CMonitor struct {
|
type I2CMonitor struct {
|
||||||
*I2CBus
|
*I2CBus
|
||||||
Devices *devs
|
Devices *devs
|
||||||
DevChan chan int
|
DevChan chan int
|
||||||
}
|
}
|
||||||
|
|
||||||
type devs struct {
|
type devs struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
m map[int]*I2CDevice
|
m map[int]*I2CDevice
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMonitor(bus int,ch chan int) *I2CMonitor {
|
func NewMonitor(bus int, ch chan int) *I2CMonitor {
|
||||||
m := &I2CMonitor{}
|
m := &I2CMonitor{}
|
||||||
b := NewBus(bus)
|
b := NewBus(bus)
|
||||||
m.I2CBus = b
|
m.I2CBus = b
|
||||||
d := make(map[int]*I2CDevice)
|
d := make(map[int]*I2CDevice)
|
||||||
m.Devices = &devs{m:d}
|
m.Devices = &devs{m: d}
|
||||||
m.DevChan = ch
|
m.DevChan = ch
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *I2CMonitor) Update() {
|
func (m *I2CMonitor) Update() {
|
||||||
/*
|
/*
|
||||||
scans bus and adds new active devices
|
scans bus and adds new active devices
|
||||||
*/
|
*/
|
||||||
devs := m.Scan()
|
devs := m.Scan()
|
||||||
chng := m.Devices.Parse(m.I2CBus,devs)
|
chng := m.Devices.Parse(m.I2CBus, devs)
|
||||||
for _, d := range chng {
|
for _, d := range chng {
|
||||||
go m.ConnectDevice(d)
|
go m.ConnectDevice(d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *I2CMonitor) Monitor() {
|
func (m *I2CMonitor) Monitor() {
|
||||||
// functon that updates the device list and notifies rlc of any changes to sensor composition
|
// functon that updates the device list and notifies rlc of any changes to sensor composition
|
||||||
s := make(chan struct{})
|
s := make(chan struct{})
|
||||||
t := 5 * time.Second
|
t := 5 * time.Second
|
||||||
go func(signal chan struct{},to time.Duration) { // simple signal func to init scan
|
go func(signal chan struct{}, to time.Duration) { // simple signal func to init scan
|
||||||
for {
|
for {
|
||||||
signal <-struct{}{}
|
signal <- struct{}{}
|
||||||
time.Sleep(to)
|
time.Sleep(to)
|
||||||
}
|
}
|
||||||
}(s,t)
|
}(s, t)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
<-s
|
<-s
|
||||||
m.Update()
|
m.Update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *I2CMonitor) ConnectDevice(addr int) {
|
func (m *I2CMonitor) ConnectDevice(addr int) {
|
||||||
m.DevChan <-addr
|
m.DevChan <- addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *I2CMonitor) GetDevice(addr int) interface{ GetAddr() int; GetData() string; GetStatus() string; GetType() string } {
|
func (m *I2CMonitor) GetDevice(addr int) interface {
|
||||||
m.Devices.Lock()
|
GetAddr() int
|
||||||
defer m.Devices.Unlock()
|
GetData() string
|
||||||
return m.Devices.m[addr]
|
GetStatus() bool
|
||||||
|
GetType() string
|
||||||
|
} {
|
||||||
|
m.Devices.Lock()
|
||||||
|
defer m.Devices.Unlock()
|
||||||
|
return m.Devices.m[addr]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *devs) Parse(bus *I2CBus,devices map[int]bool) []int {
|
func (d *devs) Parse(bus *I2CBus, devices map[int]bool) []int {
|
||||||
d.Lock()
|
d.Lock()
|
||||||
defer d.Unlock()
|
defer d.Unlock()
|
||||||
newdevs := []int{}
|
newdevs := []int{}
|
||||||
for addr, status := range devices {
|
for addr, status := range devices {
|
||||||
if dev, exists := d.m[addr]; exists {
|
if dev, exists := d.m[addr]; exists {
|
||||||
// device seen
|
// device seen
|
||||||
if status != dev.bool { // if device state changed
|
if status != dev.bool { // if device state changed
|
||||||
dev.bool = status
|
dev.bool = status
|
||||||
if status {
|
if status {
|
||||||
newdevs = append(newdevs,dev.GetAddr())
|
newdevs = append(newdevs, dev.GetAddr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// device not seen yet
|
// device not seen yet
|
||||||
if status {
|
if status {
|
||||||
// active
|
// active
|
||||||
newd := NewDevice(addr,bus)
|
newd := NewDevice(addr, bus)
|
||||||
newd.bool = status
|
newd.bool = status
|
||||||
d.m[addr] = newd
|
d.m[addr] = newd
|
||||||
newdevs = append(newdevs,newd.GetAddr())
|
newdevs = append(newdevs, newd.GetAddr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newdevs
|
return newdevs
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package sensor
|
||||||
|
|
||||||
|
// do sensor and methods
|
||||||
|
|
||||||
|
import (
|
||||||
|
pb "FRMS/internal/pkg/grpc"
|
||||||
|
"errors"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DOSensorManager struct {
|
||||||
|
// do sensor manager
|
||||||
|
Sensor *pb.Sensor // for sending/updating
|
||||||
|
sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DOSensorManager) SetName(name string) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DOSensorManager) SetStatus(status int) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DOSensorManager) SetSampleRate(rate int) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DOSensorManager) Update(sensor *pb.Sensor, config *viper.Viper) error {
|
||||||
|
// updates info
|
||||||
|
s.Lock()
|
||||||
|
defer s.Unlock()
|
||||||
|
s.Sensor = sensor
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DOSensorManager) String() string {
|
||||||
|
// #TODO
|
||||||
|
return "TODO"
|
||||||
|
}
|
@ -1,36 +1,66 @@
|
|||||||
package sensor
|
package sensor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
pb "FRMS/internal/pkg/grpc"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
this file serves as a map that the sensor library can use to determine which manager to call
|
Returns the correct manager for sensor/device
|
||||||
*/
|
*/
|
||||||
|
type SensorManager interface {
|
||||||
type NewManager interface {
|
// basic sensor stuff
|
||||||
// serves as interface to restrict managers can be relocated
|
SetName(string) error // change display name
|
||||||
|
SetStatus(int) error // update status
|
||||||
|
SetSampleRate(int) error // update sample rate
|
||||||
|
Update(*pb.Sensor, *viper.Viper) error // write updates
|
||||||
|
String() string // printable
|
||||||
}
|
}
|
||||||
|
|
||||||
type DM struct {
|
type DeviceManager interface {
|
||||||
DeviceManagers map[uint]NewManager
|
// basic device stuff
|
||||||
sync.Mutex
|
SetName(string) error // change displayed name
|
||||||
|
SetStatus(int) error // status change
|
||||||
|
SetParameter(string, string) error // key, val
|
||||||
|
Update(*pb.Device, *viper.Viper) error // write updates
|
||||||
|
String() string // printable
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewManagerDirectory() *DM {
|
func NewSensorManager(sensor *pb.Sensor) (SensorManager, error) {
|
||||||
m := map[uint]NewManager{
|
// returns correct sensor manager by ID
|
||||||
// map to set functions up
|
var sm SensorManager
|
||||||
//112: NewDOManager(),
|
var err error
|
||||||
|
|
||||||
|
switch id := sensor.GetAddr(); id {
|
||||||
|
case 97:
|
||||||
|
// DO
|
||||||
|
sm = &DOSensorManager{Sensor: sensor}
|
||||||
|
case 99:
|
||||||
|
// pH
|
||||||
|
sm = &PHSensorManager{Sensor: sensor}
|
||||||
|
case 102:
|
||||||
|
// RTD
|
||||||
|
sm = &RTDSensorManager{Sensor: sensor}
|
||||||
|
default:
|
||||||
|
err = errors.New(fmt.Sprintf("Error: sensor id %v unrecognized!", id))
|
||||||
}
|
}
|
||||||
return &DM{DeviceManagers: m}
|
return sm, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DM) GetManager(addr uint) (NewManager, error) {
|
func NewDeviceManager(device *pb.Device) (DeviceManager, error) {
|
||||||
d.Lock()
|
// returns correct device manager by ID
|
||||||
defer d.Unlock()
|
var dm DeviceManager
|
||||||
if m, ok := d.DeviceManagers[addr]; ok {
|
var err error
|
||||||
return m, nil
|
|
||||||
|
switch id := device.GetAddr(); id {
|
||||||
|
case 256:
|
||||||
|
// PWM
|
||||||
|
dm = &PWMDeviceManager{Device: device}
|
||||||
|
default:
|
||||||
|
err = errors.New(fmt.Sprintf("Error: device id %v unrecognized!", id))
|
||||||
}
|
}
|
||||||
return &DM{}, fmt.Errorf("No manager found for address %d!", addr)
|
return dm, err
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package sensor
|
||||||
|
|
||||||
|
// do sensor and methods
|
||||||
|
|
||||||
|
import (
|
||||||
|
pb "FRMS/internal/pkg/grpc"
|
||||||
|
"errors"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PHSensorManager struct {
|
||||||
|
// do sensor manager
|
||||||
|
Sensor *pb.Sensor // for sending/updating
|
||||||
|
sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PHSensorManager) SetName(name string) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PHSensorManager) SetStatus(status int) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PHSensorManager) SetSampleRate(rate int) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PHSensorManager) Update(sensor *pb.Sensor, config *viper.Viper) error {
|
||||||
|
// updates info
|
||||||
|
s.Lock()
|
||||||
|
defer s.Unlock()
|
||||||
|
s.Sensor = sensor
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PHSensorManager) String() string {
|
||||||
|
// #TODO
|
||||||
|
return "TODO"
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package sensor
|
||||||
|
|
||||||
|
// do sensor and methods
|
||||||
|
|
||||||
|
import (
|
||||||
|
pb "FRMS/internal/pkg/grpc"
|
||||||
|
"errors"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PWMDeviceManager struct {
|
||||||
|
// do sensor manager
|
||||||
|
Device *pb.Device // for sending/updating
|
||||||
|
sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PWMDeviceManager) SetName(name string) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PWMDeviceManager) SetStatus(status int) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PWMDeviceManager) SetParameter(key, val string) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PWMDeviceManager) Update(device *pb.Device, config *viper.Viper) error {
|
||||||
|
// updates info
|
||||||
|
s.Lock()
|
||||||
|
defer s.Unlock()
|
||||||
|
s.Device = device
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PWMDeviceManager) String() string {
|
||||||
|
// #TODO
|
||||||
|
return "TODO"
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package sensor
|
||||||
|
|
||||||
|
// do sensor and methods
|
||||||
|
|
||||||
|
import (
|
||||||
|
pb "FRMS/internal/pkg/grpc"
|
||||||
|
"errors"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RTDSensorManager struct {
|
||||||
|
// do sensor manager
|
||||||
|
Sensor *pb.Sensor // for sending/updating
|
||||||
|
sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RTDSensorManager) SetName(name string) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RTDSensorManager) SetStatus(status int) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RTDSensorManager) SetSampleRate(rate int) error {
|
||||||
|
// #TODO
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RTDSensorManager) Update(sensor *pb.Sensor, config *viper.Viper) error {
|
||||||
|
// updates info
|
||||||
|
s.Lock()
|
||||||
|
defer s.Unlock()
|
||||||
|
s.Sensor = sensor
|
||||||
|
return errors.New("UNIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RTDSensorManager) String() string {
|
||||||
|
// #TODO
|
||||||
|
return "TODO"
|
||||||
|
}
|
@ -1,6 +0,0 @@
|
|||||||
package sensor
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "fmt"
|
|
||||||
)
|
|
||||||
|
|
Loading…
Reference in New Issue