2018-11-19 21:36:21 +00:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2020-05-03 12:04:08 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"regexp"
|
2019-12-07 15:53:49 +00:00
|
|
|
|
|
|
|
"time"
|
|
|
|
|
2020-06-10 19:13:05 +00:00
|
|
|
"git.cryptic.systems/volker.raschek/flucky/pkg/internal/format"
|
2019-12-07 15:53:49 +00:00
|
|
|
|
2020-06-10 19:13:05 +00:00
|
|
|
"git.cryptic.systems/volker.raschek/flucky/pkg/types"
|
2019-12-07 15:53:49 +00:00
|
|
|
uuid "github.com/satori/go.uuid"
|
2020-05-03 12:04:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
validUUID = regexp.MustCompile("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")
|
2018-11-19 21:36:21 +00:00
|
|
|
)
|
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
// Config represent the configuration
|
|
|
|
type Config struct {
|
2020-06-01 10:41:48 +00:00
|
|
|
Device *types.Device `json:"device"`
|
|
|
|
Sensors []*types.Sensor `json:"sensors"`
|
|
|
|
DSN string `json:"dsn"`
|
|
|
|
DSNFallback string `json:"dsn_fallback"`
|
2019-12-07 15:53:49 +00:00
|
|
|
}
|
2019-02-17 17:23:59 +00:00
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
// AddSensor add a new sensor
|
|
|
|
func (cnf *Config) AddSensor(sensor *types.Sensor) error {
|
2018-11-19 21:36:21 +00:00
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
// Verify that a device is configured
|
|
|
|
if cnf.Device == nil {
|
|
|
|
return fmt.Errorf("No device configured")
|
2018-11-28 11:54:14 +00:00
|
|
|
}
|
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
// Define a new UUID if the current UUID is invalid
|
2020-01-10 21:03:49 +00:00
|
|
|
if !validUUID.MatchString(sensor.ID) {
|
|
|
|
sensor.ID = uuid.NewV4().String()
|
2019-12-07 15:53:49 +00:00
|
|
|
}
|
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
// Verify that the sensor has a valid name
|
|
|
|
if len(sensor.Name) <= 0 {
|
|
|
|
return fmt.Errorf("No sensor name defined")
|
|
|
|
}
|
2019-12-07 15:53:49 +00:00
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
// 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")
|
2019-12-07 15:53:49 +00:00
|
|
|
}
|
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
if cnfSensor.WireID != nil &&
|
|
|
|
sensor.WireID != nil &&
|
|
|
|
*cnfSensor.WireID == *sensor.WireID {
|
|
|
|
return fmt.Errorf("Sensor with same wire id already exist")
|
2019-03-01 13:56:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-11 12:18:38 +00:00
|
|
|
// check if sensor has a valid tick time
|
|
|
|
if _, err := time.ParseDuration(sensor.TickDuration); err != nil {
|
2020-05-03 12:04:08 +00:00
|
|
|
return fmt.Errorf("Failed to parse tick duration: %v", err)
|
2020-01-11 12:18:38 +00:00
|
|
|
}
|
|
|
|
|
2019-12-07 15:53:49 +00:00
|
|
|
// check if sensor has a valid device id
|
2020-05-03 12:04:08 +00:00
|
|
|
if sensor.DeviceID != cnf.Device.ID {
|
|
|
|
sensor.DeviceID = cnf.Device.ID
|
2019-12-07 15:53:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// overwrite creation date
|
|
|
|
sensor.CreationDate = format.FormatedTime()
|
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
// 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)
|
2019-12-07 15:53:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
cnf.Sensors = append(cnf.Sensors, sensor)
|
2019-12-07 15:53:49 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// DisableSensor disables a sensor by its name or its unique UUID
|
2020-05-03 12:04:08 +00:00
|
|
|
func (cnf *Config) DisableSensor(name string) error {
|
2019-12-07 15:53:49 +00:00
|
|
|
found := false
|
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
for _, sensor := range cnf.Sensors {
|
2019-12-07 15:53:49 +00:00
|
|
|
|
|
|
|
// disable sensor matched after name
|
|
|
|
if !validUUID.MatchString(name) &&
|
2020-01-10 21:03:49 +00:00
|
|
|
sensor.Name == name {
|
|
|
|
sensor.Enabled = false
|
2019-12-07 15:53:49 +00:00
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove machted uuid
|
|
|
|
if validUUID.MatchString(name) &&
|
2020-01-10 21:03:49 +00:00
|
|
|
sensor.ID == name {
|
|
|
|
sensor.Enabled = false
|
2019-12-07 15:53:49 +00:00
|
|
|
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
|
2020-05-03 12:04:08 +00:00
|
|
|
func (cnf *Config) EnableSensor(name string) error {
|
2019-12-07 15:53:49 +00:00
|
|
|
found := false
|
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
for _, sensor := range cnf.Sensors {
|
2019-12-07 15:53:49 +00:00
|
|
|
|
|
|
|
// disable sensor matched after name
|
|
|
|
if !validUUID.MatchString(name) &&
|
2020-01-10 21:03:49 +00:00
|
|
|
sensor.Name == name {
|
|
|
|
sensor.Enabled = true
|
2019-12-07 15:53:49 +00:00
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove machted uuid
|
|
|
|
if validUUID.MatchString(name) &&
|
2020-01-10 21:03:49 +00:00
|
|
|
sensor.ID == name {
|
|
|
|
sensor.Enabled = true
|
2019-12-07 15:53:49 +00:00
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !found {
|
|
|
|
return fmt.Errorf("Can not found sensor %v", name)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-01-11 11:10:26 +00:00
|
|
|
// GetSensorByID returns a sensor matched by his id. If no sensor has this id,
|
|
|
|
// the function returns nil
|
2020-05-03 12:04:08 +00:00
|
|
|
func (cnf *Config) GetSensorByID(id string) *types.Sensor {
|
|
|
|
for _, sensor := range cnf.Sensors {
|
2020-01-11 11:10:26 +00:00
|
|
|
if sensor.ID == id {
|
|
|
|
return sensor
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-05-17 11:00:51 +00:00
|
|
|
// 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.
|
2020-05-21 15:40:24 +00:00
|
|
|
func (cnf *Config) RemoveSensor(name string) error {
|
2020-05-17 11:00:51 +00:00
|
|
|
|
2020-05-03 12:04:08 +00:00
|
|
|
for i, sensor := range cnf.Sensors {
|
2019-12-07 15:53:49 +00:00
|
|
|
// remove machted name
|
|
|
|
if !validUUID.MatchString(name) &&
|
2020-01-10 21:03:49 +00:00
|
|
|
sensor.Name == name {
|
2020-05-03 12:04:08 +00:00
|
|
|
cnf.Sensors = append(cnf.Sensors[:i], cnf.Sensors[i+1:]...)
|
2020-05-17 11:00:51 +00:00
|
|
|
|
2019-12-07 15:53:49 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
// remove machted uuid
|
|
|
|
if validUUID.MatchString(name) &&
|
2020-01-10 21:03:49 +00:00
|
|
|
sensor.ID == name {
|
2020-05-03 12:04:08 +00:00
|
|
|
cnf.Sensors = append(cnf.Sensors[:i], cnf.Sensors[i+1:]...)
|
2020-05-17 11:00:51 +00:00
|
|
|
|
2019-12-07 15:53:49 +00:00
|
|
|
return nil
|
|
|
|
}
|
2018-11-28 11:54:14 +00:00
|
|
|
}
|
2019-12-07 15:53:49 +00:00
|
|
|
return fmt.Errorf("Can not find sensor %v", name)
|
|
|
|
}
|
2020-05-17 11:00:51 +00:00
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|