adding reactor config parser for devices

main
Keegan 2 years ago
parent 1c2868daf8
commit b1520db055

@ -26,7 +26,9 @@ func NewCoordinator(ch chan error) coordinator {
}
func LoadConfig(fname string) Config {
config.Load(fname)
if err := config.Load(fname); err != nil {
panic(err)
}
return config.LoadConfig()
}

@ -0,0 +1,5 @@
reactor:
sensors:
address: 112 # decimal
name: "DO Sensor"

@ -0,0 +1,26 @@
package config
// pacakge serves to store/load config files for reactor
import (
"sync"
)
type ReactorConf struct {
Reactor ReactorConfig `mapstructure:"reactor"`
Devices map[int]DeviceConfig `mapstructure:"devices"`
sync.RWMutex
}
type DeviceConfig struct {
Address uint32 `mapstructure:"address"`
Interval uint32 `mapstructure:"interval"`
Name string `mapstructure:"name"`
}
// loaded in other file
func (c *ReactorConf) GetURL() (string, error) {
c.RLock()
defer c.RUnlock()
return c.Reactor.URL, nil
}

@ -17,7 +17,7 @@ import (
//"bytes"
)
type Config struct {
type ServerConf struct {
Server ServerConfig `mapstructure:"server"`
Reactors map[string]ReactorConfig `mapstructure:"reactors"`
sync.RWMutex
@ -34,21 +34,36 @@ type ServerConfig struct {
type ReactorConfig struct {
Token string `mapstructure:"db-token"`
Bucket string `mapstructure:"db-bucket"`
Name string
Id uint32
URL string `mapstructure:"db-url",omitempty` // only needed by reactor
Name string `mapstructure:"name",omitempty` // not always set
Id uint32 `mapstructure:"id"`
}
var C *Config
type Config interface {
Store() error
}
var C Config
func Load(fname string) {
func Load(fname string) error {
// read stored configs
C = &Config{}
//C = &ServerConf{}
switch fname {
case "server":
C = &ServerConf{}
case "reactor":
C = &ReactorConf{}
default:
return fmt.Errorf("%s not recognized", fname)
}
logging.Debug(logging.DStart, "Loading config for %s", fname)
viper.SetConfigName(fname)
viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/frms/config") //
// defaults
viper.SetDefault("server.db-org", "ForeLight")
viper.SetDefault("server.db-url", "http://192.168.100.2:8086")
viper.AddConfigPath("/etc/frms/config")
// defaults which we don't want to set nessecarily
//viper.SetDefault("server.db-org", "ForeLight")
//viper.SetDefault("server.db-url", "http://192.168.100.2:8086")
//viper.SetDefault("reactor.db-url", "http://192.168.100.2:8086")
// unmarshalling
err := viper.ReadInConfig() // the fact i never did this is infuriating
if err != nil {
@ -65,23 +80,23 @@ func Load(fname string) {
// unmarshalled at this point
}
func LoadConfig() *Config {
func LoadConfig() Config {
return C
}
func (c *Config) GetURL() (string, error) {
func (c *ServerConf) GetURL() (string, error) {
c.RLock()
defer c.RUnlock()
return C.Server.URL, nil
}
func (c *Config) GetOrg() (string, error) {
func (c *ServerConf) GetOrg() (string, error) {
c.RLock()
defer c.RUnlock()
return c.Server.Orginization, nil
}
func (c *Config) GetPort(port string) (int, error) {
func (c *ServerConf) GetPort(port string) (int, error) {
c.RLock()
defer c.RUnlock()
portString, ok := c.Server.Ports[port]
@ -94,46 +109,46 @@ func (c *Config) GetPort(port string) (int, error) {
return portString, nil
}
func (c *Config) GetServerToken() (string, error) {
func (c *ServerConf) GetServerToken() (string, error) {
c.RLock()
defer c.RUnlock()
return c.Server.Token, nil
}
func (c *Config) GetReactorClient(id uint32) (string, string, error) {
func (c *ServerConf) GetReactorClient(id uint32) (string, string, error) {
c.RLock()
defer c.RUnlock()
idString := strconv.FormatUint(uint64(id), 10)
if r, ok := c.Reactors[idString]; ok {
return r.Bucket, r.Token, nil
}
return "", "", fmt.Errorf("Reactor %v config doesnt exist!", id)
return "", "", fmt.Errorf("reactor %v config doesnt exist", id)
}
// setters
func (c *Config) UpdateURL(url string) error {
func (c *ServerConf) UpdateURL(url string) error {
c.Lock()
defer c.Unlock()
if url == "" {
return errors.New("String cannot be empty!")
return errors.New("string cannot be empty")
}
c.Server.URL = url
viper.Set("server.db-url", url)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *Config) UpdateOrg(org string) error {
func (c *ServerConf) UpdateOrg(org string) error {
c.Lock()
defer c.Unlock()
if org == "" {
return errors.New("String cannot be empty!")
return errors.New("string cannot be empty")
}
c.Server.Orginization = org
viper.Set("server.db-org", org)
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *Config) UpdatePort(pName string, port int) error {
func (c *ServerConf) UpdatePort(pName string, port int) error {
c.Lock()
defer c.Unlock()
if port < 1024 || port > 65535 {
@ -149,7 +164,7 @@ func (c *Config) UpdatePort(pName string, port int) error {
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *Config) UpdateServerToken(token string) error {
func (c *ServerConf) UpdateServerToken(token string) error {
c.Lock()
defer c.Unlock()
if token == "" {
@ -160,7 +175,7 @@ func (c *Config) UpdateServerToken(token string) error {
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *Config) UpdateReactorClient(id uint32, bucket, token string) error {
func (c *ServerConf) UpdateReactorClient(id uint32, bucket, token string) error {
c.Lock()
c.Unlock()
sid := strconv.FormatUint(uint64(id), 10)
@ -181,6 +196,6 @@ func (c *Config) UpdateReactorClient(id uint32, bucket, token string) error {
return viper.WriteConfigAs(viper.ConfigFileUsed())
}
func (c *Config) Store() error {
func (c *ServerConf) Store() error {
return viper.WriteConfigAs(viper.ConfigFileUsed())
}

@ -1,12 +1,12 @@
package sensor
import (
_"fmt"
"time"
"sync"
"strings"
_ "FRMS/internal/pkg/I2C"
_ "fmt"
"log"
"strings"
"sync"
"time"
)
type Manager struct {

@ -0,0 +1,36 @@
package sensor
import (
"fmt"
"sync"
)
/*
this file serves as a map that the sensor library can use to determine which manager to call
*/
type NewManager interface {
// serves as interface to restrict managers can be relocated
}
type DM struct {
DeviceManagers map[uint]NewManager
sync.Mutex
}
func NewManagerDirectory() *DM {
m := map[uint]NewManager{
// map to set functions up
112: NewDOManager(),
}
return &DM{DeviceManagers: m}
}
func (d *DM) GetManager(addr uint) (NewManager, error) {
d.Lock()
defer d.Unlock()
if m, ok := d.DeviceManagers[addr]; ok {
return m, nil
}
return &DM{}, fmt.Errorf("No manager found for address %d!", addr)
}

30
notes

@ -922,3 +922,33 @@ should also probably wrap these in a seperate struct
does it make more sensor to load different configs for each entity or justhave one monolithic config (probably load for each one and then let it update itself)
going to have the init script set up the
Welcome back
#TODO 8/31
Goals:
- Add a config parser to load/store device manager struct
- start figuring out what a generic config package looks like
- figure out how to load different sensor functions dynamically
Basic reactor workflow overview
1) On boot, scan I2C bus to find active devices
2) For every device shown as active, spawn a sensor manager from the assocaited config
3) on disconnect, shut the dm down and save current settings to config

Loading…
Cancel
Save