package z2m import ( "fmt" "log" "time" "strings" "reflect" "encoding/json" "udi/config" "udi/handlers/handler" "udi/database" "udi/handlers/z2m/models/wsdcgq11lm" ) type Z2MHandler struct { handler.CommonHandler dbh *database.DatabaseHandle } func parse(T any, payload string, variables *map[string]database.VariableType) error { observationType := reflect.TypeOf(T) observation := reflect.New(observationType).Interface() err := json.Unmarshal([]byte(payload), observation) if err != nil { return fmt.Errorf("Unable to parse payload into Observation struct: %v, %s", err, payload) } observationValue := reflect.ValueOf(observation).Elem() for i := 0; i < observationType.NumField(); i++ { field := observationType.Field(i) name := field.Name unit := field.Tag.Get("unit") value := observationValue.Field(i).Interface() (*variables)[name] = database.VariableType { Label: name, Variable: "y", Unit: unit, Value: value, } } return nil } func New(id string, config config.HandlerConfigT) handler.Handler { t := &Z2MHandler { } t.Id = id t.dbh = database.NewDatabaseHandle() return t } func (self *Z2MHandler) Handle(message handler.MessageT) { log.Printf("Handler Z2M %d processing %s -> %s", self.Id, message.Topic, message.Payload) var measurement database.Measurement measurement.Time = time.Now() subTopics := strings.Split(message.Topic, "/") deviceId := subTopics[1] log.Printf("DeviceId: %s", deviceId) device, err1 := self.dbh.GetDeviceByLabel(deviceId) if err1 != nil { self.Lost("Error when loading device", err1, message) return } log.Printf("Device: %s", device) measurement.Application = device.Application.Label measurement.Device = device.Attributes["Label"].(string) var T any switch device.DeviceType.ModelIdentifier { case "WSDCGQ11LM": T = wsdcgq11lm.Observation{} default: self.Lost(fmt.Sprintf("No parser found for %s", device.DeviceType.ModelIdentifier), nil, message) return } measurement.Values = make(map[string]database.VariableType) measurement.Attributes = make(map[string]interface{}) err3 := parse(T, message.Payload, &(measurement.Values)) if err3 != nil { self.Lost("Model parser failed", err3, message) return } measurement.Attributes["Status"] = "ok" measurement.Attributes["DeviceId"] = deviceId measurement.Attributes["DeviceModel"] = device.DeviceType.ModelIdentifier log.Printf("Prepared measurement item: %s", measurement) self.dbh.StoreMeasurement(&measurement) self.S() }