first try of implementing sms alerts
This commit is contained in:
parent
d172f04081
commit
85ea0e2b06
|
|
@ -0,0 +1,41 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
func sendSMS(phonenumber string, alertMessage string) {
|
||||||
|
myurl := fmt.Sprintf("https://api.smsapi.com/sms.do?to=%s&message=%s&format=json",phonenumber,url.QueryEscape(alertMessage))
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", myurl, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error reading request. ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Authorization", "Bearer IQ4vRG2JvNOmYmrYz6RuSwAanYZgd2hHGwtN62kq")
|
||||||
|
|
||||||
|
client := &http.Client{Timeout: time.Second * 10}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error reading response. ", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error reading body. ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", body)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendAlert(deveui string, alertMessage string) {
|
||||||
|
fmt.Printf("sendAlert: deveui=%s, message=%s\n", deveui, alertMessage)
|
||||||
|
sendSMS("41765006123",alertMessage)
|
||||||
|
}
|
||||||
|
|
@ -86,6 +86,7 @@ type payload_1 struct {
|
||||||
// Global variables
|
// Global variables
|
||||||
var file *os.File
|
var file *os.File
|
||||||
|
|
||||||
|
var alertMap map[string]string
|
||||||
|
|
||||||
func DecodePayload(s string, deveui string, devaddr string, lrrlat float32, lrrlon float32, write2file bool) {
|
func DecodePayload(s string, deveui string, devaddr string, lrrlat float32, lrrlon float32, write2file bool) {
|
||||||
var ba []byte
|
var ba []byte
|
||||||
|
|
@ -159,7 +160,11 @@ func DecodePayload(s string, deveui string, devaddr string, lrrlat float32, lrrl
|
||||||
WriteDatapoint(tfp,deveui,devaddr,pl_128.Vbat,pl_128.H,pl_128.P,pl_128.W,pl_128.W1,pl_128.W2,pl_128.T,lrrlat,lrrlon)
|
WriteDatapoint(tfp,deveui,devaddr,pl_128.Vbat,pl_128.H,pl_128.P,pl_128.W,pl_128.W1,pl_128.W2,pl_128.T,lrrlat,lrrlon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Send alert if necessary
|
||||||
|
if val, ok := alertMap[deveui]; ok {
|
||||||
|
sendAlert(deveui,val)
|
||||||
|
delete(alertMap,deveui)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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) {
|
||||||
|
|
@ -182,6 +187,18 @@ func WriteDatapoint(mytime int64, deveui string, devaddr string, v uint8, h uint
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteStringToFile(s)
|
WriteStringToFile(s)
|
||||||
|
|
||||||
|
w_gram := w*5
|
||||||
|
addValue(deveui,w_gram)
|
||||||
|
w_loss := getMaxValue(deveui) - w_gram;
|
||||||
|
if (w_loss > 500) {
|
||||||
|
// Schwarmalarm!
|
||||||
|
s = 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)
|
||||||
|
WriteStringToFile(s)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,6 +215,11 @@ func WriteStringToFile(s string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
// Init Redis
|
||||||
|
initDB()
|
||||||
|
|
||||||
|
// Init alertMap
|
||||||
|
alertMap = make(map[string]string)
|
||||||
|
|
||||||
// Open Output File
|
// Open Output File
|
||||||
f, err := os.OpenFile(outputfile,os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
f, err := os.OpenFile(outputfile,os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"github.com/gomodule/redigo/redis"
|
||||||
|
)
|
||||||
|
|
||||||
|
var globalPool *redis.Pool
|
||||||
|
|
||||||
|
const lastvaluesPrefix string = "lastvalues:"
|
||||||
|
const devPrefix string = "dev:"
|
||||||
|
|
||||||
|
func newPool() *redis.Pool {
|
||||||
|
return &redis.Pool{
|
||||||
|
// Maximum number of idle connections in the pool.
|
||||||
|
MaxIdle: 80,
|
||||||
|
// max number of connections
|
||||||
|
MaxActive: 12000,
|
||||||
|
// Dial is an application supplied function for creating and
|
||||||
|
// configuring a connection.
|
||||||
|
Dial: func() (redis.Conn, error) {
|
||||||
|
c, err := redis.Dial("tcp", ":6379")
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
return c, err
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ping tests connectivity for redis (PONG should be returned)
|
||||||
|
func ping(c redis.Conn) error {
|
||||||
|
// Send PING command to Redis
|
||||||
|
// PING command returns a Redis "Simple String"
|
||||||
|
// Use redis.String to convert the interface type to string
|
||||||
|
_, err := redis.String(c.Do("PING"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func initDB() {
|
||||||
|
|
||||||
|
// newPool returns a pointer to a redis.Pool
|
||||||
|
pool := newPool()
|
||||||
|
// get a connection from the globalPool (redis.Conn)
|
||||||
|
conn := pool.Get()
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
globalPool = pool
|
||||||
|
|
||||||
|
// wir machen einen Connection Test
|
||||||
|
ping(conn)
|
||||||
|
|
||||||
|
addValue("0000000000000000",uint16(time.Now().Unix()));
|
||||||
|
}
|
||||||
|
|
||||||
|
func closeDB() {
|
||||||
|
globalPool.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkDevAvailable(deveui string) bool {
|
||||||
|
conn := globalPool.Get()
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
_, err := redis.String(conn.Do("GET", lastvaluesPrefix + deveui))
|
||||||
|
if (err == redis.ErrNil) {
|
||||||
|
return true
|
||||||
|
} else if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMaxValue(deveui string) uint16 {
|
||||||
|
var res uint16 = 0
|
||||||
|
var myvalues []uint16
|
||||||
|
conn := globalPool.Get()
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
values, _ := redis.Values(conn.Do("LRANGE", lastvaluesPrefix + deveui, 0, -1))
|
||||||
|
|
||||||
|
if err := redis.ScanSlice(values, &myvalues); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range myvalues {
|
||||||
|
if (uint16(value) > res) {
|
||||||
|
res = uint16(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func addValue(deveui string, value uint16) {
|
||||||
|
conn := globalPool.Get()
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
_, err := conn.Do("LPUSH", lastvaluesPrefix + deveui, value)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err2 := conn.Do("LTRIM", lastvaluesPrefix + deveui, 0, 4)
|
||||||
|
|
||||||
|
if err2 != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// we set an expiration time of one hour
|
||||||
|
_, err3 := conn.Do("EXPIRE", lastvaluesPrefix + deveui, 3600)
|
||||||
|
|
||||||
|
if err3 != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDevAlias(deveui string) string {
|
||||||
|
res := deveui
|
||||||
|
|
||||||
|
if deveui == "" {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
conn := globalPool.Get()
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
alias, err := redis.String(conn.Do("HGET", devPrefix+deveui, "alias"))
|
||||||
|
if err == nil {
|
||||||
|
res = alias
|
||||||
|
} else {
|
||||||
|
res = deveui
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue