flucky/pkg/config/config.go

192 lines
4.4 KiB
Go

package config
import (
"fmt"
"os"
"path/filepath"
"regexp"
"time"
"git.cryptic.systems/volker.raschek/flucky/pkg/internal/format"
"git.cryptic.systems/volker.raschek/flucky/pkg/types"
uuid "github.com/satori/go.uuid"
)
var (
validUUID = regexp.MustCompile("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")
)
// Config represent the configuration
type Config struct {
Device *types.Device `json:"device"`
Sensors []*types.Sensor `json:"sensors"`
DSN string `json:"dsn"`
DSNFallback string `json:"dsn_fallback"`
}
// AddSensor add a new sensor
func (cnf *Config) AddSensor(sensor *types.Sensor) error {
// Verify that a device is configured
if cnf.Device == nil {
return fmt.Errorf("No device configured")
}
// Define a new UUID if the current UUID is invalid
if !validUUID.MatchString(sensor.ID) {
sensor.ID = uuid.NewV4().String()
}
// Verify that the sensor has a valid name
if len(sensor.Name) <= 0 {
return fmt.Errorf("No sensor name defined")
}
// check if sensor name and sensor uuid already exists
for _, cnfSensor := range cnf.Sensors {
if cnfSensor.Name == sensor.Name ||
cnfSensor.ID == sensor.ID {
return fmt.Errorf("Sensor with same name or id already exist")
}
if cnfSensor.WireID != nil &&
sensor.WireID != nil &&
*cnfSensor.WireID == *sensor.WireID {
return fmt.Errorf("Sensor with same wire id already exist")
}
}
// check if sensor has a valid tick time
if _, err := time.ParseDuration(sensor.TickDuration); err != nil {
return fmt.Errorf("Failed to parse tick duration: %v", err)
}
// check if sensor has a valid device id
if sensor.DeviceID != cnf.Device.ID {
sensor.DeviceID = cnf.Device.ID
}
// overwrite creation date
sensor.CreationDate = format.FormatedTime()
// check if wire socket is available
if sensor.WireID != nil {
socketPath := filepath.Join("/sys/bus/w1/devices", *sensor.WireID, "/w1_slave")
if _, err := os.Stat(socketPath); os.IsNotExist(err) {
return fmt.Errorf("Wire socket not found: %v", socketPath)
}
}
cnf.Sensors = append(cnf.Sensors, sensor)
return nil
}
// DisableSensor disables a sensor by its name or its unique UUID
func (cnf *Config) DisableSensor(name string) error {
found := false
for _, sensor := range cnf.Sensors {
// disable sensor matched after name
if !validUUID.MatchString(name) &&
sensor.Name == name {
sensor.Enabled = false
found = true
break
}
// remove machted uuid
if validUUID.MatchString(name) &&
sensor.ID == name {
sensor.Enabled = false
found = true
break
}
}
if !found {
return fmt.Errorf("Can not found sensor %v", name)
}
return nil
}
// EnableSensor enables a sensor by its name or its unique UUID
func (cnf *Config) EnableSensor(name string) error {
found := false
for _, sensor := range cnf.Sensors {
// disable sensor matched after name
if !validUUID.MatchString(name) &&
sensor.Name == name {
sensor.Enabled = true
found = true
break
}
// remove machted uuid
if validUUID.MatchString(name) &&
sensor.ID == name {
sensor.Enabled = true
found = true
break
}
}
if !found {
return fmt.Errorf("Can not found sensor %v", name)
}
return nil
}
// GetSensorByID returns a sensor matched by his id. If no sensor has this id,
// the function returns nil
func (cnf *Config) GetSensorByID(id string) *types.Sensor {
for _, sensor := range cnf.Sensors {
if sensor.ID == id {
return sensor
}
}
return nil
}
// RemoveSensor deletes a sensor by its name or its unique UUID, If definitive
// is set to true, the sensor will not only be removed in the configuration file
// but also in the backend.
func (cnf *Config) RemoveSensor(name string) error {
for i, sensor := range cnf.Sensors {
// remove machted name
if !validUUID.MatchString(name) &&
sensor.Name == name {
cnf.Sensors = append(cnf.Sensors[:i], cnf.Sensors[i+1:]...)
return nil
}
// remove machted uuid
if validUUID.MatchString(name) &&
sensor.ID == name {
cnf.Sensors = append(cnf.Sensors[:i], cnf.Sensors[i+1:]...)
return nil
}
}
return fmt.Errorf("Can not find sensor %v", name)
}
// RenameSensor renamed a sensor
func (cnf *Config) RenameSensor(oldName string, newName string) error {
for _, cnfSensor := range cnf.Sensors {
if cnfSensor.Name == oldName {
cnfSensor.Name = newName
return nil
}
}
return fmt.Errorf("No sensor %v found", oldName)
}