feat(pkg/db): postgres database
This commit is contained in:
		
							
								
								
									
										7
									
								
								.env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.env
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | PG_INTERN_PORT=5432 | ||||||
|  | PG_EXTERN_PORT=5432 | ||||||
|  | PG_NAME=public | ||||||
|  | PG_USER=postgres | ||||||
|  | PG_PASSWORD=postgres | ||||||
|  |  | ||||||
|  | TZ=Europe/Berlin | ||||||
							
								
								
									
										15
									
								
								.env_dev
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								.env_dev
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
| @@ -2,4 +2,4 @@ services: | |||||||
|   - docker |   - docker | ||||||
|  |  | ||||||
| script: | script: | ||||||
|   - make container-build |   - make container-go-build | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								Makefile
									
									
									
									
									
								
							| @@ -8,7 +8,7 @@ GID?=$(shell id --group) | |||||||
| # VERSION | # VERSION | ||||||
| # If no version is specified as a parameter of make, the last git hash | # If no version is specified as a parameter of make, the last git hash | ||||||
| # value is taken. | # 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) | CONTAINER_RUNTIME?=$(shell which docker) | ||||||
|  |  | ||||||
| @@ -16,23 +16,24 @@ GOARCH?=amd64 | |||||||
| GOOS?=linux | GOOS?=linux | ||||||
|  |  | ||||||
| # default build | # default build | ||||||
| build: | go-build: bindata | ||||||
| 	GOOS=${GOOS} \ | 	GOOS=${GOOS} \ | ||||||
| 	GOARCH=${GOARCH} \ | 	GOARCH=${GOARCH} \ | ||||||
| 		go build -ldflags "-X main.version=${VERSION}" | 		go build -ldflags "-X main.version=${VERSION}" | ||||||
| 	chown -R ${UID}:${GID} * | 	chown -R ${UID}:${GID} * | ||||||
|  |  | ||||||
| test: bindata | go-test: go-build | ||||||
| 	go test -v ./pkg/... | 	go test -v ./pkg/... | ||||||
|  |  | ||||||
| bindata: | 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: | container-go-build: | ||||||
| 	$(MAKE) container-run COMMAND=build | 	$(MAKE) container-run COMMAND=go-build | ||||||
|  |  | ||||||
| container-test: | container-go-test: | ||||||
| 	$(MAKE) container-run COMMAND=test | 	$(MAKE) container-run COMMAND=go-test | ||||||
|  |  | ||||||
| container-run: | container-run: | ||||||
| 	${CONTAINER_RUNTIME} run \ | 	${CONTAINER_RUNTIME} run \ | ||||||
| @@ -42,6 +43,6 @@ container-run: | |||||||
| 			make ${COMMAND} UID=${UID} GID=${GID} VERSION=${VERSION} GOOS=${GOOS} GOARCH=${GOARCH} | 			make ${COMMAND} UID=${UID} GID=${GID} VERSION=${VERSION} GOOS=${GOOS} GOARCH=${GOARCH} | ||||||
|  |  | ||||||
| remote: | remote: | ||||||
| 	$(MAKE) build GOARCH=arm | 	$(MAKE) go-build GOARCH=arm | ||||||
| 	scp flucky ${FLUCKY_REMOTE}:/usr/local/bin | 	scp flucky ${FLUCKY_REMOTE}:/usr/local/bin | ||||||
| 	ssh ${FLUCKY_REMOTE} "chmod +x /usr/local/bin/flucky" | 	ssh ${FLUCKY_REMOTE} "chmod +x /usr/local/bin/flucky" | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								cmd/cmd.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								cmd/cmd.go
									
									
									
									
									
								
							| @@ -2,6 +2,7 @@ package cmd | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"math" | ||||||
