节点红色:如何以每分钟给定的秒数进行注入火力 [英] Node red: how to make inject fire at given seconds per minute

查看:61
本文介绍了节点红色:如何以每分钟给定的秒数进行注入火力的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以制作一个每 5 秒触发一次的注入节点,但不取决于部署,而是在固定的时间网格中触发.

例如,在 hh:mm:03 部署时,间隔为 5 秒的注入节点将在 hh:mm:08、hh:mm:13、hh:mm:18 等触发.

有没有办法延迟它,以便消息在 hh:mm:05、hh:mm:10、hh:mm:15 准确地发送 (*),无论它是在哪一秒部署的?

一种可能的解决方案是将重复间隔设置为 1 秒,并使用函数节点仅传递适当的消息(即在 5 秒的倍数时间戳后到达的第一条消息),但也许有更好的归档方式.

(*)当然在机器的范围内

根据要求描述流程实际执行的操作.该计时器用于环境监测(空气质量、水质、气象)的数据记录器.为了使该数据记录器与旧系统兼容,我们必须应用相同的时间限制.

解决方案

请仅使用 Hannes 的回答中引用的 node-red-contrib-interval-multiples-timer 节点. 它基于在我的代码上,因此当您只需单击几下即可安装 npm 包时,没有理由再从这里复制粘贴代码.我只是将代码留在这里以供参考或作为您自己实验的起点.

<小时>

最终,我创建了一个执行此操作的节点...我稍后可能会创建一个 NPM 包,现在这里是将其安装为本地节点的源.

要安装它,创建两个文件 interval-timer.jsinterval-timer.html ,内容如下,然后将它们复制到 Node-RED 安装的 nodes 目录;例如,在带有 Raspbian 的 Raspberry Pi 上,这些文件会转到 /root/.node-red/nodes/.重新启动 Node-RED 后,新的 interval timer 节点将出现在节点面板的 Input 部分.

间隔定时器.js:

module.exports = function(RED) {函数 IntervalTimerNode(config) {RED.nodes.createNode(this,config);var 节点 = 这个;var 间隔 = config.interval;无功定时器;var timeHandler = function() {node.send({payload: config.payload || Date.now()});timer = setTimeout(timeHandler, interval - (Date.now() %interval));//setInterval 显然有相当大的漂移,所以我们使用 setTimeout 尽可能地留在时间网格内};timer = setTimeout(timeHandler, interval - (Date.now() %interval));node.on('close', function() {清除超时(定时器);});}RED.nodes.registerType("interval-timer", IntervalTimerNode);}

间隔计时器.html:

<script type="text/x-red" data-template-name="interval-timer"><div class="form-row"><label for="node-input-interval"><i class="icon-repeat"></i>间隔 [ms]<input type="number" id="node-input-interval">

<div class="form-row"><label for="node-input-payload"><i class="icon-envelope"></i>有效负载(默认为当前时间戳)</label><input type="text" id="node-input-payload" placeholder="Payload">

<div class="form-row"><label for="node-input-name"><i class="icon-tag"></i>名称<input type="text" id="node-input-name" placeholder="Name">

<script type="text/x-red" data-help-name="interval-timer"><p>在给定间隔的倍数处触发的间隔计时器,从 1970 年 1 月 1 日开始测量</p>

Is it possible to make an inject node that fires every 5 seconds, but not depending on deployment, instead in a fixed time grid.

For example, an inject node with a 5 second interval would fire at hh:mm:08, hh:mm:13, hh:mm:18 etc. when deployed at hh:mm:03.

Is there a way to delay it so that messages are sent exactly(*) at hh:mm:05, hh:mm:10, hh:mm:15 no matter in which second it was deployed?

A possible solution would be to set the repeat interval to 1 second, and use a function node to only pass the appropriate messages (i.e. the first message arriving after a multiple-of-5secs-timestamp), but maybe there is a better way to archive that.

(*) within the limits of the machine, of course

Edit: Description of what the flow actually does, as requested. This timer is used in a datalogger for environmental monitoring (air quality, water quality, meteorology). To make this datalogger compatible with an older system, we have to apply the same timing constraints.

解决方案

EDIT: Please just use the node-red-contrib-interval-multiples-timer node referenced in Hannes' answer. It's based on my code, so there is no reason anymore to copy-paste code from here when you can just install the npm package with a few clicks. I just leave the code here for reference or as a starting point for your own experiments.


Eventually, I created a node that does that... I might create a NPM package later, right now here is the source to install it as a local node.

To install it, create the two files interval-timer.js and interval-timer.html with the content given below, then copy them into the nodes directory of your Node-RED installation; for example, on a Raspberry Pi with Raspbian, those files go to /root/.node-red/nodes/. After restarting Node-RED, the new interval timer node will appear in the Input section of the nodes palette.

interval-timer.js:

module.exports = function(RED) {
    function IntervalTimerNode(config) {
        RED.nodes.createNode(this,config);
        var node = this;
        var interval = config.interval;
        var timer;

        var timeHandler = function() {
            node.send({payload: config.payload || Date.now()});
            timer = setTimeout(timeHandler, interval - (Date.now() %interval));  // setInterval apparently has a considerable drift, so we use setTimeout to stay within the time grid as much as possible
        };

        timer = setTimeout(timeHandler, interval - (Date.now() %interval));        

        node.on('close', function() {
            clearTimeout(timer);
        });
    }

    RED.nodes.registerType("interval-timer", IntervalTimerNode);
}

interval-timer.html:

<script type="text/javascript">
    RED.nodes.registerType('interval-timer',{
        category: 'input',
        color: '#a6bbcf',
        defaults: {
            interval: {value:5000},
            payload: {value: ""},
            name: {value:""}
        },
        inputs:0,
        outputs:1,
        icon: "timer.png",
        label: function() {
            return this.name||"interval-timer";
        }
    });
</script>

<script type="text/x-red" data-template-name="interval-timer">
    <div class="form-row">
        <label for="node-input-interval"><i class="icon-repeat"></i> Interval [ms]</label>
        <input type="number" id="node-input-interval">
    </div>
    <div class="form-row">
        <label for="node-input-payload"><i class="icon-envelope"></i> Payload (defaults to current timestamp)</label>
        <input type="text" id="node-input-payload" placeholder="Payload">
    </div>
    <div class="form-row">
        <label for="node-input-name"><i class="icon-tag"></i> Name</label>
        <input type="text" id="node-input-name" placeholder="Name">
    </div>
</script>

<script type="text/x-red" data-help-name="interval-timer">
    <p>A interval timer that fires at multiples of the given interval, measured from Jan 1 1970</p>
</script>

这篇关于节点红色:如何以每分钟给定的秒数进行注入火力的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