fix: add, rename and remove sensor
changes: - Implement function to add, rename and remove sensors
This commit is contained in:
48
cli/daemon/daemon.go
Normal file
48
cli/daemon/daemon.go
Normal file
@ -0,0 +1,48 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/volker-raschek/flucky/pkg/config"
|
||||
"github.com/volker-raschek/flucky/pkg/daemon"
|
||||
"github.com/volker-raschek/go-logger/pkg/logger"
|
||||
)
|
||||
|
||||
// InitCmd initialize all daemon subcommands
|
||||
func InitCmd(cmd *cobra.Command) error {
|
||||
daemonCmd := &cobra.Command{
|
||||
Use: "daemon",
|
||||
Short: "Read continuously data from all enabled sensors",
|
||||
Example: "flucky daemon",
|
||||
RunE: run,
|
||||
}
|
||||
|
||||
daemonCmd.Flags().Bool("compression", true, "Compress measured values")
|
||||
daemonCmd.Flags().Uint("cached-values", 500, "Number of cached values before saveing into the storage endpoint")
|
||||
daemonCmd.Flags().Float64("round", 0.5, "Round values. The value 0 deactivates the function")
|
||||
cmd.AddCommand(daemonCmd)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func run(cmd *cobra.Command, args []string) error {
|
||||
configFile, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return fmt.Errorf("No config file defined: %v", err)
|
||||
}
|
||||
|
||||
// logLevel, err := cmd.Flags().GetString("loglevel")
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("No loglevel defined: %v", err)
|
||||
// }
|
||||
|
||||
flogger := logger.NewDefaultLogger(logger.LogLevelDebug)
|
||||
|
||||
cnf, err := config.Read(configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return daemon.Start(cnf, flogger)
|
||||
}
|
112
cli/root.go
Normal file
112
cli/root.go
Normal file
@ -0,0 +1,112 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/volker-raschek/flucky/cli/daemon"
|
||||
"github.com/volker-raschek/flucky/cli/sensor"
|
||||
"github.com/volker-raschek/flucky/pkg/config"
|
||||
"github.com/volker-raschek/flucky/pkg/types"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// Execute a
|
||||
func Execute(version *semver.Version) error {
|
||||
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "flucky",
|
||||
// Short: "flucky - operate with differen sensors, his values and remote servers to synchronize measured values",
|
||||
PersistentPreRunE: preRunError,
|
||||
Version: version.String(),
|
||||
}
|
||||
|
||||
defaultConfigFile, err := getDefaultConfigFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rootCmd.PersistentFlags().String("config", defaultConfigFile, "Config file")
|
||||
rootCmd.PersistentFlags().String("loglevel", "info", "Set the Loglevel. Possible values: debug, info, warn, error, fatal")
|
||||
|
||||
subCommands := []func(cmd *cobra.Command) error{
|
||||
daemon.InitCmd,
|
||||
sensor.InitCmd,
|
||||
}
|
||||
|
||||
for _, subCommand := range subCommands {
|
||||
if err := subCommand(rootCmd); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = rootCmd.Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func preRunError(cmd *cobra.Command, args []string) error {
|
||||
|
||||
configFile := cmd.Flag("config").Value.String()
|
||||
|
||||
// check if config file exists
|
||||
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
||||
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to determine the hostname: %v", err)
|
||||
}
|
||||
|
||||
// Time must be truncted for postgres. Postgres currently does not support
|
||||
// nanoseconds which is automatically include into the go time object
|
||||
postgresTimeStamp := time.Now()
|
||||
location, err := time.LoadLocation("Europe/Berlin")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
postgresTimeStamp = time.Date(postgresTimeStamp.Year(), postgresTimeStamp.Month(), postgresTimeStamp.Day(), postgresTimeStamp.Hour(), postgresTimeStamp.Minute(), postgresTimeStamp.Second(), int(math.Round(float64(postgresTimeStamp.Nanosecond())/1000000)*1000000), location)
|
||||
|
||||
// Default configuration
|
||||
cnf := config.Config{
|
||||
Device: &types.Device{
|
||||
ID: uuid.NewV4().String(),
|
||||
Name: hostname,
|
||||
CreationDate: postgresTimeStamp,
|
||||
},
|
||||
StorageEndpoint: "file:/var/log/flucky/sqlite.db?cache=shared&mode=memory",
|
||||
}
|
||||
|
||||
err = config.Write(&cnf, configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDefaultConfigPath returns the default path to the configuration of
|
||||
// rpm-distributor
|
||||
func getDefaultConfigFile() (string, error) {
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Can not read current user: %v", err)
|
||||
}
|
||||
|
||||
switch u.Uid {
|
||||
case "0":
|
||||
return "/etc/flucky/config.json", nil
|
||||
default:
|
||||
return filepath.Join(u.HomeDir, ".config/flucky/config.json"), nil
|
||||
}
|
||||
}
|
307
cli/sensor/sensor.go
Normal file
307
cli/sensor/sensor.go
Normal file
@ -0,0 +1,307 @@
|
||||
package sensor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/volker-raschek/flucky/pkg/cli"
|
||||
"github.com/volker-raschek/flucky/pkg/config"
|
||||
"github.com/volker-raschek/flucky/pkg/types"
|
||||
)
|
||||
|
||||
// InitCmd initialize all sensor subcommands
|
||||
func InitCmd(cmd *cobra.Command) error {
|
||||
sensorCmd := &cobra.Command{
|
||||
Use: "sensor",
|
||||
Short: "Manage Sensors",
|
||||
}
|
||||
|
||||
addSensorCmd := &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "Add Sensor",
|
||||
Aliases: []string{"append"},
|
||||
Args: cobra.ExactArgs(2),
|
||||
Example: `flucky sensor add --gpio GPIO14 indoor DHT11
|
||||
flucky sensor add --wire-id 28-011432f0bb3d outdoor DS18B20
|
||||
flucky sensor add --i2c-bus 1 --i2c-address 0x76 wetter-station BME280`,
|
||||
RunE: addSensor,
|
||||
}
|
||||
addSensorCmd.Flags().Bool("enabled", true, "Enable new sensor")
|
||||
addSensorCmd.Flags().String("gpio", "", "Defines the GPIO port")
|
||||
addSensorCmd.Flags().Uint8("i2c-address", 0, "Defines the I2C address on the I2C bus")
|
||||
addSensorCmd.Flags().Int("i2c-bus", 0, "Defines the I2C bus")
|
||||
addSensorCmd.Flags().String("location", "", "Location of the sensor")
|
||||
addSensorCmd.Flags().String("tick-duration", "1m", "Specifies how often measured values should be read from the sensor")
|
||||
addSensorCmd.Flags().String("wire-id", "", "Defines the Wire-ID")
|
||||
|
||||
disableSensorCmd := &cobra.Command{
|
||||
Use: "disable",
|
||||
Short: "Disable Sensor",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Example: "flucky sensor disable outdoor",
|
||||
RunE: disableSensor,
|
||||
}
|
||||
|
||||
enableSensorCmd := &cobra.Command{
|
||||
Use: "enable",
|
||||
Short: "Enable Sensor",
|
||||
Example: "flucky sensor enable outdoor",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: enableSensor,
|
||||
}
|
||||
|
||||
listSensorCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List Sensors",
|
||||
Aliases: []string{"ls"},
|
||||
RunE: listSensors,
|
||||
}
|
||||
|
||||
removeSensorCmd := &cobra.Command{
|
||||
Use: "remove",
|
||||
Short: "Remove Sensor",
|
||||
Aliases: []string{"rm"},
|
||||
Example: "flucky sensor remove outdoor",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: removeSensor,
|
||||
}
|
||||
removeSensorCmd.Flags().Bool("definitive", true, "Remove the sensor definitive from the backend")
|
||||
|
||||
renameSensorCmd := &cobra.Command{
|
||||
Use: "rename",
|
||||
Short: "Rename Sensor",
|
||||
Args: cobra.ExactArgs(2),
|
||||
Example: `flucky sensor rename indoor outdoor
|
||||
flucky sensor rename f98b00ea-a9b2-4e00-924f-113859d0af2d outdoor`,
|
||||
RunE: renameSensor,
|
||||
}
|
||||
|
||||
for _, subCommand := range []*cobra.Command{
|
||||
addSensorCmd,
|
||||
disableSensorCmd,
|
||||
enableSensorCmd,
|
||||
listSensorCmd,
|
||||
removeSensorCmd,
|
||||
renameSensorCmd,
|
||||
} {
|
||||
sensorCmd.AddCommand(subCommand)
|
||||
}
|
||||
|
||||
cmd.AddCommand(sensorCmd)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func addSensor(cmd *cobra.Command, args []string) error {
|
||||
|
||||
sensor := &types.Sensor{
|
||||
ID: uuid.NewV4().String(),
|
||||
Name: args[0],
|
||||
Model: args[1],
|
||||
}
|
||||
|
||||
sensorLocation, err := cmd.Flags().GetString("location")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sensor.Location = sensorLocation
|
||||
|
||||
sensorEnabled, err := cmd.Flags().GetBool("enabled")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sensor.Enabled = sensorEnabled
|
||||
|
||||
sensorGPIO, err := cmd.Flags().GetString("gpio")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(sensorGPIO) > 0 {
|
||||
sensor.GPIONumber = sensorGPIO
|
||||
}
|
||||
|
||||
sensorI2CAddress, err := cmd.Flags().GetUint8("i2c-address")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sensorI2CAddress > 0 {
|
||||
sensor.I2CAddress = &sensorI2CAddress
|
||||
}
|
||||
|
||||
sensorI2CBus, err := cmd.Flags().GetInt("i2c-bus")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sensorI2CBus > 0 {
|
||||
sensor.I2CBus = &sensorI2CBus
|
||||
}
|
||||
|
||||
sensorTickDuration, err := cmd.Flags().GetString("tick-duration")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sensor.TickDuration = sensorTickDuration
|
||||
|
||||
sensorWireID, err := cmd.Flags().GetString("wire-id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(sensorWireID) > 0 {
|
||||
sensor.WireID = &sensorWireID
|
||||
}
|
||||
|
||||
configFile, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return fmt.Errorf("No config file defined")
|
||||
}
|
||||
|
||||
cnf, err := config.Read(configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add sensor entry to list
|
||||
err = cnf.AddSensor(sensor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// save new configuration
|
||||
err = config.Write(cnf, configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func disableSensor(cmd *cobra.Command, args []string) error {
|
||||
|
||||
configFile, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return fmt.Errorf("No config file defined")
|
||||
}
|
||||
|
||||
cnf, err := config.Read(configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cnf.DisableSensor(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = config.Write(cnf, configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func enableSensor(cmd *cobra.Command, args []string) error {
|
||||
|
||||
configFile, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return fmt.Errorf("No config file defined")
|
||||
}
|
||||
|
||||
cnf, err := config.Read(configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cnf.EnableSensor(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = config.Write(cnf, configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func listSensors(cmd *cobra.Command, args []string) error {
|
||||
|
||||
configFile, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return fmt.Errorf("No config file defined")
|
||||
}
|
||||
|
||||
cnf, err := config.Read(configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cli.PrintSensors(cnf, os.Stdout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = config.Write(cnf, configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeSensor(cmd *cobra.Command, args []string) error {
|
||||
|
||||
configFile, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return fmt.Errorf("No config file defined")
|
||||
}
|
||||
|
||||
definitive, err := cmd.Flags().GetBool("definitive")
|
||||
if err != nil {
|
||||
return fmt.Errorf("No config file defined")
|
||||
}
|
||||
|
||||
cnf, err := config.Read(configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cnf.RemoveSensor(args[0], definitive)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = config.Write(cnf, configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func renameSensor(cmd *cobra.Command, args []string) error {
|
||||
|
||||
configFile, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return fmt.Errorf("No config file defined")
|
||||
}
|
||||
|
||||
cnf, err := config.Read(configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cnf.RenameSensor(args[0], args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = config.Write(cnf, configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user