From 6d9368e86c10e2b42375ec7cc08277357e5c479d Mon Sep 17 00:00:00 2001 From: Markus Pesch Date: Tue, 20 Nov 2018 22:55:06 +0100 Subject: [PATCH] fix: temperature, sensor changes: - sensor temperature add - sensor temperature list - sensor temperature rm - temperature get - temperature log - temperature push --- Gopkg.lock | 13 +- cmd/cmd.go | 5 +- cmd/config/config.go | 2 +- cmd/remote/register.go | 5 +- cmd/remote/remote.go | 6 +- cmd/sensor/sensor.go | 23 ++ cmd/sensor/temperature/add.go | 24 +++ cmd/sensor/temperature/list.go | 28 +++ cmd/sensor/temperature/rm.go | 24 +++ cmd/sensor/temperature/temperature.go | 22 ++ cmd/temperature/get.go | 8 +- cmd/temperature/logs.go | 27 +++ cmd/temperature/push.go | 24 +++ cmd/temperature/temperature.go | 7 +- pkg/config/config.go | 5 +- pkg/remote/remote.go | 57 +++-- pkg/sensor/sensor.go | 14 ++ pkg/sensor/temperature.go | 99 +++++++++ pkg/temperature/temperature.go | 138 +++++++++++- pkg/types/types.go | 16 +- .../go-flucky-server/pkg/types/types.go | 24 ++- vendor/github.com/yryz/ds18b20/.gitignore | 24 +++ vendor/github.com/yryz/ds18b20/LICENSE | 201 ++++++++++++++++++ vendor/github.com/yryz/ds18b20/README.md | 53 +++++ vendor/github.com/yryz/ds18b20/ds18b20.go | 49 +++++ 25 files changed, 850 insertions(+), 48 deletions(-) create mode 100644 cmd/sensor/sensor.go create mode 100644 cmd/sensor/temperature/add.go create mode 100644 cmd/sensor/temperature/list.go create mode 100644 cmd/sensor/temperature/rm.go create mode 100644 cmd/sensor/temperature/temperature.go create mode 100644 cmd/temperature/logs.go create mode 100644 cmd/temperature/push.go create mode 100644 pkg/sensor/sensor.go create mode 100644 pkg/sensor/temperature.go create mode 100644 vendor/github.com/yryz/ds18b20/.gitignore create mode 100644 vendor/github.com/yryz/ds18b20/LICENSE create mode 100644 vendor/github.com/yryz/ds18b20/README.md create mode 100644 vendor/github.com/yryz/ds18b20/ds18b20.go diff --git a/Gopkg.lock b/Gopkg.lock index 60d4f0b..80ad465 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,11 +3,11 @@ [[projects]] branch = "master" - digest = "1:67bdb81292d46305e49b2c67585e9d4fbf6832aa86be02e27081fb3c171d6cdb" + digest = "1:fc0785e9dcf11c34eba33d5b308e5cdc47ef03a5fea6bb9e6bc55f9cbcaa70a6" name = "git.cryptic.systems/fh-trier/go-flucky-server" packages = ["pkg/types"] pruneopts = "UT" - revision = "71ed96f2661f290526cb151fd02a2c561452d6ae" + revision = "6ee773aeec13f439a8d963bf37d67999cbfcd85c" [[projects]] digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be" @@ -41,6 +41,14 @@ revision = "298182f68c66c05229eb03ac171abe6e309ee79a" version = "v1.0.3" +[[projects]] + branch = "master" + digest = "1:5e110e5484070e6bd848e87039c68d477cd592ea06cbd20020fd5df58f8c0b5f" + name = "github.com/yryz/ds18b20" + packages = ["."] + pruneopts = "UT" + revision = "3cf383a406247c49e48a80014f3e17ddee418742" + [solve-meta] analyzer-name = "dep" analyzer-version = 1 @@ -48,6 +56,7 @@ "git.cryptic.systems/fh-trier/go-flucky-server/pkg/types", "github.com/satori/go.uuid", "github.com/spf13/cobra", + "github.com/yryz/ds18b20", ] solver-name = "gps-cdcl" solver-version = 1 diff --git a/cmd/cmd.go b/cmd/cmd.go index 2636f26..452f462 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -3,6 +3,8 @@ package cmd import ( "git.cryptic.systems/fh-trier/go-flucky/cmd/config" "git.cryptic.systems/fh-trier/go-flucky/cmd/remote" + "git.cryptic.systems/fh-trier/go-flucky/cmd/sensor" + "git.cryptic.systems/fh-trier/go-flucky/cmd/temperature" "github.com/spf13/cobra" ) @@ -21,7 +23,8 @@ func Execute(version string) { config.InitCmd(rootCmd, configDir) remote.InitCmd(rootCmd, configDir) - //temperature.InitCmd(rootCmd) + sensor.InitCmd(rootCmd, configDir) + temperature.InitCmd(rootCmd, configDir) rootCmd.Execute() } diff --git a/cmd/config/config.go b/cmd/config/config.go index d85156e..1097858 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -8,7 +8,7 @@ var configDir string var configCmd = &cobra.Command{ Use: "config", - Short: "config", + Short: "Manage configuration", } func InitCmd(cmd *cobra.Command, c string) { diff --git a/cmd/remote/register.go b/cmd/remote/register.go index 78680cc..ddbb5be 100644 --- a/cmd/remote/register.go +++ b/cmd/remote/register.go @@ -7,12 +7,14 @@ import ( "github.com/spf13/cobra" ) +var force bool + var registerRemoteCmd = &cobra.Command{ Use: "register", Short: "register on remote servers", Run: func(cmd *cobra.Command, args []string) { - if err := remote.SendDevice(configDir); err != nil { + if err := remote.RegisterDevice(configDir, force); err != nil { log.Fatal(err) } }, @@ -20,4 +22,5 @@ var registerRemoteCmd = &cobra.Command{ func init() { remoteCmd.AddCommand(registerRemoteCmd) + registerRemoteCmd.Flags().BoolVarP(&force, "force", "f", false, "Force register on a remote server") } diff --git a/cmd/remote/remote.go b/cmd/remote/remote.go index a89aefc..fb9c219 100644 --- a/cmd/remote/remote.go +++ b/cmd/remote/remote.go @@ -8,11 +8,11 @@ var configDir string var remoteCmd = &cobra.Command{ Use: "remote", - Short: "remote", + Short: "Manage Remote", } -func InitCmd(cmd *cobra.Command, c string) { - configDir = c +func InitCmd(cmd *cobra.Command, cnf string) { + configDir = cnf cmd.AddCommand(remoteCmd) } diff --git a/cmd/sensor/sensor.go b/cmd/sensor/sensor.go new file mode 100644 index 0000000..9af81b8 --- /dev/null +++ b/cmd/sensor/sensor.go @@ -0,0 +1,23 @@ +package sensor + +import ( + "git.cryptic.systems/fh-trier/go-flucky/cmd/sensor/temperature" + "github.com/spf13/cobra" +) + +var configDir string + +var sensorCmd = &cobra.Command{ + Use: "sensor", + Short: "Manage Sensors", +} + +// Execute a +func InitCmd(cmd *cobra.Command, cnf string) { + configDir = cnf + + cmd.AddCommand(sensorCmd) + + temperature.InitCmd(sensorCmd, cnf) + +} diff --git a/cmd/sensor/temperature/add.go b/cmd/sensor/temperature/add.go new file mode 100644 index 0000000..3f10979 --- /dev/null +++ b/cmd/sensor/temperature/add.go @@ -0,0 +1,24 @@ +package temperature + +import ( + "log" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" + "github.com/spf13/cobra" +) + +var addTemperatureSensorCmd = &cobra.Command{ + Use: "add", + Short: "Add Temperature Sensor", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + + if err := sensor.AddTemperature(args[0], sensorName, configDir, wirePath); err != nil { + log.Fatal(err) + } + }, +} + +func init() { + temperatureSensorCmd.AddCommand(addTemperatureSensorCmd) +} diff --git a/cmd/sensor/temperature/list.go b/cmd/sensor/temperature/list.go new file mode 100644 index 0000000..7aa5449 --- /dev/null +++ b/cmd/sensor/temperature/list.go @@ -0,0 +1,28 @@ +package temperature + +import ( + "log" + "os" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" + "github.com/spf13/cobra" +) + +var quiet bool + +var listTemperatureSensorCmd = &cobra.Command{ + Use: "list", + Short: "List Temperature Sensors", + Run: func(cmd *cobra.Command, args []string) { + + if err := sensor.PrintTemperature(os.Stdout, configDir, quiet); err != nil { + log.Fatal(err) + } + }, +} + +func init() { + temperatureSensorCmd.AddCommand(listTemperatureSensorCmd) + + listTemperatureSensorCmd.Flags().BoolVarP(&quiet, "quiet", "q", false, "List only sensor id's") +} diff --git a/cmd/sensor/temperature/rm.go b/cmd/sensor/temperature/rm.go new file mode 100644 index 0000000..36d516a --- /dev/null +++ b/cmd/sensor/temperature/rm.go @@ -0,0 +1,24 @@ +package temperature + +import ( + "log" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" + "github.com/spf13/cobra" +) + +var rmTemperatureSensorCmd = &cobra.Command{ + Use: "rm", + Short: "Remove Temperature Sensor", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + + if err := sensor.RemoveTemperature(args[0], configDir); err != nil { + log.Fatal(err) + } + }, +} + +func init() { + temperatureSensorCmd.AddCommand(rmTemperatureSensorCmd) +} diff --git a/cmd/sensor/temperature/temperature.go b/cmd/sensor/temperature/temperature.go new file mode 100644 index 0000000..49e81d4 --- /dev/null +++ b/cmd/sensor/temperature/temperature.go @@ -0,0 +1,22 @@ +package temperature + +import ( + "github.com/spf13/cobra" +) + +var configDir, sensorName, wirePath string + +var temperatureSensorCmd = &cobra.Command{ + Use: "temperature", + Short: "Manage Temperature Sensors", +} + +// Execute a +func InitCmd(cmd *cobra.Command, cnf string) { + configDir = cnf + + cmd.AddCommand(temperatureSensorCmd) + temperatureSensorCmd.PersistentFlags().StringVarP(&sensorName, "name", "n", "", "Define an name for the sensor") + temperatureSensorCmd.PersistentFlags().StringVarP(&wirePath, "wire-path", "w", "/sys/bus/w1/devices", "Default path for wire devices") + +} diff --git a/cmd/temperature/get.go b/cmd/temperature/get.go index bbe7e1d..2399d2b 100644 --- a/cmd/temperature/get.go +++ b/cmd/temperature/get.go @@ -1,4 +1,4 @@ -package remote +package temperature import ( "log" @@ -8,13 +8,15 @@ import ( "github.com/spf13/cobra" ) +var push bool + var getTemperatureCmd = &cobra.Command{ Use: "get", Short: "get temperature from sensor", - // Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - if err := temperature.Get(os.Stdout); err != nil { + if err := temperature.Get(os.Stdout, args[0], configDir); err != nil { log.Fatal(err) } }, diff --git a/cmd/temperature/logs.go b/cmd/temperature/logs.go new file mode 100644 index 0000000..3a74d59 --- /dev/null +++ b/cmd/temperature/logs.go @@ -0,0 +1,27 @@ +package temperature + +import ( + "log" + "os" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/temperature" + "github.com/spf13/cobra" +) + +//var seconds int32 + +var logTemperatureCmd = &cobra.Command{ + Use: "logs", + Short: "logs print all temperatures from all sensors", + Run: func(cmd *cobra.Command, args []string) { + + if err := temperature.Logs(os.Stdout, configDir); err != nil { + log.Fatal(err) + } + }, +} + +func init() { + temperatureCmd.AddCommand(logTemperatureCmd) + //logTemperatureCmd.Flags().Int32VarP(&seconds, "seconds", "s", 1, "Interval to print new temperatures from sensors") +} diff --git a/cmd/temperature/push.go b/cmd/temperature/push.go new file mode 100644 index 0000000..5eb923e --- /dev/null +++ b/cmd/temperature/push.go @@ -0,0 +1,24 @@ +package temperature + +import ( + "log" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/temperature" + "github.com/spf13/cobra" +) + +var pushTemperatureCmd = &cobra.Command{ + Use: "push", + Short: "push temperature from sensor to remote servers", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + + if err := temperature.Push(args[0], configDir); err != nil { + log.Fatal(err) + } + }, +} + +func init() { + temperatureCmd.AddCommand(pushTemperatureCmd) +} diff --git a/cmd/temperature/temperature.go b/cmd/temperature/temperature.go index 4ddbb0d..f8b9fc1 100644 --- a/cmd/temperature/temperature.go +++ b/cmd/temperature/temperature.go @@ -1,16 +1,19 @@ -package remote +package temperature import ( "github.com/spf13/cobra" ) +var configDir string + var temperatureCmd = &cobra.Command{ Use: "temperature", Short: "Read temperature from sensor", } // Execute a -func Init(cmd *cobra.Command) { +func InitCmd(cmd *cobra.Command, cnf string) { + configDir = cnf cmd.AddCommand(temperatureCmd) diff --git a/pkg/config/config.go b/pkg/config/config.go index 8ac2755..2fde266 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -22,7 +22,6 @@ func Create(configDir string, force bool) error { } // If no config file exists, create a new one on the location - if !force { if _, err := os.Stat(configPath); !os.IsNotExist(err) { return fmt.Errorf("%v already exists. Use -f to overwrite", configPath) @@ -54,7 +53,7 @@ func Read(configDir string) (*types.Config, error) { var config types.Config - // If no config file exists, create a new one on the location + // If no config file exists, return an error if _, err := os.Stat(configPath); os.IsNotExist(err) { return nil, fmt.Errorf("Can not find config %v: %v", configPath, err) } @@ -78,7 +77,7 @@ func Write(config *types.Config, configDir string) error { configPath := filepath.Join(configDir, configFilename) - // If no config file exists, create a new one on the location + // If no config file exists, return an error if _, err := os.Stat(configPath); os.IsNotExist(err) { return fmt.Errorf("Can not find config %v: %v", configPath, err) } diff --git a/pkg/remote/remote.go b/pkg/remote/remote.go index 5470d9b..1b9b883 100644 --- a/pkg/remote/remote.go +++ b/pkg/remote/remote.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "io" + "io/ioutil" "net/http" "text/tabwriter" @@ -44,10 +45,10 @@ func List(w io.Writer, configDir string) error { tw := tabwriter.NewWriter(w, 0, 0, 5, ' ', 0) - fmt.Fprint(tw, "name\taddress\n") + fmt.Fprint(tw, "name\taddress\tregistered\n") for _, remote := range configuration.Remotes { - fmt.Fprintf(tw, "%v\t%v\n", remote.Name, remote.Address) + fmt.Fprintf(tw, "%v\t%v\t%v\n", remote.Name, remote.Address, remote.Registered) } tw.Flush() @@ -123,7 +124,11 @@ func SendTemperature(temperature *stypes.Temperature, configDir string) error { defer resp.Body.Close() if resp.StatusCode < 200 || resp.StatusCode > 299 { - return fmt.Errorf("Invalid HTTP-Statuscode - expected 200, got %d", resp.StatusCode) + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("Invalid HTTP-Statuscode - expected 200, got %d - can not read response body: %v", resp.StatusCode, err) + } + return fmt.Errorf("Invalid HTTP-Statuscode - expected 200, got %d: %v", resp.StatusCode, string(b)) } } @@ -131,8 +136,8 @@ func SendTemperature(temperature *stypes.Temperature, configDir string) error { } -// SendDevice .. -func SendDevice(configDir string) error { +// RegisterDevice .. +func RegisterDevice(configDir string, force bool) error { con, err := config.Read(configDir) if err != nil { return err @@ -145,23 +150,39 @@ func SendDevice(configDir string) error { device.EncodeToJSON(&buffer) for _, remote := range con.Remotes { - requestURL := fmt.Sprintf("%s%s", remote.Address, "/devices") - req, err := http.NewRequest("POST", requestURL, &buffer) - if err != nil { - return err - } + if !remote.Registered || force { + requestURL := fmt.Sprintf("%s%s", remote.Address, "/devices") + req, err := http.NewRequest("POST", requestURL, &buffer) + if err != nil { + return err + } - client := http.Client{} - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() + client := http.Client{} + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() - if resp.StatusCode < 200 || resp.StatusCode > 299 { - return fmt.Errorf("Invalid HTTP-Statuscode - expected 200, got %d", resp.StatusCode) + if resp.StatusCode < 200 || resp.StatusCode > 299 { + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("Invalid HTTP-Statuscode - expected 200, got %d - can not read response body: %v", resp.StatusCode, err) + } + return fmt.Errorf("Invalid HTTP-Statuscode - expected 200, got %d: %v", resp.StatusCode, string(b)) + } + remote.Registered = true } } + if err := config.Write(con, configDir); err != nil { + return err + } + + return nil +} + +func UnregisterDevice(configDir string) error { + return nil } diff --git a/pkg/sensor/sensor.go b/pkg/sensor/sensor.go new file mode 100644 index 0000000..b1d4e00 --- /dev/null +++ b/pkg/sensor/sensor.go @@ -0,0 +1,14 @@ +package sensor + +import ( + "os" + "path/filepath" +) + +func sensorExists(wirePath, sensorID string) bool { + sensorPath := filepath.Join(wirePath, sensorID) + if _, err := os.Stat(sensorPath); os.IsNotExist(err) { + return false + } + return true +} diff --git a/pkg/sensor/temperature.go b/pkg/sensor/temperature.go new file mode 100644 index 0000000..ce4fb88 --- /dev/null +++ b/pkg/sensor/temperature.go @@ -0,0 +1,99 @@ +package sensor + +import ( + "fmt" + "io" + "path/filepath" + "text/tabwriter" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/config" + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" +) + +func AddTemperature(sensorID, sensorName, configDir, wirePath string) error { + + // read cnf file + cnf, err := config.Read(configDir) + if err != nil { + return err + } + + // check if sensor exists + if !sensorExists(wirePath, sensorID) { + return fmt.Errorf("Can not find sensor: %v", filepath.Join(wirePath, sensorID)) + } + + temperatureSensor := &types.WireSensor{ + ID: sensorID, + Name: sensorName, + WirePath: wirePath, + } + + // append sensor to list + cnf.TemperatureSensors = append(cnf.TemperatureSensors, temperatureSensor) + + // write cnf file + if err := config.Write(cnf, configDir); err != nil { + return err + } + + return nil +} + +func PrintTemperature(w io.Writer, configDir string, quiet bool) error { + + // read cnf file + cnf, err := config.Read(configDir) + if err != nil { + return err + } + + // declar tabwriter + tw := tabwriter.NewWriter(w, 0, 0, 5, ' ', 0) + + // headline + if !quiet { + fmt.Fprint(tw, "id\tname\tpath\n") + } + + for _, sensor := range cnf.TemperatureSensors { + if quiet { + fmt.Fprintf(tw, "%v\n", sensor.ID) + } else { + fmt.Fprintf(tw, "%v\t%v\t%v\n", sensor.ID, sensor.Name, sensor.WirePath) + } + } + + tw.Flush() + + return nil +} + +func RemoveTemperature(sensorID, configDir string) error { + + // read cnf file + cnf, err := config.Read(configDir) + if err != nil { + return err + } + + // remove matching sensor ids + var j int + for _, sensor := range cnf.TemperatureSensors { + if sensor.ID == sensorID { + cnf.TemperatureSensors = append(cnf.TemperatureSensors[:j], cnf.TemperatureSensors[j+1:]...) + if j > 0 { + j = j - 1 + } + continue + } + j++ + } + + // write cnf file + if err := config.Write(cnf, configDir); err != nil { + return err + } + + return nil +} diff --git a/pkg/temperature/temperature.go b/pkg/temperature/temperature.go index 2b20147..56db14b 100644 --- a/pkg/temperature/temperature.go +++ b/pkg/temperature/temperature.go @@ -1,10 +1,146 @@ package temperature import ( + "fmt" "io" + "log" + "os" + "os/signal" + "syscall" + "text/tabwriter" + "time" + + stypes "git.cryptic.systems/fh-trier/go-flucky-server/pkg/types" + "git.cryptic.systems/fh-trier/go-flucky/pkg/remote" + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/config" + + uuid "github.com/satori/go.uuid" + "github.com/yryz/ds18b20" ) -func Get(w io.Writer) error { +// Get ... +func Get(w io.Writer, sensorName string, configDir string) error { + + temperature, err := getTemperature(sensorName, configDir) + if err != nil { + return err + } + + fmt.Fprintf(w, "%3.3f\n", temperature.TemperatureValue) + return nil + +} + +// Logs ... +func Logs(w io.Writer, configDir string) error { + + // get cnf + cnf, err := config.Read(configDir) + if err != nil { + return err + } + + // declar tabwriter + tw := tabwriter.NewWriter(w, 0, 0, 5, ' ', 0) + + // headlines + for _, sensor := range cnf.TemperatureSensors { + if sensor.Name != "" { + fmt.Fprintf(tw, "%v\t", sensor.Name) + } else { + fmt.Fprintf(tw, "%v\t", sensor.ID) + } + + } + fmt.Fprint(tw, "\n") + + // body + ticker := time.NewTicker(1 * time.Second) + + go func() { + for { + select { + case _, more := <-ticker.C: + if !more { + return + } + + for _, sensor := range cnf.TemperatureSensors { + temperature, err := ds18b20.Temperature(sensor.ID) + if err != nil { + return + } + fmt.Fprintf(tw, "%3.3f°\t", temperature) + } + + fmt.Fprint(tw, "\n") + + tw.Flush() + + } + } + }() + + signalChannel := make(chan os.Signal) + signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM) + + sig := <-signalChannel + log.Printf("Got signal %s, initiating shutdown\n", sig) + ticker.Stop() return nil } + +// Push ... +func Push(sensorName, configDir string) error { + + temperature, err := getTemperature(sensorName, configDir) + if err != nil { + return err + } + + if err := remote.SendTemperature(&temperature, configDir); err != nil { + return err + } + + return nil + +} + +func getTemperature(sensorName, configDir string) (stypes.Temperature, error) { + cnf, err := config.Read(configDir) + if err != nil { + return stypes.Temperature{}, err + } + + var foundSensor types.WireSensor + var sensorFound bool + for _, sensor := range cnf.TemperatureSensors { + if sensor.ID == sensorName || sensor.Name == sensorName { + foundSensor = *sensor + sensorFound = true + break + } + } + + if !sensorFound { + return stypes.Temperature{}, fmt.Errorf("Sensor not found sensor %v in config", sensorName) + } + + t, err := ds18b20.Temperature(foundSensor.ID) + if err != nil { + return stypes.Temperature{}, fmt.Errorf("Can not read temperature from sensor %v: %v", foundSensor.ID, err) + } + + temperature := stypes.Temperature{ + TemperatureID: uuid.NewV4().String(), + TemperatureValue: t, + SensorID: foundSensor.ID, + TemperatureDate: time.Now(), + DeviceID: cnf.DeviceID, + } + + return temperature, nil +} diff --git a/pkg/types/types.go b/pkg/types/types.go index c9c6fc7..c3f4599 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -8,8 +8,9 @@ import ( ) type Config struct { - DeviceID string `json:"device_id"` - Remotes []*Remote `json:"remotes"` + DeviceID string `json:"device_id"` + Remotes []*Remote `json:"remotes"` + TemperatureSensors []*WireSensor `json:"temperature_sensors"` } func (c *Config) ToJSON() (string, error) { @@ -43,6 +44,13 @@ func (c *Config) JSONDecoder(r io.Reader) error { } type Remote struct { - Name string `json:"remote_name"` - Address string `json:"remote_address"` + Name string `json:"remote_name"` + Address string `json:"remote_address"` + Registered bool `json:"remote_registered"` +} + +type WireSensor struct { + ID string `json:"sensor_id"` + Name string `json:"sensor_name"` + WirePath string `json:"wire_path"` } diff --git a/vendor/git.cryptic.systems/fh-trier/go-flucky-server/pkg/types/types.go b/vendor/git.cryptic.systems/fh-trier/go-flucky-server/pkg/types/types.go index de9a099..cac4e11 100644 --- a/vendor/git.cryptic.systems/fh-trier/go-flucky-server/pkg/types/types.go +++ b/vendor/git.cryptic.systems/fh-trier/go-flucky-server/pkg/types/types.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "io" + "time" ) // TypeObject ... @@ -14,7 +15,8 @@ type TypeObject interface { // Device ... type Device struct { - DeviceID string `json:"device_id"` + DeviceID string `json:"device_id"` + CreationDate time.Time `json:"creation_date"` } // EncodeToJson needs a writer to write the struct into json string @@ -39,10 +41,12 @@ func (d *Device) DecodeFromJSON(r io.Reader) error { // Humidity ... type Humidity struct { - HumidityID string `json:"humidity_id"` - HumidityValue string `json:"humidity_value"` - HumidityDate string `json:"humidity_date"` - DeviceID string `json:"device_id"` + HumidityID string `json:"humidity_id"` + HumidityValue json.Number `json:"humidity_value"` + HumidityDate time.Time `json:"humidity_date"` + SensorID string `json:"sensor_id"` + DeviceID string `json:"device_id"` + CreationDate time.Time `json:"creation_date"` } // EncodeToJson needs a writer to write the struct into json string @@ -67,10 +71,12 @@ func (h *Humidity) DecodeFromJSON(r io.Reader) error { // Temperature ... type Temperature struct { - TemperatureID string `json:"temperature_id"` - TemperatureValue string `json:"temperature_value"` - TemperatureDate string `json:"temperature_date"` - DeviceID string `json:"device_id"` + TemperatureID string `json:"temperature_id"` + TemperatureValue float64 `json:"temperature_value,string"` + TemperatureDate time.Time `json:"temperature_date"` + SensorID string `json:"sensor_id"` + DeviceID string `json:"device_id"` + CreationDate time.Time `json:"creation_date"` } // EncodeToJson needs a writer to write the struct into json string diff --git a/vendor/github.com/yryz/ds18b20/.gitignore b/vendor/github.com/yryz/ds18b20/.gitignore new file mode 100644 index 0000000..daf913b --- /dev/null +++ b/vendor/github.com/yryz/ds18b20/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/vendor/github.com/yryz/ds18b20/LICENSE b/vendor/github.com/yryz/ds18b20/LICENSE new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/vendor/github.com/yryz/ds18b20/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/yryz/ds18b20/README.md b/vendor/github.com/yryz/ds18b20/README.md new file mode 100644 index 0000000..e94c34e --- /dev/null +++ b/vendor/github.com/yryz/ds18b20/README.md @@ -0,0 +1,53 @@ +# ds18b20 + +Get sensor data from ds18b20 connected to the Raspberry (GPIO w1 pin). + +## Usage + +### Connect DS18B20 +On the Raspberry Pi, you will need to add `dtoverlay=w1-gpio"` (for regular connection) or `dtoverlay=w1-gpio,pullup="y"` (for parasitic connection) to your /boot/config.txt. The default data pin is GPIO4 (RaspPi connector pin 7), but that can be changed from 4 to `x` with `dtoverlay=w1-gpio,gpiopin=x`. + +Here's what I did: +``` +sudo echo dtoverlay=w1-gpio-pullup,gpiopin=4 >> /boot/config.txt +sudo modprobe w1_gpio && sudo modprobe w1_therm +``` + +### Drivers + +1-Wire drivers need to be loaded in order to create the connection between the physical sensor and the rPI. +You can load them from the terminal (or from the bin/modules.sh script). + + sudo modprobe wire + sudo modprobe w1-gpio + sudo modprobe w1-therm + +### Install + go get github.com/yryz/ds18b20 + +### Code +```go +package main + +import ( + "fmt" + + "github.com/yryz/ds18b20" +) + +func main() { + sensors, err := ds18b20.Sensors() + if err != nil { + panic(err) + } + + fmt.Printf("sensor IDs: %v\n", sensors) + + for _, sensor := range sensors { + t, err := ds18b20.Temperature(sensor) + if err == nil { + fmt.Printf("sensor: %s temperature: %.2f°C\n", sensor, t) + } + } +} +``` diff --git a/vendor/github.com/yryz/ds18b20/ds18b20.go b/vendor/github.com/yryz/ds18b20/ds18b20.go new file mode 100644 index 0000000..10a67ae --- /dev/null +++ b/vendor/github.com/yryz/ds18b20/ds18b20.go @@ -0,0 +1,49 @@ +// Copyright 2016 yryz Author. All Rights Reserved. + +package ds18b20 + +import ( + "errors" + "io/ioutil" + "strconv" + "strings" +) + +var ErrReadSensor = errors.New("failed to read sensor temperature") + +// Sensors get all connected sensor IDs as array +func Sensors() ([]string, error) { + data, err := ioutil.ReadFile("/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves") + if err != nil { + return nil, err + } + + sensors := strings.Split(string(data), "\n") + if len(sensors) > 0 { + sensors = sensors[:len(sensors)-1] + } + + return sensors, nil +} + +// Temperature get the temperature of a given sensor +func Temperature(sensor string) (float64, error) { + data, err := ioutil.ReadFile("/sys/bus/w1/devices/" + sensor + "/w1_slave") + if err != nil { + return 0.0, ErrReadSensor + } + + raw := string(data) + + i := strings.LastIndex(raw, "t=") + if i == -1 { + return 0.0, ErrReadSensor + } + + c, err := strconv.ParseFloat(raw[i+2:len(raw)-1], 64) + if err != nil { + return 0.0, ErrReadSensor + } + + return c / 1000.0, nil +}