Hi, a couple of months ago, I was working with a Go file to handle the POST events, and it used to work fine.
Then time passes and I updated ChirpStack and didn’t work on the go file anymore, but earlier this week I came back to work on the go file, I tried to do the HTTP integration and I wasn’t getting any POST event, I did everything as I remember, but it does not seem to work.
I have 1 pc running ChirpStack(192.168.1.157), and I have another machine (192.168.1.70) where I work on the Go file, both PC can make PING and in the HTTP integration tab I have the right IP (192.168.1.70) but no POST event.
This is the Go file code but it comes from the Go example in the documentation:
package main
import (
"encoding/json"
"fmt"
"html/template"
"io"
"log"
"net/http"
"github.com/chirpstack/chirpstack/api/go/v4/integration"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
)
type handler struct {
json bool
}
type dataDispLoRaWAN struct {
Dispositivos []integration.UplinkEvent
}
var data dataDispLoRaWAN
// Funcion invocada cuando se escucha una peticion (request) desde
// la funcion 'http.ListenAndServe'
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Lectura de mensaje recibido "Body"
b, err := io.ReadAll(r.Body)
// Se depliega el error de lectura si este no es nulo
if err != nil {
panic(err)
}
// Se obtiene el evento del request entrante
event := r.URL.Query().Get("event")
fmt.Println(r.Method + " | " + r.URL.String())
// Si el metodo de la peticion es POST (se infiere desde chirpstack)
// es informacion desde los nodos y gateways
switch r.Method {
case "POST":
// Se decide en base al evento de la peticion
switch event {
// Evento "UP" de la peticion POST trae info de las lecturas de los nodos
case "up":
err = h.up(b)
// Evento "JOIN" de la peticion POST notifica la deteccion de un nuevo nodo
case "join":
err = h.join(b)
// Manejo de otros posibles eventos
default:
fmt.Printf("handler para el evento %s no esta implementado \n", event)
return
}
// Si el metodo de la peticion de GET (se infiere desde nav/usuario)
case "GET":
// Se decide en base a la URL de la peticion
switch r.URL.String() {
// "/" indica la peticion del archivo HTML
case "/":
tmpl := template.Must(template.ParseFiles("pages/layout.html"))
//tmpl := template.Must(template.ParseFiles("pages/login.html"))
tmpl.Execute(w, nil)
// "/favicon.ico" es la peticion del icono de la pestaña
case "/favicon.ico":
http.ServeFile(w, r, "assets/img/favicon/favicon.ico")
// "/update" indica la peticion de datos desde la pagina (cada 0.5s)
case "/update":
buff_json, err := json.Marshal(data)
if err != nil {
fmt.Println(err)
}
w.Write(buff_json)
default:
return
}
}
// Retorno del error en caso de no ser nulo
if err != nil {
fmt.Printf("metodo request '%s' retorna error: %s\n", event, err)
}
}
// Evento UP
func (h *handler) up(b []byte) error {
// "b" es el body de la peticion, up es el mensaje cuando se recibe data en un evento UP
var up integration.UplinkEvent
// Se procesa el cuerpo/body de la peticion y se guarda en up, ademas se retorna un error en caso de no ser nulo
if err := h.unmarshal(b, &up); err != nil {
return err
}
fmt.Println(up.GetDeviceInfo().DeviceName)
// Seccion de actualizacion de dispositivos activos
// Seccion de variable de apoyo
buff_encontrado := false
buff_pos_encont := 0
// Se busca el dispo entrante en la lista de dispos_activos
for i := range data.Dispositivos {
// Si el dispo entrante coincide con un dispo en la lista
if data.Dispositivos[i].DeviceInfo.DevEui == up.GetDeviceInfo().DevEui {
// guardo la posicion y validador
buff_pos_encont = i
buff_encontrado = true
break
}
}
// Se revisa el estado del validador encontrado
if buff_encontrado {
// De ser TRUE, de actualiza el dispo
data.Dispositivos[buff_pos_encont] = up
} else {
// De ser FALSE, se añade a la cola
data.Dispositivos = append(data.Dispositivos, up)
}
return nil
}
// Evento JOIN
func (h *handler) join(b []byte) error {
// "b" es el body, join es el mensaje cuando
// se conecta un nuevo dispo a chirpstack
//var join integration.UplinkEvent
var join integration.JoinEvent
// Se procesa el cuerpo del mensaje y se guarda en join,
// se retorna el error en caso de no ser nulo
if err := h.unmarshal(b, &join); err != nil {
return err
}
// Se notifica el nuevo dispo
fmt.Printf("dispositivo %s se ha unido con DevAddr %s \n", join.GetDeviceInfo().DevEui, join.DevAddr)
return nil
}
// Funcion para "desarmar" el JSON recibido, provista por chirpstack
func (h *handler) unmarshal(b []byte, v proto.Message) error {
if h.json {
return protojson.UnmarshalOptions{
DiscardUnknown: true,
AllowPartial: true,
}.Unmarshal(b, v)
}
return proto.Unmarshal(b, v)
}
func main() {
http.Handle("/", &handler{json: false})
http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("./assets"))))
log.Fatal(http.ListenAndServe(":8090", nil))
}
Any help is welcome
Thanks
