greenzone alert

This commit is contained in:
Joerg Lehmann 2021-06-07 19:42:00 +02:00
parent f00afc9713
commit c6c83ce708
3 changed files with 97 additions and 13 deletions

View File

@ -100,17 +100,19 @@ func DispatchAlert(deveui string, alertType string) {
} }
// then we check that an alert was not already sent out recently // then we check that an alert was not already sent out recently
if AlertAlreadySentRecently(deveui) { if AlertAlreadySentRecently(deveui, alertType) {
fmt.Printf("Error: Alert for Deveui %s has already been sent!", deveui) fmt.Printf("Error: Alert for Deveui %s has already been sent!", deveui)
return return
} }
// then we make an entry that an alert was sent, this will expire automatically // then we make an entry that an alert was sent, this will expire automatically
AddAlertAlreadySentRecently(deveui) AddAlertAlreadySentRecently(deveui, alertType)
// then we send the alert // then we send the alert
if alertType == "alert_button" { if alertType == "alert_button" {
alertMessage = fmt.Sprintf("Alarm (%s): Knopf gedrueckt, %s", getDevAlias(deveui), time.Now().Format("02.01.2006 15:04:05")) alertMessage = fmt.Sprintf("Alarm (%s): Knopf gedrueckt, %s", getDevAlias(deveui), time.Now().Format("02.01.2006 15:04:05"))
} else if alertType == "alert_greenzone" {
alertMessage = fmt.Sprintf("Alarm (%s): Gruene Zone wurde verlassen, %s", getDevAlias(deveui), time.Now().Format("02.01.2006 15:04:05"))
} }
sendAlert(deveui, alertMessage) sendAlert(deveui, alertMessage)
} }

View File

@ -192,29 +192,66 @@ func getEmail(deveui string) string {
return res return res
} }
func AlertAlreadySentRecently(deveui string) bool { func getDevGreenzone(deveui string) string {
res := ""
if deveui == "" {
return res
}
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() defer conn.Close()
exists, _ := redis.Bool(conn.Do("EXISTS", alertsentPrefix+deveui)) greenzone, err := redis.String(conn.Do("HGET", devPrefix+deveui, "greenzone"))
if err == nil {
res = greenzone
} else {
log.Print(err)
}
return res
}
func AlertAlreadySentRecently(deveui string, what string) bool {
conn := globalPool.Get()
defer conn.Close()
exists, _ := redis.Bool(conn.Do("EXISTS", alertsentPrefix+deveui+":"+what))
return exists return exists
} }
func AddAlertAlreadySentRecently(deveui string) { func AddAlertAlreadySentRecently(deveui string, what string) {
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() defer conn.Close()
expire_duration := 120
if what == "alert_greenzone" {
expire_duration = 7 * 24 * 60 * 60
}
_, err := conn.Do("SET", alertsentPrefix+deveui, "1") _, err := conn.Do("SET", alertsentPrefix+deveui+":"+what, "1")
if err != nil { if err != nil {
return return
} }
// we set an expiration time to prevent duplicate alerts // we set an expiration time to prevent duplicate alerts
_, err1 := conn.Do("EXPIRE", alertsentPrefix+deveui, 120) _, err1 := conn.Do("EXPIRE", alertsentPrefix+deveui+":"+what, expire_duration)
if err1 != nil { if err1 != nil {
return return
} }
} }
func DeleteGreenzoneAlert(deveui string) bool {
conn := globalPool.Get()
defer conn.Close()
_, err := conn.Do("DEL", alertsentPrefix+deveui+":alert_greenzone")
if err != nil {
return false
}
return true
}

View File

