From: jweigele Date: Thu, 27 Jul 2023 16:33:16 +0000 (-0700) Subject: Add wifi esp32 reporting, and an uptime gauge for tracking that X-Git-Url: http://git.hexthepla.net/?a=commitdiff_plain;h=86c94033acec6e897ee13d83262d6acbd0c0b4f1;p=rabbit_go Add wifi esp32 reporting, and an uptime gauge for tracking that --- diff --git a/helper/helper.go b/helper/helper.go index 3fb8468..e3a2127 100644 --- a/helper/helper.go +++ b/helper/helper.go @@ -225,7 +225,8 @@ func DecodeDelivery(delivery amqp.Delivery) (map[string]interface{}, error) { result := make(map[string]interface{}) // either explicitly json, or zigbee2mqtt (which we have set to only output json) isZigbee := strings.HasPrefix(delivery.RoutingKey, "zigbee2mqtt") - if delivery.ContentType == "application/json" || isZigbee { + isESP32 := strings.HasPrefix(delivery.RoutingKey, "esp32") + if delivery.ContentType == "application/json" || isZigbee || isESP32 { err := json.Unmarshal(delivery.Body, &result) if err != nil { return result, err diff --git a/reprocess/main.go b/reprocess/main.go index 9d4d805..74b8162 100644 --- a/reprocess/main.go +++ b/reprocess/main.go @@ -58,6 +58,14 @@ var ( []string{"location"}, ) + uptimeGauge = promauto.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "sensor_uptime", + Help: "Current remote sensor uptime (s)", + }, + []string{"location", "friendlyname"}, + ) + doorOpenCounter = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "sensor_door_opened_count", @@ -74,10 +82,11 @@ var ( []string{"location"}, ) - tempExpire = make(map[string]time.Time) - powerExpire = make(map[string]time.Time) - pm25Expire = make(map[string]time.Time) - aqiExpire = make(map[string]time.Time) + tempExpire = make(map[string]time.Time) + powerExpire = make(map[string]time.Time) + pm25Expire = make(map[string]time.Time) + aqiExpire = make(map[string]time.Time) + uptimeExpire = make(map[string]time.Time) doorMap = make(map[string]map[string]interface{}) @@ -131,6 +140,10 @@ type hexdevice struct { location string } +type esp32wifidevice struct { + *hexdevice +} + func (dev *powerdevice) filter() { // if this gets excessive we can pass it down the chain now := time.Now().UTC() @@ -171,6 +184,10 @@ func (dev *zigdevice) getRoutingKey() string { return fmt.Sprintf("zigbee2mqtt.%s", dev.friendlyName) } +func (dev *esp32wifidevice) getRoutingKey() string { + return fmt.Sprintf("%s", dev.friendlyName) +} + func (dev *powerdevice) getReqKey() string { return fmt.Sprintf("zigbee2mqtt.%s.get", dev.friendlyName) } @@ -210,6 +227,12 @@ func newhexdevice(friendlyName, location string) *hexdevice { } } +func newesp32wifidevice(friendlyName, location string) *esp32wifidevice { + return &esp32wifidevice{ + hexdevice: newhexdevice(friendlyName, location), + } +} + func handleTemp(obj map[string]interface{}) { logger.V(1).Info("Temperature received", "obj", obj) // these should both probably be checked for existence and type but oh well @@ -258,6 +281,18 @@ func processPM25(location string, pm25 float64, sendChannel chan helper.RabbitSe } +func processUptime(location string, friendlyName string, uptime float64, sendChannel chan helper.RabbitSend) { + // we don't want to have to loop back around on rabbit processing, so just set the gauge here + now := time.Now().UTC() + // do the label update here + uptimeGauge.With(prometheus.Labels{"location": location, "friendlyname": friendlyName}).Set(uptime) + + tempHash := labelValHash{labelValues: []string{location, friendlyName}} + expireMutex.Lock() + defer expireMutex.Unlock() + uptimeExpire[tempHash.getHash()] = now +} + func (dev *diydevice) handleDIY(obj map[string]interface{}, sendChannel chan helper.RabbitSend) { logger.V(1).Info("DIY data received", "obj", obj) _, isAction := obj["action"] @@ -343,31 +378,52 @@ func (dev *powerdevice) handlePower(obj map[string]interface{}, sendChannel chan } -func (dev *hexdevice) handleHex(obj map[string]interface{}, sendChannel chan helper.RabbitSend) { - //now := time.Now().UTC() - logger.V(1).Info("Hex data received", "obj", obj) +func hexCommon(location string, friendlyName string, obj map[string]interface{}, sendChannel chan helper.RabbitSend) { pm25, ok := obj["pm25"].(float64) if !ok { - logger.Error(nil, "contact not found in data, ignoring", "obj", obj) - return + logger.V(3).Info("pm25 not found in data, ignoring", "obj", obj) + } else { + processPM25(location, pm25, sendChannel) } - processPM25(dev.location, pm25, sendChannel) temperature, ok := obj["temperature"].(float64) if !ok { - logger.Error(nil, "contact not found in data, ignoring", "obj", obj) - return + logger.V(3).Info("temperature not found in data, ignoring it ", "obj", obj) + } else { + if temperature < -55.0 || temperature > 125.0 { + logger.Error(nil, "temperature out of range, ignoring it", "temperature", temperature) + } else { + dataMap := make(map[string]interface{}, 0) + // these should all exist properly + dataMap["fahrenheit"] = temperature*9/5 + 32 + dataMap["celsius"] = temperature + dataMap["location"] = location + logger.V(2).Info("Sending reprocessed temperature") + // hardcoded temp routingKey for this type of measurement + sendThis := helper.RabbitSend{Data: dataMap, RoutingKey: "temp", IncludeDate: true} + sendChannel <- sendThis + } } - dataMap := make(map[string]interface{}, 0) - // these should all exist properly - dataMap["fahrenheit"] = temperature*9/5 + 32 - dataMap["celsius"] = temperature - dataMap["location"] = dev.location - logger.V(2).Info("Sending reprocessed temperature") - // hardcoded temp routingKey for this type of measurement - sendThis := helper.RabbitSend{Data: dataMap, RoutingKey: "temp", IncludeDate: true} - sendChannel <- sendThis + uptime, ok := obj["uptime"].(float64) + if !ok { + logger.V(3).Info("uptime not found in data, ignoring", "obj", obj) + } else { + processUptime(location, friendlyName, uptime, sendChannel) + } + +} +func (dev *hexdevice) handleHex(obj map[string]interface{}, sendChannel chan helper.RabbitSend) { + //now := time.Now().UTC() + logger.V(1).Info("Hex data received", "obj", obj) + hexCommon(dev.location, dev.friendlyName, obj, sendChannel) +} + +// this can be from any number of devices, location is in the map +func (dev *esp32wifidevice) handleESP32wifi(obj map[string]interface{}, sendChannel chan helper.RabbitSend) { + location := obj["location"].(string) + logger.V(1).Info("esp32 data received", "obj", obj) + hexCommon(location, "wifi", obj, sendChannel) } func (dev *doordevice) handleDoor(obj map[string]interface{}, sendChannel chan helper.RabbitSend) { @@ -478,6 +534,10 @@ func readLoop(channel chan helper.RabbitSend, devices []device, rabbit helper.Ra logger.V(2).Info("Hex device, sending to handle", "device", device) device.(*hexdevice).handleHex(item, channel) + case *esp32wifidevice: + logger.V(2).Info("ESP32 wifi device, sending to handle", "device", device) + device.(*esp32wifidevice).handleESP32wifi(item, channel) + default: logger.Info("Found a device we can't classify", "device", device, "type", t) } @@ -569,6 +629,7 @@ func expireStaleMetrics() { expireStaleMetric(powerExpire, powerGauge) expireStaleMetric(pm25Expire, pm25Gauge) expireStaleMetric(aqiExpire, aqiGauge) + expireStaleMetric(uptimeExpire, uptimeGauge) } @@ -614,7 +675,9 @@ func main() { devices = append(devices, newdoordevice("data_door")) // hex devices (super custom) - devices = append(devices, newhexdevice("0xfffe7e6af7f95560", "Downstairs Test")) + devices = append(devices, newhexdevice("0x7e6af7fefff95560", "Downstairs Test")) + + devices = append(devices, newesp32wifidevice("esp32.sensor_info", "")) //currentTemp, err := fetchTemp(weatherStation) channel := make(chan helper.RabbitSend)