diff --git a/.env b/.env new file mode 100644 index 0000000..dc56b23 --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +PG_INTERN_PORT=5432 +PG_EXTERN_PORT=5432 +PG_NAME=public +PG_USER=postgres +PG_PASSWORD=postgres + +TZ=Europe/Berlin diff --git a/.env_dev b/.env_dev new file mode 100644 index 0000000..025e627 --- /dev/null +++ b/.env_dev @@ -0,0 +1,15 @@ +SERVER_PORT=80 +DATABASE_DRIVER=postgres +DATABASE_NAME=postgres +DATABASE_SCHEMA=public +DATABASE_USER=postgres +DATABASE_PASSWORD=postgres + +PG_HOST=flucky_db +PG_INTERN_PORT=5432 +PG_EXTERN_PORT=5433 +PG_NAME=public +PG_USER=postgres +PG_PASSWORD=postgres + +TZ=Europe/Berlin diff --git a/.travis.yml b/.travis.yml index 6836554..c784003 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,4 @@ services: - docker script: - - make container-build + - make container-go-build diff --git a/Makefile b/Makefile index 4b406a1..db4323c 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ GID?=$(shell id --group) # VERSION # If no version is specified as a parameter of make, the last git hash # value is taken. -VERSION:=$(or ${TRAVIS_TAG}, ${TRAVIS_TAG}, $(shell git rev-parse --short HEAD)-git) +VERSION:=$(or ${TRAVIS_TAG}, $(shell git rev-parse --short HEAD)-git) CONTAINER_RUNTIME?=$(shell which docker) @@ -16,23 +16,24 @@ GOARCH?=amd64 GOOS?=linux # default build -build: +go-build: bindata GOOS=${GOOS} \ GOARCH=${GOARCH} \ go build -ldflags "-X main.version=${VERSION}" chown -R ${UID}:${GID} * -test: bindata +go-test: go-build go test -v ./pkg/... bindata: - go-bindata -pkg logfile_test -o ./pkg/logfile/bindata_test.go ./pkg/logfile/test/*** + go-bindata -pkg db -o ./pkg/db/bindataSQL.go ./pkg/db/sql/*** + go-bindata -pkg goldenfiles -o ./test/goldenfiles/bindata.go ./test/goldenfiles/json/*** -container-build: - $(MAKE) container-run COMMAND=build +container-go-build: + $(MAKE) container-run COMMAND=go-build -container-test: - $(MAKE) container-run COMMAND=test +container-go-test: + $(MAKE) container-run COMMAND=go-test container-run: ${CONTAINER_RUNTIME} run \ @@ -42,6 +43,6 @@ container-run: make ${COMMAND} UID=${UID} GID=${GID} VERSION=${VERSION} GOOS=${GOOS} GOARCH=${GOARCH} remote: - $(MAKE) build GOARCH=arm + $(MAKE) go-build GOARCH=arm scp flucky ${FLUCKY_REMOTE}:/usr/local/bin ssh ${FLUCKY_REMOTE} "chmod +x /usr/local/bin/flucky" diff --git a/cmd/cmd.go b/cmd/cmd.go index 3ab3a76..ec7f2d5 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "math" "os" "time" @@ -34,12 +35,19 @@ var rootCmd = &cobra.Command{ return fmt.Errorf("Can not locate 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 + t := time.Now() + l, _ := time.LoadLocation("Europe/Berlin") + t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), int(math.Round(float64(t.Nanosecond())/1000000)*1000000), l) + cnf := config.Configuration{ Device: &types.Device{ DeviceID: uuid.NewV4().String(), DeviceName: hostname, Logfile: "/var/log/flucky/logfile.csv", - CreationDate: time.Now(), + CreationDate: t, }, } @@ -62,6 +70,7 @@ func Execute(version string) { compression.InitCmd(rootCmd, &configFile) convert.InitCmd(rootCmd, &configFile) daemon.InitCmd(rootCmd, &configFile) + // db.InitCmd(rootCmd, &configFile) humidity.InitCmd(rootCmd, &configFile) pressure.InitCmd(rootCmd, &configFile) rgbled.InitCmd(rootCmd, &configFile) diff --git a/cmd/db/db.go b/cmd/db/db.go new file mode 100644 index 0000000..6eb630e --- /dev/null +++ b/cmd/db/db.go @@ -0,0 +1,49 @@ +package db + +import ( + "context" + "log" + + database "github.com/go-flucky/flucky/pkg/db" + "github.com/go-flucky/flucky/pkg/types" + "github.com/spf13/cobra" +) + +var configFile *string + +var dbCmd = &cobra.Command{ + Use: "db", + Short: "Operates with the configured database", + Run: func(cmd *cobra.Command, args []string) { + + postgresDB, err := database.New(database.DBOTypePostgres, "localhost", "5432", "postgres", "postgres", "postgres") + if err != nil { + log.Fatalf("%v", err) + } + + ctx := context.Background() + + devices := []*types.Device{ + &types.Device{ + DeviceID: "1684df26-bc72-4435-a4f9-74b24bdb286c", + DeviceName: "raspberr-pi", + }, + &types.Device{ + DeviceID: "1684df26-bc72-4435-a4f9-74b24bdb286c", + DeviceName: "raspberr-pi", + }, + } + + if err := postgresDB.InsertDevices(ctx, devices); err != nil { + log.Fatalln(err) + } + }, +} + +// Execute a +func InitCmd(cmd *cobra.Command, cnfFile *string) { + configFile = cnfFile + + cmd.AddCommand(dbCmd) + +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..01f2a97 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3' + +services: + + flucky-db: + environment: + - PGTZ=${TZ} + - POSTGRES_PASSWORD=${PG_PASSWORD} + - POSTGRES_USER=${PG_USER} + - POSTGRES_DB=${PG_NAME} + - TZ=${TZ} + image: postgres:11.5-alpine + ports: + - ${PG_EXTERN_PORT}:${PG_INTERN_PORT}/tcp + restart: always + volumes: + - /etc/localtime:/etc/localtime:ro diff --git a/go.mod b/go.mod index bccf709..9440c3f 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/go-flucky/go-dht v0.1.1 github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/kr/pretty v0.1.0 // indirect + github.com/lib/pq v1.2.0 github.com/satori/go.uuid v1.2.0 github.com/spf13/cobra v0.0.3 github.com/spf13/pflag v1.0.3 // indirect diff --git a/go.sum b/go.sum index 484d28d..330c190 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= diff --git a/pkg/config/flucky.go b/pkg/config/flucky.go index 27ef1f7..c622661 100644 --- a/pkg/config/flucky.go +++ b/pkg/config/flucky.go @@ -5,6 +5,7 @@ import ( "time" + "github.com/go-flucky/flucky/pkg/internal/format" "github.com/go-flucky/flucky/pkg/rgbled" "github.com/go-flucky/flucky/pkg/sensor" @@ -101,7 +102,7 @@ func (c *Configuration) AddSensor(sensor *types.Sensor) error { } // overwrite creation date - sensor.CreationDate = time.Now() + sensor.CreationDate = format.FormatedTime() //TODO: check if wire sensor exists in /dev/bus/w1/devices diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go index 20999dd..5337811 100644 --- a/pkg/daemon/daemon.go +++ b/pkg/daemon/daemon.go @@ -8,6 +8,7 @@ import ( "time" "github.com/go-flucky/flucky/pkg/config" + "github.com/go-flucky/flucky/pkg/db" "github.com/go-flucky/flucky/pkg/logfile" "github.com/go-flucky/flucky/pkg/logger" "github.com/go-flucky/flucky/pkg/rgbled" @@ -15,6 +16,14 @@ import ( "github.com/go-flucky/flucky/pkg/types" ) +var ( + postgresHost = "markus-pc.trier.cryptic.systems" + postgresPort = "5432" + postgresDatabase = "postgres" + postgresUser = "postgres" + postgresPassword = "postgres" +) + // Start the daemon func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compression bool, round float64, logger logger.Logger) { @@ -67,7 +76,9 @@ func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compress logger.Error("Can not turn on blue info light: %v", err) } - err = logfile.Append(measuredValuesLogfile, compression, round, measuredValuesCache) + // err = logfile.Append(measuredValuesLogfile, compression, round, measuredValuesCache) + + postgres, err := db.New(db.DBOTypePostgres, postgresHost, postgresPort, postgresDatabase, postgresUser, postgresPassword) if err != nil { err = rgbled.Error(rgbLEDs) @@ -76,8 +87,22 @@ func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compress } cancel() - logger.Fatal("Can not save temperatures: %v", err) + logger.Error("Can not open database connection: %v", err) } + + postgresCtx := context.Background() + err = postgres.InsertMeasuredValues(postgresCtx, measuredValuesCache) + if err != nil { + + err = rgbled.Error(rgbLEDs) + if err != nil { + logger.Error("Can not turn on red info light: %v", err) + } + + cancel() + logger.Error("Can not save caches measured values in database: %v", err) + } + measuredValuesCache = make([]*types.MeasuredValue, 0) case measuredValues, _ := <-measuredValuesChannel: diff --git a/pkg/db/db.go b/pkg/db/db.go new file mode 100644 index 0000000..949c0a6 --- /dev/null +++ b/pkg/db/db.go @@ -0,0 +1,36 @@ +package db + +import ( + "database/sql" + "fmt" + + _ "github.com/lib/pq" +) + +type DBOType string + +func (dboType DBOType) String() string { + return string(dboType) +} + +const ( + DBOTypePostgres DBOType = "postgres" + DBOTypeOracle = "oracle" +) + +func New(dboType DBOType, host string, port string, database string, user string, password string) (Database, error) { + connStr := fmt.Sprintf("%v://%v:%v@%v:%v/%v?sslmode=disable", dboType.String(), user, password, host, port, database) + newDBO, err := sql.Open(dboType.String(), connStr) + if err != nil { + return nil, err + } + + switch dboType { + case "postgres": + return &Postgres{ + dbo: newDBO, + }, nil + default: + return nil, fmt.Errorf("Unknown Database Type") + } +} diff --git a/pkg/db/errors.go b/pkg/db/errors.go new file mode 100644 index 0000000..0b138d9 --- /dev/null +++ b/pkg/db/errors.go @@ -0,0 +1,16 @@ +package db + +import ( + "errors" +) + +var ( + errorBeginTransaction = errors.New("Can not start new transaction") + errorRowNotFound = errors.New("Can not find row by given ID") + errorPrepareStatement = errors.New("Can not prepare sql statement") + errorRollbackTransaction = errors.New("Can not rollback transaction") + errorScanRow = errors.New("Can not scan row") + errorStatementExecute = errors.New("Can not execute statement") + errorStatementQuery = errors.New("Can not query statement") + errorUnknownMeasuredValueType = errors.New("Unknown measured value type") +) diff --git a/pkg/db/interfaces.go b/pkg/db/interfaces.go new file mode 100644 index 0000000..e68f9da --- /dev/null +++ b/pkg/db/interfaces.go @@ -0,0 +1,39 @@ +package db + +import ( + "context" + + "github.com/go-flucky/flucky/pkg/types" +) + +type Database interface { + + // Close DB Connction + Close() error + + // Delete + DeleteDevices(ctx context.Context, devices []*types.Device) error + DeleteMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error + DeleteSensors(ctx context.Context, sensors []*types.Sensor) error + + // Insert + InsertDevices(ctx context.Context, devices []*types.Device) error + InsertMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error + InsertSensors(ctx context.Context, sensors []*types.Sensor) error + + // Select + SelectDeviceByID(ctx context.Context, id string) (*types.Device, error) + SelectHumidities(ctx context.Context) ([]*types.MeasuredValue, error) + SelectHumidityByID(ctx context.Context, id string) (*types.MeasuredValue, error) + SelectMeasuredValuesByIDAndType(ctx context.Context, id string, valueType types.MeasuredValueType) (*types.MeasuredValue, error) + SelectPressures(ctx context.Context) ([]*types.MeasuredValue, error) + SelectPressureByID(ctx context.Context, id string) (*types.MeasuredValue, error) + SelectSensorByID(ctx context.Context, id string) (*types.Sensor, error) + SelectTemperatures(ctx context.Context) ([]*types.MeasuredValue, error) + SelectTemperatureByID(ctx context.Context, id string) (*types.MeasuredValue, error) + + // Update + UpdateDevices(ctx context.Context, devices []*types.Device) error + UpdateMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error + UpdateSensors(ctx context.Context, sensots []*types.Sensor) error +} diff --git a/pkg/db/postgres.go b/pkg/db/postgres.go new file mode 100644 index 0000000..ba80de1 --- /dev/null +++ b/pkg/db/postgres.go @@ -0,0 +1,410 @@ +package db + +import ( + "context" + "database/sql" + "fmt" + + "github.com/go-flucky/flucky/pkg/types" + _ "github.com/lib/pq" +) + +type Postgres struct { + dbo *sql.DB +} + +func (p *Postgres) Close() error { + return p.Close() +} + +func (p *Postgres) DeleteDevices(ctx context.Context, devices []*types.Device) error { + query := string(MustAsset("pkg/db/sql/psql/deleteDevice.sql")) + + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + defer stmt.Close() + + for _, device := range devices { + _, err := stmt.ExecContext(ctx, &device.DeviceID) + if err != nil { + return fmt.Errorf("%v: %v", errorStatementExecute, err) + } + } + + return nil +} + +func (p *Postgres) DeleteSensors(ctx context.Context, sensors []*types.Sensor) error { + query := string(MustAsset("pkg/db/sql/psql/deleteSensor.sql")) + + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + defer stmt.Close() + + for _, sensor := range sensors { + _, err := stmt.ExecContext(ctx, &sensor.SensorID) + if err != nil { + return fmt.Errorf("%v: %v", errorStatementExecute, err) + } + } + + return nil +} + +func (p *Postgres) DeleteMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error { + + deleteMeasuredValue := func(ctx context.Context, query string, measuredValues []*types.MeasuredValue) error { + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + defer stmt.Close() + + for _, measuredValue := range measuredValues { + _, err := stmt.ExecContext(ctx, &measuredValue.ID) + if err != nil { + return fmt.Errorf("%v: %v", errorStatementExecute, err) + } + } + return nil + } + + sortedMeasuredValueTypes := make(map[types.MeasuredValueType][]*types.MeasuredValue) + for _, measuredValue := range measuredValues { + if _, ok := sortedMeasuredValueTypes[measuredValue.ValueType]; !ok { + sortedMeasuredValueTypes[measuredValue.ValueType] = make([]*types.MeasuredValue, 0) + } + sortedMeasuredValueTypes[measuredValue.ValueType] = append(sortedMeasuredValueTypes[measuredValue.ValueType], measuredValue) + } + + for measuredValueType, sortedMeasuredValues := range sortedMeasuredValueTypes { + switch measuredValueType { + case types.MeasuredValueTypeHumidity: + if err := deleteMeasuredValue(ctx, string(MustAsset("pkg/db/sql/psql/deleteHumidity.sql")), sortedMeasuredValues); err != nil { + return err + } + case types.MeasuredValueTypePressure: + if err := deleteMeasuredValue(ctx, string(MustAsset("pkg/db/sql/psql/deletePressure.sql")), sortedMeasuredValues); err != nil { + return err + } + case types.MeasuredValueTypeTemperature: + if err := deleteMeasuredValue(ctx, string(MustAsset("pkg/db/sql/psql/deleteTemperature.sql")), sortedMeasuredValues); err != nil { + return err + } + } + } + + return nil +} + +func (p *Postgres) InsertDevices(ctx context.Context, devices []*types.Device) error { + + query := string(MustAsset("pkg/db/sql/psql/insertDevice.sql")) + + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + defer stmt.Close() + + for _, device := range devices { + _, err := stmt.ExecContext(ctx, &device.DeviceID, &device.DeviceName, &device.DeviceLocation, &device.CreationDate) + if err != nil { + return fmt.Errorf("%v: %v", errorStatementExecute, err) + } + } + + return nil +} + +func (p *Postgres) InsertMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error { + + sortedMeasuredValueTypes := make(map[types.MeasuredValueType][]*types.MeasuredValue) + + for _, measuredValue := range measuredValues { + if _, ok := sortedMeasuredValueTypes[measuredValue.ValueType]; !ok { + sortedMeasuredValueTypes[measuredValue.ValueType] = make([]*types.MeasuredValue, 0) + } + sortedMeasuredValueTypes[measuredValue.ValueType] = append(sortedMeasuredValueTypes[measuredValue.ValueType], measuredValue) + } + + for measuredValueType, sortedMeasuredValues := range sortedMeasuredValueTypes { + switch measuredValueType { + case types.MeasuredValueTypeHumidity: + if err := p.insertHumidity(ctx, sortedMeasuredValues); err != nil { + return err + } + case types.MeasuredValueTypePressure: + if err := p.insertPressure(ctx, sortedMeasuredValues); err != nil { + return err + } + case types.MeasuredValueTypeTemperature: + if err := p.insertTemperature(ctx, sortedMeasuredValues); err != nil { + return err + } + } + } + + return nil +} + +func (p *Postgres) insertHumidity(ctx context.Context, measuredValues []*types.MeasuredValue) error { + + query := string(MustAsset("pkg/db/sql/psql/insertHumidity.sql")) + + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + defer stmt.Close() + + for _, measuredValue := range measuredValues { + + if measuredValue.ValueType != types.MeasuredValueTypeHumidity { + continue + } + + _, err := stmt.ExecContext(ctx, &measuredValue.ID, &measuredValue.Value, &measuredValue.FromDate, &measuredValue.TillDate, &measuredValue.SensorID, &measuredValue.CreationDate, &measuredValue.UpdateDate) + if err != nil { + return fmt.Errorf("%v: %v", errorStatementExecute, err) + } + } + return nil +} + +func (p *Postgres) insertPressure(ctx context.Context, measuredValues []*types.MeasuredValue) error { + + query := string(MustAsset("pkg/db/sql/psql/insertPressure.sql")) + + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + defer stmt.Close() + + for _, measuredValue := range measuredValues { + + if measuredValue.ValueType != types.MeasuredValueTypePressure { + continue + } + + _, err := stmt.ExecContext(ctx, &measuredValue.ID, &measuredValue.Value, &measuredValue.FromDate, &measuredValue.TillDate, &measuredValue.SensorID, &measuredValue.CreationDate, &measuredValue.UpdateDate) + if err != nil { + return fmt.Errorf("%v: %v", errorStatementExecute, err) + } + } + return nil +} + +func (p *Postgres) insertTemperature(ctx context.Context, measuredValues []*types.MeasuredValue) error { + + query := string(MustAsset("pkg/db/sql/psql/insertTemperature.sql")) + + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + defer stmt.Close() + + for _, measuredValue := range measuredValues { + + if measuredValue.ValueType != types.MeasuredValueTypeTemperature { + continue + } + + _, err := stmt.ExecContext(ctx, &measuredValue.ID, &measuredValue.Value, &measuredValue.FromDate, &measuredValue.TillDate, &measuredValue.SensorID, &measuredValue.CreationDate, &measuredValue.UpdateDate) + if err != nil { + return fmt.Errorf("%v: %v", errorStatementExecute, err) + } + } + return nil +} + +func (p *Postgres) InsertSensors(ctx context.Context, sensors []*types.Sensor) error { + + query := string(MustAsset("pkg/db/sql/psql/insertSensor.sql")) + + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + defer stmt.Close() + + for _, sensor := range sensors { + + _, err := stmt.ExecContext(ctx, &sensor.SensorID, &sensor.SensorName, &sensor.SensorLocation, &sensor.WireID, &sensor.I2CBus, &sensor.I2CAddress, &sensor.GPIONumber, &sensor.SensorModel, &sensor.SensorEnabled, &sensor.DeviceID, &sensor.CreationDate) + if err != nil { + return fmt.Errorf("%v: %v", errorStatementExecute, err) + } + } + return nil +} + +func (p *Postgres) SelectDeviceByID(ctx context.Context, id string) (*types.Device, error) { + query := string(MustAsset("pkg/db/sql/psql/selectDeviceByID.sql")) + + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return nil, fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + + row := stmt.QueryRowContext(ctx, id) + if row == nil { + return nil, errorRowNotFound + } + + device := new(types.Device) + err = row.Scan(&device.DeviceID, &device.DeviceName, &device.DeviceLocation, &device.CreationDate) + if err != nil { + return nil, fmt.Errorf("%v: %v", errorScanRow, err) + } + + return device, nil +} + +func (p *Postgres) SelectMeasuredValuesByIDAndType(ctx context.Context, id string, valueType types.MeasuredValueType) (*types.MeasuredValue, error) { + switch valueType { + case types.MeasuredValueTypeHumidity: + return p.SelectHumidityByID(ctx, id) + case types.MeasuredValueTypePressure: + return p.SelectPressureByID(ctx, id) + case types.MeasuredValueTypeTemperature: + return p.SelectTemperatureByID(ctx, id) + default: + return nil, fmt.Errorf("%v: %v", errorUnknownMeasuredValueType, valueType) + } +} + +func (p *Postgres) SelectHumidities(ctx context.Context) ([]*types.MeasuredValue, error) { + queryFile := "pkg/db/sql/psql/selectHumidities.sql" + measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypeHumidity, queryFile, nil) + if err != nil { + return nil, err + } + return measuredValues, nil +} + +func (p *Postgres) SelectHumidityByID(ctx context.Context, id string) (*types.MeasuredValue, error) { + queryFile := "pkg/db/sql/psql/selectHumidityByID.sql" + args := []interface{}{id} + measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypeHumidity, queryFile, args) + if err != nil { + return nil, err + } + + if len(measuredValues) == 0 { + return nil, fmt.Errorf("%v: %v", errorRowNotFound, id) + } + + return measuredValues[0], nil +} + +func (p *Postgres) SelectPressures(ctx context.Context) ([]*types.MeasuredValue, error) { + queryFile := "pkg/db/sql/psql/selectPressures.sql" + measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypePressure, queryFile, nil) + if err != nil { + return nil, err + } + return measuredValues, nil +} + +func (p *Postgres) SelectPressureByID(ctx context.Context, id string) (*types.MeasuredValue, error) { + queryFile := "pkg/db/sql/psql/selectPressureByID.sql" + args := []interface{}{id} + measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypePressure, queryFile, args) + if err != nil { + return nil, err + } + + if len(measuredValues) == 0 { + return nil, fmt.Errorf("%v: %v", errorRowNotFound, id) + } + + return measuredValues[0], nil +} + +func (p *Postgres) SelectSensorByID(ctx context.Context, id string) (*types.Sensor, error) { + query := string(MustAsset("pkg/db/sql/psql/selectSensorByID.sql")) + + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return nil, fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + + row := stmt.QueryRowContext(ctx, id) + if row == nil { + return nil, errorRowNotFound + } + + sensor := new(types.Sensor) + err = row.Scan(&sensor.SensorID, &sensor.SensorName, &sensor.SensorLocation, &sensor.WireID, &sensor.I2CBus, &sensor.I2CAddress, &sensor.GPIONumber, &sensor.SensorModel, &sensor.SensorEnabled, &sensor.DeviceID, &sensor.CreationDate) + if err != nil { + return nil, fmt.Errorf("%v: %v", errorScanRow, err) + } + + return sensor, nil +} + +func (p *Postgres) SelectTemperatures(ctx context.Context) ([]*types.MeasuredValue, error) { + queryFile := "pkg/db/sql/psql/selectTemperatures.sql" + measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypeTemperature, queryFile, nil) + if err != nil { + return nil, err + } + return measuredValues, nil +} + +func (p *Postgres) SelectTemperatureByID(ctx context.Context, id string) (*types.MeasuredValue, error) { + queryFile := "pkg/db/sql/psql/selectTemperatureByID.sql" + args := []interface{}{id} + measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypeTemperature, queryFile, args) + if err != nil { + return nil, err + } + + if len(measuredValues) == 0 { + return nil, fmt.Errorf("%v: %v", errorRowNotFound, id) + } + + return measuredValues[0], nil +} + +func (p *Postgres) selectMeasuredValues(ctx context.Context, measuredValueType types.MeasuredValueType, queryFile string, queryArgs []interface{}) ([]*types.MeasuredValue, error) { + query := string(MustAsset(queryFile)) + + stmt, err := p.dbo.PrepareContext(ctx, query) + if err != nil { + return nil, fmt.Errorf("%v: %v", errorPrepareStatement, err) + } + + rows, err := stmt.QueryContext(ctx, queryArgs...) + if err != nil { + return nil, fmt.Errorf("%v: %v", errorStatementQuery, err) + } + + measuredValues := make([]*types.MeasuredValue, 0) + for rows.Next() { + measuredValue := new(types.MeasuredValue) + measuredValue.ValueType = measuredValueType + rows.Scan(&measuredValue.ID, &measuredValue.Value, &measuredValue.FromDate, &measuredValue.TillDate, &measuredValue.SensorID, &measuredValue.CreationDate, &measuredValue.UpdateDate) + measuredValues = append(measuredValues, measuredValue) + } + + return measuredValues, nil +} + +func (p *Postgres) UpdateDevices(ctx context.Context, devices []*types.Device) error { + return nil +} + +func (p *Postgres) UpdateMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error { + return nil +} + +func (p *Postgres) UpdateSensors(ctx context.Context, sensots []*types.Sensor) error { + return nil +} diff --git a/pkg/db/postgres_test.go b/pkg/db/postgres_test.go new file mode 100644 index 0000000..cfb3a74 --- /dev/null +++ b/pkg/db/postgres_test.go @@ -0,0 +1,273 @@ +package db_test + +import ( + "context" + "testing" + + "github.com/go-flucky/flucky/pkg/db" + "github.com/go-flucky/flucky/pkg/types" + "github.com/go-flucky/flucky/test/goldenfiles" + "github.com/stretchr/testify/require" +) + +type test struct { + Name string + Test func(*testing.T) +} + +var ( + database db.Database + + postgresContainerImage string = "docker.io/postgres/postgres" + postgresHost string = "localhost" + postgresPort string = "5432" + postgresUser string = "postgres" + postgresPassword string = "postgres" + postgresDatabase string = "postgres" + + goldenDevicesFilePath string = "test/goldenfiles/json/goldenDevices.json" + goldenSensorsFilePath string = "test/goldenfiles/json/goldenSensors.json" + goldenMeasuredValuesFilePath string = "test/goldenfiles/json/goldenMeasuredValues.json" + goldenPressuresFilePath string = "test/goldenfiles/json/goldenPressures.json" + goldenHumiditiesFilePath string = "test/goldenfiles/json/goldenHumidities.json" + goldenTemperaturesFilePath string = "test/goldenfiles/json/goldenTemperatures.json" + + goldenDevices []*types.Device + goldenSensors []*types.Sensor + goldenMeasuredValues []*types.MeasuredValue + goldenPressures []*types.MeasuredValue + goldenHumidites []*types.MeasuredValue + goldenTemperatures []*types.MeasuredValue +) + +func load(t *testing.T) { + require := require.New(t) + + d, err := goldenfiles.GetGoldenDevices(goldenDevicesFilePath) + require.NoError(err) + goldenDevices = d + + s, err := goldenfiles.GetGoldenSensors(goldenSensorsFilePath) + require.NoError(err) + goldenSensors = s + + hum, err := goldenfiles.GetGoldenMeasuredValues(goldenHumiditiesFilePath) + require.NoError(err) + goldenHumidites = hum + + mv, err := goldenfiles.GetGoldenMeasuredValues(goldenMeasuredValuesFilePath) + require.NoError(err) + goldenMeasuredValues = mv + + pres, err := goldenfiles.GetGoldenMeasuredValues(goldenPressuresFilePath) + require.NoError(err) + goldenPressures = pres + + temp, err := goldenfiles.GetGoldenMeasuredValues(goldenTemperaturesFilePath) + require.NoError(err) + goldenTemperatures = temp + +} + +func TestPostgres(t *testing.T) { + require := require.New(t) + + load(t) + + db, err := db.New(db.DBOTypePostgres, postgresHost, postgresPort, postgresDatabase, postgresUser, postgresPassword) + database = db + require.Nil(err) + + tests := []*test{ + &test{ + Name: "insertDevices", + Test: testInsertDevices, + }, + &test{ + Name: "insertSensors", + Test: testInsertSensors, + }, + &test{ + Name: "insertHumidity", + Test: testInsertHumidity, + }, + &test{ + Name: "insertPressure", + Test: testInsertPressure, + }, + &test{ + Name: "insertTemperatures", + Test: testInsertTemperatures, + }, + &test{ + Name: "deleteHumidities", + Test: testDeleteHumidity, + }, + &test{ + Name: "deletePressures", + Test: testDeletePressures, + }, + &test{ + Name: "deleteTemperatures", + Test: testDeleteTemperatures, + }, + &test{ + Name: "insertMeasuredValues", + Test: testInsertMeasuredValues, + }, + &test{ + Name: "deleteMeasuredValues", + Test: testDeleteMeasuredValues, + }, + &test{ + Name: "deleteSensors", + Test: testDeleteSensors, + }, + &test{ + Name: "deleteDevices", + Test: testDeleteDevices, + }, + } + + for _, test := range tests { + t.Run(test.Name, test.Test) + } +} + +func testInsertDevices(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.InsertDevices(ctx, goldenDevices) + require.NoError(err) + for _, goldenDevice := range goldenDevices { + testDevice, err := database.SelectDeviceByID(ctx, goldenDevice.DeviceID) + require.NoError(err) + goldenfiles.CompareMeasuredValues(t, goldenDevice, testDevice) + } +} + +func testInsertSensors(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.InsertSensors(ctx, goldenSensors) + require.NoError(err) + for _, goldenSensor := range goldenSensors { + testSensor, err := database.SelectSensorByID(ctx, goldenSensor.SensorID) + require.NoError(err) + goldenfiles.CompareMeasuredValues(t, goldenSensor, testSensor) + } +} + +func testInsertHumidity(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.InsertMeasuredValues(ctx, goldenHumidites) + require.NoError(err) + for _, goldenHumidity := range goldenHumidites { + testHumidity, err := database.SelectHumidityByID(ctx, goldenHumidity.ID) + require.NoError(err) + goldenfiles.CompareMeasuredValues(t, []*types.MeasuredValue{testHumidity}, []*types.MeasuredValue{testHumidity}) + } +} + +func testInsertMeasuredValues(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.InsertMeasuredValues(ctx, goldenMeasuredValues) + require.NoError(err) + for _, goldenMeasuredValue := range goldenMeasuredValues { + testMeasuredValue, err := database.SelectMeasuredValuesByIDAndType(ctx, goldenMeasuredValue.ID, goldenMeasuredValue.ValueType) + require.NoError(err) + goldenfiles.CompareMeasuredValues(t, []*types.MeasuredValue{goldenMeasuredValue}, []*types.MeasuredValue{testMeasuredValue}) + } +} + +func testInsertPressure(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.InsertMeasuredValues(ctx, goldenPressures) + require.NoError(err) + for _, goldenPressure := range goldenPressures { + testPressure, err := database.SelectPressureByID(ctx, goldenPressure.ID) + require.NoError(err) + goldenfiles.CompareMeasuredValues(t, []*types.MeasuredValue{testPressure}, []*types.MeasuredValue{testPressure}) + } +} + +func testInsertTemperatures(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.InsertMeasuredValues(ctx, goldenTemperatures) + require.NoError(err) + for _, goldenTemperature := range goldenTemperatures { + testTemperature, err := database.SelectTemperatureByID(ctx, goldenTemperature.ID) + require.NoError(err) + goldenfiles.CompareMeasuredValues(t, []*types.MeasuredValue{goldenTemperature}, []*types.MeasuredValue{testTemperature}) + } +} + +func testDeleteDevices(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.DeleteDevices(ctx, goldenDevices) + require.NoError(err) + for _, goldenDevice := range goldenDevices { + _, err := database.SelectDeviceByID(ctx, goldenDevice.DeviceID) + require.Error(err) + } +} + +func testDeleteSensors(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.DeleteSensors(ctx, goldenSensors) + require.NoError(err) + for _, goldenSensor := range goldenSensors { + _, err := database.SelectDeviceByID(ctx, goldenSensor.SensorID) + require.Error(err) + } +} + +func testDeleteHumidity(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.DeleteMeasuredValues(ctx, goldenHumidites) + require.NoError(err) + for _, goldenHumidity := range goldenHumidites { + _, err := database.SelectHumidityByID(ctx, goldenHumidity.ID) + require.Error(err) + } +} + +func testDeleteMeasuredValues(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.DeleteMeasuredValues(ctx, goldenMeasuredValues) + require.NoError(err) + for _, goldenMeasuredValue := range goldenMeasuredValues { + _, err := database.SelectPressureByID(ctx, goldenMeasuredValue.ID) + require.Error(err) + } +} + +func testDeletePressures(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.DeleteMeasuredValues(ctx, goldenPressures) + require.NoError(err) + for _, goldenPressure := range goldenPressures { + _, err := database.SelectPressureByID(ctx, goldenPressure.ID) + require.Error(err) + } +} + +func testDeleteTemperatures(t *testing.T) { + require := require.New(t) + ctx := context.Background() + err := database.DeleteMeasuredValues(ctx, goldenTemperatures) + require.NoError(err) + for _, goldenTemperature := range goldenTemperatures { + _, err := database.SelectTemperatureByID(ctx, goldenTemperature.ID) + require.Error(err) + } +} diff --git a/pkg/db/sql/psql/deleteDevice.sql b/pkg/db/sql/psql/deleteDevice.sql new file mode 100644 index 0000000..5d75ead --- /dev/null +++ b/pkg/db/sql/psql/deleteDevice.sql @@ -0,0 +1,2 @@ +DELETE FROM devices +WHERE device_id = $1; \ No newline at end of file diff --git a/pkg/db/sql/psql/deleteHumidity.sql b/pkg/db/sql/psql/deleteHumidity.sql new file mode 100644 index 0000000..9eec66e --- /dev/null +++ b/pkg/db/sql/psql/deleteHumidity.sql @@ -0,0 +1,2 @@ +DELETE FROM humidities +WHERE humidity_id = $1; \ No newline at end of file diff --git a/pkg/db/sql/psql/deletePressure.sql b/pkg/db/sql/psql/deletePressure.sql new file mode 100644 index 0000000..62723d2 --- /dev/null +++ b/pkg/db/sql/psql/deletePressure.sql @@ -0,0 +1,2 @@ +DELETE FROM pressures +WHERE pressure_id = $1; \ No newline at end of file diff --git a/pkg/db/sql/psql/deleteSensor.sql b/pkg/db/sql/psql/deleteSensor.sql new file mode 100644 index 0000000..dba0c3f --- /dev/null +++ b/pkg/db/sql/psql/deleteSensor.sql @@ -0,0 +1,2 @@ +DELETE FROM sensors +WHERE sensor_id = $1; \ No newline at end of file diff --git a/pkg/db/sql/psql/deleteTemperature.sql b/pkg/db/sql/psql/deleteTemperature.sql new file mode 100644 index 0000000..1d8ebf8 --- /dev/null +++ b/pkg/db/sql/psql/deleteTemperature.sql @@ -0,0 +1,2 @@ +DELETE FROM temperatures +WHERE temperature_id = $1; \ No newline at end of file diff --git a/pkg/db/sql/psql/insertDevice.sql b/pkg/db/sql/psql/insertDevice.sql new file mode 100644 index 0000000..d197f24 --- /dev/null +++ b/pkg/db/sql/psql/insertDevice.sql @@ -0,0 +1,7 @@ +INSERT INTO devices ( + device_id, + device_name, + device_location, + creation_date +) +VALUES ($1, $2, $3, $4); \ No newline at end of file diff --git a/pkg/db/sql/psql/insertHumidity.sql b/pkg/db/sql/psql/insertHumidity.sql new file mode 100644 index 0000000..e7a7041 --- /dev/null +++ b/pkg/db/sql/psql/insertHumidity.sql @@ -0,0 +1,10 @@ +INSERT INTO humidities ( + humidity_id, + humidity_value, + humidity_from_date, + humidity_till_date, + sensor_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6, $7); \ No newline at end of file diff --git a/pkg/db/sql/psql/insertPressure.sql b/pkg/db/sql/psql/insertPressure.sql new file mode 100644 index 0000000..8add4b5 --- /dev/null +++ b/pkg/db/sql/psql/insertPressure.sql @@ -0,0 +1,10 @@ +INSERT INTO pressures ( + pressure_id, + pressure_value, + pressure_from_date, + pressure_till_date, + sensor_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6, $7); \ No newline at end of file diff --git a/pkg/db/sql/psql/insertSensor.sql b/pkg/db/sql/psql/insertSensor.sql new file mode 100644 index 0000000..25078e8 --- /dev/null +++ b/pkg/db/sql/psql/insertSensor.sql @@ -0,0 +1,14 @@ +INSERT INTO sensors ( + sensor_id, + sensor_name, + sensor_location, + wire_id, + i2c_bus, + i2c_address, + gpio_number, + sensor_model, + sensor_enabled, + device_id, + creation_date +) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11); diff --git a/pkg/db/sql/psql/insertTemperature.sql b/pkg/db/sql/psql/insertTemperature.sql new file mode 100644 index 0000000..520555a --- /dev/null +++ b/pkg/db/sql/psql/insertTemperature.sql @@ -0,0 +1,10 @@ +INSERT INTO temperatures ( + temperature_id, + temperature_value, + temperature_from_date, + temperature_till_date, + sensor_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6, $7); \ No newline at end of file diff --git a/pkg/db/sql/psql/schema.sql b/pkg/db/sql/psql/schema.sql new file mode 100644 index 0000000..3f13721 --- /dev/null +++ b/pkg/db/sql/psql/schema.sql @@ -0,0 +1,146 @@ +DROP TABLE IF EXISTS devices CASCADE; +DROP TABLE IF EXISTS sensors CASCADE; +DROP TABLE IF EXISTS humidities CASCADE; +DROP TABLE IF EXISTS pressures CASCADE; +DROP TABLE IF EXISTS temperatures CASCADE; + + +-- +----------------------------------------+ +-- | TABLES | +-- +----------------------------------------+ +CREATE TABLE IF NOT EXISTS devices( + device_id CHAR(36) CONSTRAINT pk_devices PRIMARY KEY, + device_name VARCHAR(32) NOT NULL, + device_location VARCHAR(32), + device_last_contact TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, + creation_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE IF NOT EXISTS sensors ( + sensor_id CHAR(36) CONSTRAINT pk_sensors PRIMARY KEY, + sensor_name VARCHAR(32) NOT NULL, + sensor_location VARCHAR(32) NOT NULL, + wire_id VARCHAR(15), + i2c_bus VARCHAR(255), + i2c_address VARCHAR(12), + gpio_number VARCHAR(6), + sensor_model VARCHAR(16) NOT NULL, + sensor_enabled BOOLEAN DEFAULT TRUE NOT NULL, + sensor_last_contact TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, + device_id CHAR(36), + creation_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL +); + +CREATE TABLE IF NOT EXISTS humidities ( + humidity_id CHAR(36) CONSTRAINT pk_humidities PRIMARY KEY, + humidity_value NUMERIC(9,3) NOT NULL, + humidity_from_date TIMESTAMP WITH TIME ZONE NOT NULL, + humidity_till_date TIMESTAMP WITH TIME ZONE, + sensor_id CHAR(36), + creation_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, + update_date TIMESTAMP WITH TIME ZONE +); + +CREATE TABLE IF NOT EXISTS pressures ( + pressure_id CHAR(36) CONSTRAINT pk_pressures PRIMARY KEY, + pressure_value NUMERIC(10,3) NOT NULL, + pressure_from_date TIMESTAMP WITH TIME ZONE NOT NULL, + pressure_till_date TIMESTAMP WITH TIME ZONE, + sensor_id CHAR(36), + creation_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, + update_date TIMESTAMP WITH TIME ZONE +); + +CREATE TABLE IF NOT EXISTS temperatures ( + temperature_id CHAR(36) CONSTRAINT pk_temperatures PRIMARY KEY, + temperature_value NUMERIC(5,3) NOT NULL, + temperature_from_date TIMESTAMP WITH TIME ZONE NOT NULL, + temperature_till_date TIMESTAMP WITH TIME ZONE, + sensor_id CHAR(36), + creation_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, + update_date TIMESTAMP WITH TIME ZONE +); + +-- +----------------------------------------+ +-- | FOREIGN-KEYS | +-- +----------------------------------------+ +ALTER TABLE sensors +ADD FOREIGN KEY (device_id) +REFERENCES devices(device_id) +ON DELETE CASCADE +ON UPDATE CASCADE; + +ALTER TABLE humidities +ADD FOREIGN KEY (sensor_id) +REFERENCES sensors(sensor_id) +ON DELETE CASCADE +ON UPDATE CASCADE; + +ALTER TABLE pressures +ADD FOREIGN KEY (sensor_id) +REFERENCES sensors(sensor_id) +ON DELETE CASCADE +ON UPDATE CASCADE; + +ALTER TABLE temperatures +ADD FOREIGN KEY (sensor_id) +REFERENCES sensors(sensor_id) +ON DELETE CASCADE +ON UPDATE CASCADE; + +-- +----------------------------------------+ +-- | Trigger-Functions | +-- +----------------------------------------+ +CREATE OR REPLACE FUNCTION device_last_contact() + RETURNS trigger AS +$BODY$ +BEGIN + UPDATE devices + SET device_last_contact = CURRENT_TIMESTAMP + WHERE device_id = NEW.device_id; + RETURN NEW; +END; +$BODY$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION sensor_last_contact() + RETURNS trigger AS +$BODY$ +BEGIN + UPDATE sensors + SET sensor_last_contact = CURRENT_TIMESTAMP, + sensor_enabled = true + WHERE sensor_id = NEW.sensor_id; + RETURN NEW; +END; +$BODY$ LANGUAGE plpgsql; + +-- +----------------------------------------+ +-- | Trigger | +-- +----------------------------------------+ +DROP TRIGGER IF EXISTS ai_humidities ON humidities; +DROP TRIGGER IF EXISTS ai_pressure ON pressures; +DROP TRIGGER IF EXISTS ai_temperatures ON temperatures; + +CREATE TRIGGER au_sensors + AFTER UPDATE + ON sensors + FOR EACH ROW + EXECUTE PROCEDURE device_last_contact(); + +CREATE TRIGGER ai_humidities + AFTER INSERT + ON humidities + FOR EACH ROW + EXECUTE PROCEDURE sensor_last_contact(); + +CREATE TRIGGER ai_pressures + AFTER INSERT + ON pressures + FOR EACH ROW + EXECUTE PROCEDURE sensor_last_contact(); + +CREATE TRIGGER ai_temperatures + AFTER INSERT + ON temperatures + FOR EACH ROW + EXECUTE PROCEDURE sensor_last_contact(); \ No newline at end of file diff --git a/pkg/db/sql/psql/selectDeviceByID.sql b/pkg/db/sql/psql/selectDeviceByID.sql new file mode 100644 index 0000000..a56b927 --- /dev/null +++ b/pkg/db/sql/psql/selectDeviceByID.sql @@ -0,0 +1,8 @@ +SELECT + device_id, + device_name, + device_location, + creation_date +FROM + devices +WHERE device_id = $1; \ No newline at end of file diff --git a/pkg/db/sql/psql/selectHumidities.sql b/pkg/db/sql/psql/selectHumidities.sql new file mode 100644 index 0000000..5342200 --- /dev/null +++ b/pkg/db/sql/psql/selectHumidities.sql @@ -0,0 +1,10 @@ +SELECT + humidity_id, + humidity_value, + humidity_from_date, + humidity_till_date, + sensor_id, + creation_date, + update_date +FROM + humidities; \ No newline at end of file diff --git a/pkg/db/sql/psql/selectHumidityByID.sql b/pkg/db/sql/psql/selectHumidityByID.sql new file mode 100644 index 0000000..1b719d4 --- /dev/null +++ b/pkg/db/sql/psql/selectHumidityByID.sql @@ -0,0 +1,12 @@ +SELECT + humidity_id, + humidity_value, + humidity_from_date, + humidity_till_date, + sensor_id, + creation_date, + update_date +FROM + humidities +WHERE + humidity_id = $1; \ No newline at end of file diff --git a/pkg/db/sql/psql/selectPressureByID.sql b/pkg/db/sql/psql/selectPressureByID.sql new file mode 100644 index 0000000..62d652d --- /dev/null +++ b/pkg/db/sql/psql/selectPressureByID.sql @@ -0,0 +1,12 @@ +SELECT + pressure_id, + pressure_value, + pressure_from_date, + pressure_till_date, + sensor_id, + creation_date, + update_date +FROM + pressures +WHERE + pressure_id = $1; \ No newline at end of file diff --git a/pkg/db/sql/psql/selectPressures.sql b/pkg/db/sql/psql/selectPressures.sql new file mode 100644 index 0000000..9ed957e --- /dev/null +++ b/pkg/db/sql/psql/selectPressures.sql @@ -0,0 +1,10 @@ +SELECT + pressure_id, + pressure_value, + pressure_from_date, + pressure_till_date, + sensor_id, + creation_date, + update_date +FROM + pressures; \ No newline at end of file diff --git a/pkg/db/sql/psql/selectSensorByID.sql b/pkg/db/sql/psql/selectSensorByID.sql new file mode 100644 index 0000000..0d6f164 --- /dev/null +++ b/pkg/db/sql/psql/selectSensorByID.sql @@ -0,0 +1,16 @@ +SELECT + sensor_id, + sensor_name, + sensor_location, + wire_id, + i2c_bus, + i2c_address, + gpio_number, + sensor_model, + sensor_enabled, + device_id, + creation_date +FROM + sensors +WHERE + sensor_id = $1; \ No newline at end of file diff --git a/pkg/db/sql/psql/selectTemperatureByID.sql b/pkg/db/sql/psql/selectTemperatureByID.sql new file mode 100644 index 0000000..9e7be50 --- /dev/null +++ b/pkg/db/sql/psql/selectTemperatureByID.sql @@ -0,0 +1,12 @@ +SELECT + temperature_id, + temperature_value, + temperature_from_date, + temperature_till_date, + sensor_id, + creation_date, + update_date +FROM + temperatures +WHERE + temperature_id = $1; \ No newline at end of file diff --git a/pkg/db/sql/psql/selectTemperatures.sql b/pkg/db/sql/psql/selectTemperatures.sql new file mode 100644 index 0000000..8a4c3dd --- /dev/null +++ b/pkg/db/sql/psql/selectTemperatures.sql @@ -0,0 +1,10 @@ +SELECT + temperature_id, + temperature_value, + temperature_from_date, + temperature_till_date, + sensor_id, + creation_date, + update_date +FROM + temperatures; \ No newline at end of file diff --git a/pkg/internal/format/format.go b/pkg/internal/format/format.go new file mode 100644 index 0000000..7bcda39 --- /dev/null +++ b/pkg/internal/format/format.go @@ -0,0 +1,23 @@ +package format + +import ( + "errors" + "math" + "time" +) + +var ( + errorPraseTime = errors.New("Can not parse time") + + TimeFormat = "2006-01-02T15:04:05.999999Z07:00" +) + +// FormatedTime returns a current timestamp without nano seconds. Postgres +// currently does not support nanoseconds which is automatically include into +// the go time object +func FormatedTime() time.Time { + t := time.Now() + l, _ := time.LoadLocation("Europe/Berlin") + return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), int(math.Round(float64(t.Nanosecond())/1000000)*1000000), l) + +} diff --git a/pkg/logfile/csv.go b/pkg/logfile/csv.go index ebcd631..de4eaed 100644 --- a/pkg/logfile/csv.go +++ b/pkg/logfile/csv.go @@ -7,6 +7,7 @@ import ( "strconv" "time" + "github.com/go-flucky/flucky/pkg/internal/format" "github.com/go-flucky/flucky/pkg/types" ) @@ -50,7 +51,7 @@ func (cl *csvLogfile) Read() ([]*types.MeasuredValue, error) { // Times times := make([]time.Time, 0) for _, i := range []int{3, 4} { - time, err := time.Parse(timeFormat, record[i]) + time, err := time.Parse(format.TimeFormat, record[i]) if err != nil { return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[i], err) } @@ -67,14 +68,14 @@ func (cl *csvLogfile) Read() ([]*types.MeasuredValue, error) { } // Creation date - creationDate, err := time.Parse(timeFormat, record[6]) + creationDate, err := time.Parse(format.TimeFormat, record[6]) if err != nil { return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[6], err) } - measuredValue.CreationDate = &creationDate + measuredValue.CreationDate = creationDate if record[7] != "null" { - updateDate, err := time.Parse(timeFormat, record[7]) + updateDate, err := time.Parse(format.TimeFormat, record[7]) if err != nil { return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[7], err) } @@ -106,19 +107,15 @@ func (cl *csvLogfile) Write(measuredValues []*types.MeasuredValue) error { measuredValue.ID, fmt.Sprintf("%v", measuredValue.ValueType), fmt.Sprintf("%v", measuredValue.Value), - measuredValue.FromDate.Format(timeFormat), - measuredValue.TillDate.Format(timeFormat), + measuredValue.FromDate.Format(format.TimeFormat), + measuredValue.TillDate.Format(format.TimeFormat), measuredValue.SensorID, } - if measuredValue.CreationDate != nil { - record = append(record, measuredValue.CreationDate.Format(timeFormat)) - } else { - record = append(record, "null") - } + record = append(record, measuredValue.CreationDate.Format(format.TimeFormat)) if measuredValue.UpdateDate != nil { - record = append(record, measuredValue.UpdateDate.Format(timeFormat)) + record = append(record, measuredValue.UpdateDate.Format(format.TimeFormat)) } else { record = append(record, "null") } diff --git a/pkg/logfile/errors.go b/pkg/logfile/errors.go index e2993a7..2a078ca 100644 --- a/pkg/logfile/errors.go +++ b/pkg/logfile/errors.go @@ -2,25 +2,27 @@ package logfile import "errors" -var errorLogfileCreate = errors.New("Can not create logfile") -var errorLogfileDecode = errors.New("Can not decode from reader") -var errorLogfileEncode = errors.New("Can not encode from writer") -var errorLogfileMarshal = errors.New("Can not marshal values") -var errorLogfileNotFound = errors.New("Can not find logfile") -var errorLogfileOpen = errors.New("Can not open logfile") -var errorLogfileRead = errors.New("Can not read from given reader") -var errorLogfileUnmarshal = errors.New("Can not unmarshal values") -var errorLogfileWrite = errors.New("Can not write with given writer") +var ( + errorLogfileCreate = errors.New("Can not create logfile") + errorLogfileDecode = errors.New("Can not decode from reader") + errorLogfileEncode = errors.New("Can not encode from writer") + errorLogfileMarshal = errors.New("Can not marshal values") + errorLogfileNotFound = errors.New("Can not find logfile") + errorLogfileOpen = errors.New("Can not open logfile") + errorLogfileRead = errors.New("Can not read from given reader") + errorLogfileUnmarshal = errors.New("Can not unmarshal values") + errorLogfileWrite = errors.New("Can not write with given writer") -var errorParseFloat = errors.New("Can not parse float") -var errorParseMeasurementUnit = errors.New("Can not parse mesaurement unit") -var errorParseTime = errors.New("Can not parse time") + errorParseFloat = errors.New("Can not parse float") + errorParseMeasurementUnit = errors.New("Can not parse mesaurement unit") + errorParseTime = errors.New("Can not parse time") -var errorNoValidHumidityID = errors.New("No valid humidity id detected or available") -var errorNoValidMesuredValue = errors.New("No mesured value detected or available") -var errorNoValidSensorID = errors.New("No sensor id detected or available") -var errorNoValidTemperatureID = errors.New("No valid temperature id detected or available") -var errorNoValidTime = errors.New("No time detected or available") -var errorNoValidTimePeriods = errors.New("No valid time periods") + errorNoValidHumidityID = errors.New("No valid humidity id detected or available") + errorNoValidMesuredValue = errors.New("No mesured value detected or available") + errorNoValidSensorID = errors.New("No sensor id detected or available") + errorNoValidTemperatureID = errors.New("No valid temperature id detected or available") + errorNoValidTime = errors.New("No time detected or available") + errorNoValidTimePeriods = errors.New("No valid time periods") -var errorTypeSwitch = errors.New("Can not detect type via type switch") + errorTypeSwitch = errors.New("Can not detect type via type switch") +) diff --git a/pkg/logfile/logfile.go b/pkg/logfile/logfile.go index 6cba3fb..1a099b7 100644 --- a/pkg/logfile/logfile.go +++ b/pkg/logfile/logfile.go @@ -4,13 +4,12 @@ import ( "math" "path/filepath" "sort" - "time" + "github.com/go-flucky/flucky/pkg/internal/format" "github.com/go-flucky/flucky/pkg/types" ) // var validUUID = regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$") -var timeFormat = "2006-01-02T15:04:05.999999Z07:00" // Append adds an array of several measured values to a logfile func Append(logfile Logfile, compression bool, round float64, measuredValues []*types.MeasuredValue) error { @@ -56,7 +55,7 @@ func Compression(measuredValues []*types.MeasuredValue) []*types.MeasuredValue { return measuredValues[i].FromDate.Before(measuredValues[j].TillDate) }) - now := time.Now() + now := format.FormatedTime() for _, measuredValue := range measuredValues { if _, ok := lastMeasuredValuesBySensors[measuredValue.SensorID]; !ok { @@ -124,11 +123,10 @@ func New(logfile string) Logfile { } -func writeCreationDate(measuredValues []*types.MeasuredValue) { - now := time.Now() +func writeCreationDate(measuredValues []*types.MeasuredValue) error { for _, measuredValue := range measuredValues { - if measuredValue.CreationDate == nil { - measuredValue.CreationDate = &now - } + now := format.FormatedTime() + measuredValue.CreationDate = now } + return nil } diff --git a/pkg/sensor/bme280.go b/pkg/sensor/bme280.go index 19d9fd1..938244b 100644 --- a/pkg/sensor/bme280.go +++ b/pkg/sensor/bme280.go @@ -5,11 +5,11 @@ import ( "fmt" "log" "sync" - "time" "github.com/d2r2/go-bsbmp" "github.com/d2r2/go-i2c" "github.com/d2r2/go-logger" + "github.com/go-flucky/flucky/pkg/internal/format" "github.com/go-flucky/flucky/pkg/types" uuid "github.com/satori/go.uuid" ) @@ -67,24 +67,24 @@ func (s *BME280) Read() ([]*types.MeasuredValue, error) { ID: uuid.NewV4().String(), Value: float64(humidityValue), ValueType: types.MeasuredValueTypeHumidity, - FromDate: time.Now(), - TillDate: time.Now(), + FromDate: format.FormatedTime(), + TillDate: format.FormatedTime(), SensorID: s.SensorID, }, &types.MeasuredValue{ ID: uuid.NewV4().String(), Value: float64(pressureValue), ValueType: types.MeasuredValueTypePressure, - FromDate: time.Now(), - TillDate: time.Now(), + FromDate: format.FormatedTime(), + TillDate: format.FormatedTime(), SensorID: s.SensorID, }, &types.MeasuredValue{ ID: uuid.NewV4().String(), Value: float64(temperatureValue), ValueType: types.MeasuredValueTypeTemperature, - FromDate: time.Now(), - TillDate: time.Now(), + FromDate: format.FormatedTime(), + TillDate: format.FormatedTime(), SensorID: s.SensorID, }, } diff --git a/pkg/sensor/dht11.go b/pkg/sensor/dht11.go index cf8b5a7..cf02196 100644 --- a/pkg/sensor/dht11.go +++ b/pkg/sensor/dht11.go @@ -4,8 +4,8 @@ import ( "context" "fmt" "sync" - "time" + "github.com/go-flucky/flucky/pkg/internal/format" "github.com/go-flucky/flucky/pkg/types" "github.com/go-flucky/go-dht" uuid "github.com/satori/go.uuid" @@ -49,16 +49,16 @@ func (s *DHT11) Read() ([]*types.MeasuredValue, error) { ID: uuid.NewV4().String(), Value: float64(humidityValue), ValueType: types.MeasuredValueTypeHumidity, - FromDate: time.Now(), - TillDate: time.Now(), + FromDate: format.FormatedTime(), + TillDate: format.FormatedTime(), SensorID: s.SensorID, }, &types.MeasuredValue{ ID: uuid.NewV4().String(), Value: float64(temperatureValue), ValueType: types.MeasuredValueTypeTemperature, - FromDate: time.Now(), - TillDate: time.Now(), + FromDate: format.FormatedTime(), + TillDate: format.FormatedTime(), SensorID: s.SensorID, }, } diff --git a/pkg/sensor/dht22.go b/pkg/sensor/dht22.go index 91cb422..ad45482 100644 --- a/pkg/sensor/dht22.go +++ b/pkg/sensor/dht22.go @@ -4,8 +4,8 @@ import ( "context" "fmt" "sync" - "time" + "github.com/go-flucky/flucky/pkg/internal/format" "github.com/go-flucky/flucky/pkg/types" "github.com/go-flucky/go-dht" uuid "github.com/satori/go.uuid" @@ -49,16 +49,16 @@ func (s *DHT22) Read() ([]*types.MeasuredValue, error) { ID: uuid.NewV4().String(), Value: float64(humidityValue), ValueType: types.MeasuredValueTypeHumidity, - FromDate: time.Now(), - TillDate: time.Now(), + FromDate: format.FormatedTime(), + TillDate: format.FormatedTime(), SensorID: s.SensorID, }, &types.MeasuredValue{ ID: uuid.NewV4().String(), Value: float64(temperatureValue), ValueType: types.MeasuredValueTypeTemperature, - FromDate: time.Now(), - TillDate: time.Now(), + FromDate: format.FormatedTime(), + TillDate: format.FormatedTime(), SensorID: s.SensorID, }, } diff --git a/pkg/sensor/ds18b20.go b/pkg/sensor/ds18b20.go index 589f62c..f18f220 100644 --- a/pkg/sensor/ds18b20.go +++ b/pkg/sensor/ds18b20.go @@ -8,8 +8,8 @@ import ( "strconv" "strings" "sync" - "time" + "github.com/go-flucky/flucky/pkg/internal/format" "github.com/go-flucky/flucky/pkg/types" uuid "github.com/satori/go.uuid" ) @@ -55,8 +55,8 @@ func (s *DS18B20) Read() ([]*types.MeasuredValue, error) { ID: uuid.NewV4().String(), Value: float64(temperatureValue), ValueType: types.MeasuredValueTypeTemperature, - FromDate: time.Now(), - TillDate: time.Now(), + FromDate: format.FormatedTime(), + TillDate: format.FormatedTime(), SensorID: s.SensorID, }, } diff --git a/pkg/types/device.go b/pkg/types/device.go index 37fe16c..83cd812 100644 --- a/pkg/types/device.go +++ b/pkg/types/device.go @@ -4,10 +4,10 @@ import "time" // Device ... type Device struct { - DeviceID string `json:"device_id" xml:"device_id"` - DeviceName string `json:"device_name" xml:"device_name"` - DeviceLocation *string `json:"device_location" xml:"device_location"` - DeviceLastContact time.Time `json:"device_last_contact" xml:"device_last_contact"` - Logfile string `json:"logfile" xml:"logfile"` - CreationDate time.Time `json:"creation_date" xml:"creation_date"` + DeviceID string `json:"device_id" xml:"device_id"` + DeviceName string `json:"device_name" xml:"device_name"` + DeviceLocation *string `json:"device_location" xml:"device_location"` + DeviceLastContact *time.Time `json:"device_last_contact" xml:"device_last_contact"` + Logfile string `json:"logfile" xml:"logfile"` + CreationDate time.Time `json:"creation_date" xml:"creation_date"` } diff --git a/pkg/types/measuredValue.go b/pkg/types/measuredValue.go index 5bccdc8..c5a179c 100644 --- a/pkg/types/measuredValue.go +++ b/pkg/types/measuredValue.go @@ -12,7 +12,7 @@ type MeasuredValue struct { FromDate time.Time `json:"from_date" xml:"from_date"` TillDate time.Time `json:"till_date" xml:"till_date"` SensorID string `json:"sensor_id" xml:"sensor_id"` - CreationDate *time.Time `json:"creation_date" xml:"creation_date"` + CreationDate time.Time `json:"creation_date" xml:"creation_date"` UpdateDate *time.Time `json:"update_date" xml:"update_date"` } diff --git a/pkg/types/sensor.go b/pkg/types/sensor.go index c741ea3..0245979 100644 --- a/pkg/types/sensor.go +++ b/pkg/types/sensor.go @@ -18,7 +18,7 @@ type Sensor struct { GPIONumber *GPIO `json:"gpio_number" xml:"gpio_number"` SensorModel SensorModel `json:"sensor_model" xml:"sensor_model"` SensorEnabled bool `json:"sensor_enabled" xml:"sensor_enabled"` - SensorLastContact time.Time `json:"sensor_last_contact" xml:"sensor_last_contact"` + SensorLastContact *time.Time `json:"sensor_last_contact" xml:"sensor_last_contact"` DeviceID string `json:"device_id" xml:"device_id"` CreationDate time.Time `json:"creation_date" xml:"creation_date"` } diff --git a/test/goldenfiles/goldenfiles.go b/test/goldenfiles/goldenfiles.go new file mode 100644 index 0000000..9ead369 --- /dev/null +++ b/test/goldenfiles/goldenfiles.go @@ -0,0 +1,69 @@ +package goldenfiles + +import ( + "bytes" + "encoding/json" + "strings" + "testing" + + "github.com/go-flucky/flucky/pkg/types" + "github.com/stretchr/testify/require" +) + +func CompareMeasuredValues(t *testing.T, goldenInterface interface{}, testInterface interface{}) { + require := require.New(t) + + goldenBuffer := new(bytes.Buffer) + testBuffer := new(bytes.Buffer) + + jsonEncoder := json.NewEncoder(goldenBuffer) + jsonEncoder.SetIndent("", " ") + err := jsonEncoder.Encode(&goldenInterface) + require.NoError(err) + + jsonEncoder = json.NewEncoder(testBuffer) + jsonEncoder.SetIndent("", " ") + err = jsonEncoder.Encode(&testInterface) + require.NoError(err) + + // t.Log(goldenBuffer.String(), testBuffer.String()) + + require.Equal(goldenBuffer.String(), testBuffer.String(), "Expected are not equal with actual value") + +} + +func GetGoldenDevices(goldenFilePath string) ([]*types.Device, error) { + file := string(MustAsset(goldenFilePath)) + reader := strings.NewReader(file) + devices := make([]*types.Device, 0) + jsonDecoder := json.NewDecoder(reader) + err := jsonDecoder.Decode(&devices) + if err != nil { + return nil, err + } + return devices, nil +} + +func GetGoldenMeasuredValues(goldenFilePath string) ([]*types.MeasuredValue, error) { + f := string(MustAsset(goldenFilePath)) + r := strings.NewReader(f) + measuredValues := make([]*types.MeasuredValue, 0) + jsonDecoder := json.NewDecoder(r) + err := jsonDecoder.Decode(&measuredValues) + if err != nil { + return nil, err + } + return measuredValues, nil +} + +func GetGoldenSensors(goldenFilePath string) ([]*types.Sensor, error) { + f := string(MustAsset(goldenFilePath)) + r := strings.NewReader(f) + sensors := make([]*types.Sensor, 0) + jsonDecoder := json.NewDecoder(r) + err := jsonDecoder.Decode(&sensors) + if err != nil { + return nil, err + } + return sensors, nil +} diff --git a/test/goldenfiles/json/goldenDevices.json b/test/goldenfiles/json/goldenDevices.json new file mode 100644 index 0000000..54f72ba --- /dev/null +++ b/test/goldenfiles/json/goldenDevices.json @@ -0,0 +1,9 @@ +[ + { + "device_id": "1efc3092-871e-4ac4-b0d4-ea5e5715460d", + "device_name": "poseidon", + "device_location": null, + "device_last_contact": null, + "creation_date": "2019-03-06T20:02:48.839308+01:00" + } +] \ No newline at end of file diff --git a/test/goldenfiles/json/goldenHumidities.json b/test/goldenfiles/json/goldenHumidities.json new file mode 100644 index 0000000..6941860 --- /dev/null +++ b/test/goldenfiles/json/goldenHumidities.json @@ -0,0 +1,142 @@ +[ + { + "id": "f94bb22a-d896-4bf7-bb48-74acd9211698", + "value": "45", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:20.409105+02:00", + "till_date": "2019-08-23T20:38:21.369122+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401141+02:00", + "update_date": "2019-08-23T20:41:05.347411+02:00" + }, + { + "id": "4bf1f15f-2175-454d-b711-7642600437e4", + "value": "75", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:22.249136+02:00", + "till_date": "2019-08-23T20:38:22.249137+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401477+02:00", + "update_date": null + }, + { + "id": "8e7653a4-c9c6-418c-8acb-73e73023cad2", + "value": "66", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:23.289123+02:00", + "till_date": "2019-08-23T20:38:23.289124+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401789+02:00", + "update_date": null + }, + { + "id": "4dd27ac3-ec52-4453-9391-2f8483574161", + "value": "64.5", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:24.16919+02:00", + "till_date": "2019-08-23T20:38:24.169192+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401447+02:00", + "update_date": null + }, + { + "id": "0e5ccd47-3ca0-4fe1-875b-a248790d44df", + "value": "64.25", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:25.209098+02:00", + "till_date": "2019-08-23T20:38:25.209117+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401447+02:00", + "update_date": null + }, + { + "id": "9de64ca1-b4bd-4a0b-a750-1f751eb36031", + "value": "64", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:26.169711+02:00", + "till_date": "2019-08-23T20:38:27.049147+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401975+02:00", + "update_date": "2019-08-23T20:41:05.347447+02:00" + }, + { + "id": "8c952afc-6824-4b06-bfd0-16a0d8c5fc80", + "value": "78", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:28.089+02:00", + "till_date": "2019-08-23T20:38:28.089+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401457+02:00", + "update_date": null + }, + { + "id": "780c1008-fb17-494b-9c61-e0a34245d63c", + "value": "77", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:28.969711+02:00", + "till_date": "2019-08-23T20:38:28.96974+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401141+02:00", + "update_date": null + }, + { + "id": "b206b39d-9f80-4ba8-bb6b-d171abc3c458", + "value": "61", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:30.009741+02:00", + "till_date": "2019-08-23T20:38:30.969711+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401668+02:00", + "update_date": "2019-08-23T20:41:05.347446+02:00" + }, + { + "id": "4d381d84-a56c-4bc8-89c7-ea41b2432eaf", + "value": "55.25", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:31.929108+02:00", + "till_date": "2019-08-23T20:38:38.569141+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.407891+02:00", + "update_date": "2019-08-23T20:41:05.347789+02:00" + }, + { + "id": "07ce5f6c-d860-448e-98cd-b390bdcf63b3", + "value": "55", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:39.529164+02:00", + "till_date": "2019-08-23T20:38:40.569106+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401456+02:00", + "update_date": "2019-08-23T20:41:05.347789+02:00" + }, + { + "id": "18145034-237e-4066-a998-0dd1b4a0a3b4", + "value": "50", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:41.529216+02:00", + "till_date": "2019-08-23T20:38:41.529217+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401789+02:00", + "update_date": null + }, + { + "id": "56794741-0758-401b-8697-e42998a53d2d", + "value": "49.5", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:42.489113+02:00", + "till_date": "2019-08-23T20:38:42.489114+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401789+02:00", + "update_date": null + }, + { + "id": "7dbf1aa5-a122-4ba7-8444-fc7aac22246f", + "value": "48.5", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:43.369131+02:00", + "till_date": "2019-08-23T20:46:04.409158+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.401221+02:00", + "update_date": "2019-08-23T20:46:05.341739+02:00" + } +] \ No newline at end of file diff --git a/test/goldenfiles/json/goldenMeasuredValues.json b/test/goldenfiles/json/goldenMeasuredValues.json new file mode 100644 index 0000000..ada77b5 --- /dev/null +++ b/test/goldenfiles/json/goldenMeasuredValues.json @@ -0,0 +1,422 @@ +[ + { + "id": "f94bb22a-d896-4bf7-bb48-74acd9211698", + "value": "45", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:20.409105+02:00", + "till_date": "2019-08-23T20:38:21.369122+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "4bf1f15f-2175-454d-b711-7642600437e4", + "value": "75", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:22.249136+02:00", + "till_date": "2019-08-23T20:38:22.249137+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "8e7653a4-c9c6-418c-8acb-73e73023cad2", + "value": "66", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:23.289123+02:00", + "till_date": "2019-08-23T20:38:23.289124+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "4dd27ac3-ec52-4453-9391-2f8483574161", + "value": "64.5", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:24.16919+02:00", + "till_date": "2019-08-23T20:38:24.169192+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "0e5ccd47-3ca0-4fe1-875b-a248790d44df", + "value": "64.25", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:25.209098+02:00", + "till_date": "2019-08-23T20:38:25.2091+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "9de64ca1-b4bd-4a0b-a750-1f751eb36031", + "value": "64", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:26.169175+02:00", + "till_date": "2019-08-23T20:38:27.049148+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "8c952afc-6824-4b06-bfd0-16a0d8c5fc80", + "value": "78", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:28.089115+02:00", + "till_date": "2019-08-23T20:38:28.089116+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "780c1008-fb17-494b-9c61-e0a34245d63c", + "value": "77", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:28.969102+02:00", + "till_date": "2019-08-23T20:38:28.969104+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "b206b39d-9f80-4ba8-bb6b-d171abc3c458", + "value": "61", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:30.009139+02:00", + "till_date": "2019-08-23T20:38:30.969136+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "4d381d84-a56c-4bc8-89c7-ea41b2432eaf", + "value": "55.25", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:31.929108+02:00", + "till_date": "2019-08-23T20:38:38.569141+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "07ce5f6c-d860-448e-98cd-b390bdcf63b3", + "value": "55", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:39.529164+02:00", + "till_date": "2019-08-23T20:38:40.569106+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "18145034-237e-4066-a998-0dd1b4a0a3b4", + "value": "50", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:41.529216+02:00", + "till_date": "2019-08-23T20:38:41.529217+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "56794741-0758-401b-8697-e42998a53d2d", + "value": "49.5", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:42.489113+02:00", + "till_date": "2019-08-23T20:38:42.489114+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "7dbf1aa5-a122-4ba7-8444-fc7aac22246f", + "value": "48.5", + "value_type": "humidity", + "from_date": "2019-08-23T20:38:43.369131+02:00", + "till_date": "2019-08-23T20:46:04.409158+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:46:05.341739+02:00" + }, + { + "id": "f94bb22a-d896-4bf7-bb48-74acd9211698", + "value": "100146.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:20.409105+02:00", + "till_date": "2019-08-23T20:38:21.369122+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "4bf1f15f-2175-454d-b711-7642600437e4", + "value": "100147.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:22.249136+02:00", + "till_date": "2019-08-23T20:38:22.249137+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "8e7653a4-c9c6-418c-8acb-73e73023cad2", + "value": "100144.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:23.289123+02:00", + "till_date": "2019-08-23T20:38:23.289124+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "4dd27ac3-ec52-4453-9391-2f8483574161", + "value": "100666.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:24.16919+02:00", + "till_date": "2019-08-23T20:38:24.169192+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "0e5ccd47-3ca0-4fe1-875b-a248790d44df", + "value": "100612.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:25.209098+02:00", + "till_date": "2019-08-23T20:38:25.2091+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "9de64ca1-b4bd-4a0b-a750-1f751eb36031", + "value": "100550.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:26.169175+02:00", + "till_date": "2019-08-23T20:38:27.049148+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "8c952afc-6824-4b06-bfd0-16a0d8c5fc80", + "value": "100609.750", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:28.089115+02:00", + "till_date": "2019-08-23T20:38:28.089116+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "780c1008-fb17-494b-9c61-e0a34245d63c", + "value": "100609.250", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:28.969102+02:00", + "till_date": "2019-08-23T20:38:28.969104+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "b206b39d-9f80-4ba8-bb6b-d171abc3c458", + "value": "100146.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:30.009139+02:00", + "till_date": "2019-08-23T20:38:30.969136+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "4d381d84-a56c-4bc8-89c7-ea41b2432eaf", + "value": "100149.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:31.929108+02:00", + "till_date": "2019-08-23T20:38:38.569141+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "07ce5f6c-d860-448e-98cd-b390bdcf63b3", + "value": "100114.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:39.529164+02:00", + "till_date": "2019-08-23T20:38:40.569106+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "18145034-237e-4066-a998-0dd1b4a0a3b4", + "value": "100149.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:41.529216+02:00", + "till_date": "2019-08-23T20:38:41.529217+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "56794741-0758-401b-8697-e42998a53d2d", + "value": "100166.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:42.489113+02:00", + "till_date": "2019-08-23T20:38:42.489114+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "7dbf1aa5-a122-4ba7-8444-fc7aac22246f", + "value": "100178.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:43.369131+02:00", + "till_date": "2019-08-23T20:46:04.409158+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:46:05.341739+02:00" + }, + { + "id": "f94bb22a-d896-4bf7-bb48-74acd9211698", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:20.409105+02:00", + "till_date": "2019-08-23T20:38:21.369122+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "4bf1f15f-2175-454d-b711-7642600437e4", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:22.249136+02:00", + "till_date": "2019-08-23T20:38:22.249137+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "8e7653a4-c9c6-418c-8acb-73e73023cad2", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:23.289123+02:00", + "till_date": "2019-08-23T20:38:23.289124+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "4dd27ac3-ec52-4453-9391-2f8483574161", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:24.16919+02:00", + "till_date": "2019-08-23T20:38:24.169192+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "0e5ccd47-3ca0-4fe1-875b-a248790d44df", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:25.209098+02:00", + "till_date": "2019-08-23T20:38:25.2091+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "9de64ca1-b4bd-4a0b-a750-1f751eb36031", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:26.169175+02:00", + "till_date": "2019-08-23T20:38:27.049148+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "8c952afc-6824-4b06-bfd0-16a0d8c5fc80", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:28.089115+02:00", + "till_date": "2019-08-23T20:38:28.089116+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "780c1008-fb17-494b-9c61-e0a34245d63c", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:28.969102+02:00", + "till_date": "2019-08-23T20:38:28.969104+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "b206b39d-9f80-4ba8-bb6b-d171abc3c458", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:30.009139+02:00", + "till_date": "2019-08-23T20:38:30.969136+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "4d381d84-a56c-4bc8-89c7-ea41b2432eaf", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:31.929108+02:00", + "till_date": "2019-08-23T20:38:38.569141+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "07ce5f6c-d860-448e-98cd-b390bdcf63b3", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:39.529164+02:00", + "till_date": "2019-08-23T20:38:40.569106+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "18145034-237e-4066-a998-0dd1b4a0a3b4", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:41.529216+02:00", + "till_date": "2019-08-23T20:38:41.529217+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "56794741-0758-401b-8697-e42998a53d2d", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:42.489113+02:00", + "till_date": "2019-08-23T20:38:42.489114+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "7dbf1aa5-a122-4ba7-8444-fc7aac22246f", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:43.369131+02:00", + "till_date": "2019-08-23T20:46:04.409158+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:46:05.341739+02:00" + } +] \ No newline at end of file diff --git a/test/goldenfiles/json/goldenPressures.json b/test/goldenfiles/json/goldenPressures.json new file mode 100644 index 0000000..6774d79 --- /dev/null +++ b/test/goldenfiles/json/goldenPressures.json @@ -0,0 +1,142 @@ +[ + { + "id": "f94bb22a-d896-4bf7-bb48-74acd9211698", + "value": "100146.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:20.409105+02:00", + "till_date": "2019-08-23T20:38:21.369122+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "4bf1f15f-2175-454d-b711-7642600437e4", + "value": "100147.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:22.249136+02:00", + "till_date": "2019-08-23T20:38:22.249137+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "8e7653a4-c9c6-418c-8acb-73e73023cad2", + "value": "100144.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:23.289123+02:00", + "till_date": "2019-08-23T20:38:23.289124+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "4dd27ac3-ec52-4453-9391-2f8483574161", + "value": "100666.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:24.16919+02:00", + "till_date": "2019-08-23T20:38:24.169192+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881587+02:00", + "update_date": null + }, + { + "id": "0e5ccd47-3ca0-4fe1-875b-a248790d44df", + "value": "100612.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:25.209098+02:00", + "till_date": "2019-08-23T20:38:25.2091+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "9de64ca1-b4bd-4a0b-a750-1f751eb36031", + "value": "100550.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:26.169175+02:00", + "till_date": "2019-08-23T20:38:27.049148+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "8c952afc-6824-4b06-bfd0-16a0d8c5fc80", + "value": "100609.750", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:28.089115+02:00", + "till_date": "2019-08-23T20:38:28.089116+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "780c1008-fb17-494b-9c61-e0a34245d63c", + "value": "100609.250", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:28.969102+02:00", + "till_date": "2019-08-23T20:38:28.969104+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "b206b39d-9f80-4ba8-bb6b-d171abc3c458", + "value": "100146.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:30.009139+02:00", + "till_date": "2019-08-23T20:38:30.969136+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "4d381d84-a56c-4bc8-89c7-ea41b2432eaf", + "value": "100149.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:31.929108+02:00", + "till_date": "2019-08-23T20:38:38.569141+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "07ce5f6c-d860-448e-98cd-b390bdcf63b3", + "value": "100114.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:39.529164+02:00", + "till_date": "2019-08-23T20:38:40.569106+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "18145034-237e-4066-a998-0dd1b4a0a3b4", + "value": "100149.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:41.529216+02:00", + "till_date": "2019-08-23T20:38:41.529217+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "56794741-0758-401b-8697-e42998a53d2d", + "value": "100166.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:42.489113+02:00", + "till_date": "2019-08-23T20:38:42.489114+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "7dbf1aa5-a122-4ba7-8444-fc7aac22246f", + "value": "100178.500", + "value_type": "pressure", + "from_date": "2019-08-23T20:38:43.369131+02:00", + "till_date": "2019-08-23T20:46:04.409158+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:46:05.341739+02:00" + } +] \ No newline at end of file diff --git a/test/goldenfiles/json/goldenSensors.json b/test/goldenfiles/json/goldenSensors.json new file mode 100644 index 0000000..05313d2 --- /dev/null +++ b/test/goldenfiles/json/goldenSensors.json @@ -0,0 +1,44 @@ +[ + { + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "sensor_name": "DS18B20-rechts", + "sensor_location": "Wohnzimmer", + "wire_id": "28-02131dbffeaa", + "i2c_bus": null, + "i2c_address": null, + "gpio_number": "GPIO14", + "sensor_model": "DS18B20", + "sensor_enabled": false, + "sensor_last_contact": null, + "device_id": "1efc3092-871e-4ac4-b0d4-ea5e5715460d", + "creation_date": "2019-03-06T20:02:48.839304+01:00" + }, + { + "sensor_id": "84eac248-6927-4db6-b6f9-7891ce2d301e", + "sensor_name": "DS18B20-links", + "sensor_location": "Wohnzimmer", + "wire_id": "28-01131646f11d", + "i2c_bus": null, + "i2c_address": null, + "gpio_number": "GPIO14", + "sensor_model": "DS18B20", + "sensor_enabled": false, + "sensor_last_contact": null, + "device_id": "1efc3092-871e-4ac4-b0d4-ea5e5715460d", + "creation_date": "2019-03-06T20:03:08.215219+01:00" + }, + { + "sensor_id": "4c1a4549-483f-44de-9ce0-459b577e6244", + "sensor_name": "BME280", + "sensor_location": "", + "wire_id": null, + "i2c_bus": 1, + "i2c_address": 118, + "gpio_number": null, + "sensor_model": "BME280", + "sensor_enabled": true, + "sensor_last_contact": null, + "device_id": "1efc3092-871e-4ac4-b0d4-ea5e5715460d", + "creation_date": "2019-06-30T13:42:24.089319+02:00" + } +] \ No newline at end of file diff --git a/test/goldenfiles/json/goldenTemperatures.json b/test/goldenfiles/json/goldenTemperatures.json new file mode 100644 index 0000000..85593bd --- /dev/null +++ b/test/goldenfiles/json/goldenTemperatures.json @@ -0,0 +1,142 @@ +[ + { + "id": "f94bb22a-d896-4bf7-bb48-74acd9211698", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:20.409105+02:00", + "till_date": "2019-08-23T20:38:21.369122+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.839308+02:00" + }, + { + "id": "4bf1f15f-2175-454d-b711-7642600437e4", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:22.249136+02:00", + "till_date": "2019-08-23T20:38:22.249137+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "8e7653a4-c9c6-418c-8acb-73e73023cad2", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:23.289123+02:00", + "till_date": "2019-08-23T20:38:23.289124+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "4dd27ac3-ec52-4453-9391-2f8483574161", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:24.16919+02:00", + "till_date": "2019-08-23T20:38:24.169192+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "0e5ccd47-3ca0-4fe1-875b-a248790d44df", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:25.209098+02:00", + "till_date": "2019-08-23T20:38:25.2091+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "9de64ca1-b4bd-4a0b-a750-1f751eb36031", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:26.169175+02:00", + "till_date": "2019-08-23T20:38:27.049148+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "8c952afc-6824-4b06-bfd0-16a0d8c5fc80", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:28.089115+02:00", + "till_date": "2019-08-23T20:38:28.089116+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "780c1008-fb17-494b-9c61-e0a34245d63c", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:28.969102+02:00", + "till_date": "2019-08-23T20:38:28.969104+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "b206b39d-9f80-4ba8-bb6b-d171abc3c458", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:30.009139+02:00", + "till_date": "2019-08-23T20:38:30.969136+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "4d381d84-a56c-4bc8-89c7-ea41b2432eaf", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:31.929108+02:00", + "till_date": "2019-08-23T20:38:38.569141+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "07ce5f6c-d860-448e-98cd-b390bdcf63b3", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:39.529164+02:00", + "till_date": "2019-08-23T20:38:40.569106+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:41:05.347223+02:00" + }, + { + "id": "18145034-237e-4066-a998-0dd1b4a0a3b4", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:41.529216+02:00", + "till_date": "2019-08-23T20:38:41.529217+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "56794741-0758-401b-8697-e42998a53d2d", + "value": "25", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:42.489113+02:00", + "till_date": "2019-08-23T20:38:42.489114+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": null + }, + { + "id": "7dbf1aa5-a122-4ba7-8444-fc7aac22246f", + "value": "25.5", + "value_type": "temperature", + "from_date": "2019-08-23T20:38:43.369131+02:00", + "till_date": "2019-08-23T20:46:04.409158+02:00", + "sensor_id": "efcd755e-82d1-4789-a50b-355b8735b8d8", + "creation_date": "2019-08-23T20:41:05.40881+02:00", + "update_date": "2019-08-23T20:46:05.341739+02:00" + } +] \ No newline at end of file