@ -11,6 +11,8 @@ import (
"log" "log"
"net/http" "net/http"
"os" "os"
"strconv"
"strings"
"time" "time"
) )
@ -65,6 +67,30 @@ func Convert2Hex(payload_raw string) (string, error) {
return res, err return res, err
} }
func IsOutsideGreenzone(deveui string, lon float64, lat float64) bool {
res := false
if lon < 1 {
return res
}
if lat < 1 {
return res
}
greenzone := getDevGreenzone(deveui)
if greenzone != "" {
coords := strings.Split(greenzone, ",")
if len(coords) == 4 {
lon_min, _ := strconv.ParseFloat(coords[0], 32)
lat_min, _ := strconv.ParseFloat(coords[1], 32)
lon_max, _ := strconv.ParseFloat(coords[2], 32)
lat_max, _ := strconv.ParseFloat(coords[3], 32)
res = (lon < lon_min || lon > lon_max || lat < lat_min || lat > lat_max)
} else {
log.Printf("greenzone does not have right format: %s!", greenzone)
}
}
return res
}
func DecodePayload(s string, deveui string) { func DecodePayload(s string, deveui string) {
type payload struct { type payload struct {
Latitude uint32 Latitude uint32
@ -85,18 +111,27 @@ func DecodePayload(s string, deveui string) {
fmt.Println(err) fmt.Println(err)
} }
log.Printf("Latitude: %.5f", float32(pl.Latitude)/1000000.0) log.Printf("Latitude: %.5f", float32(pl.Latitude)/1000000.0)
log.Printf("Longitude: %.5f", float32(pl.Longitude)/1000000.0) log.Printf("Longitude: %.5f", float32(pl.Longitude)/1000000.0)
log.Printf("AlarmBat: %d", pl.AlarmBat) log.Printf("AlarmBat: %d", pl.AlarmBat)
log.Printf("Flag: %d", pl.Flag) log.Printf("Flag: %d", pl.Flag)
vbat := (pl.AlarmBat & 0x3fff) // Battery Voltage in mV vbat := (pl.AlarmBat & 0x3fff) // Battery Voltage in mV
fw := 160 + (pl.Flag & 0x1f) // Firmware version; 5 bits fw := 160 + (pl.Flag & 0x1f) // Firmware version; 5 bits
alarm := (pl.AlarmBat & 0x4000) == 0x4000 // Alarm Bit alarm := (pl.AlarmBat & 0x4000) == 0x4000 // Alarm Bit
outsideGreenzone := IsOutsideGreenzone(deveui, float64(pl.Longitude)/1000000.0, float64(pl.Latitude)/1000000.0)
flags := 0
if outsideGreenzone {
flags += 2
}
if alarm {
flags += 1
}
log.Printf("AlarmBit: %v", alarm) log.Printf("AlarmBit: %v", alarm)
log.Printf("outsideGreenzone: %v", outsideGreenzone)
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() * 1000 * 1000 * 1000)) mystring := fmt.Sprintf("measurement,deveui=%s lat=%.5f,lon=%.5f,vbat=%d,fw=%d,flags=%d %d\n", deveui, float32(pl.Latitude)/1000000.0, float32(pl.Longitude)/1000000.0, vbat, fw, flags, (time.Now().Unix() * 1000 * 1000 * 1000))
WriteStringToFile(mystring, deveui) WriteStringToFile(mystring, deveui)
// we send an alert, when the alert bit is set // we send an alert, when the alert bit is set
@ -104,6 +139,16 @@ func DecodePayload(s string, deveui string) {
log.Printf("DispatchAlert (button pressed) for %s\n", deveui) log.Printf("DispatchAlert (button pressed) for %s\n", deveui)
DispatchAlert(deveui, "alert_button") DispatchAlert(deveui, "alert_button")
} }
if outsideGreenzone {
log.Printf("DispatchAlert (outside greenzone) for %s\n", deveui)
DispatchAlert(deveui, "alert_greenzone")
} else {
// we reset the alert, when we are again withing the greenzone
if AlertAlreadySentRecently(deveui, "alert_greenzone") {
fmt.Printf("Info: we are again in Greenzone for Deveui %s, clear alert!", deveui)
DeleteGreenzoneAlert(deveui)
}
}
} else { } else {
log.Printf("Payload is not >= 11 bytes (22 chars): %s", s) log.Printf("Payload is not >= 11 bytes (22 chars): %s", s)