mini-beieli-lorahandler/main.go

671 lines
21 KiB
Go

package main
import (
"bytes"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"time"
)
const (
MyDB = "beieliscaledb"
username = "beieli"
password = "beieli4president"
outputfile = "/home/beieli/mini-beieli-lorahandler/mini-beieli-lorahandler.log"
NOT_PLAUSIBLE_16 = 65535
NOT_PLAUSIBLE_32 = 2147483647
)
type TTNv3EndDeviceIds struct {
Dev_eui string `json:"dev_eui"`
}
type TTNv3UplinkMessage struct {
Frm_payload string `json:"frm_payload"`
Received_at string `json:"received_at"`
}
type MessageTTNv3 struct {
EndDeviceIds TTNv3EndDeviceIds `json:"end_device_ids"`
UplinkMessage TTNv3UplinkMessage `json:"uplink_message"`
}
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"`
LrrLAT float32 `json:"LrrLAT"`
LrrLON float32 `json:"LrrLON"`
}
type Message struct {
Prop MessageProperties `json:"DevEUI_uplink"`
}
type payload_128 struct {
Version uint8
Fw_version int32
Vbat uint8
H uint8
T int16
P uint8
W1 int32
W2 int32
W1_0 int32
W2_0 int32
W1_C float32
W2_C float32
}
type payload_129 struct {
Version uint8
Fw_version int32
Vbat uint8
H uint8
T int16
P uint8
W1 int32
W2 int32
W uint16
}
type payload_130 struct {
Version uint8
Fw_version int32
Vbat uint8
T int16
H uint8
P uint8
W1 int32
W2 int32
W1_0 int32
W2_0 int32
W1_C float32
W2_C float32
}
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
}
type payload_2 struct {
Version uint8
Vbat uint8
T int16
H uint8
P uint8
TC1 int8
TC2 int8
TC3 int8
TC4 int8
TC5 int8
TC6 int8
TC7 int8
W1 uint16
WC1 int8
WC2 int8
WC3 int8
WC4 int8
WC5 int8
WC6 int8
W8 uint16
O uint8
}
// Global variables
var file *os.File
var alertMap map[string]string
var alertLogMap map[string]string
func ProcessInitPacket(deveui string, w1_0 int32, w2_0 int32, w1_c float32, w2_c float32, w1 int32, w2 int32) {
var downlink_command string
fmt.Printf("Processing Init Packet for Deveui %s\n", deveui)
downlink_command = GetDownlinkCommand(deveui)
if downlink_command == "do_nothing" {
// do nothing
fmt.Printf("Init Packet, downlink_command set to do_nothing (or not set at all), nothing to do... Deveui %s\n", deveui)
} else if downlink_command == "tare_0" {
// reset node to 0
ResetNodeToZero(deveui, w1, w2)
} else if strings.HasPrefix(downlink_command, "tare_a ") {
// calibrate Scale A : tare_a <gram_a>
CalibrateScale(deveui, downlink_command, w1, w2)
} else if strings.HasPrefix(downlink_command, "tare_b ") {
// calibrate Scale B : tare_b <gram_b>
CalibrateScale(deveui, downlink_command, w1, w2)
} else if strings.HasPrefix(downlink_command, "tare ") {
// calibrate both Scale A and Scale B in on step : tare <gram_a> <gram_b>
CalibrateScale(deveui, downlink_command, w1, w2)
} else {
fmt.Printf("Error: Unknown downlink_command: %s (DevEUI: %s)\n", downlink_command, deveui)
}
// We update the local settings on each init package (if something changed...)
UpdateCalibrationSettingsFromNode(deveui, w1_0, w2_0, w1_c, w2_c)
}
func DecodePayload(s string, deveui string, devaddr string, lrrlat float32, lrrlon float32, write2file bool) {
var ba []byte
var pl_1 payload_1
var pl_2 payload_2
var pl_128 payload_128
var pl_129 payload_129
var pl_130 payload_130
ba, _ = hex.DecodeString(s)
pl_1 = payload_1{}
pl_2 = payload_2{}
pl_128 = payload_128{}
pl_129 = payload_129{}
pl_130 = payload_130{}
br := bytes.NewReader(ba)
fmt.Printf("Payload String: %s\n", s)
if s[0:2] == "01" {
err := binary.Read(br, binary.LittleEndian, &pl_1)
if err != nil {
fmt.Println(err)
}
} else if s[0:2] == "02" {
err := binary.Read(br, binary.LittleEndian, &pl_2)
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 if s[0:2] == "81" {
err := binary.Read(br, binary.LittleEndian, &pl_129)
if err != nil {
fmt.Println(err)
}
} else if s[0:2] == "82" {
err := binary.Read(br, binary.LittleEndian, &pl_130)
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)
humidity_values := []uint8{pl_1.H1, pl_1.H2, pl_1.H3, pl_1.H4, pl_1.H5, pl_1.H6, pl_1.H7, pl_1.H8}
valid_measurements := 0
for _, v := range humidity_values {
if v > 0 {
valid_measurements = valid_measurements + 1
}
}
fmt.Printf("Valid Measurements: %d,\n", valid_measurements)
var step int64
if valid_measurements > 1 {
step = int64(int(pl_1.O) / (valid_measurements - 1))
}
// the first temperature is usually too high (maybe becaus of lorawan send, so we take
// the second measurement as first..., the same for humidity, which is usually too low...
t := pl_1.T
t = t + int16(pl_1.TC1)
if valid_measurements > 0 {
WriteDatapoint(tfp, deveui, devaddr, pl_1.Vbat, pl_1.H1, pl_1.P1, pl_1.W1, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
//t = t + int16(pl_1.TC1)
if valid_measurements > 1 {
WriteDatapoint(tfp+(step), deveui, devaddr, 0, pl_1.H2, pl_1.P2, pl_1.W2, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_1.TC2)
if valid_measurements > 2 {
WriteDatapoint(tfp+(2*step), deveui, devaddr, 0, pl_1.H3, pl_1.P3, pl_1.W3, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_1.TC3)
if valid_measurements > 3 {
WriteDatapoint(tfp+(3*step), deveui, devaddr, 0, pl_1.H4, pl_1.P4, pl_1.W4, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_1.TC4)
if valid_measurements > 4 {
WriteDatapoint(tfp+(4*step), deveui, devaddr, 0, pl_1.H5, pl_1.P5, pl_1.W5, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_1.TC5)
if valid_measurements > 5 {
WriteDatapoint(tfp+(5*step), deveui, devaddr, 0, pl_1.H6, pl_1.P6, pl_1.W6, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_1.TC6)
if valid_measurements > 6 {
WriteDatapoint(tfp+(6*step), deveui, devaddr, 0, pl_1.H7, pl_1.P7, pl_1.W7, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_1.TC7)
if valid_measurements > 7 {
WriteDatapoint(tfp+(7*step), deveui, devaddr, 0, pl_1.H8, pl_1.P8, pl_1.W8, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
}
} else if s[0:2] == "02" {
fmt.Printf("{\n")
fmt.Printf(" version: %d,\n", pl_2.Version)
fmt.Printf(" vbat: %d,\n", pl_2.Vbat)
fmt.Printf(" offset: %d\n", pl_2.O)
fmt.Printf(" weight: [%d,%d,%d,%d,%d,%d,%d,%d],\n", pl_2.W1, pl_2.WC1, pl_2.WC2, pl_2.WC3, pl_2.WC4, pl_2.WC5, pl_2.WC6, pl_2.W8)
fmt.Printf(" temp: %d,\n", pl_2.T)
fmt.Printf(" temp_change: [%d,%d,%d,%d,%d,%d,%d],\n", pl_2.TC1, pl_2.TC2, pl_2.TC3, pl_2.TC4, pl_2.TC5, pl_2.TC6, pl_2.TC7)
fmt.Printf(" humidity: %d\n", pl_2.H)
fmt.Printf(" pressure: %d\n", pl_2.P)
fmt.Printf("}\n")
if write2file {
// Time of first Packet
var tfp = (time.Now().Unix() / 60) - int64(pl_2.O)
temp_change_values := []int8{pl_2.TC1, pl_2.TC2, pl_2.TC3, pl_2.TC4, pl_2.TC5, pl_2.TC6, pl_2.TC7}
valid_measurements := 1
for _, v := range temp_change_values {
if v < 127 {
valid_measurements = valid_measurements + 1
}
}
fmt.Printf("Valid Measurements: %d,\n", valid_measurements)
var step int64
if valid_measurements > 1 {
step = int64(int(pl_2.O) / (valid_measurements - 1))
}
// the first temperature is usually too high (maybe becaus of lorawan send, so we take
// the second measurement as first...
t := pl_2.T
w := pl_2.W1
t = t + int16(pl_2.TC1)
if valid_measurements > 0 {
WriteDatapoint(tfp, deveui, devaddr, pl_2.Vbat, pl_2.H, pl_2.P, w, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
//t = t + int16(pl_2.TC1)
w = w + uint16(pl_2.WC1)
if valid_measurements > 1 {
WriteDatapoint(tfp+(step), deveui, devaddr, 0, 1, 0, w, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_2.TC2)
w = w + uint16(pl_2.WC2)
if valid_measurements > 2 {
WriteDatapoint(tfp+(2*step), deveui, devaddr, 0, 1, 0, w, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_2.TC3)
w = w + uint16(pl_2.WC3)
if valid_measurements > 3 {
WriteDatapoint(tfp+(3*step), deveui, devaddr, 0, 1, 0, w, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_2.TC4)
w = w + uint16(pl_2.WC4)
if valid_measurements > 4 {
WriteDatapoint(tfp+(4*step), deveui, devaddr, 0, 1, 0, w, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_2.TC5)
w = w + uint16(pl_2.WC5)
if valid_measurements > 5 {
WriteDatapoint(tfp+(5*step), deveui, devaddr, 0, 1, 0, w, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_2.TC6)
w = w + uint16(pl_2.WC6)
if valid_measurements > 6 {
WriteDatapoint(tfp+(6*step), deveui, devaddr, 0, 1, 0, w, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
t = t + int16(pl_2.TC7)
w = pl_2.W8
if valid_measurements > 7 {
WriteDatapoint(tfp+(7*step), deveui, devaddr, 0, 1, 0, w, 0, 0, t, lrrlat, lrrlon, 0, 0, 0, 0, 0)
}
}
} else if s[0:2] == "80" {
fmt.Printf("{\n")
fmt.Printf(" version: %d,\n", pl_128.Version)
fmt.Printf(" fw_version: %d,\n", pl_128.Fw_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(" cal_1_0: %d\n", pl_128.W1_0)
fmt.Printf(" cal_2_0: %d\n", pl_128.W2_0)
fmt.Printf(" cal_1_C: %f\n", pl_128.W1_C)
fmt.Printf(" cal_2_C: %f\n", pl_128.W2_C)
fmt.Printf(" temp: %d\n", pl_128.T)
fmt.Printf("}\n")
if write2file {
// Time of Packet received
var tfp = (time.Now().Unix() / 60)
// we calculate the weight...
var w32 int32
var w uint16
w1_0_real := pl_128.W1_0
w2_0_real := pl_128.W2_0
w32 = int32(((float64(pl_128.W1-w1_0_real) / float64(pl_128.W1_C)) + (float64(pl_128.W2-w2_0_real) / float64(pl_128.W2_C))) / 5.0)
if w32 < 0 {
w = 0
} else if w32 > 65535 {
// this is not realistic (>320 kg), we set this to 0 as well...
w = 0
} else {
w = uint16(w32)
}
WriteDatapoint(tfp, deveui, devaddr, pl_128.Vbat, pl_128.H, pl_128.P, w, pl_128.W1, pl_128.W2, pl_128.T, lrrlat, lrrlon, pl_128.Fw_version, pl_128.W1_0, pl_128.W2_0, pl_128.W1_C, pl_128.W2_C)
}
ProcessInitPacket(deveui, pl_128.W1_0, pl_128.W2_0, pl_128.W1_C, pl_128.W2_C, pl_128.W1, pl_128.W2)
} else if s[0:2] == "81" {
fmt.Printf("{\n")
fmt.Printf(" version: %d,\n", pl_129.Version)
fmt.Printf(" fw_version: %d,\n", pl_129.Fw_version)
fmt.Printf(" vbat: %d,\n", pl_129.Vbat)
fmt.Printf(" humidity: %d\n", pl_129.H)
fmt.Printf(" pressure: %d\n", pl_129.P)
fmt.Printf(" weight1: %d\n", pl_129.W1)
fmt.Printf(" weight2: %d\n", pl_129.W2)
fmt.Printf(" weight: %d\n", pl_129.W)
fmt.Printf(" temp: %d\n", pl_129.T)
fmt.Printf("}\n")
if write2file {
// Time of Packet received
var tfp = (time.Now().Unix() / 60)
WriteDatapoint(tfp, deveui, devaddr, pl_129.Vbat, pl_129.H, pl_129.P, pl_129.W, pl_129.W1, pl_129.W2, pl_129.T, lrrlat, lrrlon, pl_129.Fw_version, 0, 0, 0, 0)
}
} else if s[0:2] == "82" {
fmt.Printf("{\n")
fmt.Printf(" version: %d,\n", pl_130.Version)
fmt.Printf(" fw_version: %d,\n", pl_130.Fw_version)
fmt.Printf(" vbat: %d,\n", pl_130.Vbat)
fmt.Printf(" weight1: %d\n", pl_130.W1)
fmt.Printf(" weight2: %d\n", pl_130.W2)
fmt.Printf(" cal_1_0: %d\n", pl_130.W1_0)
fmt.Printf(" cal_2_0: %d\n", pl_130.W2_0)
fmt.Printf(" cal_1_C: %f\n", pl_130.W1_C)
fmt.Printf(" cal_2_C: %f\n", pl_130.W2_C)
fmt.Printf(" temp: %d\n", pl_130.T)
fmt.Printf(" humidity: %d\n", pl_130.H)
fmt.Printf(" pressure: %d\n", pl_130.P)
fmt.Printf("}\n")
if write2file {
// Time of Packet received
var tfp = (time.Now().Unix() / 60)
// we calculate the weight...
var w32 int32
var w uint16
w1_0_real := pl_130.W1_0
w2_0_real := pl_130.W2_0
w32 = int32(((float64(pl_130.W1-w1_0_real) / float64(pl_130.W1_C)) + (float64(pl_130.W2-w2_0_real) / float64(pl_130.W2_C))) / 5.0)
if w32 < 0 {
w = 0
} else if w32 > 65535 {
// this is not realistic (>320 kg), we set this to 0 as well...
w = 0
} else {
w = uint16(w32)
}
WriteDatapoint(tfp, deveui, devaddr, pl_130.Vbat, pl_130.H, pl_130.P, w, pl_130.W1, pl_130.W2, pl_130.T, lrrlat, lrrlon, pl_130.Fw_version, pl_130.W1_0, pl_130.W2_0, pl_130.W1_C, pl_130.W2_C)
}
}
// Send alert if necessary
if val, ok := alertMap[deveui]; ok {
sendAlert(deveui, val)
delete(alertMap, deveui)
// alte Werte loeschen
deleteValues(deveui)
}
if val2, ok2 := alertLogMap[deveui]; ok2 {
WriteStringToFile(val2, deveui, false)
delete(alertLogMap, deveui)
}
}
func IsDayTime() bool {
hours, _, _ := time.Now().Clock()
return ((hours >= 6) && (hours < 22))
}
func WriteDatapoint(mytime int64, deveui string, devaddr string, v uint8, h uint8, p uint8, w uint16, w1 int32, w2 int32, t int16, lrrlat float32, lrrlon float32, fw_version int32, w1_0 int32, w2_0 int32, w1_c float32, w2_c float32) {
// wir nehmen humidity als Referenz, wenn diese > 0 ist, dann ist es
// eine gueltige Messung, wenn humidity = 1 ist, dann geben wir h und p nicht aus
var vp int16 // Voltage in %
var implausible bool
//fmt.Printf("WriteDatapoint: h: %d\n", h)
if h > 0 {
sv := ""
// vp for Lipo
vp = int16(v) - 70
if vp < 0 {
vp = 0
} else if vp > 100 {
vp = 100
}
sv = fmt.Sprintf("v=%di,vp=%di,", int32(v)*7+2510, vp)
s := ""
sfw := ""
if fw_version > 0 {
sfw = fmt.Sprintf(",fw_version=%di,w1=%di,w2=%di,w1_0=%di,w2_0=%di,w1_c=%f,w2_c=%f", fw_version, w1, w2, w1_0, w2_0, w1_c, w2_c)
}
if h == 1 {
s = fmt.Sprintf("measurement,deveui=%s devaddr=\"%s\",%sw=%di,t=%.1f,lrrlat=%f,lrrlon=%f%s %d\n", deveui, devaddr, sv, uint32(w)*5, float32(t)/10, lrrlat, lrrlon, sfw, mytime*60*1000*1000*1000)
} else {
s = fmt.Sprintf("measurement,deveui=%s devaddr=\"%s\",%sh=%di,p=%di,w=%di,t=%.1f,lrrlat=%f,lrrlon=%f%s %d\n", deveui, devaddr, sv, h, int32(p)+825, uint32(w)*5, float32(t)/10, lrrlat, lrrlon, sfw, mytime*60*1000*1000*1000)
}
implausible = (w1 == NOT_PLAUSIBLE_32) || (w2 == NOT_PLAUSIBLE_32) || (w == NOT_PLAUSIBLE_16)
WriteStringToFile(s, deveui, implausible)
w_gram := uint32(w) * 5
if !implausible {
addValue(deveui, w_gram)
w_loss := getMaxValue(deveui) - w_gram
if w_loss > 750 && IsDayTime() {
// Schwarmalarm!
alertLogMap[deveui] = fmt.Sprintf("alert,deveui=%s reason=\"swarmalarm\",w=%di,w_loss=%di %d\n", deveui, w_gram, w_loss, mytime*60*1000*1000*1000)
location, _ := time.LoadLocation("Europe/Zurich")
alertMap[deveui] = fmt.Sprintf("*** Schwarmalarm ***\n%s\n%s\nGewichtsverlust: %d g", getDevAlias(deveui), time.Unix(mytime*60, 0).In(location).Format("02.01.2006 15:04"), w_loss)
}
}
}
}
func WriteStringToFile(s string, deveui string, implausible bool) {
if !implausible {
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/beieli/mini-beieli-lorahandler/logs/" + deveui + "-" + datestr + ".log"
if implausible {
individual_file = "/home/beieli/mini-beieli-lorahandler/logs/" + "implausible" + "-" + 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 main() {
// Init Redis
initDB()
// Init alertMap
alertMap = make(map[string]string)
alertLogMap = make(map[string]string)
// 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
var message_ttnv3 MessageTTNv3
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-v3") {
fmt.Printf("Seems to be a TTNv3 Packet...\n")
// it is probably a TTNv3 package...
err := json.NewDecoder(r.Body).Decode(&message_ttnv3)
if err != nil {
http.Error(w, err.Error(), 400)
return
}
fmt.Println("Time: " + message_ttnv3.UplinkMessage.Received_at)
fmt.Println("Payload Raw: " + message_ttnv3.UplinkMessage.Frm_payload)
fmt.Println("DevEUI: " + message_ttnv3.EndDeviceIds.Dev_eui)
payload_hex, err := Convert2Hex(message_ttnv3.UplinkMessage.Frm_payload)
if err == nil {
DecodePayload(payload_hex, message_ttnv3.EndDeviceIds.Dev_eui, "N/A", 0, 0, true)
} else {
fmt.Println("Error: could not convert raw_package to hex: %s" + message_ttnv3.UplinkMessage.Frm_payload)
}
} else if strings.Contains(string(buf), "mini-beieli") {
fmt.Printf("Seems to be a TTNv2 Packet...\n")
// it is probably a TTNv2 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, "N/A", 0, 0, true)
} 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)
fmt.Printf("LrrLAT: %f\n", message_swisscom.Prop.LrrLAT)
fmt.Printf("LrrLON: %f\n", message_swisscom.Prop.LrrLON)
DecodePayload(message_swisscom.Prop.Payload_hex, message_swisscom.Prop.DevEUI, message_swisscom.Prop.DevAddr, message_swisscom.Prop.LrrLAT, message_swisscom.Prop.LrrLON, true)
}
})
log.Fatal(http.ListenAndServe(":8080", nil))
}