[]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",
[]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{})
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()
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)
}
}
}
+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
}
+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"]
}
-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) {
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)
}
expireStaleMetric(powerExpire, powerGauge)
expireStaleMetric(pm25Expire, pm25Gauge)
expireStaleMetric(aqiExpire, aqiGauge)
+ expireStaleMetric(uptimeExpire, uptimeGauge)
}
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)