| 	"os" | 	"os" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| @@ -34,12 +35,19 @@ var rootCmd = &cobra.Command{ | |||||||
| 				return fmt.Errorf("Can not locate the hostname: %v", err) | 				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{ | 			cnf := config.Configuration{ | ||||||
| 				Device: &types.Device{ | 				Device: &types.Device{ | ||||||
| 					DeviceID:     uuid.NewV4().String(), | 					DeviceID:     uuid.NewV4().String(), | ||||||
| 					DeviceName:   hostname, | 					DeviceName:   hostname, | ||||||
| 					Logfile:      "/var/log/flucky/logfile.csv", | 					Logfile:      "/var/log/flucky/logfile.csv", | ||||||
| 					CreationDate: time.Now(), | 					CreationDate: t, | ||||||
| 				}, | 				}, | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -62,6 +70,7 @@ func Execute(version string) { | |||||||
| 	compression.InitCmd(rootCmd, &configFile) | 	compression.InitCmd(rootCmd, &configFile) | ||||||
| 	convert.InitCmd(rootCmd, &configFile) | 	convert.InitCmd(rootCmd, &configFile) | ||||||
| 	daemon.InitCmd(rootCmd, &configFile) | 	daemon.InitCmd(rootCmd, &configFile) | ||||||
|  | 	// db.InitCmd(rootCmd, &configFile) | ||||||
| 	humidity.InitCmd(rootCmd, &configFile) | 	humidity.InitCmd(rootCmd, &configFile) | ||||||
| 	pressure.InitCmd(rootCmd, &configFile) | 	pressure.InitCmd(rootCmd, &configFile) | ||||||
| 	rgbled.InitCmd(rootCmd, &configFile) | 	rgbled.InitCmd(rootCmd, &configFile) | ||||||
|   | |||||||
							
								
								
									
										49
									
								
								cmd/db/db.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								cmd/db/db.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @@ -9,6 +9,7 @@ require ( | |||||||
| 	github.com/go-flucky/go-dht v0.1.1 | 	github.com/go-flucky/go-dht v0.1.1 | ||||||
| 	github.com/inconshreveable/mousetrap v1.0.0 // indirect | 	github.com/inconshreveable/mousetrap v1.0.0 // indirect | ||||||
| 	github.com/kr/pretty v0.1.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/satori/go.uuid v1.2.0 | ||||||
| 	github.com/spf13/cobra v0.0.3 | 	github.com/spf13/cobra v0.0.3 | ||||||
| 	github.com/spf13/pflag v1.0.3 // indirect | 	github.com/spf13/pflag v1.0.3 // indirect | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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/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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= | ||||||
| github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||||
| github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= | github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import ( | |||||||
|  |  | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/go-flucky/flucky/pkg/internal/format" | ||||||
| 	"github.com/go-flucky/flucky/pkg/rgbled" | 	"github.com/go-flucky/flucky/pkg/rgbled" | ||||||
| 	"github.com/go-flucky/flucky/pkg/sensor" | 	"github.com/go-flucky/flucky/pkg/sensor" | ||||||
|  |  | ||||||
| @@ -101,7 +102,7 @@ func (c *Configuration) AddSensor(sensor *types.Sensor) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// overwrite creation date | 	// overwrite creation date | ||||||
| 	sensor.CreationDate = time.Now() | 	sensor.CreationDate = format.FormatedTime() | ||||||
|  |  | ||||||
| 	//TODO: check if wire sensor exists in /dev/bus/w1/devices | 	//TODO: check if wire sensor exists in /dev/bus/w1/devices | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/go-flucky/flucky/pkg/config" | 	"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/logfile" | ||||||
| 	"github.com/go-flucky/flucky/pkg/logger" | 	"github.com/go-flucky/flucky/pkg/logger" | ||||||
| 	"github.com/go-flucky/flucky/pkg/rgbled" | 	"github.com/go-flucky/flucky/pkg/rgbled" | ||||||
| @@ -15,6 +16,14 @@ import ( | |||||||
| 	"github.com/go-flucky/flucky/pkg/types" | 	"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 | // Start the daemon | ||||||
| func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compression bool, round float64, logger logger.Logger) { | 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) | 				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 { | 			if err != nil { | ||||||
|  |  | ||||||
| 				err = rgbled.Error(rgbLEDs) | 				err = rgbled.Error(rgbLEDs) | ||||||
| @@ -76,8 +87,22 @@ func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compress | |||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				cancel() | 				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) | 			measuredValuesCache = make([]*types.MeasuredValue, 0) | ||||||
|  |  | ||||||
| 		case measuredValues, _ := <-measuredValuesChannel: | 		case measuredValues, _ := <-measuredValuesChannel: | ||||||
|   | |||||||
							
								
								
									
										36
									
								
								pkg/db/db.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								pkg/db/db.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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") | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								pkg/db/errors.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								pkg/db/errors.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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") | ||||||
|  | ) | ||||||
							
								
								
									
										39
									
								
								pkg/db/interfaces.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								pkg/db/interfaces.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
|  | } | ||||||
							
								
								
									
										410
									
								
								pkg/db/postgres.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										410
									
								
								pkg/db/postgres.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
|  | } | ||||||
							
								
								
									
										273
									
								
								pkg/db/postgres_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										273
									
								
								pkg/db/postgres_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								pkg/db/sql/psql/deleteDevice.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								pkg/db/sql/psql/deleteDevice.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | DELETE FROM devices | ||||||
|  | WHERE device_id = $1; | ||||||
							
								
								
									
										2
									
								
								pkg/db/sql/psql/deleteHumidity.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								pkg/db/sql/psql/deleteHumidity.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | DELETE FROM humidities | ||||||
|  | WHERE humidity_id = $1; | ||||||
							
								
								
									
										2
									
								
								pkg/db/sql/psql/deletePressure.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								pkg/db/sql/psql/deletePressure.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | DELETE FROM pressures | ||||||
|  | WHERE pressure_id = $1; | ||||||
							
								
								
									
										2
									
								
								pkg/db/sql/psql/deleteSensor.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								pkg/db/sql/psql/deleteSensor.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | DELETE FROM sensors | ||||||
|  | WHERE sensor_id = $1; | ||||||
							
								
								
									
										2
									
								
								pkg/db/sql/psql/deleteTemperature.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								pkg/db/sql/psql/deleteTemperature.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | DELETE FROM temperatures | ||||||
|  | WHERE temperature_id = $1; | ||||||
							
								
								
									
										7
									
								
								pkg/db/sql/psql/insertDevice.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pkg/db/sql/psql/insertDevice.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | INSERT INTO devices ( | ||||||
|  |   device_id, | ||||||
|  |   device_name, | ||||||
|  |   device_location, | ||||||
|  |   creation_date | ||||||
|  | ) | ||||||
|  | VALUES ($1, $2, $3, $4); | ||||||
							
								
								
									
										10
									
								
								pkg/db/sql/psql/insertHumidity.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								pkg/db/sql/psql/insertHumidity.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||||
							
								
								
									
										10
									
								
								pkg/db/sql/psql/insertPressure.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								pkg/db/sql/psql/insertPressure.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||||
							
								
								
									
										14
									
								
								pkg/db/sql/psql/insertSensor.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								pkg/db/sql/psql/insertSensor.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||||
							
								
								
									
										10
									
								
								pkg/db/sql/psql/insertTemperature.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								pkg/db/sql/psql/insertTemperature.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||||
							
								
								
									
										146
									
								
								pkg/db/sql/psql/schema.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								pkg/db/sql/psql/schema.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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(); | ||||||
							
								
								
									
										8
									
								
								pkg/db/sql/psql/selectDeviceByID.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pkg/db/sql/psql/selectDeviceByID.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | SELECT | ||||||
|  |   device_id, | ||||||
|  |   device_name, | ||||||
|  |   device_location, | ||||||
|  |   creation_date | ||||||
|  | FROM | ||||||
|  |   devices | ||||||
|  | WHERE device_id = $1; | ||||||
							
								
								
									
										10
									
								
								pkg/db/sql/psql/selectHumidities.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								pkg/db/sql/psql/selectHumidities.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | SELECT | ||||||
|  |   humidity_id, | ||||||
|  |   humidity_value, | ||||||
|  |   humidity_from_date, | ||||||
|  |   humidity_till_date, | ||||||
|  |   sensor_id, | ||||||
|  |   creation_date, | ||||||
|  |   update_date | ||||||
|  | FROM | ||||||
|  |   humidities; | ||||||
							
								
								
									
										12
									
								
								pkg/db/sql/psql/selectHumidityByID.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								pkg/db/sql/psql/selectHumidityByID.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||||
							
								
								
									
										12
									
								
								pkg/db/sql/psql/selectPressureByID.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								pkg/db/sql/psql/selectPressureByID.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||||
							
								
								
									
										10
									
								
								pkg/db/sql/psql/selectPressures.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								pkg/db/sql/psql/selectPressures.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | SELECT | ||||||
|  |   pressure_id, | ||||||
|  |   pressure_value, | ||||||
|  |   pressure_from_date, | ||||||
|  |   pressure_till_date, | ||||||
|  |   sensor_id, | ||||||
|  |   creation_date, | ||||||
|  |   update_date | ||||||
|  | FROM | ||||||
|  |   pressures; | ||||||
							
								
								
									
										16
									
								
								pkg/db/sql/psql/selectSensorByID.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								pkg/db/sql/psql/selectSensorByID.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||||
							
								
								
									
										12
									
								
								pkg/db/sql/psql/selectTemperatureByID.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								pkg/db/sql/psql/selectTemperatureByID.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||||
							
								
								
									
										10
									
								
								pkg/db/sql/psql/selectTemperatures.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								pkg/db/sql/psql/selectTemperatures.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | SELECT | ||||||
|  |   temperature_id, | ||||||
|  |   temperature_value, | ||||||
|  |   temperature_from_date, | ||||||
|  |   temperature_till_date, | ||||||
|  |   sensor_id, | ||||||
|  |   creation_date, | ||||||
|  |   update_date | ||||||
|  | FROM | ||||||
|  |   temperatures; | ||||||
							
								
								
									
										23
									
								
								pkg/internal/format/format.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								pkg/internal/format/format.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -7,6 +7,7 @@ import ( | |||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/go-flucky/flucky/pkg/internal/format" | ||||||
| 	"github.com/go-flucky/flucky/pkg/types" | 	"github.com/go-flucky/flucky/pkg/types" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -50,7 +51,7 @@ func (cl *csvLogfile) Read() ([]*types.MeasuredValue, error) { | |||||||
| 		// Times | 		// Times | ||||||
| 		times := make([]time.Time, 0) | 		times := make([]time.Time, 0) | ||||||
| 		for _, i := range []int{3, 4} { | 		for _, i := range []int{3, 4} { | ||||||
| 			time, err := time.Parse(timeFormat, record[i]) | 			time, err := time.Parse(format.TimeFormat, record[i]) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[i], err) | 				return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[i], err) | ||||||
| 			} | 			} | ||||||
| @@ -67,14 +68,14 @@ func (cl *csvLogfile) Read() ([]*types.MeasuredValue, error) { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Creation date | 		// Creation date | ||||||
| 		creationDate, err := time.Parse(timeFormat, record[6]) | 		creationDate, err := time.Parse(format.TimeFormat, record[6]) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[6], err) | 			return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[6], err) | ||||||
| 		} | 		} | ||||||
| 		measuredValue.CreationDate = &creationDate | 		measuredValue.CreationDate = creationDate | ||||||
|  |  | ||||||
| 		if record[7] != "null" { | 		if record[7] != "null" { | ||||||
| 			updateDate, err := time.Parse(timeFormat, record[7]) | 			updateDate, err := time.Parse(format.TimeFormat, record[7]) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, fmt.Errorf("%v %v: %v", errorParseTime, record[7], err) | 				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, | 			measuredValue.ID, | ||||||
| 			fmt.Sprintf("%v", measuredValue.ValueType), | 			fmt.Sprintf("%v", measuredValue.ValueType), | ||||||
| 			fmt.Sprintf("%v", measuredValue.Value), | 			fmt.Sprintf("%v", measuredValue.Value), | ||||||
| 			measuredValue.FromDate.Format(timeFormat), | 			measuredValue.FromDate.Format(format.TimeFormat), | ||||||
| 			measuredValue.TillDate.Format(timeFormat), | 			measuredValue.TillDate.Format(format.TimeFormat), | ||||||
| 			measuredValue.SensorID, | 			measuredValue.SensorID, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if measuredValue.CreationDate != nil { | 		record = append(record, measuredValue.CreationDate.Format(format.TimeFormat)) | ||||||
| 			record = append(record, measuredValue.CreationDate.Format(timeFormat)) |  | ||||||
| 		} else { |  | ||||||
| 			record = append(record, "null") |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if measuredValue.UpdateDate != nil { | 		if measuredValue.UpdateDate != nil { | ||||||
| 			record = append(record, measuredValue.UpdateDate.Format(timeFormat)) | 			record = append(record, measuredValue.UpdateDate.Format(format.TimeFormat)) | ||||||
| 		} else { | 		} else { | ||||||
| 			record = append(record, "null") | 			record = append(record, "null") | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -2,25 +2,27 @@ package logfile | |||||||
|  |  | ||||||
| import "errors" | import "errors" | ||||||
|  |  | ||||||
| var errorLogfileCreate = errors.New("Can not create logfile") | var ( | ||||||
| var errorLogfileDecode = errors.New("Can not decode from reader") | 	errorLogfileCreate    = errors.New("Can not create logfile") | ||||||
| var errorLogfileEncode = errors.New("Can not encode from writer") | 	errorLogfileDecode    = errors.New("Can not decode from reader") | ||||||
| var errorLogfileMarshal = errors.New("Can not marshal values") | 	errorLogfileEncode    = errors.New("Can not encode from writer") | ||||||
| var errorLogfileNotFound = errors.New("Can not find logfile") | 	errorLogfileMarshal   = errors.New("Can not marshal values") | ||||||
| var errorLogfileOpen = errors.New("Can not open logfile") | 	errorLogfileNotFound  = errors.New("Can not find logfile") | ||||||
| var errorLogfileRead = errors.New("Can not read from given reader") | 	errorLogfileOpen      = errors.New("Can not open logfile") | ||||||
| var errorLogfileUnmarshal = errors.New("Can not unmarshal values") | 	errorLogfileRead      = errors.New("Can not read from given reader") | ||||||
| var errorLogfileWrite = errors.New("Can not write with given writer") | 	errorLogfileUnmarshal = errors.New("Can not unmarshal values") | ||||||
|  | 	errorLogfileWrite     = errors.New("Can not write with given writer") | ||||||
|  |  | ||||||
| var errorParseFloat = errors.New("Can not parse float") | 	errorParseFloat           = errors.New("Can not parse float") | ||||||
| var errorParseMeasurementUnit = errors.New("Can not parse mesaurement unit") | 	errorParseMeasurementUnit = errors.New("Can not parse mesaurement unit") | ||||||
| var errorParseTime = errors.New("Can not parse time") | 	errorParseTime            = errors.New("Can not parse time") | ||||||
|  |  | ||||||
| var errorNoValidHumidityID = errors.New("No valid humidity id detected or available") | 	errorNoValidHumidityID    = errors.New("No valid humidity id detected or available") | ||||||
| var errorNoValidMesuredValue = errors.New("No mesured value detected or available") | 	errorNoValidMesuredValue  = errors.New("No mesured value detected or available") | ||||||
| var errorNoValidSensorID = errors.New("No sensor id detected or available") | 	errorNoValidSensorID      = errors.New("No sensor id detected or available") | ||||||
| var errorNoValidTemperatureID = errors.New("No valid temperature id detected or available") | 	errorNoValidTemperatureID = errors.New("No valid temperature id detected or available") | ||||||
| var errorNoValidTime = errors.New("No time detected or available") | 	errorNoValidTime          = errors.New("No time detected or available") | ||||||
| var errorNoValidTimePeriods = errors.New("No valid time periods") | 	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") | ||||||
|  | ) | ||||||
|   | |||||||
| @@ -4,13 +4,12 @@ import ( | |||||||
| 	"math" | 	"math" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
|  | 	"github.com/go-flucky/flucky/pkg/internal/format" | ||||||
| 	"github.com/go-flucky/flucky/pkg/types" | 	"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 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 | // Append adds an array of several measured values to a logfile | ||||||
| func Append(logfile Logfile, compression bool, round float64, measuredValues []*types.MeasuredValue) error { | 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) | 		return measuredValues[i].FromDate.Before(measuredValues[j].TillDate) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	now := time.Now() | 	now := format.FormatedTime() | ||||||
|  |  | ||||||
| 	for _, measuredValue := range measuredValues { | 	for _, measuredValue := range measuredValues { | ||||||
| 		if _, ok := lastMeasuredValuesBySensors[measuredValue.SensorID]; !ok { | 		if _, ok := lastMeasuredValuesBySensors[measuredValue.SensorID]; !ok { | ||||||
| @@ -124,11 +123,10 @@ func New(logfile string) Logfile { | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func writeCreationDate(measuredValues []*types.MeasuredValue) { | func writeCreationDate(measuredValues []*types.MeasuredValue) error { | ||||||
| 	now := time.Now() |  | ||||||
| 	for _, measuredValue := range measuredValues { | 	for _, measuredValue := range measuredValues { | ||||||
| 		if measuredValue.CreationDate == nil { | 		now := format.FormatedTime() | ||||||
| 			measuredValue.CreationDate = &now | 		measuredValue.CreationDate = now | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,11 +5,11 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"log" | 	"log" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/d2r2/go-bsbmp" | 	"github.com/d2r2/go-bsbmp" | ||||||
| 	"github.com/d2r2/go-i2c" | 	"github.com/d2r2/go-i2c" | ||||||
| 	"github.com/d2r2/go-logger" | 	"github.com/d2r2/go-logger" | ||||||
|  | 	"github.com/go-flucky/flucky/pkg/internal/format" | ||||||
| 	"github.com/go-flucky/flucky/pkg/types" | 	"github.com/go-flucky/flucky/pkg/types" | ||||||
| 	uuid "github.com/satori/go.uuid" | 	uuid "github.com/satori/go.uuid" | ||||||
| ) | ) | ||||||
| @@ -67,24 +67,24 @@ func (s *BME280) Read() ([]*types.MeasuredValue, error) { | |||||||
| 			ID:        uuid.NewV4().String(), | 			ID:        uuid.NewV4().String(), | ||||||
| 			Value:     float64(humidityValue), | 			Value:     float64(humidityValue), | ||||||
| 			ValueType: types.MeasuredValueTypeHumidity, | 			ValueType: types.MeasuredValueTypeHumidity, | ||||||
| 			FromDate:  time.Now(), | 			FromDate:  format.FormatedTime(), | ||||||
| 			TillDate:  time.Now(), | 			TillDate:  format.FormatedTime(), | ||||||
| 			SensorID:  s.SensorID, | 			SensorID:  s.SensorID, | ||||||
| 		}, | 		}, | ||||||
| 		&types.MeasuredValue{ | 		&types.MeasuredValue{ | ||||||
| 			ID:        uuid.NewV4().String(), | 			ID:        uuid.NewV4().String(), | ||||||
| 			Value:     float64(pressureValue), | 			Value:     float64(pressureValue), | ||||||
| 			ValueType: types.MeasuredValueTypePressure, | 			ValueType: types.MeasuredValueTypePressure, | ||||||
| 			FromDate:  time.Now(), | 			FromDate:  format.FormatedTime(), | ||||||
| 			TillDate:  time.Now(), | 			TillDate:  format.FormatedTime(), | ||||||
| 			SensorID:  s.SensorID, | 			SensorID:  s.SensorID, | ||||||
| 		}, | 		}, | ||||||
| 		&types.MeasuredValue{ | 		&types.MeasuredValue{ | ||||||
| 			ID:        uuid.NewV4().String(), | 			ID:        uuid.NewV4().String(), | ||||||
| 			Value:     float64(temperatureValue), | 			Value:     float64(temperatureValue), | ||||||
| 			ValueType: types.MeasuredValueTypeTemperature, | 			ValueType: types.MeasuredValueTypeTemperature, | ||||||
| 			FromDate:  time.Now(), | 			FromDate:  format.FormatedTime(), | ||||||
| 			TillDate:  time.Now(), | 			TillDate:  format.FormatedTime(), | ||||||
| 			SensorID:  s.SensorID, | 			SensorID:  s.SensorID, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -4,8 +4,8 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
|  | 	"github.com/go-flucky/flucky/pkg/internal/format" | ||||||
| 	"github.com/go-flucky/flucky/pkg/types" | 	"github.com/go-flucky/flucky/pkg/types" | ||||||
| 	"github.com/go-flucky/go-dht" | 	"github.com/go-flucky/go-dht" | ||||||
| 	uuid "github.com/satori/go.uuid" | 	uuid "github.com/satori/go.uuid" | ||||||
| @@ -49,16 +49,16 @@ func (s *DHT11) Read() ([]*types.MeasuredValue, error) { | |||||||
| 			ID:        uuid.NewV4().String(), | 			ID:        uuid.NewV4().String(), | ||||||
| 			Value:     float64(humidityValue), | 			Value:     float64(humidityValue), | ||||||
| 			ValueType: types.MeasuredValueTypeHumidity, | 			ValueType: types.MeasuredValueTypeHumidity, | ||||||
| 			FromDate:  time.Now(), | 			FromDate:  format.FormatedTime(), | ||||||
| 			TillDate:  time.Now(), | 			TillDate:  format.FormatedTime(), | ||||||
| 			SensorID:  s.SensorID, | 			SensorID:  s.SensorID, | ||||||
| 		}, | 		}, | ||||||
| 		&types.MeasuredValue{ | 		&types.MeasuredValue{ | ||||||
| 			ID:        uuid.NewV4().String(), | 			ID:        uuid.NewV4().String(), | ||||||
| 			Value:     float64(temperatureValue), | 			Value:     float64(temperatureValue), | ||||||
| 			ValueType: types.MeasuredValueTypeTemperature, | 			ValueType: types.MeasuredValueTypeTemperature, | ||||||
| 			FromDate:  time.Now(), | 			FromDate:  format.FormatedTime(), | ||||||
| 			TillDate:  time.Now(), | 			TillDate:  format.FormatedTime(), | ||||||
| 			SensorID:  s.SensorID, | 			SensorID:  s.SensorID, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -4,8 +4,8 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
|  | 	"github.com/go-flucky/flucky/pkg/internal/format" | ||||||
| 	"github.com/go-flucky/flucky/pkg/types" | 	"github.com/go-flucky/flucky/pkg/types" | ||||||
| 	"github.com/go-flucky/go-dht" | 	"github.com/go-flucky/go-dht" | ||||||
| 	uuid "github.com/satori/go.uuid" | 	uuid "github.com/satori/go.uuid" | ||||||
| @@ -49,16 +49,16 @@ func (s *DHT22) Read() ([]*types.MeasuredValue, error) { | |||||||
| 			ID:        uuid.NewV4().String(), | 			ID:        uuid.NewV4().String(), | ||||||
| 			Value:     float64(humidityValue), | 			Value:     float64(humidityValue), | ||||||
| 			ValueType: types.MeasuredValueTypeHumidity, | 			ValueType: types.MeasuredValueTypeHumidity, | ||||||
| 			FromDate:  time.Now(), | 			FromDate:  format.FormatedTime(), | ||||||
| 			TillDate:  time.Now(), | 			TillDate:  format.FormatedTime(), | ||||||
| 			SensorID:  s.SensorID, | 			SensorID:  s.SensorID, | ||||||
| 		}, | 		}, | ||||||
| 		&types.MeasuredValue{ | 		&types.MeasuredValue{ | ||||||
| 			ID:        uuid.NewV4().String(), | 			ID:        uuid.NewV4().String(), | ||||||
| 			Value:     float64(temperatureValue), | 			Value:     float64(temperatureValue), | ||||||
| 			ValueType: types.MeasuredValueTypeTemperature, | 			ValueType: types.MeasuredValueTypeTemperature, | ||||||
| 			FromDate:  time.Now(), | 			FromDate:  format.FormatedTime(), | ||||||
| 			TillDate:  time.Now(), | 			TillDate:  format.FormatedTime(), | ||||||
| 			SensorID:  s.SensorID, | 			SensorID:  s.SensorID, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -8,8 +8,8 @@ import ( | |||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
|  | 	"github.com/go-flucky/flucky/pkg/internal/format" | ||||||
| 	"github.com/go-flucky/flucky/pkg/types" | 	"github.com/go-flucky/flucky/pkg/types" | ||||||
| 	uuid "github.com/satori/go.uuid" | 	uuid "github.com/satori/go.uuid" | ||||||
| ) | ) | ||||||
| @@ -55,8 +55,8 @@ func (s *DS18B20) Read() ([]*types.MeasuredValue, error) { | |||||||
| 			ID:        uuid.NewV4().String(), | 			ID:        uuid.NewV4().String(), | ||||||
| 			Value:     float64(temperatureValue), | 			Value:     float64(temperatureValue), | ||||||
| 			ValueType: types.MeasuredValueTypeTemperature, | 			ValueType: types.MeasuredValueTypeTemperature, | ||||||
| 			FromDate:  time.Now(), | 			FromDate:  format.FormatedTime(), | ||||||
| 			TillDate:  time.Now(), | 			TillDate:  format.FormatedTime(), | ||||||
| 			SensorID:  s.SensorID, | 			SensorID:  s.SensorID, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -4,10 +4,10 @@ import "time" | |||||||
|  |  | ||||||
| // Device ... | // Device ... | ||||||
| type Device struct { | type Device struct { | ||||||
| 	DeviceID          string    `json:"device_id" xml:"device_id"` | 	DeviceID          string     `json:"device_id" xml:"device_id"` | ||||||
| 	DeviceName        string    `json:"device_name" xml:"device_name"` | 	DeviceName        string     `json:"device_name" xml:"device_name"` | ||||||
| 	DeviceLocation    *string   `json:"device_location" xml:"device_location"` | 	DeviceLocation    *string    `json:"device_location" xml:"device_location"` | ||||||
| 	DeviceLastContact time.Time `json:"device_last_contact" xml:"device_last_contact"` | 	DeviceLastContact *time.Time `json:"device_last_contact" xml:"device_last_contact"` | ||||||
| 	Logfile           string    `json:"logfile" xml:"logfile"` | 	Logfile           string     `json:"logfile" xml:"logfile"` | ||||||
| 	CreationDate      time.Time `json:"creation_date" xml:"creation_date"` | 	CreationDate      time.Time  `json:"creation_date" xml:"creation_date"` | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ type MeasuredValue struct { | |||||||
| 	FromDate     time.Time         `json:"from_date" xml:"from_date"` | 	FromDate     time.Time         `json:"from_date" xml:"from_date"` | ||||||
| 	TillDate     time.Time         `json:"till_date" xml:"till_date"` | 	TillDate     time.Time         `json:"till_date" xml:"till_date"` | ||||||
| 	SensorID     string            `json:"sensor_id" xml:"sensor_id"` | 	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"` | 	UpdateDate   *time.Time        `json:"update_date" xml:"update_date"` | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ type Sensor struct { | |||||||
| 	GPIONumber        *GPIO       `json:"gpio_number" xml:"gpio_number"` | 	GPIONumber        *GPIO       `json:"gpio_number" xml:"gpio_number"` | ||||||
| 	SensorModel       SensorModel `json:"sensor_model" xml:"sensor_model"` | 	SensorModel       SensorModel `json:"sensor_model" xml:"sensor_model"` | ||||||
| 	SensorEnabled     bool        `json:"sensor_enabled" xml:"sensor_enabled"` | 	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"` | 	DeviceID          string      `json:"device_id" xml:"device_id"` | ||||||
| 	CreationDate      time.Time   `json:"creation_date" xml:"creation_date"` | 	CreationDate      time.Time   `json:"creation_date" xml:"creation_date"` | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										69
									
								
								test/goldenfiles/goldenfiles.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								test/goldenfiles/goldenfiles.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								test/goldenfiles/json/goldenDevices.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								test/goldenfiles/json/goldenDevices.json
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||||
|  |   } | ||||||
|  | ] | ||||||
							
								
								
									
										142
									
								
								test/goldenfiles/json/goldenHumidities.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								test/goldenfiles/json/goldenHumidities.json
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||||
|  |   } | ||||||
|  | ] | ||||||
							
								
								
									
										422
									
								
								test/goldenfiles/json/goldenMeasuredValues.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										422
									
								
								test/goldenfiles/json/goldenMeasuredValues.json
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||||
|  |   } | ||||||
|  | ] | ||||||
							
								
								
									
										142
									
								
								test/goldenfiles/json/goldenPressures.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								test/goldenfiles/json/goldenPressures.json
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||||
|  |   } | ||||||
|  | ] | ||||||
							
								
								
									
										44
									
								
								test/goldenfiles/json/goldenSensors.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								test/goldenfiles/json/goldenSensors.json
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||||
|  |   } | ||||||
|  | ] | ||||||
							
								
								
									
										142
									
								
								test/goldenfiles/json/goldenTemperatures.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								test/goldenfiles/json/goldenTemperatures.json
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||||
|  |   } | ||||||
|  | ] | ||||||
		Reference in New Issue
	
	Block a user