1
0
Fork 0
mirror of https://github.com/shouptech/tempgopher.git synced 2026-02-03 08:39:43 +00:00

Merge branch 'feature/influx' into 'develop'

Closes #11
Writes states to InfluxDB
Updated config utility and documentation to assist with Influx

See merge request shouptech/tempgopher!5
This commit is contained in:
Mike Shoup 2018-10-12 20:59:30 +00:00
commit cfa7fc7fe8
7 changed files with 122 additions and 14 deletions

View file

@ -39,6 +39,7 @@ You will be asked some questions during the initial configuration of TempGopher.
* `Heating GPIO:` - The pin your heating relay switch is hooked into. * `Heating GPIO:` - The pin your heating relay switch is hooked into.
* `Invert heating switch` - If set to `true`, the heating will be ON when the switch is LOW. This should usually be `false`, so that is the default * `Invert heating switch` - If set to `true`, the heating will be ON when the switch is LOW. This should usually be `false`, so that is the default
* `Enable verbose logging` - If set to `true`, TempGopher will display in the console every thermostat reading. This can be quite verbose, so the default is `false`. * `Enable verbose logging` - If set to `true`, TempGopher will display in the console every thermostat reading. This can be quite verbose, so the default is `false`.
* `Write data to an Influx database?` - Whether or not to configure an Influx database
## Example configuration script ## Example configuration script
@ -73,4 +74,13 @@ Heating minutes: 0.5
Heating GPIO: 13 Heating GPIO: 13
Invert heating switch [false]: Invert heating switch [false]:
Enable verbose logging [false]: Enable verbose logging [false]:
Write data to an Influx database?
[Y/n]: y
Influx address [http://influx:8086]:
Influx Username []:
Influx Password []:
Influx UserAgent [InfluxDBClient]:
Influx timeout (in seconds) [30]:
Influx database []: tempgopher
Enable InsecureSkipVerify? [fasle]:
``` ```

32
cli.go
View file

@ -158,6 +158,38 @@ func PromptForConfiguration() Config {
config.Sensors = append(config.Sensors, s) config.Sensors = append(config.Sensors, s)
} }
fmt.Println("Write data to an Influx database?")
fmt.Print("[Y/n]: ")
choice := ReadInput(reader, "y")
if strings.ToLower(choice)[0] == 'y' {
fmt.Print("Influx address [http://influx:8086]: ")
config.Influx.Addr = ReadInput(reader, "http://influx:8086")
fmt.Print("Influx Username []: ")
config.Influx.Username = ReadInput(reader, "")
fmt.Print("Influx Password []: ")
config.Influx.Password = ReadInput(reader, "")
fmt.Print("Influx UserAgent [InfluxDBClient]: ")
config.Influx.UserAgent = ReadInput(reader, "InfluxDBClient")
fmt.Print("Influx timeout (in seconds) [30]: ")
config.Influx.Timeout, err = strconv.ParseFloat(ReadInput(reader, "30"), 64)
if err != nil {
panic(err)
}
fmt.Print("Influx database []: ")
config.Influx.Database = ReadInput(reader, "")
fmt.Print("Enable InsecureSkipVerify? [fasle]: ")
config.Influx.InsecureSkipVerify, err = strconv.ParseBool(ReadInput(reader, "false"))
if err != nil {
panic(err)
}
}
return config return config
} }

View file

@ -10,6 +10,17 @@ import (
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
// Influx defines an Influx database configuration
type Influx struct {
Addr string `json:"string" yaml:"addr"`
Username string `json:"username" yaml:"username"`
Password string `json:"-" yaml:"password"`
UserAgent string `json:"useragent" yaml:"useragent"`
Timeout float64 `json:"timeout" yaml:"timeout"`
InsecureSkipVerify bool `json:"insecureskipverify" yaml:"insecureskipverify"`
Database string `json:"database" yaml:"database"`
}
// Sensor defines configuration for a temperature sensor. // Sensor defines configuration for a temperature sensor.
type Sensor struct { type Sensor struct {
ID string `json:"id" yaml:"id"` ID string `json:"id" yaml:"id"`
@ -31,6 +42,7 @@ type Config struct {
BaseURL string `yaml:"baseurl"` BaseURL string `yaml:"baseurl"`
ListenAddr string `yaml:"listenaddr"` ListenAddr string `yaml:"listenaddr"`
DisplayFahrenheit bool `yaml:"displayfahrenheit"` DisplayFahrenheit bool `yaml:"displayfahrenheit"`
Influx Influx `yaml:"influx"`
} }
var configFilePath string var configFilePath string

View file

@ -7,25 +7,27 @@ import (
) )
func Test_LoadConfig(t *testing.T) { func Test_LoadConfig(t *testing.T) {
testSensor := Sensor{
ID: "28-000008083108",
Alias: "fermenter",
HighTemp: 8,
LowTemp: 4,
HeatGPIO: 5,
HeatInvert: true,
HeatMinutes: 5,
CoolGPIO: 17,
CoolInvert: false,
CoolMinutes: 10,
Verbose: true,
}
testConfig := Config{ testConfig := Config{
Sensors: []Sensor{testSensor}, Sensors: []Sensor{
Sensor{
ID: "28-000008083108",
Alias: "fermenter",
HighTemp: 8,
LowTemp: 4,
HeatGPIO: 5,
HeatInvert: true,
HeatMinutes: 5,
CoolGPIO: 17,
CoolInvert: false,
CoolMinutes: 10,
Verbose: true,
},
},
BaseURL: "https://foo.bar", BaseURL: "https://foo.bar",
ListenAddr: "127.0.0.1:8080", ListenAddr: "127.0.0.1:8080",
DisplayFahrenheit: true, DisplayFahrenheit: true,
Influx: Influx{Addr: "http://foo:8086"},
} }
loadedConfig, err := LoadConfig("tests/test_config.yml") loadedConfig, err := LoadConfig("tests/test_config.yml")

46
influx.go Normal file
View file

@ -0,0 +1,46 @@
package main
import (
"time"
client "github.com/influxdata/influxdb/client/v2"
)
// WriteStateToInflux writes a State object to an Influx database
func WriteStateToInflux(s State, config Influx) error {
c, err := client.NewHTTPClient(client.HTTPConfig{
Addr: config.Addr,
Username: config.Username,
Password: config.Password,
UserAgent: config.UserAgent,
Timeout: time.Duration(config.Timeout * 1000000000),
InsecureSkipVerify: config.InsecureSkipVerify,
})
if err != nil {
return err
}
defer c.Close()
bp, err := client.NewBatchPoints(client.BatchPointsConfig{
Database: config.Database,
Precision: "s",
})
if err != nil {
return err
}
tags := map[string]string{"alias": s.Alias}
fields := map[string]interface{}{"value": s.Temp}
pt, err := client.NewPoint("temperature", tags, fields, s.When)
if err != nil {
return err
}
bp.AddPoint(pt)
if err := c.Write(bp); err != nil {
return err
}
return nil
}

View file

@ -13,3 +13,5 @@ sensors:
baseurl: https://foo.bar baseurl: https://foo.bar
listenaddr: 127.0.0.1:8080 listenaddr: 127.0.0.1:8080
displayfahrenheit: true displayfahrenheit: true
influx:
addr: http://foo:8086

View file

@ -216,6 +216,10 @@ func RunThermostat(path string, sc chan<- State, wg *sync.WaitGroup) {
default: default:
break break
} }
if config.Influx.Addr != "" {
go WriteStateToInflux(states[v.ID], config.Influx)
}
} }
} }