Skip to content

Commit

Permalink
switch to gocron, write data points with no update
Browse files Browse the repository at this point in the history
gocron for scheduling on the top of the minute
write no-update points for better compatibility with victoriametrics aggregation functions
  • Loading branch information
Ted Pearson committed Dec 21, 2021
1 parent d2727d2 commit dd91f56
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 24 deletions.
2 changes: 1 addition & 1 deletion ecobee2influx.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ ecobee:
thermostat_id: YOUR_THERMOSTAT_ID
app_id: YOUR_APP_ID
auth_cache_file: /var/lib/ecobee2influx/auth-cache
poll_frequency: 3m
poll_cron: "* * * * *"
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.15

require (
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/go-co-op/gocron v1.11.0
github.com/iancoleman/strcase v0.1.2
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab
github.com/magiconair/properties v1.8.4 // indirect
Expand All @@ -16,7 +17,6 @@ require (
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.5.1 // indirect
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 // indirect
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect
Expand Down
13 changes: 11 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-co-op/gocron v1.11.0 h1:ujOMubCpGcTxnnR/9vJIPIEpgwuAjbueAYqJRNr+nHg=
github.com/go-co-op/gocron v1.11.0/go.mod h1:qtlsoMpHlSdIZ3E/xuZzrrAbeX3u5JtPvWf2TcdutU0=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
Expand Down Expand Up @@ -245,6 +247,8 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rspier/go-ecobee v0.0.0-20201001045826-171fa1acecfb h1:7xlYvw1C7ITR4m73o/S48vdf0G6PR6MIAcoZV+mpBRg=
Expand Down Expand Up @@ -283,8 +287,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
Expand Down Expand Up @@ -392,6 +396,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down Expand Up @@ -580,6 +586,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
40 changes: 20 additions & 20 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"flag"
"fmt"
"github.com/go-co-op/gocron"
"github.com/iancoleman/strcase"
influxdb1 "github.com/influxdata/influxdb1-client/v2"
"github.com/mitchellh/go-homedir"
Expand Down Expand Up @@ -68,20 +69,19 @@ func main() {
Password: ic.Password,
})

d, err := time.ParseDuration(config.Ecobee.PollFrequency)
s := gocron.NewScheduler(time.UTC)
_, err = s.Cron(config.Ecobee.PollCron).WaitForSchedule().SingletonMode().Do(run, e, influx, id, config)
if err != nil {
log.Fatalf("Can't parse poll frequency '%s' from config", config.Ecobee.PollFrequency)
}
ticker := time.NewTicker(d)
defer ticker.Stop()
runtimeRev := ""
for ; true; <-ticker.C {
runtimeRev = run(e, influx, id, config, runtimeRev)
log.Fatalf("Failed to schedule: %+v", err)
}
s.StartBlocking()

// todo: create utility to just authorize the app
}

func run(e *ecobee.Client, influx influxdb1.Client, id string, config Config, runtimeRev string) string {
var lastRevision string

func run(e *ecobee.Client, influx influxdb1.Client, id string, config Config) {
now := time.Now()

tsm, err := e.GetThermostatSummary(
Expand All @@ -92,13 +92,9 @@ func run(e *ecobee.Client, influx influxdb1.Client, id string, config Config, ru
})
if err != nil {
log.Printf("error retrieving thermostat s for %s: %v", id, err)
return runtimeRev
return
}
s := tsm[id]
if s.RuntimeRevision == runtimeRev {
log.Println("--- No Update ---")
return runtimeRev
}

ts, err := e.GetThermostats(ecobee.Selection{
SelectionType: "thermostats",
Expand All @@ -110,10 +106,15 @@ func run(e *ecobee.Client, influx influxdb1.Client, id string, config Config, ru
})
if err != nil {
log.Printf("error retrieving thermostat: %v", err)
return runtimeRev
return
}

t := ts[0]
if s.RuntimeRevision == lastRevision {
log.Println("--- No Update ---")
} else {
log.Printf("--- Got updated data on thermostat and %d sensors from Ecobee ---", len(t.RemoteSensors))
}
therm := ThermostatFields{
CoolingSetpoint: float64(t.Runtime.DesiredCool) / 10,
HeatingSetpoint: float64(t.Runtime.DesiredHeat) / 10,
Expand Down Expand Up @@ -183,15 +184,14 @@ func run(e *ecobee.Client, influx influxdb1.Client, id string, config Config, ru
Occupancy: AllOccupancy(sensors),
},
}
log.Printf("--- Got updated data on thermostat and %d sensors from Ecobee ---", len(t.RemoteSensors))
sensors[len(sensors)-1] = thermSensor

points, err := influxdb1.NewBatchPoints(influxdb1.BatchPointsConfig{
Database: config.InfluxDB.Database,
})
if err != nil {
log.Printf("Failed to make BatchPoints: %+v", errors.WithStack(err))
return ""
return
}

addPoint := func(metric interface{}, name string, measurement string) {
Expand All @@ -207,12 +207,12 @@ func run(e *ecobee.Client, influx influxdb1.Client, id string, config Config, ru
addPoint(sensor.SensorFields, sensor.Name, config.InfluxDB.Measurements.Sensor)
}
addPoint(therm, t.Name, config.InfluxDB.Measurements.Thermostat)

err = influx.Write(points)
if err != nil {
log.Printf("Write failed: %+v", errors.WithStack(err))
}
return s.RuntimeRevision
lastRevision = s.RuntimeRevision
return
}

func FieldsToPoint(value interface{}, now time.Time, name string, measurement string) (*influxdb1.Point, error) {
Expand Down Expand Up @@ -294,7 +294,7 @@ type Config struct {
ThermostatId string `mapstructure:"thermostat_id"`
AppId string `mapstructure:"app_id"`
AuthCacheFile string `mapstructure:"auth_cache_file"`
PollFrequency string `mapstructure:"poll_frequency"`
PollCron string `mapstructure:"poll_cron"`
}
}

Expand Down

0 comments on commit dd91f56

Please sign in to comment.