parent
4b3f6c0d72
commit
41d558488e
@ -0,0 +1,60 @@
|
||||
name: CI
|
||||
|
||||
# Controls when the action will run. Triggers the workflow on push to master or development
|
||||
# with a tag like v1.0.0 or v1.0.0-dev
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-[a-zA-Z]+
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Get Version
|
||||
id: get_version
|
||||
uses: battila7/get-version-action@v2.0.0
|
||||
|
||||
- name: install buildx
|
||||
id: buildx
|
||||
uses: crazy-max/ghaction-docker-buildx@v1
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Docker Login
|
||||
# You may pin to the exact commit or the version.
|
||||
# uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
|
||||
uses: docker/login-action@v1.10.0
|
||||
with:
|
||||
registry: ${{ secrets.DR_URL }}
|
||||
# Username used to log against the Docker registry
|
||||
username: ${{ secrets.DH_USERNAME }}
|
||||
# Password or personal access token used to log against the Docker registry
|
||||
password: ${{ secrets.DH_PASSWORD }}
|
||||
# Log out from the Docker registry at the end of a job
|
||||
logout: true
|
||||
|
||||
- name: Docker Build & Push
|
||||
env:
|
||||
IMAGE_TAG: ${{ steps.get_version.outputs.version-without-v }}
|
||||
run: |
|
||||
docker buildx build --push \
|
||||
--tag ${{ secrets.DR_URL }}/weather:$IMAGE_TAG \
|
||||
--platform linux/amd64,linux/arm/v7,linux/arm64 .
|
||||
- name: Update deployment file
|
||||
run: TAG=${{ steps.get_version.outputs.version-without-v }} && sed -i 's|<IMAGE>|${{ secrets.DR_URL }}/weather:'${TAG}'|' $GITHUB_WORKSPACE/deployment.yml
|
||||
|
||||
- uses: azure/k8s-set-context@v1
|
||||
with:
|
||||
method: kubeconfig
|
||||
kubeconfig: ${{ secrets.KUBE_CONFIG }}
|
||||
id: setcontext
|
||||
|
||||
- name: Deploy to Kubernetes
|
||||
run: kubectl apply -f $GITHUB_WORKSPACE/deployment.yml
|
||||
@ -0,0 +1,20 @@
|
||||
FROM golang:1.17-alpine as dev
|
||||
|
||||
WORKDIR /go/src/weather
|
||||
COPY ./go.mod .
|
||||
COPY ./go.sum .
|
||||
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
RUN go install ./...
|
||||
|
||||
CMD [ "go", "run", "cmd/weather/main.go"]
|
||||
|
||||
from alpine
|
||||
|
||||
WORKDIR /bin
|
||||
|
||||
COPY --from=dev /go/bin/weather ./weather
|
||||
|
||||
CMD [ "weather" ]
|
||||
@ -1 +1,2 @@
|
||||
# weather
|
||||
# weather
|
||||
Golang server to bridge common Weather stations to MQTT and a database
|
||||
|
||||
@ -0,0 +1,147 @@
|
||||
package weather
|
||||
|
||||
import "time"
|
||||
|
||||
type AmbientService interface {
|
||||
Event(uint64) (*AmbientEntry, error)
|
||||
AddEvent(*AmbientEntry) (*AmbientEntry, error)
|
||||
UpdateEvent(*AmbientEntry) error
|
||||
DeleteEvent(*AmbientEntry) error
|
||||
}
|
||||
|
||||
type AmbientEntry struct {
|
||||
ID uint64
|
||||
MAC string `schema:"MAC"`
|
||||
DateUTC time.Time `schema:"dateutc"`
|
||||
WindDir int `schema:"winddir"`
|
||||
WindSpeedMPH float32 `schema:"windspeedmph"`
|
||||
WindGustMPH float32 `schema:"windgustmph"`
|
||||
WindGustDir int `schema:"windgustdir"`
|
||||
MaxDailyGust float32 `schema:"maxdailygust"`
|
||||
WindSpdMPH_Avg2m float32 `schema:"windspdmph_avg2m"`
|
||||
WindDir_Avg2m int `schema:"winddir_avg2m"`
|
||||
WindSpdMPH_Avg10m float32 `schema:"windspdmph_avg10m"`
|
||||
WindDir_Avg10m int `schema:"winddir_avg10m"`
|
||||
WindGustMPH_Interval int `schema:"windgustmph_interval"`
|
||||
Humidity int `schema:"humidity"`
|
||||
Humidity1 int `schema:"humidity1"`
|
||||
Humidity2 int `schema:"humidity2"`
|
||||
Humidity3 int `schema:"humidity3"`
|
||||
Humidity4 int `schema:"humidity4"`
|
||||
Humidity5 int `schema:"humidity5"`
|
||||
Humidity6 int `schema:"humidity6"`
|
||||
Humidity7 int `schema:"humidity7"`
|
||||
Humidity8 int `schema:"humidity8"`
|
||||
Humidity9 int `schema:"humidity9"`
|
||||
Humidity10 int `schema:"humidity10"`
|
||||
HumidityIn int `schema:"humidityin"`
|
||||
TempF float32 `schema:"tempf"`
|
||||
Temp1F float32 `schema:"temp1f"`
|
||||
Temp2F float32 `schema:"temp2f"`
|
||||
Temp3F float32 `schema:"temp3f"`
|
||||
Temp4F float32 `schema:"temp4f"`
|
||||
Temp5F float32 `schema:"temp5f"`
|
||||
Temp6F float32 `schema:"temp6f"`
|
||||
Temp7F float32 `schema:"temp7f"`
|
||||
Temp8F float32 `schema:"temp8f"`
|
||||
Temp9F float32 `schema:"temp9f"`
|
||||
Temp10F float32 `schema:"temp10f"`
|
||||
TempInF float32 `schema:"tempinf"`
|
||||
HourlyRainIn float32 `schema:"hourlyrainin"`
|
||||
DailyRainIn float32 `schema:"dailyrainin"`
|
||||
Last24HourRainIn float32 `schema:"24hourrainin"`
|
||||
WeeklyRainIn float32 `schema:"weeklyrainin"`
|
||||
MonthlyRainIn float32 `schema:"monthlyrainin"`
|
||||
YearlyRainIn float32 `schema:"yearlyrainin"`
|
||||
EventRainIn float32 `schema:"eventrainin"`
|
||||
TotalRainIn float32 `schema:"totalrainin"`
|
||||
BaromRelIn float32 `schema:"baromrelin"`
|
||||
BaromAbsIn float32 `schema:"baromabsin"`
|
||||
UV int `schema:"uv"`
|
||||
SolarRadiation float32 `schema:"solarradiation"`
|
||||
CO2 int `schema:"co2"`
|
||||
PM25 int `schema:"pm25"`
|
||||
PM25_24H float32 `schema:"pm25_24h"`
|
||||
PM25_In int `schema:"pm25_in"`
|
||||
PM25_In_24H float32 `schema:"pm25_in_24h"`
|
||||
PM10_In int `schema:"pm10_in"`
|
||||
PM10_In_24H float32 `schema:"pm10_in_24h"`
|
||||
CO2_In int `schema:"co2_in"`
|
||||
CO2_In_24H float32 `schema:"co2_in_24h"`
|
||||
PM_In_Temp float32 `schema:"pm_in_temp"`
|
||||
PM_in_Humidity int `schema:"pm_in_humidity"`
|
||||
Relay1 bool `schema:"relay1"`
|
||||
Relay2 bool `schema:"relay2"`
|
||||
Relay3 bool `schema:"relay3"`
|
||||
Relay4 bool `schema:"relay4"`
|
||||
Relay5 bool `schema:"relay5"`
|
||||
Relay6 bool `schema:"relay6"`
|
||||
Relay7 bool `schema:"relay7"`
|
||||
Relay8 bool `schema:"relay8"`
|
||||
Relay9 bool `schema:"relay9"`
|
||||
Relay10 bool `schema:"relay10"`
|
||||
SoilTemp1 float32 `schema:"soiltemp1"`
|
||||
SoilTemp2 float32 `schema:"soiltemp2"`
|
||||
SoilTemp3 float32 `schema:"soiltemp3"`
|
||||
SoilTemp4 float32 `schema:"soiltemp4"`
|
||||
SoilTemp5 float32 `schema:"soiltemp5"`
|
||||
SoilTemp6 float32 `schema:"soiltemp6"`
|
||||
SoilTemp7 float32 `schema:"soiltemp7"`
|
||||
SoilTemp8 float32 `schema:"soiltemp8"`
|
||||
SoilTemp9 float32 `schema:"soiltemp9"`
|
||||
SoilTemp10 float32 `schema:"soiltemp10"`
|
||||
SoilHum1 int `schema:"soilhum1"`
|
||||
SoilHum2 int `schema:"soilhum2"`
|
||||
SoilHum3 int `schema:"soilhum3"`
|
||||
SoilHum4 int `schema:"soilhum4"`
|
||||
SoilHum5 int `schema:"soilhum5"`
|
||||
SoilHum6 int `schema:"soilhum6"`
|
||||
SoilHum7 int `schema:"soilhum7"`
|
||||
SoilHum8 int `schema:"soilhum8"`
|
||||
SoilHum9 int `schema:"soilhum9"`
|
||||
SoilHum10 int `schema:"soilhum10"`
|
||||
Leak1 bool `schema:"leak1"`
|
||||
Leak2 bool `schema:"leak2"`
|
||||
Leak3 bool `schema:"leak3"`
|
||||
Leak4 bool `schema:"leak4"`
|
||||
Lightning_Time time.Time `schema:"lightning_time"`
|
||||
Lightning_Day int `schema:"lightning_day"`
|
||||
Lightning_Distance float32 `schema:"lightning_distance"`
|
||||
BattOut bool `schema:"battout"`
|
||||
BattIn bool `schema:"battin"`
|
||||
Batt1 bool `schema:"batt1"`
|
||||
Batt2 bool `schema:"batt2"`
|
||||
Batt3 bool `schema:"batt3"`
|
||||
Batt4 bool `schema:"batt4"`
|
||||
Batt5 bool `schema:"batt5"`
|
||||
Batt6 bool `schema:"batt6"`
|
||||
Batt7 bool `schema:"batt7"`
|
||||
Batt8 bool `schema:"batt8"`
|
||||
Batt9 bool `schema:"batt9"`
|
||||
Batt10 bool `schema:"batt10"`
|
||||
BattR1 bool `schema:"battr1"`
|
||||
BattR2 bool `schema:"battr2"`
|
||||
BattR3 bool `schema:"battr3"`
|
||||
BattR4 bool `schema:"battr4"`
|
||||
BattR5 bool `schema:"battr5"`
|
||||
BattR6 bool `schema:"battr6"`
|
||||
BattR7 bool `schema:"battr7"`
|
||||
BattR8 bool `schema:"battr8"`
|
||||
BattR9 bool `schema:"battr9"`
|
||||
BattR10 bool `schema:"battr10"`
|
||||
Batt_25 bool `schema:"batt_25"`
|
||||
Batt_25In bool `schema:"batt_25in"`
|
||||
BatLeak1 bool `schema:"batleak1"`
|
||||
BatLeak2 bool `schema:"batleak2"`
|
||||
BatLeak3 bool `schema:"batleak3"`
|
||||
BatLeak4 bool `schema:"batleak4"`
|
||||
Batt_Lightning bool `schema:"batt_lightning"`
|
||||
BattSM1 bool `schema:"battsm1"`
|
||||
BattSM2 bool `schema:"battsm2"`
|
||||
BattSM3 bool `schema:"battsm3"`
|
||||
BattSM4 bool `schema:"battsm4"`
|
||||
BattRain bool `schema:"battrain"`
|
||||
BattCO2 bool `schema:"batt_co2"`
|
||||
StationType string `schema:"stationtype"`
|
||||
PASSKEY string `schema:"passkey"`
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/dustinpianalto/weather/internal/mqtt"
|
||||
"github.com/dustinpianalto/weather/internal/postgres"
|
||||
"github.com/dustinpianalto/weather/pkg/endpoints"
|
||||
"github.com/dustinpianalto/weather/pkg/services"
|
||||
)
|
||||
|
||||
func main() {
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/data/report", endpoints.AmbientHandler)
|
||||
router.HandleFunc("/data/report/", endpoints.AmbientHandler)
|
||||
router.HandleFunc("/", endpoints.AmbientHandler)
|
||||
|
||||
dbConnString := os.Getenv("DATABASE_URL")
|
||||
postgres.ConnectDatabase(dbConnString)
|
||||
host := os.Getenv("MQTT_HOST")
|
||||
port, err := strconv.Atoi(os.Getenv("MQTT_PORT"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
user := os.Getenv("MQTT_USER")
|
||||
pass := os.Getenv("MQTT_PASSWORD")
|
||||
mqtt.CreateMQTTClient(host, user, pass, port)
|
||||
services.InitServices()
|
||||
|
||||
log.Fatal(http.ListenAndServe(":8080", router))
|
||||
}
|
||||
@ -0,0 +1,125 @@
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: weather
|
||||
namespace: weather
|
||||
labels:
|
||||
app: weather
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: weather
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 1
|
||||
minReadySeconds: 120
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: weather
|
||||
spec:
|
||||
containers:
|
||||
- name: pgbouncer
|
||||
image: timoha/pgbouncer:1.15.0
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "0.5"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "1"
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: weather
|
||||
key: pgbouncer_url
|
||||
- name: SERVER_TLS_SSLMODE
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: weather
|
||||
key: pgbouncer_ssl
|
||||
- name: AUTH_TYPE
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: weather
|
||||
key: pgbouncer_auth
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
- name: weather
|
||||
image: <IMAGE>
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "0.5"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "1"
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: weather
|
||||
key: database_url
|
||||
- name: MQTT_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: weather
|
||||
key: mqtt_host
|
||||
- name: MQTT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: weather
|
||||
key: mqtt_password
|
||||
- name: MQTT_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: weather
|
||||
key: mqtt_user
|
||||
- name: MQTT_PORT
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: weather
|
||||
key: mqtt_port
|
||||
imagePullSecrets:
|
||||
- name: registry-1
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: weather-service
|
||||
namespace: weather
|
||||
labels:
|
||||
app: weather
|
||||
spec:
|
||||
selector:
|
||||
app: weather
|
||||
ports:
|
||||
- protocol: TCP
|
||||
name: http
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: weather
|
||||
namespace: weather
|
||||
spec:
|
||||
rules:
|
||||
- host: weather.djpianalto.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: weather-service
|
||||
port:
|
||||
number: 8080
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
module github.com/dustinpianalto/weather
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/dustinpianalto/errors v0.1.0
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.5
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/schema v1.2.0
|
||||
github.com/lib/pq v1.10.4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect
|
||||
)
|
||||
@ -0,0 +1,18 @@
|
||||
github.com/dustinpianalto/errors v0.1.0 h1:1wG0dhtE1w0u3+QRrQnR6vRO3QrVGpqIEP/0X83i4f4=
|
||||
github.com/dustinpianalto/errors v0.1.0/go.mod h1:Fo865gGhrM1eyVIp5H5U8kQkZtFc/daiU3QBpUCd+B4=
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.5 h1:sWtmgNxYM9P2sP+xEItMozsR3w0cqZFlqnNN1bdl41Y=
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.5/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
|
||||
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U=
|
||||
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -0,0 +1,46 @@
|
||||
package mqtt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/dustinpianalto/errors"
|
||||
"github.com/dustinpianalto/weather"
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
)
|
||||
|
||||
var (
|
||||
AmbientService weather.AmbientService
|
||||
)
|
||||
|
||||
func CreateMQTTClient(host, username, password string, port int) {
|
||||
opts := mqtt.NewClientOptions()
|
||||
opts.AddBroker(fmt.Sprintf("tcp://%s:%d", host, port))
|
||||
opts.SetClientID("weather_bridge")
|
||||
opts.SetUsername(username)
|
||||
opts.SetPassword(password)
|
||||
opts.OnConnect = connectHandler
|
||||
opts.OnConnectionLost = connectionLostHandler
|
||||
client := mqtt.NewClient(opts)
|
||||
log.Println("mqtt client created")
|
||||
token := client.Connect()
|
||||
if token.Wait() && token.Error() != nil {
|
||||
log.Println(token.Error())
|
||||
return
|
||||
}
|
||||
initServices(&client)
|
||||
log.Println("mqtt client initalized")
|
||||
}
|
||||
|
||||
func connectHandler(client mqtt.Client) {
|
||||
log.Println("MQTT Connected")
|
||||
}
|
||||
|
||||
func connectionLostHandler(client mqtt.Client, err error) {
|
||||
const method string = "mqtt/connectionLostHandler"
|
||||
log.Println(errors.E(method, errors.Internal, "MQTT Connection Lost", err))
|
||||
}
|
||||
|
||||
func initServices(client *mqtt.Client) {
|
||||
AmbientService = eventService{client: client}
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package mqtt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/dustinpianalto/weather"
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
)
|
||||
|
||||
type eventService struct {
|
||||
client *mqtt.Client
|
||||
}
|
||||
|
||||
func (e eventService) Event(i uint64) (*weather.AmbientEntry, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (e eventService) AddEvent(event *weather.AmbientEntry) (*weather.AmbientEntry, error) {
|
||||
m := eventToMap(event)
|
||||
for k, v := range m {
|
||||
(*e.client).Publish(fmt.Sprintf("weather/WS-2920C/%s", k), 0, false, v)
|
||||
}
|
||||
return event, nil
|
||||
}
|
||||
|
||||
func (e eventService) UpdateEvent(event *weather.AmbientEntry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e eventService) DeleteEvent(event *weather.AmbientEntry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func eventToMap(event *weather.AmbientEntry) map[string]string {
|
||||
m := make(map[string]string)
|
||||
iVal := reflect.ValueOf(event).Elem()
|
||||
typ := iVal.Type()
|
||||
for i := 0; i < iVal.NumField(); i++ {
|
||||
f := iVal.Field(i)
|
||||
var v string
|
||||
switch f.Interface().(type) {
|
||||
case int, int8, int16, int32, int64:
|
||||
v = strconv.FormatInt(f.Int(), 10)
|
||||
case uint, uint8, uint16, uint32, uint64:
|
||||
v = strconv.FormatUint(f.Uint(), 10)
|
||||
case float32:
|
||||
v = strconv.FormatFloat(f.Float(), 'f', 4, 32)
|
||||
case float64:
|
||||
v = strconv.FormatFloat(f.Float(), 'f', 4, 64)
|
||||
case []byte:
|
||||
v = string(f.Bytes())
|
||||
case string:
|
||||
v = f.String()
|
||||
case bool:
|
||||
if f.Bool() {
|
||||
v = "true"
|
||||
} else {
|
||||
v = "false"
|
||||
}
|
||||
case time.Time:
|
||||
v = strconv.FormatInt(f.Interface().(time.Time).Unix(), 10)
|
||||
}
|
||||
m[typ.Field(i).Name] = v
|
||||
|
||||
}
|
||||
return m
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/dustinpianalto/weather"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
var (
|
||||
EventService weather.AmbientService
|
||||
)
|
||||
|
||||
func ConnectDatabase(dbConnString string) {
|
||||
db, err := sql.Open("postgres", dbConnString)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Can't connect to the database. %v", err))
|
||||
}
|
||||
db.SetMaxOpenConns(75) // The RDS instance has a max of 75 open connections
|
||||
db.SetMaxIdleConns(5)
|
||||
db.SetConnMaxLifetime(300)
|
||||
log.Println("Database Connected")
|
||||
initServices(db)
|
||||
log.Println("Postgres Database Initialized")
|
||||
}
|
||||
|
||||
func initServices(db *sql.DB) {
|
||||
EventService = eventService{db: db}
|
||||
}
|
||||
@ -0,0 +1,173 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/dustinpianalto/weather"
|
||||
)
|
||||
|
||||
type eventService struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func (e eventService) Event(i uint64) (*weather.AmbientEntry, error) {
|
||||
queryString := `SELECT
|
||||
mac, dateutc, winddir, windspeedmph, windgustmph, windgustdir, maxdailygust,
|
||||
windspdmph_avg2m, winddir_avg2m, windspdmph_avg10m, winddir_avg10m, windgustmph_interval,
|
||||
humidity, humidity1, humidity2, humidity3, humidity4, humidity5, humidity6, humidity7,
|
||||
humidity8, humidity9, humidity10, humidityin, tempf, temp1f, temp2f, temp3f, temp4f, temp5f,
|
||||
temp6f, temp7f, temp8f, temp9f, temp10f, tempinf, hourlyrainin, dailyrainin, last24hourrainin,
|
||||
weeklyrainin, monthlyrainin, yearlyrainin, eventrainin, totalrainin, baromrelin, baromabsin,
|
||||
uv, solarradiation, co2, pm25, pm25_24h, pm25_in, pm25_in_24h, pm10_in, pm10_in_24h, co2_in,
|
||||
co2_in_24h, pm_in_temp, pm_in_humidity, relay1, relay2, relay3, relay4, relay5, relay6,
|
||||
relay7, relay8, relay9, relay10, soiltemp1, soiltemp2, soiltemp3, soiltemp4, soiltemp5,
|
||||
soiltemp6, soiltemp7, soiltemp8, soiltemp9, soiltemp10, soilhum1, soilhum2, soilhum3, soilhum4,
|
||||
soilhum5, soilhum6, soilhum7, soilhum8, soilhum9, soilhum10, leak1, leak2, leak3, leak4,
|
||||
lightning_time, lightning_day, lightning_distance, battout, battin, batt1, batt2, batt3, batt4,
|
||||
batt5, batt6, batt7, batt8, batt9, batt10, battr1, battr2, battr3, battr4, battr5, battr6,
|
||||
battr7, battr8, battr9, battr10, batt_25, batt_25in, batleak1, batleak2, batleak3, batleak4,
|
||||
batt_lightning, battsm1, battsm2, battsm3, battsm4, battrain, batt_co2, stationtype, passkey
|
||||
FROM events WHERE id = $1`
|
||||
event := weather.AmbientEntry{
|
||||
ID: i,
|
||||
}
|
||||
err := e.db.QueryRow(queryString, i).Scan(
|
||||
&event.MAC, &event.DateUTC, &event.WindDir, &event.WindSpeedMPH, &event.WindGustMPH,
|
||||
&event.WindGustDir, &event.MaxDailyGust, &event.WindSpdMPH_Avg2m, &event.WindDir_Avg2m,
|
||||
&event.WindSpdMPH_Avg10m, &event.WindDir_Avg10m, &event.WindGustMPH_Interval, &event.Humidity,
|
||||
&event.Humidity1, &event.Humidity2, &event.Humidity3, &event.Humidity4, &event.Humidity5,
|
||||
&event.Humidity6, &event.Humidity7, &event.Humidity8, &event.Humidity9, &event.Humidity10,
|
||||
&event.HumidityIn, &event.TempF, &event.Temp1F, &event.Temp2F, &event.Temp3F, &event.Temp4F,
|
||||
&event.Temp5F, &event.Temp6F, &event.Temp7F, &event.Temp8F, &event.Temp9F, &event.Temp10F,
|
||||
&event.TempInF, &event.HourlyRainIn, &event.DailyRainIn, &event.Last24HourRainIn,
|
||||
&event.WeeklyRainIn, &event.MonthlyRainIn, &event.YearlyRainIn, &event.EventRainIn,
|
||||
&event.TotalRainIn, &event.BaromRelIn, &event.BaromAbsIn, &event.UV, &event.SolarRadiation,
|
||||
&event.CO2, &event.PM25, &event.PM25_24H, &event.PM25_In, &event.PM25_In_24H, &event.PM10_In,
|
||||
&event.PM10_In_24H, &event.CO2_In, &event.CO2_In_24H, &event.PM_In_Temp, &event.PM_in_Humidity,
|
||||
&event.Relay1, &event.Relay2, &event.Relay3, &event.Relay4, &event.Relay5, &event.Relay6,
|
||||
&event.Relay7, &event.Relay8, &event.Relay9, &event.Relay10, &event.SoilTemp1, &event.SoilTemp2,
|
||||
&event.SoilTemp3, &event.SoilTemp4, &event.SoilTemp5, &event.SoilTemp6, &event.SoilTemp7,
|
||||
&event.SoilTemp8, &event.SoilTemp9, &event.SoilTemp10, &event.SoilHum1, &event.SoilHum2,
|
||||
&event.SoilHum3, &event.SoilHum4, &event.SoilHum5, &event.SoilHum6, &event.SoilHum7,
|
||||
&event.SoilHum8, &event.SoilHum9, &event.SoilHum10, &event.Leak1, &event.Leak2, &event.Leak3,
|
||||
&event.Leak4, &event.Lightning_Time, &event.Lightning_Day, &event.Lightning_Distance,
|
||||
&event.BattOut, &event.BattIn, &event.Batt1, &event.Batt2, &event.Batt3, &event.Batt4,
|
||||
&event.Batt5, &event.Batt6, &event.Batt7, &event.Batt8, &event.Batt9, &event.Batt10,
|
||||
&event.BattR1, &event.BattR2, &event.BattR3, &event.BattR4, &event.BattR5, &event.BattR6,
|
||||
&event.BattR7, &event.BattR8, &event.BattR9, &event.BattR10, &event.Batt_25, &event.Batt_25In,
|
||||
&event.BatLeak1, &event.BatLeak2, &event.BatLeak3, &event.BatLeak4, &event.Batt_Lightning,
|
||||
&event.BattSM1, &event.BattSM2, &event.BattSM3, &event.BattSM4, &event.BattRain, &event.BattCO2,
|
||||
&event.StationType, &event.PASSKEY)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &event, nil
|
||||
}
|
||||
|
||||
func (e eventService) AddEvent(event *weather.AmbientEntry) (*weather.AmbientEntry, error) {
|
||||
queryString := `INSERT INTO events
|
||||
(mac, dateutc, winddir, windspeedmph, windgustmph, windgustdir, maxdailygust,
|
||||
windspdmph_avg2m, winddir_avg2m, windspdmph_avg10m, winddir_avg10m, windgustmph_interval,
|
||||
humidity, humidity1, humidity2, humidity3, humidity4, humidity5, humidity6, humidity7,
|
||||
humidity8, humidity9, humidity10, humidityin, tempf, temp1f, temp2f, temp3f, temp4f,
|
||||
temp5f, temp6f, temp7f, temp8f, temp9f, temp10f, tempinf, hourlyrainin, dailyrainin,
|
||||
last24hourrainin, weeklyrainin, monthlyrainin, yearlyrainin, eventrainin, totalrainin, baromrelin,
|
||||
baromabsin, uv, solarradiation, co2, pm25, pm25_24h, pm25_in, pm25_in_24h, pm10_in, pm10_in_24h,
|
||||
co2_in, co2_in_24h, pm_in_temp, pm_in_humidity, relay1, relay2, relay3, relay4, relay5, relay6,
|
||||
relay7, relay8, relay9, relay10, soiltemp1, soiltemp2, soiltemp3, soiltemp4, soiltemp5, soiltemp6,
|
||||
soiltemp7, soiltemp8, soiltemp9, soiltemp10, soilhum1, soilhum2, soilhum3, soilhum4, soilhum5,
|
||||
soilhum6, soilhum7, soilhum8, soilhum9, soilhum10, leak1, leak2, leak3, leak4, lightning_time,
|
||||
lightning_day, lightning_distance, battout, battin, batt1, batt2, batt3, batt4, batt5, batt6,
|
||||
batt7, batt8, batt9, batt10, battr1, battr2, battr3, battr4, battr5, battr6, battr7, battr8,
|
||||
battr9, battr10, batt_25, batt_25in, batleak1, batleak2, batleak3, batleak4, batt_lightning,
|
||||
battsm1, battsm2, battsm3, battsm4, battrain, batt_co2, stationtype, passkey)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21,
|
||||
$22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35, $36, $37, $38, $39, $40,
|
||||
$41, $42, $43, $44, $45, $46, $47, $48, $49, $50, $51, $52, $53, $54, $55, $56, $57, $58, $59,
|
||||
$60, $61, $62, $63, $64, $65, $66, $67, $68, $69, $70, $71, $72, $73, $74, $75, $76, $77, $78,
|
||||
$79, $80, $81, $82, $83, $84, $85, $86, $87, $88, $89, $90, $91, $92, $93, $94, $95, $96, $97,
|
||||
$98, $99, $100, $101, $102, $103, $104, $105, $106, $107, $108, $109, $110, $111, $112, $113,
|
||||
$114, $115, $116, $117, $118, $119, $120, $121, $122, $123, $124, $125, $126, $127, $128, $129,
|
||||
$130, $131, $132, $133)
|
||||
RETURNING id`
|
||||
err := e.db.QueryRow(queryString, event.MAC, event.DateUTC, event.WindDir, event.WindSpeedMPH,
|
||||
event.WindGustMPH, event.WindGustDir, event.MaxDailyGust, event.WindSpdMPH_Avg2m, event.WindDir_Avg2m,
|
||||
event.WindSpdMPH_Avg10m, event.WindDir_Avg10m, event.WindGustMPH_Interval, event.Humidity,
|
||||
event.Humidity1, event.Humidity2, event.Humidity3, event.Humidity4, event.Humidity5, event.Humidity6,
|
||||
event.Humidity7, event.Humidity8, event.Humidity9, event.Humidity10, event.HumidityIn, event.TempF,
|
||||
event.Temp1F, event.Temp2F, event.Temp3F, event.Temp4F, event.Temp5F, event.Temp6F, event.Temp7F,
|
||||
event.Temp8F, event.Temp9F, event.Temp10F, event.TempInF, event.HourlyRainIn, event.DailyRainIn,
|
||||
event.Last24HourRainIn, event.WeeklyRainIn, event.MonthlyRainIn, event.YearlyRainIn, event.EventRainIn,
|
||||
event.TotalRainIn, event.BaromRelIn, event.BaromAbsIn, event.UV, event.SolarRadiation, event.CO2,
|
||||
event.PM25, event.PM25_24H, event.PM25_In, event.PM25_In_24H, event.PM10_In, event.PM10_In_24H,
|
||||
event.CO2_In, event.CO2_In_24H, event.PM_In_Temp, event.PM_in_Humidity, event.Relay1, event.Relay2,
|
||||
event.Relay3, event.Relay4, event.Relay5, event.Relay6, event.Relay7, event.Relay8, event.Relay9,
|
||||
event.Relay10, event.SoilTemp1, event.SoilTemp2, event.SoilTemp3, event.SoilTemp4, event.SoilTemp5,
|
||||
event.SoilTemp6, event.SoilTemp7, event.SoilTemp8, event.SoilTemp9, event.SoilTemp10, event.SoilHum1,
|
||||
event.SoilHum2, event.SoilHum3, event.SoilHum4, event.SoilHum5, event.SoilHum6, event.SoilHum7,
|
||||
event.SoilHum8, event.SoilHum9, event.SoilHum10, event.Leak1, event.Leak2, event.Leak3, event.Leak4,
|
||||
event.Lightning_Time, event.Lightning_Day, event.Lightning_Distance, event.BattOut, event.BattIn,
|
||||
event.Batt1, event.Batt2, event.Batt3, event.Batt4, event.Batt5, event.Batt6, event.Batt7, event.Batt8,
|
||||
event.Batt9, event.Batt10, event.BattR1, event.BattR2, event.BattR3, event.BattR4, event.BattR5,
|
||||
event.BattR6, event.BattR7, event.BattR8, event.BattR9, event.BattR10, event.Batt_25, event.Batt_25In,
|
||||
event.BatLeak1, event.BatLeak2, event.BatLeak3, event.BatLeak4, event.Batt_Lightning, event.BattSM1,
|
||||
event.BattSM2, event.BattSM3, event.BattSM4, event.BattRain, event.BattCO2, event.StationType,
|
||||
event.PASSKEY).Scan(&event.ID)
|
||||
return event, err
|
||||
}
|
||||
|
||||
func (e eventService) UpdateEvent(event *weather.AmbientEntry) error {
|
||||
queryString := `UPDATE events SET
|
||||
mac = $2, dateutc = $3, winddir = $4, windspeedmph = $5, windgustmph = $6, windgustdir = $7,
|
||||
maxdailygust = $8, windspdmph_avg2m = $9, winddir_avg2m = $10, windspdmph_avg10m = $11, winddir_avg10m = $12,
|
||||
windgustmph_interval = $13, humidity = $14, humidity1 = $15, humidity2 = $16, humidity3 = $17, humidity4 = $18,
|
||||
humidity5 = $19, humidity6 = $20, humidity7 = $21, humidity8 = $22, humidity9 = $23, humidity10 = $24,
|
||||
humidityin = $25, tempf = $26, temp1f = $27, temp2f = $28, temp3f = $29, temp4f = $30, temp5f = $31,
|
||||
temp6f = $32, temp7f = $33, temp8f = $34, temp9f = $35, temp10f = $36, tempinf = $37, hourlyrainin = $38,
|
||||
dailyrainin = $39, last24hourrainin = $40, weeklyrainin = $41, monthlyrainin = $42, yearlyrainin = $43,
|
||||
eventrainin = $44, totalrainin = $45, baromrelin = $46, baromabsin = $47, uv = $48, solarradiation = $49,
|
||||
co2 = $50, pm25 = $51, pm25_24h = $52, pm25_in = $53, pm25_in_24h = $54, pm10_in = $55, pm10_in_24h = $56,
|
||||
co2_in = $57, co2_in_24h = $58, pm_in_temp = $59, pm_in_humidity = $60, relay1 = $61, relay2 = $62,
|
||||
relay3 = $63, relay4 = $64, relay5 = $65, relay6 = $66, relay7 = $67, relay8 = $68, relay9 = $69,
|
||||
relay10 = $70, soiltemp1 = $71, soiltemp2 = $72, soiltemp3 = $73, soiltemp4 = $74, soiltemp5 = $75,
|
||||
soiltemp6 = $76, soiltemp7 = $77, soiltemp8 = $78, soiltemp9 = $79, soiltemp10 = $80, soilhum1 = $81,
|
||||
soilhum2 = $82, soilhum3 = $83, soilhum4 = $84, soilhum5 = $85, soilhum6 = $86, soilhum7 = $87,
|
||||
soilhum8 = $88, soilhum9 = $89, soilhum10 = $90, leak1 = $91, leak2 = $92, leak3 = $93, leak4 = $94,
|
||||
lightning_time = $95, lightning_day = $96, lightning_distance = $97, battout = $98, battin = $99,
|
||||
batt1 = $100, batt2 = $101, batt3 = $102, batt4 = $103, batt5 = $104, batt6 = $105, batt7 = $106,
|
||||
batt8 = $107, batt9 = $108, batt10 = $109, battr1 = $110, battr2 = $111, battr3 = $112, battr4 = $113,
|
||||
battr5 = $114, battr6 = $115, battr7 = $116, battr8 = $117, battr9 = $118, battr10 = $119, batt_25 = $120,
|
||||
batt_25in = $121, batleak1 = $122, batleak2 = $123, batleak3 = $124, batleak4 = $125, batt_lightning = $126,
|
||||
battsm1 = $127, battsm2 = $128, battsm3 = $129, battsm4 = $130, battrain = $131, batt_co2 = $132,
|
||||
stationtype = $133, passkey = $134, WHERE id = $1`
|
||||
_, err := e.db.Exec(queryString, event.ID, event.MAC, event.DateUTC, event.WindDir, event.WindSpeedMPH,
|
||||
event.WindGustMPH, event.WindGustDir, event.MaxDailyGust, event.WindSpdMPH_Avg2m, event.WindDir_Avg2m,
|
||||
event.WindSpdMPH_Avg10m, event.WindDir_Avg10m, event.WindGustMPH_Interval, event.Humidity, event.Humidity1,
|
||||
event.Humidity2, event.Humidity3, event.Humidity4, event.Humidity5, event.Humidity6, event.Humidity7,
|
||||
event.Humidity8, event.Humidity9, event.Humidity10, event.HumidityIn, event.TempF, event.Temp1F,
|
||||
event.Temp2F, event.Temp3F, event.Temp4F, event.Temp5F, event.Temp6F, event.Temp7F, event.Temp8F,
|
||||
event.Temp9F, event.Temp10F, event.TempInF, event.HourlyRainIn, event.DailyRainIn, event.Last24HourRainIn,
|
||||
event.WeeklyRainIn, event.MonthlyRainIn, event.YearlyRainIn, event.EventRainIn, event.TotalRainIn,
|
||||
event.BaromRelIn, event.BaromAbsIn, event.UV, event.SolarRadiation, event.CO2, event.PM25, event.PM25_24H,
|
||||
event.PM25_In, event.PM25_In_24H, event.PM10_In, event.PM10_In_24H, event.CO2_In, event.CO2_In_24H,
|
||||
event.PM_In_Temp, event.PM_in_Humidity, event.Relay1, event.Relay2, event.Relay3, event.Relay4, event.Relay5,
|
||||
event.Relay6, event.Relay7, event.Relay8, event.Relay9, event.Relay10, event.SoilTemp1, event.SoilTemp2,
|
||||
event.SoilTemp3, event.SoilTemp4, event.SoilTemp5, event.SoilTemp6, event.SoilTemp7, event.SoilTemp8,
|
||||
event.SoilTemp9, event.SoilTemp10, event.SoilHum1, event.SoilHum2, event.SoilHum3, event.SoilHum4,
|
||||
event.SoilHum5, event.SoilHum6, event.SoilHum7, event.SoilHum8, event.SoilHum9, event.SoilHum10,
|
||||
event.Leak1, event.Leak2, event.Leak3, event.Leak4, event.Lightning_Time, event.Lightning_Day,
|
||||
event.Lightning_Distance, event.BattOut, event.BattIn, event.Batt1, event.Batt2, event.Batt3, event.Batt4,
|
||||
event.Batt5, event.Batt6, event.Batt7, event.Batt8, event.Batt9, event.Batt10, event.BattR1, event.BattR2,
|
||||
event.BattR3, event.BattR4, event.BattR5, event.BattR6, event.BattR7, event.BattR8, event.BattR9,
|
||||
event.BattR10, event.Batt_25, event.Batt_25In, event.BatLeak1, event.BatLeak2, event.BatLeak3, event.BatLeak4,
|
||||
event.Batt_Lightning, event.BattSM1, event.BattSM2, event.BattSM3, event.BattSM4, event.BattRain,
|
||||
event.BattCO2, event.StationType, event.PASSKEY)
|
||||
return err
|
||||
}
|
||||
|
||||
func (e eventService) DeleteEvent(event *weather.AmbientEntry) error {
|
||||
queryString := "DELETE FROM events WHERE id = $1"
|
||||
_, err := e.db.Exec(queryString, event.ID)
|
||||
return err
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
CREATE TABLE IF NOT EXISTS events (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
mac char(17) not null,
|
||||
dateutc timestamp not null,
|
||||
winddir integer,
|
||||
windspeedmph float,
|
||||
windgustmph float,
|
||||
windgustdir integer,
|
||||
maxdailygust float,
|
||||
windspdmph_avg2m float,
|
||||
winddir_avg2m integer,
|
||||
windspdmph_avg10m float,
|
||||
winddir_avg10m integer,
|
||||
windgustmph_interval integer,
|
||||
humidity integer,
|
||||
humidity1 integer,
|
||||
humidity2 integer,
|
||||
humidity3 integer,
|
||||
humidity4 integer,
|
||||
humidity5 integer,
|
||||
humidity6 integer,
|
||||
humidity7 integer,
|
||||
humidity8 integer,
|
||||
humidity9 integer,
|
||||
humidity10 integer,
|
||||
humidityin integer,
|
||||
tempf float,
|
||||
temp1f float,
|
||||
temp2f float,
|
||||
temp3f float,
|
||||
temp4f float,
|
||||
temp5f float,
|
||||
temp6f float,
|
||||
temp7f float,
|
||||
temp8f float,
|
||||
temp9f float,
|
||||
temp10f float,
|
||||
tempinf float,
|
||||
hourlyrainin float,
|
||||
dailyrainin float,
|
||||
last24hourrainin float,
|
||||
weeklyrainin float,
|
||||
monthlyrainin float,
|
||||
yearlyrainin float,
|
||||
eventrainin float,
|
||||
totalrainin float,
|
||||
baromrelin float,
|
||||
baromabsin float,
|
||||
uv integer,
|
||||
solarradiation float,
|
||||
co2 integer,
|
||||
pm25 integer,
|
||||
pm25_24h float,
|
||||
pm25_in integer,
|
||||
pm25_in_24h float,
|
||||
pm10_in integer,
|
||||
pm10_in_24h float,
|
||||
co2_in integer,
|
||||
co2_in_24h float,
|
||||
pm_in_temp float,
|
||||
pm_in_humidity integer,
|
||||
relay1 boolean,
|
||||
relay2 boolean,
|
||||
relay3 boolean,
|
||||
relay4 boolean,
|
||||
relay5 boolean,
|
||||
relay6 boolean,
|
||||
relay7 boolean,
|
||||
relay8 boolean,
|
||||
relay9 boolean,
|
||||
relay10 boolean,
|
||||
soiltemp1 float,
|
||||
soiltemp2 float,
|
||||
soiltemp3 float,
|
||||
soiltemp4 float,
|
||||
soiltemp5 float,
|
||||
soiltemp6 float,
|
||||
soiltemp7 float,
|
||||
soiltemp8 float,
|
||||
soiltemp9 float,
|
||||
soiltemp10 float,
|
||||
soilhum1 integer,
|
||||
soilhum2 integer,
|
||||
soilhum3 integer,
|
||||
soilhum4 integer,
|
||||
soilhum5 integer,
|
||||
soilhum6 integer,
|
||||
soilhum7 integer,
|
||||
soilhum8 integer,
|
||||
soilhum9 integer,
|
||||
soilhum10 integer,
|
||||
leak1 boolean,
|
||||
leak2 boolean,
|
||||
leak3 boolean,
|
||||
leak4 boolean,
|
||||
lightning_time timestamp,
|
||||
lightning_day integer,
|
||||
lightning_distance float,
|
||||
battout boolean,
|
||||
battin boolean,
|
||||
batt1 boolean,
|
||||
batt2 boolean,
|
||||
batt3 boolean,
|
||||
batt4 boolean,
|
||||
batt5 boolean,
|
||||
batt6 boolean,
|
||||
batt7 boolean,
|
||||
batt8 boolean,
|
||||
batt9 boolean,
|
||||
batt10 boolean,
|
||||
battr1 boolean,
|
||||
battr2 boolean,
|
||||
battr3 boolean,
|
||||
battr4 boolean,
|
||||
battr5 boolean,
|
||||
battr6 boolean,
|
||||
battr7 boolean,
|
||||
battr8 boolean,
|
||||
battr9 boolean,
|
||||
battr10 boolean,
|
||||
batt_25 boolean,
|
||||
batt_25in boolean,
|
||||
batleak1 boolean,
|
||||
batleak2 boolean,
|
||||
batleak3 boolean,
|
||||
batleak4 boolean,
|
||||
batt_lightning boolean,
|
||||
battsm1 boolean,
|
||||
battsm2 boolean,
|
||||
battsm3 boolean,
|
||||
battsm4 boolean,
|
||||
battrain boolean,
|
||||
batt_co2 boolean,
|
||||
stationtype varchar(30),
|
||||
passkey char(17)
|
||||
);
|
||||
@ -0,0 +1,46 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/dustinpianalto/errors"
|
||||
"github.com/dustinpianalto/weather"
|
||||
"github.com/dustinpianalto/weather/pkg/services"
|
||||
"github.com/gorilla/schema"
|
||||
)
|
||||
|
||||
func AmbientHandler(w http.ResponseWriter, r *http.Request) {
|
||||
const method errors.Method = "endpoints/AmbientHandler"
|
||||
entry := &weather.AmbientEntry{}
|
||||
decoder := schema.NewDecoder()
|
||||
decoder.RegisterConverter(time.Time{}, timeConverter)
|
||||
if err := decoder.Decode(entry, r.URL.Query()); err != nil {
|
||||
log.Println(errors.E(method, errors.Malformed, "error decoding AmbientEntry", err))
|
||||
return
|
||||
}
|
||||
if entry.MAC == "" && entry.PASSKEY != "" {
|
||||
entry.MAC = entry.PASSKEY
|
||||
}
|
||||
entry, err := services.EventService.AddEvent(entry)
|
||||
if err != nil {
|
||||
log.Println(errors.E(method, errors.Internal, "error adding entry to database", err))
|
||||
return
|
||||
}
|
||||
log.Printf("%#v\n\n", entry)
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte{})
|
||||
}
|
||||
|
||||
func timeConverter(value string) reflect.Value {
|
||||
if v, err := time.Parse("2006-01-02 15:04:05", value); err == nil {
|
||||
return reflect.ValueOf(v)
|
||||
} else if i, err := strconv.ParseInt(value, 10, 64); err == nil {
|
||||
return reflect.ValueOf(time.Unix(i, 0))
|
||||
}
|
||||
return reflect.Value{}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/dustinpianalto/weather"
|
||||
"github.com/dustinpianalto/weather/internal/mqtt"
|
||||
"github.com/dustinpianalto/weather/internal/postgres"
|
||||
)
|
||||
|
||||
var EventService weather.AmbientService
|
||||
|
||||
func InitServices() {
|
||||
EventService = eventService{
|
||||
postgesService: postgres.EventService,
|
||||
mqttService: mqtt.AmbientService,
|
||||
}
|
||||
log.Println("Services Initialized")
|
||||
}
|
||||
|
||||
type eventService struct {
|
||||
postgesService weather.AmbientService
|
||||
mqttService weather.AmbientService
|
||||
}
|
||||
|
||||
func (e eventService) Event(i uint64) (*weather.AmbientEntry, error) {
|
||||
return e.postgesService.Event(i)
|
||||
}
|
||||
|
||||
func (e eventService) AddEvent(event *weather.AmbientEntry) (*weather.AmbientEntry, error) {
|
||||
event, err := e.postgesService.AddEvent(event)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
event, err = e.mqttService.AddEvent(event)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
return event, nil
|
||||
}
|
||||
|
||||
func (e eventService) UpdateEvent(event *weather.AmbientEntry) error {
|
||||
return e.postgesService.UpdateEvent(event)
|
||||
}
|
||||
|
||||
func (e eventService) DeleteEvent(event *weather.AmbientEntry) error {
|
||||
return e.postgesService.UpdateEvent(event)
|
||||
}
|
||||
Loading…
Reference in new issue