mini-beieli-web/metrics.go

305 lines
10 KiB
Go

package main
import (
"bytes"
"fmt"
"log"
"net/http"
"time"
"io/ioutil"
"bufio"
"strings"
)
type OneMetric struct {
Deveui string
Alias string
Alarmactive string
Smsnumber string
Timestamp string
Temperature string
Humidity string
Weight string
Pressure string
BatteryPercent string
}
// Contains tells whether a contains x.
func Contains(a []string, x string) bool {
log.Println("Search for: "+x)
for _, n := range a {
log.Println("Piece of Array: "+n)
if x == n {
return true
}
}
return false
}
// metrics handler
func metricsHandler(response http.ResponseWriter, request *http.Request) {
name := getUserName(request)
if name != "" {
property, ok := request.URL.Query()["property"]
if !ok || len(property[0]) < 1 {
log.Println("Url Param 'property' is missing")
fmt.Fprintf(response, "{ \"msg\": \"property must be specified in URL\" }")
return
}
deveui, ok := request.URL.Query()["deveui"]
if !ok || len(deveui[0]) < 1 {
log.Println("Url Param 'deveui' is missing")
fmt.Fprintf(response, "{ \"msg\": \"deveui must be specified in URL\" }")
return
}
// Query()["deveui"] will return an array of items,
// we only want the single item.
mydeveui := deveui[0]
if !(Contains(getMyDevs(name),mydeveui)) {
log.Println("specified 'deveui' does not belong to this user")
fmt.Fprintf(response, "{ \"msg\": \"specified deveui does not belong to this user\" }")
return
}
log.Println("Url Param 'deveui' is: " + string(mydeveui))
url := "http://localhost:9999/api/v2/query?org=beieliorg"
data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") |> range(start:-24h) |> filter(fn: (r) => r._field == "%s") |> filter(fn: (r) => r.deveui == "%s")`,property[0],mydeveui))
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
log.Fatal("Error reading request. ", err)
}
// Set headers
req.Header.Set("Authorization", "Token xXnq8ADcDygAyM_L0B_10c9yuoOv-cYcUfIXkJunRrIDMhB5ZNmza-Whr1ELcbKNzW8GzUMMYD85QohUHQdAmg==")
req.Header.Set("accept", "application/csv")
req.Header.Set("content-type", "application/vnd.flux")
// Set client timeout
client := &http.Client{Timeout: time.Second * 10}
// Send request
resp, err := client.Do(req)
if err != nil {
log.Fatal("Error reading response. ", err)
}
defer resp.Body.Close()
fmt.Println("response Status:", resp.Status)
fmt.Println("response Headers:", resp.Header)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal("Error reading body. ", err)
}
fmt.Fprintf(response,"[\n")
scanner := bufio.NewScanner(strings.NewReader(string(body)))
first := true
for scanner.Scan() {
s := strings.Split(scanner.Text(),",")
if ((len(s) >= 7) && !(strings.HasPrefix(s[5],"_"))) {
t,err := time.Parse(time.RFC3339,s[5])
if err != nil {
continue
}
a := t.Unix()
b := s[6]
if !(first) {
fmt.Fprintf(response,",")
} else {
first = false
}
fmt.Fprintf(response,"[%d000,%s]\n",a,b)
}
}
fmt.Fprintf(response,"]\n")
} else {
fmt.Fprintf(response, "{ \"msg\": \"Only available for logged in users\" }")
}
}
func lastmetricsHandler(response http.ResponseWriter, request *http.Request) {
name := getUserName(request)
if name != "" {
deveui, ok := request.URL.Query()["deveui"]
if !ok || len(deveui[0]) < 1 {
log.Println("Url Param 'deveui' is missing")
fmt.Fprintf(response, "{ \"msg\": \"deveui must be specified in URL\" }")
return
}
// Query()["deveui"] will return an array of items,
// we only want the single item.
mydeveui := deveui[0]
if !(Contains(getMyDevs(name),mydeveui)) {
log.Println("specified 'deveui' does not belong to this user")
fmt.Fprintf(response, "{ \"msg\": \"specified deveui does not belong to this user\" }")
return
}
log.Println("Url Param 'deveui' is: " + string(mydeveui))
url := "http://localhost:9999/api/v2/query?org=beieliorg"
//data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") |> range(start:-365d) |> filter(fn: (r) => r.deveui == "%s") |> filter(fn: (r) => r._field == "v" or r._field == "t") |> last() |> yield(name: "last")`,mydeveui))
data := []byte(fmt.Sprintf(`from(bucket:"beielibucket")
|> range(start:-365d)
|> filter(fn: (r) => r.deveui == "%s")
|> filter(fn: (r) => r._field == "t" or r._field == "h" or r._field == "w" or r._field == "p" or r._field == "vp")
|> last() |> yield(name: "last")`,mydeveui))
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
log.Fatal("Error reading request. ", err)
}
// Set headers
req.Header.Set("Authorization", "Token xXnq8ADcDygAyM_L0B_10c9yuoOv-cYcUfIXkJunRrIDMhB5ZNmza-Whr1ELcbKNzW8GzUMMYD85QohUHQdAmg==")
req.Header.Set("accept", "application/csv")
req.Header.Set("content-type", "application/vnd.flux")
// Set client timeout
client := &http.Client{Timeout: time.Second * 10}
// Send request
resp, err := client.Do(req)
if err != nil {
log.Fatal("Error reading response. ", err)
}
defer resp.Body.Close()
fmt.Println("response Status:", resp.Status)
fmt.Println("response Headers:", resp.Header)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal("Error reading body. ", err)
}
fmt.Println("response Body:", string(body))
scanner := bufio.NewScanner(strings.NewReader(string(body)))
ts := ""
t := ""
h := ""
w := ""
p := ""
vp := ""
location, err := time.LoadLocation("Europe/Zurich")
for scanner.Scan() {
s := strings.Split(scanner.Text(),",")
if ((len(s) >= 7) && !(strings.HasPrefix(s[5],"_"))) {
mytime,err := time.Parse(time.RFC3339,s[5])
if err != nil {
continue
}
ts = mytime.In(location).Format("02.01.2006 15:04")
value := s[6]
field := s[7]
if field == "t" {
t = value
} else if field == "h" {
h = value
} else if field == "w" {
w = value
} else if field == "p" {
p = value
} else if field == "vp" {
vp = value
}
}
}
fmt.Fprintf(response,`{
"ts": "%s",
"t": "%s",
"h": "%s",
"w": "%s",
"p": "%s",
"vp": "%s"
}`,ts,t,h,w,p,vp)
} else {
fmt.Fprintf(response, "{ \"msg\": \"Only available for logged in users\" }")
}
}
func getLastMetrics(deveui string) OneMetric {
var res OneMetric
url := "http://localhost:9999/api/v2/query?org=beieliorg"
data := []byte(fmt.Sprintf(`from(bucket:"beielibucket")
|> range(start:-365d)
|> filter(fn: (r) => r.deveui == "%s")
|> filter(fn: (r) => r._field == "t" or r._field == "h" or r._field == "w" or r._field == "p" or r._field == "vp")
|> last() |> yield(name: "last")`,deveui))
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
log.Fatal("Error reading request. ", err)
}
// Set headers
req.Header.Set("Authorization", "Token xXnq8ADcDygAyM_L0B_10c9yuoOv-cYcUfIXkJunRrIDMhB5ZNmza-Whr1ELcbKNzW8GzUMMYD85QohUHQdAmg==")
req.Header.Set("accept", "application/csv")
req.Header.Set("content-type", "application/vnd.flux")
// Set client timeout
client := &http.Client{Timeout: time.Second * 10}
// Send request
resp, err := client.Do(req)
if err != nil {
log.Fatal("Error reading response. ", err)
}
defer resp.Body.Close()
fmt.Println("response Status:", resp.Status)
fmt.Println("response Headers:", resp.Header)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal("Error reading body. ", err)
}
fmt.Println("response Body:", string(body))
scanner := bufio.NewScanner(strings.NewReader(string(body)))
location, err := time.LoadLocation("Europe/Zurich")
for scanner.Scan() {
s := strings.Split(scanner.Text(),",")
if ((len(s) >= 7) && !(strings.HasPrefix(s[5],"_"))) {
mytime,err := time.Parse(time.RFC3339,s[5])
if err != nil {
continue
}
res.Timestamp = mytime.In(location).Format("02.01.2006 15:04")
value := s[6]
field := s[7]
if field == "t" {
res.Temperature = value
} else if field == "h" {
res.Humidity = value
} else if field == "w" {
res.Weight = value
} else if field == "p" {
res.Pressure = value
} else if field == "vp" {
res.BatteryPercent = value
}
}
}
res.Deveui = deveui
res.Alias = getDevAlias(deveui)
res.Alarmactive = getDevAlarmactive(deveui)
res.Smsnumber = getDevSmsnumber(deveui)
return res
}