commit e66ae9695b4d094d563d39a552e29c7c7b262407 Author: Joerg Lehmann Date: Tue Mar 2 19:40:05 2021 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3ba2f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +lorahandler +lorahandler.log* +logs/* diff --git a/show_timestamps b/show_timestamps new file mode 100755 index 0000000..6bd3eee --- /dev/null +++ b/show_timestamps @@ -0,0 +1,3 @@ +#!/bin/bash + +awk '{$3=strftime("%Y-%m-%d %H:%M:%S", substr($NF,1,10)); print $0}' lorahandler.log diff --git a/systemd/wo-bisch-lorahandler.service b/systemd/wo-bisch-lorahandler.service new file mode 100644 index 0000000..f95387a --- /dev/null +++ b/systemd/wo-bisch-lorahandler.service @@ -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 diff --git a/wo-bisch-lorahandler b/wo-bisch-lorahandler new file mode 100755 index 0000000..3112151 Binary files /dev/null and b/wo-bisch-lorahandler differ diff --git a/wo-bisch-lorahandler.go b/wo-bisch-lorahandler.go new file mode 100644 index 0000000..415a963 --- /dev/null +++ b/wo-bisch-lorahandler.go @@ -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)) +} diff --git a/wo-bisch-lorahandler.log b/wo-bisch-lorahandler.log new file mode 100644 index 0000000..a2219f3 --- /dev/null +++ b/wo-bisch-lorahandler.log @@ -0,0 +1 @@ +measurement,deveui=A8404100018193D7 lat=46.00000,lon=7.00000,vbat=4055,fw=164 26911834