diff --git a/src/udi/database/abstract_database.go b/src/udi/database/abstract_database.go index 7fcc086..9beeb67 100644 --- a/src/udi/database/abstract_database.go +++ b/src/udi/database/abstract_database.go @@ -35,8 +35,8 @@ type DeviceType struct { type Device struct { gorm.Model - Label string `gorm:"not null"` - ApplicationID int `gorm:"not null"` + Label string `gorm:"not null;uniqueIndex:idx_label_application_id"` + ApplicationID int `gorm:"not null;uniqueIndex:idx_label_application_id"` Application Application DeviceTypeID int `gorm:"not null"` DeviceType DeviceType diff --git a/src/udi/database/database.go b/src/udi/database/database.go index 7320c44..7fda18e 100644 --- a/src/udi/database/database.go +++ b/src/udi/database/database.go @@ -4,6 +4,7 @@ package database import ( "log" //"time" + "fmt" "gorm.io/driver/postgres" "gorm.io/gorm" ) @@ -27,13 +28,13 @@ func NewDatabaseHandle(dsn string) *DatabaseHandle { return &db } -func (dbh *DatabaseHandle) StoreMeasurement(measurement *Measurement) { - if ! dbh.initialized { +func (self *DatabaseHandle) StoreMeasurement(measurement *Measurement) { + if ! self.initialized { log.Printf("Database connection not initialized, can not store, measurement %s lost", measurement) return } - result := dbh.dbh.Create(measurement) + result := self.dbh.Create(measurement) if result.Error != nil { log.Printf("Unable to insert, measurement %s lost, error: %s", measurement, result.Error) return @@ -42,4 +43,27 @@ func (dbh *DatabaseHandle) StoreMeasurement(measurement *Measurement) { log.Println("Successfully stored measurement") } +func (self *DatabaseHandle) GetDeviceByLabelAndApplication(applicationLabel string, deviceLabel string) (*Device, error) { + if ! self.initialized { + err := fmt.Errorf("Database connection not initialized") + return nil, err + } + + var device Device + result := self.dbh. + Preload("Application"). + Preload("DeviceType"). + Joins("JOIN applications ON devices.application_id = applications.id"). + Where("devices.label = ? AND applications.label = ?", deviceLabel, applicationLabel). + First(&device) + + if result.Error != nil { + err := fmt.Errorf("Query failed: %s", result.Error) + return nil, err + } + + return &device, nil +} + + diff --git a/src/udi/handlers/ttn/models/emuProfIILoRa/emuProfIILoRa.go b/src/udi/handlers/ttn/models/emuProfIILoRa/emuProfIILoRa.go new file mode 100644 index 0000000..3695e97 --- /dev/null +++ b/src/udi/handlers/ttn/models/emuProfIILoRa/emuProfIILoRa.go @@ -0,0 +1,11 @@ +package emuProfIILoRa + +import ( + "fmt" + "udi/database" +) + +func Parse(decodedPayload interface{}) ([]database.VariableType, error) { + return nil, fmt.Errorf("Nothing works so far") +} + diff --git a/src/udi/handlers/ttn/ttn.go b/src/udi/handlers/ttn/ttn.go index 2b7af39..1709cb8 100644 --- a/src/udi/handlers/ttn/ttn.go +++ b/src/udi/handlers/ttn/ttn.go @@ -5,11 +5,14 @@ import "fmt" import "encoding/json" import "udi/config" import "udi/handlers/handler" +import "udi/handlers/ttn/models/emuProfIILoRa" +import "udi/database" var idSeq int = 0 type TTNHandler struct { id int + dbh *database.DatabaseHandle } type uplinkMessage struct { @@ -66,6 +69,7 @@ func NewTTNHandler(config config.HandlerConfigT) handler.Handler { id: idSeq, } idSeq += 1 + t.dbh = database.NewDatabaseHandle(config.DatabaseConnStr) return t } @@ -73,15 +77,20 @@ func (self *TTNHandler) GetId() string { return fmt.Sprintf("TTN%d", self.id) } +func lost(msg string, message handler.MessageT) { + log.Printf("Error: %s, message %s is lost", msg, message) +} + func (self *TTNHandler) Handle(message handler.MessageT) { log.Printf("Handler TTN %d processing %s -> %s", self.id, message.Topic, message.Payload) var uplinkMessage uplinkMessage err := json.Unmarshal([]byte(message.Payload), &uplinkMessage) if err != nil { - log.Printf("Error when unmarshaling message: %s", err) + lost(fmt.Sprintf("Error when unmarshaling message: %s, ", err), message) + return } - log.Printf("Parsed message: %s", uplinkMessage) + //log.Printf("Parsed message: %s", uplinkMessage) var attributes attributes attributes.DeviceId = uplinkMessage.EndDeviceIds.DeviceId @@ -95,7 +104,26 @@ func (self *TTNHandler) Handle(message handler.MessageT) { g := gatewayAttributes { GatewayId: rxm.GatewayIds.GatewayId, Rssi: rxm.Rssi, Snr: rxm.Snr } attributes.Gateways = append(attributes.Gateways, g) } - log.Printf("Attributes: %s", attributes) + //log.Printf("Attributes: %s", attributes) + + log.Printf("ApplicationId: %s, DeviceId: %s", attributes.ApplicationId, attributes.DeviceId) + device, err2 := self.dbh.GetDeviceByLabelAndApplication(attributes.ApplicationId, attributes.DeviceId) + if err2 != nil { + lost(fmt.Sprintf("Error when loading device: %s, ", err2), message) + return + } + + log.Printf("DeviceLabel: %s, DeviceType: %s", device.Label, device.DeviceType.ModelIdentifier) + + switch device.DeviceType.ModelIdentifier { + case "emu-prof-ii-lora": + _, err3 := emuProfIILoRa.Parse(uplinkMessage.UplinkMessage.DecodedPayload) + if err3 != nil { + lost(fmt.Sprintf("Model parser failed: %s", err3), message) + return + } + } + }