mini-beieli-lorahandler/lorahandler.go

243 lines
6.6 KiB
Go

package main
import (
"bytes"
"encoding/json"
"encoding/hex"
"encoding/binary"
"fmt"
"os"
"io/ioutil"
"log"
"net/http"
"time"
)
const (
MyDB = "beieliscaledb"
username = "beieli"
password = "beieli4president"
outputfile = "/home/beieli/lorahandler/lorahandler.log"
)
type MessageProperties struct {
Time string `json:"Time"`
Payload_hex string `json:"payload_hex"`
DevAddr string `json:"DevAddr"`
LrrLAT float32 `json:"LrrLAT"`
LrrLON float32 `json:"LrrLON"`
}
type Message struct {
Prop MessageProperties `json:"DevEUI_uplink"`
}
type payload_128 struct {
Version uint8
Vbat uint8
H uint8
T int16
P uint8
W1 int32
W2 int32
W uint16
}
type payload_1 struct {
Version uint8
Vbat uint8
H1 uint8
H2 uint8
H3 uint8
H4 uint8
H5 uint8
H6 uint8
H7 uint8
H8 uint8
T int16
TC1 int8
TC2 int8
TC3 int8
TC4 int8
TC5 int8
TC6 int8
TC7 int8
P1 uint8
P2 uint8
P3 uint8
P4 uint8
P5 uint8
P6 uint8
P7 uint8
P8 uint8
W1 uint16
W2 uint16
W3 uint16
W4 uint16
W5 uint16
W6 uint16
W7 uint16
W8 uint16
O uint8
}
// Global variables
var file *os.File
func DecodePayload(s string, devaddr string, lrrlat float32, lrrlon float32, write2file bool) {
var ba []byte
var pl_1 payload_1
var pl_128 payload_128
ba, _ = hex.DecodeString(s)
pl_1 = payload_1{}
pl_128 = payload_128{}
br := bytes.NewReader(ba)
if (s[0:2] == "01") {
err := binary.Read(br, binary.LittleEndian, &pl_1)
if err != nil {
fmt.Println(err)
}
} else if (s[0:2] == "80") {
err := binary.Read(br, binary.LittleEndian, &pl_128)
if err != nil {
fmt.Println(err)
}
} else {
fmt.Printf("Payload String is unknown: %s\n",s)
}
if (s[0:2] == "01") {
fmt.Printf("{\n")
fmt.Printf(" version: %d,\n", pl_1.Version)
fmt.Printf(" vbat: %d,\n", pl_1.Vbat)
fmt.Printf(" offset: %d\n",pl_1.O)
fmt.Printf(" humidity: [%d,%d,%d,%d,%d,%d,%d,%d],\n",pl_1.H1,pl_1.H2,pl_1.H3,pl_1.H4,pl_1.H5,pl_1.H6,pl_1.H7,pl_1.H8)
fmt.Printf(" pressure: [%d,%d,%d,%d,%d,%d,%d,%d],\n",pl_1.P1,pl_1.P2,pl_1.P3,pl_1.P4,pl_1.P5,pl_1.P6,pl_1.P7,pl_1.P8)
fmt.Printf(" weight: [%d,%d,%d,%d,%d,%d,%d,%d],\n",pl_1.W1,pl_1.W2,pl_1.W3,pl_1.W4,pl_1.W5,pl_1.W6,pl_1.W7,pl_1.W8)
fmt.Printf(" temp: %d,\n",pl_1.T)
fmt.Printf(" temp_change: [%d,%d,%d,%d,%d,%d,%d],\n",pl_1.TC1,pl_1.TC2,pl_1.TC3,pl_1.TC4,pl_1.TC5,pl_1.TC6,pl_1.TC7)
fmt.Printf("}\n")
if write2file {
// Time of first Packet
var tfp = (time.Now().Unix() / 60) - int64(pl_1.O)
var step = int64(pl_1.O / 7)
t := pl_1.T
WriteDatapoint(tfp,devaddr,pl_1.Vbat,pl_1.H1,pl_1.P1,pl_1.W1,0,0,t,lrrlat,lrrlon)
t = t + int16(pl_1.TC1)
WriteDatapoint(tfp + (step),devaddr,0,pl_1.H2,pl_1.P2,pl_1.W2,0,0,t,lrrlat,lrrlon)
t = t + int16(pl_1.TC2)
WriteDatapoint(tfp + (2 * step),devaddr,0,pl_1.H3,pl_1.P3,pl_1.W3,0,0,t,lrrlat,lrrlon)
t = t + int16(pl_1.TC3)
WriteDatapoint(tfp + (3 * step),devaddr,0,pl_1.H4,pl_1.P4,pl_1.W4,0,0,t,lrrlat,lrrlon)
t = t + int16(pl_1.TC4)
WriteDatapoint(tfp + (4 * step),devaddr,0,pl_1.H5,pl_1.P5,pl_1.W5,0,0,t,lrrlat,lrrlon)
t = t + int16(pl_1.TC5)
WriteDatapoint(tfp + (5 * step),devaddr,0,pl_1.H6,pl_1.P6,pl_1.W6,0,0,t,lrrlat,lrrlon)
t = t + int16(pl_1.TC6)
WriteDatapoint(tfp + (6 * step),devaddr,0,pl_1.H7,pl_1.P7,pl_1.W7,0,0,t,lrrlat,lrrlon)
t = t + int16(pl_1.TC7)
WriteDatapoint(tfp + (7 * step),devaddr,0,pl_1.H8,pl_1.P8,pl_1.W8,0,0,t,lrrlat,lrrlon)
}
} else if (s[0:2] == "80") {
fmt.Printf("{\n")
fmt.Printf(" version: %d,\n", pl_128.Version)
fmt.Printf(" vbat: %d,\n", pl_128.Vbat)
fmt.Printf(" humidity: %d\n",pl_128.H)
fmt.Printf(" pressure: %d\n",pl_128.P)
fmt.Printf(" weight1: %d\n",pl_128.W1)
fmt.Printf(" weight2: %d\n",pl_128.W2)
fmt.Printf(" weight: %d\n",pl_128.W)
fmt.Printf(" temp: %d\n",pl_128.T)
fmt.Printf("}\n")
if write2file {
// Time of Packet received
var tfp = (time.Now().Unix() / 60)
WriteDatapoint(tfp,devaddr,pl_128.Vbat,pl_128.H,pl_128.P,pl_128.W,pl_128.W1,pl_128.W2,pl_128.T,lrrlat,lrrlon)
}
}
}
func WriteDatapoint(mytime int64, devaddr string, v uint8, h uint8, p uint8, w uint16, w1 int32, w2 int32, t int16, lrrlat float32, lrrlon float32) {
// wir nehmen humidity als Referenz, wenn diese > 0 ist, dann ist es
// eine gueltige Messung
var vp uint8 // Voltage in %
if (h > 0) {
vp = v - 70
if vp < 0 {
vp = 0
} else if vp > 100 {
vp = 100
}
s := ""
if (v > 0) {
s = fmt.Sprintf("measurement,devaddr=%s v=%di,vp=%di,h=%di,p=%di,w=%di,w1=%di,w2=%di,t=%.1f,lrrlat=%f,lrrlon=%f %d\n",devaddr,int32(v)*7+2510,vp,h,int32(p)+825,w*5,w1,w2,float32(t)/10,lrrlat,lrrlon,mytime*60*1000*1000*1000)
} else {
s = fmt.Sprintf("measurement,devaddr=%s h=%di,p=%di,w=%di,w1=%di,w2=%di,t=%.1f,lrrlat=%f,lrrlon=%f %d\n",devaddr,h,int32(p)+825,w*5,w1,w2,float32(t)/10,lrrlat,lrrlon,mytime*60*1000*1000*1000)
}
WriteStringToFile(s)
}
}
func WriteStringToFile(s string) {
n, err := file.WriteString(s)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if n != len(s) {
fmt.Println("failed to write data")
os.Exit(1)
}
}
func main() {
// Open Output File
f, err := os.OpenFile(outputfile,os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
file = f
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer file.Close()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var u Message
if r.Body == nil {
http.Error(w, "Please send a request body", 400)
return
}
buf, bodyErr := ioutil.ReadAll(r.Body)
if bodyErr != nil {
log.Print("bodyErr ", bodyErr.Error())
http.Error(w, bodyErr.Error(), http.StatusInternalServerError)
return
}
rdr1 := ioutil.NopCloser(bytes.NewBuffer(buf))
rdr2 := ioutil.NopCloser(bytes.NewBuffer(buf))
log.Printf("BODY: %s", rdr1)
r.Body = rdr2
err := json.NewDecoder(r.Body).Decode(&u)
if err != nil {
http.Error(w, err.Error(), 400)
return
}
fmt.Println("Time: " + u.Prop.Time)
fmt.Println("Payload Hex: " + u.Prop.Payload_hex)
fmt.Println("DevAddr: " + u.Prop.DevAddr)
fmt.Printf("LrrLAT: %f\n",u.Prop.LrrLAT)
fmt.Printf("LrrLON: %f\n",u.Prop.LrrLON)
DecodePayload(u.Prop.Payload_hex, u.Prop.DevAddr, u.Prop.LrrLAT, u.Prop.LrrLON, true)
})
log.Fatal(http.ListenAndServe(":8080", nil))
}