Initial commit
This commit is contained in:
commit
e66ae9695b
|
|
@ -0,0 +1,3 @@
|
|||
lorahandler
|
||||
lorahandler.log*
|
||||
logs/*
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
awk '{$3=strftime("%Y-%m-%d %H:%M:%S", substr($NF,1,10)); print $0}' lorahandler.log
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=wo-bisch-lorahandler web service
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=appuser
|
||||
Group=appuser
|
||||
WorkingDirectory=/home/appuser/wo-bisch-lorahandler
|
||||
ExecStart=/home/appuser/wo-bisch-lorahandler/wo-bisch-lorahandler
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Binary file not shown.
|
|
@ -0,0 +1,185 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
outputfile = "/home/appuser/wo-bisch-lorahandler/wo-bisch-lorahandler.log"
|
||||
)
|
||||
|
||||
type MetadataTTN struct {
|
||||
Time string `json:"time"`
|
||||
}
|
||||
|
||||
type MessageTTN struct {
|
||||
Hardware_serial string `json:"hardware_serial"`
|
||||
Metadata MetadataTTN `json:"metadata"`
|
||||
Payload_raw string `json:"payload_raw"`
|
||||
}
|
||||
|
||||
type MessageProperties struct {
|
||||
Time string `json:"Time"`
|
||||
Payload_hex string `json:"payload_hex"`
|
||||
DevEUI string `json:"DevEUI"`
|
||||
DevAddr string `json:"DevAddr"`
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
Prop MessageProperties `json:"DevEUI_uplink"`
|
||||
}
|
||||
|
||||
// Global variables
|
||||
var file *os.File
|
||||
|
||||
func WriteStringToFile(s string, deveui 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)
|
||||
}
|
||||
|
||||
// Also write to individual files
|
||||
datestr := time.Now().Format("2006-01")
|
||||
individual_file := "/home/appuser/wo-bisch-lorahandler/logs/" + deveui + "-" + datestr + ".log"
|
||||
|
||||
fi, err := os.OpenFile(individual_file, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer fi.Close()
|
||||
fi.WriteString(s)
|
||||
}
|
||||
|
||||
func Convert2Hex(payload_raw string) (string, error) {
|
||||
res := "error"
|
||||
p, err := base64.StdEncoding.DecodeString(payload_raw)
|
||||
if err == nil {
|
||||
res = hex.EncodeToString(p)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func DecodePayload(s string, deveui string) {
|
||||
type payload struct {
|
||||
Latitude uint32
|
||||
Longitude uint32
|
||||
AlarmBat uint16
|
||||
Flag uint8
|
||||
}
|
||||
|
||||
var ba []byte
|
||||
var pl payload
|
||||
|
||||
if len(s) >= 22 {
|
||||
ba, _ = hex.DecodeString(s[0:22])
|
||||
br := bytes.NewReader(ba)
|
||||
pl = payload{}
|
||||
err := binary.Read(br, binary.BigEndian, &pl)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
log.Printf("Latitude: %.5f", float32(pl.Latitude / 1000000.0))
|
||||
log.Printf("Longitude: %.5f", float32(pl.Longitude / 1000000.0))
|
||||
log.Printf("AlarmBat: %d", pl.AlarmBat)
|
||||
log.Printf("Flag: %d", pl.Flag)
|
||||
|
||||
vbat := (pl.AlarmBat & 0x3fff) // Battery Voltage in mV
|
||||
fw := 160 + (pl.Flag & 0x1f) // Firmware version; 5 bits
|
||||
|
||||
mystring := fmt.Sprintf("measurement,deveui=%s lat=%.5f,lon=%.5f,vbat=%d,fw=%d %d\n", deveui, float32(pl.Latitude / 1000000.0), float32(pl.Longitude / 1000000.0), vbat, fw, (time.Now().Unix() / 60))
|
||||
|
||||
WriteStringToFile(mystring, deveui)
|
||||
|
||||
} else {
|
||||
log.Printf("Payload is not >= 11 bytes (22 chars): %s", s)
|
||||
}
|
||||
}
|
||||
|
||||
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 message_swisscom Message
|
||||
var message_ttn MessageTTN
|
||||
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
|
||||
|
||||
// We look for the text string "mini-beieli" in the buffer, then it is a TTN Packet,
|
||||
// otherwise it should be a Swisscom Packet...
|
||||
|
||||
fmt.Printf("Length of JSON Body: %d\n", len(buf))
|
||||
|
||||
if strings.Contains(string(buf), "mini-beieli") {
|
||||
fmt.Printf("Seems to be a TTN Packet...\n")
|
||||
// it is probably a TTN package...
|
||||
err := json.NewDecoder(r.Body).Decode(&message_ttn)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 400)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Time: " + message_ttn.Metadata.Time)
|
||||
fmt.Println("Payload Raw: " + message_ttn.Payload_raw)
|
||||
fmt.Println("DevEUI: " + message_ttn.Hardware_serial)
|
||||
payload_hex, err := Convert2Hex(message_ttn.Payload_raw)
|
||||
if err == nil {
|
||||
DecodePayload(payload_hex, message_ttn.Hardware_serial)
|
||||
} else {
|
||||
fmt.Println("Error: could not convert raw_package to hex: %s" + message_ttn.Payload_raw)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("Seems to be a Swisscom Packet...\n")
|
||||
// it is probably a Swisscom package...
|
||||
err := json.NewDecoder(r.Body).Decode(&message_swisscom)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 400)
|
||||
return
|
||||
}
|
||||
fmt.Println("Time: " + message_swisscom.Prop.Time)
|
||||
fmt.Println("Payload Hex: " + message_swisscom.Prop.Payload_hex)
|
||||
fmt.Println("DevEUI: " + message_swisscom.Prop.DevEUI)
|
||||
fmt.Println("DevAddr: " + message_swisscom.Prop.DevAddr)
|
||||
DecodePayload(message_swisscom.Prop.Payload_hex, message_swisscom.Prop.DevEUI)
|
||||
}
|
||||
})
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
measurement,deveui=A8404100018193D7 lat=46.00000,lon=7.00000,vbat=4055,fw=164 26911834
|
||||
Loading…
Reference in New Issue