使用InfluxDB和NODE-RED使您的数据生动起来

导航到

将您的物联网数据放入后端系统很好。能够查询和可视化您的物联网数据则更好。真正应该成为物联网数据系统最终目标的是使物联网数据可操作。正如我们在之前的帖子中所看到的,前几件事情相对简单且容易完成。正如我们接下来将要看到的,使数据可操作同样简单且相对容易。

可视化您的数据使您能够实时查看数据并获得您可能无法获得的见解。它是物联网数据工具箱中一个非常有用的工具,但仅仅在分析时看到数据是不够的。为了有用,物联网数据必须是可操作的。我将给出一个简单的例子,但它可以很容易地扩展到其他用例。我将使用我的传感器数据来创建警报,然后使用这些警报使用GlowOrb创建一个可视警报。

由于我已经从多个传感器中收集传感器数据(请参阅我关于此主题的上一篇文章),所以不再赘述,但请随意回顾一下那篇文章。

我还会在这个例子中使用NODE-RED,因此您应该已经安装并运行了NODE-RED,以及您的InfluxData TICK Stack安装。这涵盖了先决条件,让我们开始吧。

配置 NODE-RED

Node-RED 设置简单,启动也很容易。使用 GlowOrb 甚至更简单。一旦我将 GlowOrb 连接到我的 WiFi,我只需访问 http://mqtt.org/GO/XXXX-YYYY/(我的 GlowOrb 的序列号)并给出一个完整的 NODE-RED 设置 JSON

[
	{
		"id": "6f3203ca.13859c",
		"type": "inject",
		"z": "58595b89.4b164c",
		"name": "red",
		"topic": "",
		"payload": "#ff0000",
		"payloadType": "str",
		"repeat": "",
		"crontab": "",
		"once": false,
		"x": 170,
		"y": 300,
		"wires": [
			[
				"e3af354.bd4ccc8"
			]
		]
	},
	{
		"id": "3d87bb90.0141bc",
		"type": "inject",
		"z": "58595b89.4b164c",
		"name": "green",
		"topic": "",
		"payload": "#00ff00",
		"payloadType": "str",
		"repeat": "",
		"crontab": "",
		"once": false,
		"x": 170,
		"y": 340,
		"wires": [
			[
				"e3af354.bd4ccc8"
			]
		]
	},
	{
		"id": "b446c882.3503c8",
		"type": "inject",
		"z": "58595b89.4b164c",
		"name": "blue",
		"topic": "",
		"payload": "#0000ff",
		"payloadType": "str",
		"repeat": "",
		"crontab": "",
		"once": false,
		"x": 170,
		"y": 380,
		"wires": [
			[
				"e3af354.bd4ccc8"
			]
		]
	},
	{
		"id": "e3af354.bd4ccc8",
		"type": "mqtt out",
		"z": "58595b89.4b164c",
		"name": "GlowOrb XXXX-YYYY",
		"topic": "iot-2/evt/command/fmt/text",
		"qos": "",
		"retain": "",
		"broker": "3ecd43e1.c325e4",
		"x": 410,
		"y": 340,
		"wires": [

		]
	},
	{
		"id": "ee113762.3d4e5",
		"type": "mqtt in",
		"z": "58595b89.4b164c",
		"name": "cheerlights",
		"topic": "cheerlightsRGB",
		"qos": "2",
		"broker": "3c0e7ff3.d2e5b8",
		"x": 160,
		"y": 440,
		"wires": [
			[

			]
		]
	},
	{
		"id": "3ecd43e1.c325e4",
		"type": "mqtt-broker",
		"z": "",
		"broker": "jit4q3.messaging.internetofthings.ibmcloud.com",
		"port": "1883",
		"clientid": "d:jit4q3:GlowOrbControl:XXXX-YYYY",
		"usetls": false,
		"compatmode": false,
		"keepalive": "60",
		"cleansession": true,
		"willTopic": "",
		"willQos": "0",
		"willRetain": "false",
		"willPayload": "",
		"birthTopic": "",
		"birthQos": "0",
		"birthRetain": "false",
		"birthPayload": "",
		"credentials": {
			"user": "use-token-auth",
			"password": "cMlWUog8wY+Qp1LIyw"
		}
	},
	{
		"id": "3c0e7ff3.d2e5b8",
		"type": "mqtt-broker",
		"z": "",
		"broker": "iot.eclipse.org",
		"port": "1883",
		"clientid": "",
		"usetls": false,
		"compatmode": true,
		"keepalive": "60",
		"cleansession": true,
		"willTopic": "",
		"willQos": "0",
		"willPayload": "",
		"birthTopic": "",
		"birthQos": "0",
		"birthPayload": ""
	}
]

这是一大堆 JSON,但如果将其复制并粘贴到 NODE-RED 流中,你会得到以下内容

SafariScreenSnapz006

单击任何这些蓝色方块都将将 GlowOrb 的颜色更改为对应的颜色。但这不是我们想要的,所以我们将添加几个 http 端点节点,根据 http 通知来更改颜色。

SafariScreenSnapz007

我将这些“-notice”节点定义如下

SafariScreenSnapz009

现在我已经有了 Kapacitor 警报的 http 端点!

设置 Kapacitor 警报

现在我已经设置了 GlowOrb,并设置了 http 通知的正确端点,我所要做的就是设置 Kapacitor 警报!在 Chronograf 中,我转到“警报”选项卡,然后是“警报规则”选项卡,并定义一个新的警报规则,然后创建一个查询

SafariScreenSnapz013

然后定义警报何时发生(触发条件)

SafariScreenSnapz019

以及应该发生什么

SafariScreenSnapz014

