diff --git a/src/udi/config-test.json b/src/udi/config-test.json new file mode 100644 index 0000000..454fff8 --- /dev/null +++ b/src/udi/config-test.json @@ -0,0 +1,115 @@ +{ + "mqtt": { + "broker": "mqtt://172.23.1.102:1883", + "tlsEnable": "false" + }, + "topicMappings": [ + { + "topics": [ "dt1/ai/periodic/1" ], + "handler": "DT1T", + "id": "DT1T.0", + "config": { + "attributes": { + "Application": "Temperature Wago", + "Device": "Freezer", + "HardLow": "-273", + "SoftLow": "-50", + "SoftHigh": "20", + "HardHigh": "100" + } + } + }, + { + "topics": [ "dt1/ai/periodic/3" ], + "handler": "DT1T", + "id": "DT1T.1", + "config": { + "attributes": { + "Application": "Temperature Wago", + "Device": "Outdoor", + "HardLow": "-273", + "SoftLow": "-60", + "SoftHigh": "60", + "HardHigh": "100" + } + } + }, + { + "topics": [ "IoT/OneWireGW/Bus 1/#" ], + "handler": "SVER", + "id": "SVER0", + "config": { + "databaseConnStr": "", + "attributes": { + "application": "Temperature Heating", + "payloadRegex": "(\\d+(\\.\\d+)?)\\s*([^0-9\\s]\\S*)", + "deviceFrom": "topic", + "devicePart": "3", + "valueFrom": "payload", + "valuePart": "1", + "unitFrom": "payload", + "unitPart": "3" + } + } + }, + { + "topics": [ "NR/Multisensor/+/Temperatur" ], + "handler": "SVEJ", + "id": "SVEJ0", + "config": { + "databaseConnStr": "", + "attributes": { + "application": "Temperature Multisensor", + "deviceSelector": "T:2", + "valueSelector": "J:$.CurrentTemperature", + "unitSelector": "C:°C" + } + } + }, + { + "topics": [ "NR/Multisensor/+/Feuchte" ], + "handler": "SVEJ", + "id": "SVEJ1", + "config": { + "databaseConnStr": "", + "attributes": { + "application": "Humidity Multisensor", + "deviceSelector": "T:2", + "valueSelector": "J:$.CurrentRelativeHumidity", + "unitSelector": "C:%" + } + } + }, + { + "topics": [ "shellyplusht/+/status/temperature:0" ], + "handler": "SVEJ", + "id": "SVEJ2", + "config": { + "databaseConnStr": "", + "attributes": { + "application": "Temperature Shelly Plus HT", + "deviceSelector": "T:1", + "valueSelector": "J:$.tC", + "unitSelector": "C:°C" + } + } + }, + { + "topics": [ "shellyplusht/+/status/humidity:0" ], + "handler": "SVEJ", + "id": "SVE4", + "config": { + "databaseConnStr": "", + "attributes": { + "application": "Humidity Shelly Plus HT", + "deviceSelector": "T:1", + "valueSelector": "J:$.rh", + "unitSelector": "C:%" + } + } + } + ], + "archiver": { + "dir": "./tmp/udi" + } +} diff --git a/src/udi/handlers/dt1t/dt1t.go b/src/udi/handlers/dt1t/dt1t.go new file mode 100644 index 0000000..a578b3b --- /dev/null +++ b/src/udi/handlers/dt1t/dt1t.go @@ -0,0 +1,91 @@ +package dt1t + +import ( + "log" + "fmt" + "time" + "strconv" + "udi/handlers/handler" + "udi/database" + "udi/config" +) + + +var idSeq int = 0 + +type Dt1tHandler struct { + id int + ready bool + dbh *database.DatabaseHandle + application string + device string + +} + +func NewDt1tHandler(config config.HandlerConfigT) handler.Handler { + t := &Dt1tHandler { + id: idSeq, + } + + if config.Attributes["Application"] == "" { + log.Println("Error: application not configured") + return t + } + t.application = config.Attributes["Application"] + if config.Attributes["Device"] == "" { + log.Println("Error: device not configured") + return t + } + t.device = config.Attributes["Device"] + + + idSeq += 1 + t.dbh = database.NewDatabaseHandle() + t.ready = true + return t +} + +func (self *Dt1tHandler) GetId() string { + return fmt.Sprintf("DT1T%d", self.id) +} + +func lost(msg string, message handler.MessageT) { + log.Printf("Error: %s, message %s is lost", msg, message) +} + +func (self *Dt1tHandler) Handle(message handler.MessageT) { + if ! self.ready { + log.Println("Handler is not marked as ready, message %s is lost", message) + return + } + log.Printf("Handler DT1T %d processing %s -> %s", self.id, message.Topic, message.Payload) + + temperature, err := strconv.Atoi(message.Payload) + if err != nil { + lost(fmt.Sprintf("Invalid raw value: %s", err), message) + return + } + if temperature & 0x8000 != 0{ + temperature = ((temperature - 1) ^ 0xffff) * -1 + } + temperatureF := float32(temperature) / 10.0 + log.Printf("TemperatureF: %f", temperatureF) + + var measurement database.Measurement + measurement.Time = time.Now() + measurement.Application = self.application + measurement.Device = self.device + + var variable database.VariableType + variable.Label = "Temperature" + variable.Variable = "" + variable.Unit = "°C" + variable.Value = fmt.Sprintf("%f", temperatureF) + measurement.Values = make(map[string]database.VariableType) + measurement.Values["Value"] = variable + + log.Printf("Prepared measurement item: %s", measurement) + self.dbh.StoreMeasurement(&measurement) +} + +