PKGBUILD/pkg/temperature/temperature.go
Markus Pesch 500d1a5823
fix: splited temperatures
Changes:
- Split temperatures from log file into blocks.
  Every block has a size of 500 entries. Every block would be send to
  the remote host
2018-12-07 22:50:28 +01:00

293 lines
6.0 KiB
Go

package temperature
import (
"fmt"
"io"
"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/httpcall"
"git.cryptic.systems/fh-trier/go-flucky/pkg/logs"
"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"
)
var temperatureLog = "temperature.log"
// Get ...
func Get(sensorNames []string, push bool, configDir string, w io.Writer) error {
// get cnf
cnf, err := config.Read(configDir)
if err != nil {
return err
}
// get sensors
sensors, err := getSensors(sensorNames, cnf)
if err != nil {
return err
}
// get temperatures
temperatures, err := getTemperatures(sensors)
if err != nil {
return err
}
tw := tabwriter.NewWriter(w, 0, 0, 5, ' ', 0)
// headlines
for _, sensor := range sensors {
if sensor.SensorName != nil && *sensor.SensorName != "" {
fmt.Fprintf(tw, "%v\t", *sensor.SensorName)
} else {
fmt.Fprintf(tw, "%v\t", sensor.SensorID)
}
}
fmt.Fprint(tw, "\n")
// body
for _, temperature := range temperatures {
fmt.Fprintf(tw, "%v\t", temperature.TemperatureValue)
}
fmt.Fprint(tw, "\n")
tw.Flush()
// write logfiles or push
if !push {
if err := logs.AppendTemperature(temperatures, cnf); err != nil {
return err
}
} else {
if err := httpcall.SendTemperatures(temperatures, configDir); err != nil {
return err
}
}
return nil
}
// Fetch ...
func Fetch(sensorNames []string, push bool, configDir string) error {
// get cnf
cnf, err := config.Read(configDir)
if err != nil {
return err
}
// get sensors
sensors, err := getSensors(sensorNames, cnf)
if err != nil {
return err
}
// get temperatures
temperatures, err := getTemperatures(sensors)
if err != nil {
return err
}
// write logfiles or push
if !push {
if err := logs.AppendTemperature(temperatures, cnf); err != nil {
return err
}
} else {
if err := httpcall.SendTemperatures(temperatures, configDir); err != nil {
return err
}
}
return nil
}
// Follow ...
func Follow(sensorNames []string, push bool, configDir string, w io.Writer) error {
// get cnf
cnf, err := config.Read(configDir)
if err != nil {
return err
}
// get sensors
sensors, err := getSensors(sensorNames, cnf)
if err != nil {
return err
}
tw := tabwriter.NewWriter(w, 0, 0, 5, ' ', 0)
// headlines
for _, sensor := range sensors {
if sensor.SensorName != nil && *sensor.SensorName != "" {
fmt.Fprintf(tw, "%v\t", *sensor.SensorName)
} else {
fmt.Fprintf(tw, "%v\t", sensor.SensorID)
}
}
fmt.Fprint(tw, "\n")
// body
temperatures := []*stypes.Temperature{}
ticker := time.NewTicker(1 * time.Second)
// TODO: create channel for own sensor
go func() {
for {
select {
case _, more := <-ticker.C:
if !more {
return
}
// get temperatures from sensors and write them into writer
t, err := getTemperatures(sensors)
// TODO: get error back over channel
if err != nil {
return
}
// append temperatures to temperature list
temperatures = append(temperatures, t...)
for _, temperature := range t {
fmt.Fprintf(tw, "%3.3f\t", temperature.TemperatureValue)
}
fmt.Fprint(tw, "\n")
// flush writer
tw.Flush()
}
}
}()
signalChannel := make(chan os.Signal)
signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM)
sig := <-signalChannel
fmt.Printf("Got signal %s, initiating shutdown\n", sig)
ticker.Stop()
// write logfiles or push
if !push {
if err := logs.AppendTemperature(temperatures, cnf); err != nil {
return err
}
} else {
if err := httpcall.SendTemperatures(temperatures, configDir); err != nil {
return err
}
}
return nil
}
// Push ...
func Push(configDir string) error {
// get cnf
cnf, err := config.Read(configDir)
if err != nil {
return err
}
temperatures, err := logs.ReadTemperatures(cnf)
if err != nil {
return err
}
if err := httpcall.SendTemperatures(temperatures, configDir); err != nil {
return err
}
if err := logs.FlushTemperatures(cnf); err != nil {
return err
}
return nil
}
func getTemperatures(sensors []*stypes.Sensor) ([]*stypes.Temperature, error) {
temperatures := []*stypes.Temperature{}
for _, sensor := range sensors {
t, err := ds18b20.Temperature(*sensor.WireID)
if err != nil {
return []*stypes.Temperature{}, fmt.Errorf("Can not read temperature from sensor %v: %v", sensor.SensorID, err)
}
temperature := &stypes.Temperature{
TemperatureID: uuid.NewV4().String(),
TemperatureValue: t,
TemperatureDate: time.Now(),
SensorID: sensor.SensorID,
CreationDate: time.Now(),
}
temperatures = append(temperatures, temperature)
}
return temperatures, nil
}
func getSensors(sensorNames []string, cnf *types.Config) ([]*stypes.Sensor, error) {
sensors := []*stypes.Sensor{}
if len(sensorNames) > 0 {
for _, sensorName := range sensorNames {
for _, sensor := range cnf.Sensors {
if sensorName == *sensor.SensorName && *sensor.SensorEnabled ||
sensorName == sensor.SensorID && *sensor.SensorEnabled ||
sensorName == *sensor.WireID && *sensor.SensorEnabled {
sensors = append(sensors, sensor)
}
}
}
} else {
for _, sensor := range cnf.Sensors {
if *sensor.SensorEnabled {
sensors = append(sensors, sensor)
}
}
}
if len(sensors) == 0 {
return nil, fmt.Errorf("No matched Sensors. Check if your sensor is configured or enabled")
}
// check if sensor exists in cnf and has a wire id
for _, filterdSensor := range sensors {
if filterdSensor.WireID == nil || *filterdSensor.WireID == "" {
return nil, fmt.Errorf("Sensor %v has no wire id", filterdSensor.SensorID)
}
var found bool
for _, cnfSensor := range cnf.Sensors {
if filterdSensor.SensorID == cnfSensor.SensorID {
found = true
}
}
if !found {
return nil, fmt.Errorf("Can not found sensor %v in config", filterdSensor.SensorID)
}
}
return sensors, nil
}