所以现在我的警报将在我之前定义的 NODE-RED 端点处发出,当温度读数超过 85.1º F 时。实际上,如果我在 NODE-RED 服务器的调试控制台中查看,我会看到

SafariScreenSnapz008

这表明它真的非常热!我应该对此做点什么。此外,我的 GlowOrb 已经变成了红色!成功!

细化警报

我真正想要的是根据温度显示更多精度,为此,我必须编写以下自定义 TICK 脚本

var db = 'iotdata'
  var rp = 'autogen'
  var measurement = 'influxdata_sensors'
  var groupBy = [*] 
  var whereFilter = lambda: ("location" == 'TravelingWilbury')
  var name = 'relative-temp'
  var idVar = name + ':{{.Group}}'
  var message = ' {{ index .Fields "value" }}'
  var idTag = 'alertID'
  var levelTag = 'level'
  var messageField = 'message'
  var durationField = 'duration'
  var outputDB = 'chronograf'
  var outputRP = 'autogen'
  var outputMeasurement = 'alerts'
  var triggerType = 'relative'
  var shift = 5s
  0s
  var crit = 0.5
  var data = stream
   |from()
     .database(db)
     .retentionPolicy(rp)
     .measurement(measurement)
     .groupBy(groupBy)
     .where(whereFilter)
   |eval(lambda: "temp_f")
     .as('value')
   |window()
     .period(3s)
     .every(1s)
     .align()
  var max = data
   |max('value')
     .as('value')
  var min = data
   |min('value')
     .as('value')
  var trigger = max
   |join(min)
     .as('max', 'min')
     .tolerance(100ms)
   |eval(lambda: float("max.value" - "min.value"))
     .keep()
     .as('chng')
   |log()
     .level('ERROR')
  trigger
   |influxDBOut()
     .create()
     .database('derived_iotdata')
     .measurement('influxdata_sensors')
  trigger
   |alert()
     .crit(lambda: abs("chng") > crit)
     .stateChangesOnly()
     .message(message)
     .id(idVar)
     .idTag(idTag)
     .levelTag(levelTag)
     .messageField(messageField)
     .durationField(durationField)
     .post('http://XXXX.com:1880/sensor-reading')
  trigger
   |influxDBOut()
     .create()
     .database(outputDB)
     .retentionPolicy(outputRP)
     .measurement(outputMeasurement)
     .tag('alertName', name)
     .tag('triggerType', triggerType)
  trigger |httpOut('output')

这看起来很多,但大部分脚本是由 Chronograf 为“相对”警报构建的,然后我进行了一些修改。我所做的修改是添加

|window()
        .period(3s)
        .every(1s)
        .align()

trigger
    |influxDBOut()
        .create()
        .database(outputDB)
        .retentionPolicy(outputRP)
        .measurement(outputMeasurement)
        .tag('alertName', name)
        .tag('triggerType', triggerType)

这样数据在比较时就会正确对齐,然后我添加了另一个触发器,将上一个温度、当前温度和变化值写回不同的数据库,这样我就可以监控我的温度监控了。多么元!

最后,我必须对我的 NODE-RED 脚本进行一些修改,如下所示

SafariScreenSnapz021

我创建了一个名为“readings”的警报端点(并删除了其他端点),然后为端点创建了一个 http 响应(以便正确关闭连接)。响应节点只是返回 HTTP 状态码 204。至于“ExtractTemp”节点,我必须为它编写一小段 JavaScript

var myMsg = {};
var val =  myData.data.series[0].values[0][2];
node.log(val);
if(val > 90){
    myMsg.payload = "#ff0000";
    return myMsg;
} else if (val > 88){
    myMsg.payload = "#ff4000";
    return myMsg;
} else if (val > 86){
    myMsg.payload = "#ff8000";
    return myMsg;
} else if (val > 84){
    myMsg.payload = "#ff8000";
    return myMsg;
} else if (val > 82){
    myMsg.payload = "#ffff00";
    return myMsg;
}else if (val > 80){
    myMsg.payload = "#bfff00";
    return myMsg;
} else if (val > 78){
    myMsg.payload = "#80ff00";
    return myMsg;
} else if (val > 76){
    myMsg.payload = "#40ff00";
    return myMsg;
}else if (val > 74){
    myMsg.payload = "#00ff00";
    return myMsg;
}else if (val > 72){
    myMsg.payload = "#00ff40";
    return myMsg;
} else if (val > 70){
    myMsg.payload = "#00ff80";
    return myMsg;
} else if (val > 68){
    myMsg.payload = "#00ffbf";
    return myMsg;
} else if (val > 66){
    myMsg.payload = "#00ffff";
    return myMsg;
} else if (val > 64){
    myMsg.payload = "#00bfff";
    return myMsg;
} else if (val > 62){
    myMsg.payload = "#0080ff";
    return myMsg;
} else if (val > 60){
    myMsg.payload = "#0040ff";
    return myMsg;
} else if (val > 58){
    myMsg.payload = "#0000ff";
    return myMsg;
} else if (val > 56){
    myMsg.payload = "#4000ff";
    return myMsg;
} else if (val > 54){
    myMsg.payload = "#8000ff";
    return myMsg;
} else {
    myMsg.payload = "#bf00ff";
}
return myMsg;

现在我的 GlowOrb 每 2 度变化一次颜色。为了简单起见,我从 W3Schools 中获取颜色。

结论

这是一个有趣的项目,使用 NODE-RED 和 InfluxDB 相对容易地设置。我能够快速将传感器读数转换为数据,然后将这些数据既显示在仪表板上,又对物理世界产生影响。这是一个简单的例子,但我也同样容易地将输出连接到控制空调出风口的伺服电机来调节温度等。

现在的问题是:你会控制什么?