mirror of
https://github.com/node-red/node-red-nodes.git
synced 2025-03-01 10:37:43 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
eb4d35b140
8
analysis/mlsentiment/locales/de/mlsentiment.json
Normal file
8
analysis/mlsentiment/locales/de/mlsentiment.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"mlsentiment": {
|
||||
"sentiment": "sentiment",
|
||||
"label": {
|
||||
"language": "Sprache"
|
||||
}
|
||||
}
|
||||
}
|
29
analysis/mlsentiment/locales/en-US/mlsentiment.html
Normal file
29
analysis/mlsentiment/locales/en-US/mlsentiment.html
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
<script type="text/html" data-help-name="mlsentiment">
|
||||
<p>Analyses the chosen property, default <code>payload</code>, and adds a <code>sentiment</code> object.</p>
|
||||
<h3>Outputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>sentiment <span class="property-type">object</span></dt>
|
||||
<dd>contains the resulting AFINN-111 sentiment.</dd>
|
||||
<dt>sentiment.score <span class="property-type">number</span></dt>
|
||||
<dd>the sentiment score.</dd>
|
||||
</dl>
|
||||
<h3>Inputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>words <span class="property-type">object</span></dt>
|
||||
<dd>an object of words and scores to override or add words can be supplied - <code>{ word:score,... }</code>.</dd>
|
||||
</dl>
|
||||
<dl class="message-properties">
|
||||
<dt>lang <span class="property-type">string</span></dt>
|
||||
<dd>Two letter cldr code to specify the language to use - from the list below</dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>A score greater than zero is positive and less than zero is negative.</p>
|
||||
<p>The score typically ranges from -5 to +5, but can go higher and lower.</p>
|
||||
<p>See <a href="https://github.com/marcellobarile/multilang-sentiment/blob/develop/README.md" target="_blank">the Sentiment docs here</a>.</p>
|
||||
<p>The node can also be configured to let the language be specified by setting <code>msg.lang</code> to one of the codes below</p>
|
||||
<p>The language codes supported are - af, am, ar, az, be, bg, bn, bs, ca, ceb, co, cs, cy, da, de, el, en, eo, es, et, eu, fa, fi,
|
||||
fr, fy, ga, gd, gl, gu, ha, haw, hi, hmn, hr, ht, hu, hy, id, ig, is, it, iw, ja, jw, ka, kk, km, kn, ko, ku, ky, la, lb, lo, lt,
|
||||
lv, mg, mi, mk, ml, mn, mr, ms, mt, my, ne, nl, no, ny, pa, pl, ps, pt, ro, ru, sd, si, sk, sl, sm, sn, so, sq, sr, st, su, sv,
|
||||
sw, ta, te, tg, th, tl, tr, uk, ur, uz, vi, xh, yi, yo, zh, zh-tw, zu</p>
|
||||
</script>
|
@ -1,5 +1,5 @@
|
||||
|
||||
<script type="text/x-red" data-help-name="mlsentiment">
|
||||
<script type="text/html" data-help-name="mlsentiment">
|
||||
<p>指定したプロパティ(デフォルトは<code>payload</code>)を分析し、<code>sentiment</code>オブジェクトを追加します。</p>
|
||||
<h3>出力</h3>
|
||||
<dl class="message-properties">
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="mlsentiment">
|
||||
<script type="text/html" data-template-name="mlsentiment">
|
||||
<div class="form-row">
|
||||
<label for="node-input-lang"><i class="fa fa-language"></i> <span data-i18n="mlsentiment.label.language"></span></label>
|
||||
<select type="text" id="node-input-lang" style="width:70%;">
|
||||
@ -118,35 +118,6 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="mlsentiment">
|
||||
<p>Analyses the chosen property, default <code>payload</code>, and adds a <code>sentiment</code> object.</p>
|
||||
<h3>Outputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>sentiment <span class="property-type">object</span></dt>
|
||||
<dd>contains the resulting AFINN-111 sentiment.</dd>
|
||||
<dt>sentiment.score <span class="property-type">number</span></dt>
|
||||
<dd>the sentiment score.</dd>
|
||||
</dl>
|
||||
<h3>Inputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>words <span class="property-type">object</span></dt>
|
||||
<dd>an object of words and scores to override or add words can be supplied - <code>{ word:score,... }</code>.</dd>
|
||||
</dl>
|
||||
<dl class="message-properties">
|
||||
<dt>lang <span class="property-type">string</span></dt>
|
||||
<dd>Two letter cldr code to specify the language to use - from the list below</dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>A score greater than zero is positive and less than zero is negative.</p>
|
||||
<p>The score typically ranges from -5 to +5, but can go higher and lower.</p>
|
||||
<p>See <a href="https://github.com/marcellobarile/multilang-sentiment/blob/develop/README.md" target="_blank">the Sentiment docs here</a>.</p>
|
||||
<p>The node can also be configured to let the language be specified by setting <code>msg.lang</code> to one of the codes below</p>
|
||||
<p>The language codes supported are - af, am, ar, az, be, bg, bn, bs, ca, ceb, co, cs, cy, da, de, el, en, eo, es, et, eu, fa, fi,
|
||||
fr, fy, ga, gd, gl, gu, ha, haw, hi, hmn, hr, ht, hu, hy, id, ig, is, it, iw, ja, jw, ka, kk, km, kn, ko, ku, ky, la, lb, lo, lt,
|
||||
lv, mg, mi, mk, ml, mn, mr, ms, mt, my, ne, nl, no, ny, pa, pl, ps, pt, ro, ru, sd, si, sk, sl, sm, sn, so, sq, sr, st, su, sv,
|
||||
sw, ta, te, tg, th, tl, tr, uk, ur, uz, vi, xh, yi, yo, zh, zh-tw, zu</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('mlsentiment',{
|
||||
category: 'analysis-function',
|
||||
|
@ -1,4 +1,4 @@
|
||||
<script type="text/x-red" data-template-name="sentiment">
|
||||
<script type="text/html" data-template-name="sentiment">
|
||||
<div class="form-row">
|
||||
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
|
||||
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||
|
8
analysis/sentiment/locales/de/72-sentiment.json
Normal file
8
analysis/sentiment/locales/de/72-sentiment.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"sentiment": {
|
||||
"sentiment": "sentiment",
|
||||
"label": {
|
||||
"language": "Sprache"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="badwords">
|
||||
<script type="text/html" data-template-name="badwords">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="badwords">
|
||||
<script type="text/html" data-help-name="badwords">
|
||||
<p>Analyses the <code>msg.payload</code> and tries to filter out any messages containing bad swear words...</p>
|
||||
<p><b>Note:</b> this only operates on payloads of type <b>string</b>. Everything else is blocked.</p>
|
||||
</script>
|
||||
|
8
function/PID/locales/en-US/pidcontrol.html
Normal file
8
function/PID/locales/en-US/pidcontrol.html
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
<script type="text/html" data-help-name="PID control">
|
||||
<p>A PID controller node.</p>
|
||||
<p>This node ONLY expects a numeric <code>msg.payload</code> containing the current reading.
|
||||
It will output the correction that needs to be applied in order to move to the preset <i>set point</i> value.</p>
|
||||
<p>See <a href="https://en.wikipedia.org/wiki/PID_controller" target="_new">Wikipedia</a> for more details.</p>
|
||||
<p>The <i>set point</i> may be overridden by <code>msg.setpoint</code>. If you do so the edit box value can be used as the initial value.</p>
|
||||
</script>
|
@ -1,5 +1,5 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="PID control">
|
||||
<script type="text/html" data-template-name="PID control">
|
||||
<div class="form-row">
|
||||
<label for="node-input-target" style="width:120px;"><i class="fa fa-dot-circle-o"></i> Set Point</label>
|
||||
<input type="text" id="node-input-target" placeholder="target value" style="width:60%;">
|
||||
@ -24,14 +24,6 @@
|
||||
The damping factors are typically in the range 0 - 1.<br></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="PID control">
|
||||
<p>A PID controller node.</p>
|
||||
<p>This node ONLY expects a numeric <code>msg.payload</code> containing the current reading.
|
||||
It will output the correction that needs to be applied in order to move to the preset <i>set point</i> value.</p>
|
||||
<p>See <a href="https://en.wikipedia.org/wiki/PID_controller" target="_new">Wikipedia</a> for more details.</p>
|
||||
<p>The <i>set point</i> may be overridden by <code>msg.setpoint</code>. If you do so the edit box value can be used as the initial value.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('PID control',{
|
||||
color:"#d6ba48",
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="data-generator">
|
||||
<script type="text/html" data-template-name="data-generator">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
@ -25,17 +25,6 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="data-generator">
|
||||
<p>Creates dummy data strings based on a handlebars-style template.</p>
|
||||
<p>Uses the <i><a href="https://github.com/webroo/dummy-json/blob/master/README.md" target="_new">dummy-json</a></i>
|
||||
module, which can create rich sets of dummy data for testing or other uses.</p>
|
||||
<p>Will build a string or a parsed JSON object, creating values based on the helper names below:
|
||||
<pre style="word-break:normal">title, firstName, lastName, company, domain, tld, email, street, city, country, countryCode, zipcode, postcode, lat, long, phone, color, hexColor, guid, ipv4, ipv6, lorem [nn], date, time, lowercase, uppercase, int, float, boolean</pre>
|
||||
<p>Multiple values can be generated by use of the <i>repeat</i> syntax.</p>
|
||||
<p>In addition any properties passed in on <code>msg</code> can also be used - for example <code>{{payload}}</code>.</p>
|
||||
<p>Finally <code>msg.seed</code> can be used to preset the pseudo-random seed to ensure repeatability across calls.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('data-generator',{
|
||||
color:"rgb(243, 181, 103)",
|
||||
|
13
function/datagenerator/locales/de/datagenerator.json
Normal file
13
function/datagenerator/locales/de/datagenerator.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"datagen": {
|
||||
"datagen": "data generator",
|
||||
"label": {
|
||||
"syntax": "Rückgabe",
|
||||
"text": "ein Text-String",
|
||||
"json": "ein analysiertes (parsed) JSON-Objekt"
|
||||
},
|
||||
"errors": {
|
||||
"json-error": "Fehler beim Versuch, String zu JSON zu analysieren (parsen)"
|
||||
}
|
||||
}
|
||||
}
|
11
function/datagenerator/locales/en-US/datagenerator.html
Normal file
11
function/datagenerator/locales/en-US/datagenerator.html
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
<script type="text/html" data-help-name="data-generator">
|
||||
<p>Creates dummy data strings based on a handlebars-style template.</p>
|
||||
<p>Uses the <i><a href="https://github.com/webroo/dummy-json/blob/master/README.md" target="_new">dummy-json</a></i>
|
||||
module, which can create rich sets of dummy data for testing or other uses.</p>
|
||||
<p>Will build a string or a parsed JSON object, creating values based on the helper names below:
|
||||
<pre style="word-break:normal">title, firstName, lastName, company, domain, tld, email, street, city, country, countryCode, zipcode, postcode, lat, long, phone, color, hexColor, guid, ipv4, ipv6, lorem [nn], date, time, lowercase, uppercase, int, float, boolean</pre>
|
||||
<p>Multiple values can be generated by use of the <i>repeat</i> syntax.</p>
|
||||
<p>In addition any properties passed in on <code>msg</code> can also be used - for example <code>{{payload}}</code>.</p>
|
||||
<p>Finally <code>msg.seed</code> can be used to preset the pseudo-random seed to ensure repeatability across calls.</p>
|
||||
</script>
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red-node-data-generator",
|
||||
"version" : "0.1.1",
|
||||
"version" : "0.2.0",
|
||||
"description" : "A Node-RED node to create a string of dummy data values from a template. Useful for test-cases.",
|
||||
"dependencies" : {
|
||||
"dummy-json": "^2.0.0"
|
||||
|
13
function/random/locales/de/random.json
Normal file
13
function/random/locales/de/random.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"random": {
|
||||
"label": {
|
||||
"generate": "Generiere",
|
||||
"wholeNumber": "eine Ganzzahl (integer)",
|
||||
"realNumber": "eine reelle Zahl (floating point)",
|
||||
"from": "Von",
|
||||
"lowestNumber": "kleinste Zahl",
|
||||
"to": "Bis",
|
||||
"highestNumber": "größte Zahl"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red-node-random",
|
||||
"version" : "0.3.1",
|
||||
"version" : "0.4.0",
|
||||
"description" : "A Node-RED node that when triggered generates a random number between two values.",
|
||||
"dependencies" : {
|
||||
},
|
||||
|
40
function/rbe/locales/de/rbe.html
Normal file
40
function/rbe/locales/de/rbe.html
Normal file
@ -0,0 +1,40 @@
|
||||
<script type="text/html" data-help-name="rbe">
|
||||
<p>Report by Exception (RBE) - Daten-Weiterleitung nur bei Änderung der Nutzdaten (Payload).
|
||||
Der Node kann auch blockieren oder weiterleiten, wenn die Wertänderung eine Grenze überschreitet (Totband- und Nahband-Modus).</p>
|
||||
<h3>Eingangsdaten</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>payload
|
||||
<span class="property-type">number | string | (object)</span>
|
||||
</dt>
|
||||
<dd>Der RBE-Modus mit Prüfung auf Wertänderung akzeptiert Zahlen (numbers), Zeichenfolgen (string) und einfache Objekte (object).
|
||||
Bei den anderen wertvergleichenden Modies müssen analysierbare (parseable) Zahlenwerte übergeben werden.</dd>
|
||||
<dt class="optional">topic <span class="property-type">string</span>
|
||||
</dt>
|
||||
<dd>Wenn vorgegeben erfolgt die Auswertung separat für jedes Topic</dd>
|
||||
<dt class="optional">reset<span class="property-type">any</span></dt>
|
||||
<dd>Wenn gesetzt wird/werden der/die gespeicherte(n) Wert(e) rückgesetzt</dd>
|
||||
</dl>
|
||||
<h3>Ausgangsdaten</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>payload
|
||||
<span class="property-type">wie Eingangsdaten</span>
|
||||
</dt>
|
||||
<dd>Wenn Bedingung erfüllt, sind die Ausgangsdaten gleich den Eingangsdaten</dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>Im <i>RBE</i>-Modus mit Prüfung auf Wertänderung blockiert dieser Node die Datenweitergabe bis
|
||||
<code>msg.payload</code> (oder die eingestellte Eigenschaft) verändert ist gegenüber dessen vorherigen Wert.
|
||||
Wenn benötigt, wird der Anfangswert ignoriert, sodass beim Start nichts gesendet wird.</p>
|
||||
<p>In den <i>Totband</i>-Modies werden die Eingangswerte geblockt,
|
||||
<i>bis</i> die Wertänderung größer oder größer-gleich ist als ± des Bandes um den voherigen Wert.</p>
|
||||
<p>In den <i>Nahband</i>-Modies werden die Eingangswerte geblockt,
|
||||
<i>wenn</i> die Wertänderung größer oder größer-gleich ist als ± des Bandes um den voherigen Wert.
|
||||
Dies ist beispielsweise nützlich, um Ausreißer eines fehlerhaften Sensors zu ignorieren.</p>
|
||||
<p>In den Totband und Nahband-Modies müssen die Eingangswerte analysierbare (parseable) Zahlenwerte sein und
|
||||
beide unterstützen auch % (prozentuale Angabe), d.h. der Node sendet nur, wenn der Eingangswert mehr als x% vom vorherigen Wert abweicht.</p>
|
||||
<p>Die Totband- und Nahband-Modies erlauben den Vergleich entweder gegen den letzten gültigen Ausgangswert,
|
||||
dieses zum Ignorieren von Werten außerhalb des gültigen Bereichs, oder gegen den des vorherigen Eingangswertes,
|
||||
welches den Sollwert rücksetzt, was einen allmähligen Drift (Totband) oder einen eine schrittweise Veränderung (Nahband) ermöglicht.</p>
|
||||
<p><b>Hinweis</b>: Dieser Node arbeitet auf per-<code>msg.topic</code>-Basis.
|
||||
Dies bedeutet, dass ein einzelner rbe-Node mehrere verschiedene Topics parallel bearbeiten kann.</p>
|
||||
</script>
|
29
function/rbe/locales/de/rbe.json
Normal file
29
function/rbe/locales/de/rbe.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"rbe": {
|
||||
"rbe": "rbe",
|
||||
"label": {
|
||||
"func": "Modus",
|
||||
"init": "Sende Anfangswert",
|
||||
"start": "Startwert",
|
||||
"name": "Name",
|
||||
"septopics": "Modus für jedes msg.topic separat anwenden"
|
||||
},
|
||||
"placeholder":{
|
||||
"bandgap": "z.B. 10 oder 5%",
|
||||
"start": "Leer lassen, um erste empfangenen Daten zu nutzen"
|
||||
},
|
||||
"opts": {
|
||||
"rbe": "Blockieren bis Wertänderung",
|
||||
"rbei": "Blockieren bis Wertänderung (Anfangswert ignorieren)",
|
||||
"deadband": "Blockieren bis Wertänderung ist größer als",
|
||||
"deadbandEq": "Blockieren bis Wertänderung ist größer-gleich",
|
||||
"narrowband": "Blockieren wenn Wertänderung ist größer als",
|
||||
"narrowbandEq": "Blockieren wenn Wertänderung ist größer-gleich",
|
||||
"in": "verglichen mit letzten Eingangswert",
|
||||
"out": "verglichen mit letzten gültigen Ausgangswert"
|
||||
},
|
||||
"warn": {
|
||||
"nonumber": "Keine Zahl gefunden in den Nutzdaten (Payload)"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,19 @@
|
||||
<script type="text/html" data-help-name="rbe">
|
||||
<p>Report by Exception node - only passes on data if the payload has changed.</p>
|
||||
<p>It can also block unless, or ignore if the value changes by a specified amount.</p>
|
||||
<p>Report by Exception (RBE) node - only passes on data if the payload has changed.
|
||||
It can also block unless, or ignore if the value changes by a specified amount (Dead- and Narrowband mode).</p>
|
||||
<h3>Inputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>payload
|
||||
<span class="property-type">number | string | (object)</span>
|
||||
</dt>
|
||||
<dd>RBE mode will accept numbers, strings, and simple objects. Other modes must provide a parseable number.</dd>
|
||||
<dd>RBE mode will accept numbers, strings, and simple objects.
|
||||
Other modes must provide a parseable number.</dd>
|
||||
<dt class="optional">topic <span class="property-type">string</span>
|
||||
</dt>
|
||||
<dd>if specified the function will work on a per topic basis.</dd>
|
||||
<dt class="optional">reset<span class="property-type">any</span></dt>
|
||||
<dd>if set clears the stored value for the specified msg.topic, or
|
||||
all topics if msg.topic is not specified.</dd>
|
||||
all topics if msg.topic is not specified.</dd>
|
||||
</dl>
|
||||
<h3>Outputs</h3>
|
||||
<dl class="message-properties">
|
||||
@ -23,16 +24,18 @@
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>In RBE mode this node will block until the <code>msg.payload</code>,
|
||||
(or selected property) value is different to the previous one. If required
|
||||
it can ignore the intial value, so as not to send anything at start.</p>
|
||||
<p>In the Deadband modes the incoming value must contain a parseable number and will block
|
||||
unless the change is greater than + or - the band gap away from a previous value.</p>
|
||||
<p>Deadband also supports % - only sends if the input differs by more than x% of the original value.</p>
|
||||
<p>The Narrowband modes will block if the incoming value change is greater than + or - the band gap
|
||||
away from the previous value. Useful for ignoring outliers from a faulty sensor for example.</p>
|
||||
(or selected property) value is different to the previous one.
|
||||
If required it can ignore the intial value, so as not to send anything at start.</p>
|
||||
<p>The <a href="https://en.wikipedia.org/wiki/Deadband" target="_blank">Deadband</a> modes will block the incoming value
|
||||
<i>unless</i> its change is greater or greater-equal than ± the band gap away from a previous value.</p>
|
||||
<p>The Narrowband modes will block the incoming value,
|
||||
<i>if</i> its change is greater or greater-equal than ± the band gap away from the previous value.
|
||||
It is useful for ignoring outliers from a faulty sensor for example.</p>
|
||||
<p>Both in Deadband and Narrowband modes the incoming value must contain a parseable number and
|
||||
both also supports % - only sends if/unless the input differs by more than x% of the original value.</p>
|
||||
<p>Both Deadband and Narrowband allow comparison against either the previous valid output value, thus
|
||||
ignoring any values out of range; or the previous input value, which resets the set point, thus allowing
|
||||
ignoring any values out of range, or the previous input value, which resets the set point, thus allowing
|
||||
gradual drift (deadband), or a step change (narrowband).</p>
|
||||
<p><b>Note:</b> This works on a per <code>msg.topic</code> basis. This means that a single rbe node can
|
||||
handle multiple different topics at the same time.</p>
|
||||
<p><b>Note:</b> This works on a per <code>msg.topic</code> basis.
|
||||
This means that a single rbe node can handle multiple different topics at the same time.</p>
|
||||
</script>
|
||||
|
@ -5,7 +5,8 @@
|
||||
"func": "Mode",
|
||||
"init": "Send initial value",
|
||||
"start": "Start value",
|
||||
"name": "Name"
|
||||
"name": "Name",
|
||||
"septopics": "Apply mode for each msg.topic separately"
|
||||
},
|
||||
"placeholder":{
|
||||
"bandgap": "e.g. 10 or 5%",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red-node-rbe",
|
||||
"version" : "0.2.9",
|
||||
"version" : "0.5.0",
|
||||
"description" : "A Node-RED node that provides report-by-exception (RBE) and deadband capabilities.",
|
||||
"dependencies" : {
|
||||
},
|
||||
|
@ -27,6 +27,11 @@
|
||||
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
|
||||
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-septopics" style="display:inline-block; width:20px; vertical-align:baseline;">
|
||||
<span data-i18n="rbe.label.septopics"></span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="rbe.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]rbe.label.name" style="width:70%;">
|
||||
@ -43,6 +48,7 @@
|
||||
gap: {value:"",validate:RED.validators.regex(/^(\d*[.]*\d*|)(%|)$/)},
|
||||
start: {value:""},
|
||||
inout: {value:"out"},
|
||||
septopics: {value:true},
|
||||
property: {value:"payload",required:true}
|
||||
},
|
||||
inputs:1,
|
||||
@ -59,6 +65,9 @@
|
||||
if (this.property === undefined) {
|
||||
$("#node-input-property").val("payload");
|
||||
}
|
||||
if (this.septopics === undefined) {
|
||||
$("#node-input-septopics").prop('checked', true);
|
||||
}
|
||||
$("#node-input-property").typedInput({default:'msg',types:['msg']});
|
||||
//$( "#node-input-gap" ).spinner({min:0});
|
||||
if ($("#node-input-inout").val() === null) {
|
||||
|
@ -14,20 +14,25 @@ module.exports = function(RED) {
|
||||
}
|
||||
this.g = this.gap;
|
||||
this.property = n.property||"payload";
|
||||
this.septopics = true;
|
||||
if (n.septopics !== undefined && n.septopics === false) {
|
||||
this.septopics = false;
|
||||
}
|
||||
|
||||
var node = this;
|
||||
|
||||
node.previous = {};
|
||||
this.on("input",function(msg) {
|
||||
if (msg.hasOwnProperty("reset")) {
|
||||
if (msg.hasOwnProperty("topic") && (typeof msg.topic === "string") && (msg.topic !== "")) {
|
||||
if (node.septopics && msg.hasOwnProperty("topic") && (typeof msg.topic === "string") && (msg.topic !== "")) {
|
||||
delete node.previous[msg.topic];
|
||||
}
|
||||
else { node.previous = {}; }
|
||||
}
|
||||
var value = RED.util.getMessageProperty(msg,node.property);
|
||||
if (value !== undefined) {
|
||||
var t = msg.topic || "_no_topic";
|
||||
var t = "_no_topic";
|
||||
if (node.septopics) { t = msg.topic || t; }
|
||||
if ((this.func === "rbe") || (this.func === "rbei")) {
|
||||
var doSend = (this.func !== "rbei") || (node.previous.hasOwnProperty(t)) || false;
|
||||
if (typeof(value) === "object") {
|
||||
|
@ -45,16 +45,6 @@
|
||||
<div class="form-tips" id="node-tip">Tip: This node ONLY works with numbers.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="smooth">
|
||||
<p>A simple node to provide various functions across several previous values, including max, min, mean, high and low pass filters.</p>
|
||||
<p>Messages arriving with different <code>msg.topic</code> can be treated as separate streams if so configured.</p>
|
||||
<p>Max, Min and Mean work over a specified number of previous values.</p>
|
||||
<p>The High and Low pass filters use a smoothing factor. The higher the number the more the smoothing. E.g. a value of 10 is similar to an α of 0.1. It is analagous to an RC time constant - but there is no time component to this as the time is based on events arriving.</p>
|
||||
<p>Enabling the Reduce option causes the node to only emit one message per N values (available for the Max, Min and Mean functions). E.g. if set to Mean over 10 values, there will only be one outgoing message per 10 incoming ones.</p>
|
||||
<p>If <code>msg.reset</code> is received (with any value), all the counters and intermediate values are reset to an initial state.</p>
|
||||
<p><b>Note:</b> This only operates on <b>numbers</b>. Anything else will try to be made into a number and rejected if that fails.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('smooth', {
|
||||
color: "#E2D96E",
|
||||
|
10
function/smooth/locales/en-US/17-smooth.html
Normal file
10
function/smooth/locales/en-US/17-smooth.html
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
<script type="text/html" data-help-name="smooth">
|
||||
<p>A simple node to provide various functions across several previous values, including max, min, mean, high and low pass filters.</p>
|
||||
<p>Messages arriving with different <code>msg.topic</code> can be treated as separate streams if so configured.</p>
|
||||
<p>Max, Min and Mean work over a specified number of previous values.</p>
|
||||
<p>The High and Low pass filters use a smoothing factor. The higher the number the more the smoothing. E.g. a value of 10 is similar to an α of 0.1. It is analagous to an RC time constant - but there is no time component to this as the time is based on events arriving.</p>
|
||||
<p>Enabling the Reduce option causes the node to only emit one message per N values (available for the Max, Min and Mean functions). E.g. if set to Mean over 10 values, there will only be one outgoing message per 10 incoming ones.</p>
|
||||
<p>If <code>msg.reset</code> is received (with any value), all the counters and intermediate values are reset to an initial state.</p>
|
||||
<p><b>Note:</b> This only operates on <b>numbers</b>. Anything else will try to be made into a number and rejected if that fails.</p>
|
||||
</script>
|
@ -24,14 +24,6 @@
|
||||
<div class="form-tips"><span data-i18n="[html]arduino.tip.io"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="arduino in">
|
||||
<p>Arduino input node. Connects to a local Arduino and monitors the selected pin for changes. Uses <a href="http://firmata.org/" target="_new"><i>Firmata</i>.</a></p>
|
||||
<p>The Arduino must be loaded with the Standard Firmata sketch available in the Arduino examples.</p>
|
||||
<p>You can select either Digital or Analogue input. Outputs the value read as <code>msg.payload</code> and the pin number as <code>msg.topic</code>.</p>
|
||||
<p>It only outputs on a change of value - fine for digital inputs, but you can get a lot of data from analogue pins which you must then handle.</p>
|
||||
<p>For example you could use a <code>delay</code> node set to rate limit and drop intermediate values, or an <code>rbe</code> node to only report when it changes by a certain amount.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('arduino in',{
|
||||
category: 'Arduino',
|
||||
@ -85,14 +77,6 @@
|
||||
<div class="form-tips"><span data-i18n="[html]arduino.tip.io"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="arduino out">
|
||||
<p>Arduino output node. Connects to local Arduino and writes to the selected digital
|
||||
pin. Uses <a href="http://firmata.org/" target="_new"><i>Firmata</i>.</a></p>
|
||||
<p>The Arduino must be loaded with the Standard Firmata sketch available in the Arduino examples.</p>
|
||||
<p>You can select Digital, Analogue (PWM) or Servo type outputs. Expects an integer numeric
|
||||
value in <code>msg.payload</code>. The pin number is set in the properties panel.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('arduino out', {
|
||||
category: 'Arduino',
|
||||
|
42
hardware/Arduino/locales/de/35-arduino.json
Normal file
42
hardware/Arduino/locales/de/35-arduino.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"arduino": {
|
||||
"label": {
|
||||
"pin": "Pin",
|
||||
"type": "Typ",
|
||||
"port": "Port"
|
||||
},
|
||||
"placeholder": {
|
||||
"port": "z. B. /dev/ttyUSB0 COM1"
|
||||
},
|
||||
"status": {
|
||||
"connectfirst": "Verbinde mit zuerst gefundenen Board",
|
||||
"connect": "Verbinde mit __device__",
|
||||
"connected": "Verbunden mit __device__",
|
||||
"version": "Version: __version__",
|
||||
"portclosed": "Serieller Arduino-Port geschlossen"
|
||||
},
|
||||
"state": {
|
||||
"in": {
|
||||
"digital": "Digitaler Pin",
|
||||
"pullup": "Digitaler Pin mit Pullup",
|
||||
"analogue": "Analoger Pin",
|
||||
"string": "String"
|
||||
},
|
||||
"out": {
|
||||
"digital": "Digital (0/1)",
|
||||
"analogue": "Analog (0-255)",
|
||||
"servo": "Servo (0-180)",
|
||||
"string": "String"
|
||||
}
|
||||
},
|
||||
"tip": {
|
||||
"io": "<b>Hinweis:</b> Derselbe Pin kann nicht gleichzeitig als Ausgang und Eingang verwendet werden",
|
||||
"conf": "<b>Tipp:</b> Zur automatischen Erkennung des seriellen Ports die Suche verwenden"
|
||||
},
|
||||
"errors": {
|
||||
"portnotconf": "Port nicht konfiguriert",
|
||||
"portnotfound": "Port nicht gefunden: __device__",
|
||||
"devnotfound": "Device __dev__ nicht gefunden. Versuche Board zu finden."
|
||||
}
|
||||
}
|
||||
}
|
16
hardware/Arduino/locales/en-US/35-arduino.html
Normal file
16
hardware/Arduino/locales/en-US/35-arduino.html
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
<script type="text/html" data-help-name="arduino in">
|
||||
<p>Arduino input node. Connects to a local Arduino and monitors the selected pin for changes. Uses <a href="http://firmata.org/" target="_new"><i>Firmata</i>.</a></p>
|
||||
<p>The Arduino must be loaded with the Standard Firmata sketch available in the Arduino examples.</p>
|
||||
<p>You can select either Digital or Analogue input. Outputs the value read as <code>msg.payload</code> and the pin number as <code>msg.topic</code>.</p>
|
||||
<p>It only outputs on a change of value - fine for digital inputs, but you can get a lot of data from analogue pins which you must then handle.</p>
|
||||
<p>For example you could use a <code>delay</code> node set to rate limit and drop intermediate values, or an <code>rbe</code> node to only report when it changes by a certain amount.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="arduino out">
|
||||
<p>Arduino output node. Connects to local Arduino and writes to the selected digital
|
||||
pin. Uses <a href="http://firmata.org/" target="_new"><i>Firmata</i>.</a></p>
|
||||
<p>The Arduino must be loaded with the Standard Firmata sketch available in the Arduino examples.</p>
|
||||
<p>You can select Digital, Analogue (PWM) or Servo type outputs. Expects an integer numeric
|
||||
value in <code>msg.payload</code>. The pin number is set in the properties panel.</p>
|
||||
</script>
|
@ -1,5 +1,5 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="rpi-piface in">
|
||||
<script type="text/html" data-template-name="rpi-piface in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-pin"><i class="fa fa-circle"></i> GPIO Pin</label>
|
||||
<select type="text" id="node-input-pin" style="width: 150px;">
|
||||
@ -42,7 +42,7 @@
|
||||
<div class="form-tips">Tip: Only Digital I/O is supported - input must be 0 or 1.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="rpi-piface in">
|
||||
<script type="text/html" data-help-name="rpi-piface in">
|
||||
<p>Raspberry Pi PiFace input node. Generates a <code>msg.payload</code> with either a 0 or 1 depending
|
||||
on the state of the input pin.</p>
|
||||
<p>You may also enable the input pullup resistor if required.</p>
|
||||
@ -76,7 +76,7 @@
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/x-red" data-template-name="rpi-piface out">
|
||||
<script type="text/html" data-template-name="rpi-piface out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-pin"><i class="fa fa-circle"></i> GPIO Pin</label>
|
||||
<select type="text" id="node-input-pin" style="width: 150px;">
|
||||
@ -111,7 +111,7 @@
|
||||
<div class="form-tips">Tip: Only Digital I/O is supported - input must be 0 or 1.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="rpi-piface out">
|
||||
<script type="text/html" data-help-name="rpi-piface out">
|
||||
<p>Raspberry Pi PiFace output node. The PiFace board must be fitted.</p>
|
||||
<p>Will set the selected relay, LED, or pin on or off depending on the value passed in. Expects a <code>msg.payload</code> with either a 1 or 0 (or true or false).</p>
|
||||
<p>Requires the WiringPi gpio command in order to work.</p>
|
||||
|
@ -78,86 +78,86 @@
|
||||
<div class="pinTableCellR pinColorPower"><label><input disabled type="radio" name="pins" value=""> 2 - 5V Power</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-3">SDA1 - GPIO02 - 3 <input id="pinTable-pin-3" type="radio" name="pins" value="3"></label></div>
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-3">SDA1 - GPIO02 - 3 <input id="pinTable-pin-3" type="radio" name="pins" value="2"></label></div>
|
||||
<div class="pinTableCellR pinColorPower"><label><input disabled type="radio" name="pins" value=""> 4 - 5V Power</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-5">SCL1 - GPIO03 - 5 <input id="pinTable-pin-5" type="radio" name="pins" value="5"></label></div>
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-5">SCL1 - GPIO03 - 5 <input id="pinTable-pin-5" type="radio" name="pins" value="3"></label></div>
|
||||
<div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 6 - Ground</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-7">GPIO04 - 7 <input id="pinTable-pin-7" type="radio" name="pins" value="7"></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-8"><input id="pinTable-pin-8" type="radio" name="pins" value="8"> 8 - GPIO14 - TxD</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-7">GPIO04 - 7 <input id="pinTable-pin-7" type="radio" name="pins" value="4"></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-8"><input id="pinTable-pin-8" type="radio" name="pins" value="14"> 8 - GPIO14 - TxD</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGround"><label>Ground - 9 <input disabled type="radio" name="pins" value=""></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-10"><input id="pinTable-pin-10" type="radio" name="pins" value="10"> 10 - GPIO15 - RxD</label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-10"><input id="pinTable-pin-10" type="radio" name="pins" value="15"> 10 - GPIO15 - RxD</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-11">GPIO17 - 11 <input id="pinTable-pin-11" type="radio" name="pins" value="11"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-12"><input id="pinTable-pin-12" type="radio" name="pins" value="12"> 12 - GPIO18</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-11">GPIO17 - 11 <input id="pinTable-pin-11" type="radio" name="pins" value="17"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-12"><input id="pinTable-pin-12" type="radio" name="pins" value="18"> 12 - GPIO18</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-13">GPIO27 - 13 <input id="pinTable-pin-13" type="radio" name="pins" value="13"></label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-13">GPIO27 - 13 <input id="pinTable-pin-13" type="radio" name="pins" value="27"></label></div>
|
||||
<div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 14 - Ground</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-15">GPIO22 - 15 <input id="pinTable-pin-15" type="radio" name="pins" value="15"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-16"><input id="pinTable-pin-16" type="radio" name="pins" value="16"> 16 - GPIO23</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-15">GPIO22 - 15 <input id="pinTable-pin-15" type="radio" name="pins" value="22"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-16"><input id="pinTable-pin-16" type="radio" name="pins" value="23"> 16 - GPIO23</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorPower"><label>3.3V Power - 17 <input disabled type="radio" name="pins" value=""></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-18"><input id="pinTable-pin-18" type="radio" name="pins" value="18"> 18 - GPIO24</label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-18"><input id="pinTable-pin-18" type="radio" name="pins" value="24"> 18 - GPIO24</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-19">MOSI - GPIO10 - 19 <input id="pinTable-pin-19" type="radio" name="pins" value="19"></label></div>
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-19">MOSI - GPIO10 - 19 <input id="pinTable-pin-19" type="radio" name="pins" value="10"></label></div>
|
||||
<div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 20 - Ground</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-21">MISO - GPIO09 - 21 <input id="pinTable-pin-21" type="radio" name="pins" value="21"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-22"><input id="pinTable-pin-22" type="radio" name="pins" value="22"> 22 - GPIO25</label></div>
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-21">MISO - GPIO09 - 21 <input id="pinTable-pin-21" type="radio" name="pins" value="9"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-22"><input id="pinTable-pin-22" type="radio" name="pins" value="25"> 22 - GPIO25</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-23">SCLK - GPIO11 - 23 <input id="pinTable-pin-23" type="radio" name="pins" value="23"></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-24"><input id="pinTable-pin-24" type="radio" name="pins" value="24"> 24 - GPIO8 - CE0</label></div>
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-23">SCLK - GPIO11 - 23 <input id="pinTable-pin-23" type="radio" name="pins" value="11"></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-24"><input id="pinTable-pin-24" type="radio" name="pins" value="8"> 24 - GPIO8 - CE0</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGround"><label>Ground - 25 <input disabled type="radio" name="pins" value=""></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-26"><input id="pinTable-pin-26" type="radio" name="pins" value="26"> 26 - GPIO7 - CE1</label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-26"><input id="pinTable-pin-26" type="radio" name="pins" value="7"> 26 - GPIO7 - CE1</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorSD"><label>SD - 27 <input disabled type="radio" name="pins" value=""></label></div>
|
||||
<div class="pinTableCellR pinColorSD"><label><input disabled type="radio" name="pins" value=""> 28 - SC</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-29">GPIO05 - 29 <input id="pinTable-pin-29" type="radio" name="pins" value="29"></label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-29">GPIO05 - 29 <input id="pinTable-pin-29" type="radio" name="pins" value="5"></label></div>
|
||||
<div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 30 - Ground</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-31">GPIO06 - 31 <input id="pinTable-pin-31" type="radio" name="pins" value="31"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-32"><input id="pinTable-pin-32" type="radio" name="pins" value="32"> 32 - GPIO12</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-31">GPIO06 - 31 <input id="pinTable-pin-31" type="radio" name="pins" value="6"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-32"><input id="pinTable-pin-32" type="radio" name="pins" value="12"> 32 - GPIO12</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-33">GPIO13 - 33 <input id="pinTable-pin-33" type="radio" name="pins" value="33"></label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-33">GPIO13 - 33 <input id="pinTable-pin-33" type="radio" name="pins" value="13"></label></div>
|
||||
<div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 34 - Ground</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-35">GPIO19 - 35 <input id="pinTable-pin-35" type="radio" name="pins" value="35"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-36"><input id="pinTable-pin-36" type="radio" name="pins" value="36"> 36 - GPIO16</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-35">GPIO19 - 35 <input id="pinTable-pin-35" type="radio" name="pins" value="19"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-36"><input id="pinTable-pin-36" type="radio" name="pins" value="16"> 36 - GPIO16</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-37">GPIO26 - 37 <input id="pinTable-pin-37" type="radio" name="pins" value="37"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-38"><input id="pinTable-pin-38" type="radio" name="pins" value="38"> 38 - GPIO20</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-37">GPIO26 - 37 <input id="pinTable-pin-37" type="radio" name="pins" value="26"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-38"><input id="pinTable-pin-38" type="radio" name="pins" value="20"> 38 - GPIO20</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGround"><label>Ground - 39 <input disabled type="radio" name="pins" value=""></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-40"><input id="pinTable-pin-40" type="radio" name="pins" value="40"> 40 - GPIO21</label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-40"><input id="pinTable-pin-40" type="radio" name="pins" value="21"> 40 - GPIO21</label></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<label> BCM GPIO</label>
|
||||
<input type="text" id="node-input-pin" style="width: 352px">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
@ -189,8 +189,12 @@
|
||||
"23":"16", "24":"18", "10":"19", "9":"21", "25":"22", "11":"23", "8":"24", "7":"26",
|
||||
"5":"29", "6":"31", "12":"32", "13":"33", "19":"35", "16":"36", "26":"37", "20":"38", "21":"40"
|
||||
};
|
||||
var pin2bcm = { '3':'2', '5':'3', '7':'4', '8':'14', '10':'15', '11':'17', '12':'18', '13':'27',
|
||||
'15':'22', '16':'23', '18':'24', '19':'10', '21':'9', '22':'25', '23':'11', '24':'8', '26':'7',
|
||||
'29':'5', '31':'6', '32':'12', '33':'13', '35':'19', '36':'16', '37':'26', '38':'20', '40':'21'
|
||||
}
|
||||
var pinsInUse = {};
|
||||
var validPinValues = Object.values(bcm2pin);
|
||||
|
||||
var isEnvVar = function (value) {
|
||||
var re = /^\${([0-9a-zA-Z_]+)}$/;
|
||||
var match = value.match(re);
|
||||
@ -205,17 +209,18 @@
|
||||
}
|
||||
}
|
||||
var validatePin = function (value) {
|
||||
return isEnvVar(value) || (isInt(value) && validPinValues.includes(value));
|
||||
return isEnvVar(value) || (isInt(value) && value>=0 && value<=45);
|
||||
};
|
||||
RED.nodes.registerType('rpi-gpio in',{
|
||||
category: 'Raspberry Pi',
|
||||
color:"#c6dbef",
|
||||
defaults: {
|
||||
name: { value:"" },
|
||||
pin: { value:"tri",required:true,validate:validatePin },
|
||||
pin: { value:"",required:true,validate:validatePin },
|
||||
intype: { value:"tri" },
|
||||
debounce: { value:"25" },
|
||||
read: { value:false }
|
||||
read: { value:false },
|
||||
bcm: { value:true }
|
||||
},
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
@ -227,10 +232,12 @@
|
||||
else { return ""; }
|
||||
},
|
||||
label: function() {
|
||||
if (!this.bcm) { this.pin = pin2bcm[this.pin]; this.bcm = true; }
|
||||
var p = bcm2pin[this.pin];
|
||||
var suf = "";
|
||||
if (this.intype === "up") { suf = "↑ "}
|
||||
if (this.intype === "down") { suf = "↓ "}
|
||||
return this.name || "PIN: "+suf+this.pin ;
|
||||
if (this.intype === "up") { suf = " ↑"}
|
||||
if (this.intype === "down") { suf = " ↓"}
|
||||
return this.name || (p ? "PIN: "+p+suf : "GPIO: "+this.pin+suf) ;
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
@ -292,86 +299,86 @@
|
||||
<div class="pinTableCellR pinColorPower"><label><input disabled type="radio" name="pins" value=""> 2 - 5V Power</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-3">SDA1 - GPIO02 - 3 <input id="pinTable-pin-3" type="radio" name="pins" value="3"></label></div>
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-3">SDA1 - GPIO02 - 3 <input id="pinTable-pin-3" type="radio" name="pins" value="2"></label></div>
|
||||
<div class="pinTableCellR pinColorPower"><label><input disabled type="radio" name="pins" value=""> 4 - 5V Power</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-5">SCL1 - GPIO03 - 5 <input id="pinTable-pin-5" type="radio" name="pins" value="5"></label></div>
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-5">SCL1 - GPIO03 - 5 <input id="pinTable-pin-5" type="radio" name="pins" value="3"></label></div>
|
||||
<div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 6 - Ground</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-7">GPIO04 - 7 <input id="pinTable-pin-7" type="radio" name="pins" value="7"></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-8"><input id="pinTable-pin-8" type="radio" name="pins" value="8"> 8 - GPIO14 - TxD</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-7">GPIO04 - 7 <input id="pinTable-pin-7" type="radio" name="pins" value="4"></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-8"><input id="pinTable-pin-8" type="radio" name="pins" value="14"> 8 - GPIO14 - TxD</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGround"><label>Ground - 9 <input disabled type="radio" name="pins" value=""></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-10"><input id="pinTable-pin-10" type="radio" name="pins" value="10"> 10 - GPIO15 - RxD</label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-10"><input id="pinTable-pin-10" type="radio" name="pins" value="15"> 10 - GPIO15 - RxD</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-11">GPIO17 - 11 <input id="pinTable-pin-11" type="radio" name="pins" value="11"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-12"><input id="pinTable-pin-12" type="radio" name="pins" value="12"> 12 - GPIO18</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-11">GPIO17 - 11 <input id="pinTable-pin-11" type="radio" name="pins" value="17"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-12"><input id="pinTable-pin-12" type="radio" name="pins" value="18"> 12 - GPIO18</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-13">GPIO27 - 13 <input id="pinTable-pin-13" type="radio" name="pins" value="13"></label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-13">GPIO27 - 13 <input id="pinTable-pin-13" type="radio" name="pins" value="27"></label></div>
|
||||
<div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 14 - Ground</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-15">GPIO22 - 15 <input id="pinTable-pin-15" type="radio" name="pins" value="15"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-16"><input id="pinTable-pin-16" type="radio" name="pins" value="16"> 16 - GPIO23</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-15">GPIO22 - 15 <input id="pinTable-pin-15" type="radio" name="pins" value="22"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-16"><input id="pinTable-pin-16" type="radio" name="pins" value="23"> 16 - GPIO23</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorPower"><label>3.3V Power - 17 <input disabled type="radio" name="pins" value=""></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-18"><input id="pinTable-pin-18" type="radio" name="pins" value="18"> 18 - GPIO24</label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-18"><input id="pinTable-pin-18" type="radio" name="pins" value="24"> 18 - GPIO24</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-19">MOSI - GPIO10 - 19 <input id="pinTable-pin-19" type="radio" name="pins" value="19"></label></div>
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-19">MOSI - GPIO10 - 19 <input id="pinTable-pin-19" type="radio" name="pins" value="10"></label></div>
|
||||
<div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 20 - Ground</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-21">MISO - GPIO09 - 21 <input id="pinTable-pin-21" type="radio" name="pins" value="21"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-22"><input id="pinTable-pin-22" type="radio" name="pins" value="22"> 22 - GPIO25</label></div>
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-21">MISO - GPIO09 - 21 <input id="pinTable-pin-21" type="radio" name="pins" value="9"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-22"><input id="pinTable-pin-22" type="radio" name="pins" value="25"> 22 - GPIO25</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-23">SCLK - GPIO11 - 23 <input id="pinTable-pin-23" type="radio" name="pins" value="23"></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-24"><input id="pinTable-pin-24" type="radio" name="pins" value="24"> 24 - GPIO8 - CE0</label></div>
|
||||
<div class="pinTableCellL pinColorDual"><label for="pinTable-pin-23">SCLK - GPIO11 - 23 <input id="pinTable-pin-23" type="radio" name="pins" value="11"></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-24"><input id="pinTable-pin-24" type="radio" name="pins" value="8"> 24 - GPIO8 - CE0</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGround"><label>Ground - 25 <input disabled type="radio" name="pins" value=""></label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-26"><input id="pinTable-pin-26" type="radio" name="pins" value="26"> 26 - GPIO7 - CE1</label></div>
|
||||
<div class="pinTableCellR pinColorDual"><label for="pinTable-pin-26"><input id="pinTable-pin-26" type="radio" name="pins" value="7"> 26 - GPIO7 - CE1</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorSD"><label>SD - 27 <input disabled type="radio" name="pins" value=""></label></div>
|
||||
<div class="pinTableCellR pinColorSD"><label><input disabled type="radio" name="pins" value=""> 28 - SC</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-29">GPIO05 - 29 <input id="pinTable-pin-29" type="radio" name="pins" value="29"></label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-29">GPIO05 - 29 <input id="pinTable-pin-29" type="radio" name="pins" value="5"></label></div>
|
||||
<div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 30 - Ground</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-31">GPIO06 - 31 <input id="pinTable-pin-31" type="radio" name="pins" value="31"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-32"><input id="pinTable-pin-32" type="radio" name="pins" value="32"> 32 - GPIO12</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-31">GPIO06 - 31 <input id="pinTable-pin-31" type="radio" name="pins" value="6"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-32"><input id="pinTable-pin-32" type="radio" name="pins" value="12"> 32 - GPIO12</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-33">GPIO13 - 33 <input id="pinTable-pin-33" type="radio" name="pins" value="33"></label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-33">GPIO13 - 33 <input id="pinTable-pin-33" type="radio" name="pins" value="13"></label></div>
|
||||
<div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 34 - Ground</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-35">GPIO19 - 35 <input id="pinTable-pin-35" type="radio" name="pins" value="35"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-36"><input id="pinTable-pin-36" type="radio" name="pins" value="36"> 36 - GPIO16</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-35">GPIO19 - 35 <input id="pinTable-pin-35" type="radio" name="pins" value="19"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-36"><input id="pinTable-pin-36" type="radio" name="pins" value="16"> 36 - GPIO16</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-37">GPIO26 - 37 <input id="pinTable-pin-37" type="radio" name="pins" value="37"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-38"><input id="pinTable-pin-38" type="radio" name="pins" value="38"> 38 - GPIO20</label></div>
|
||||
<div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-37">GPIO26 - 37 <input id="pinTable-pin-37" type="radio" name="pins" value="26"></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-38"><input id="pinTable-pin-38" type="radio" name="pins" value="20"> 38 - GPIO20</label></div>
|
||||
</div>
|
||||
<div class="pinTableRow">
|
||||
<div class="pinTableCellL pinColorGround"><label>Ground - 39 <input disabled type="radio" name="pins" value=""></label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-40"><input id="pinTable-pin-40" type="radio" name="pins" value="40"> 40 - GPIO21</label></div>
|
||||
<div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-40"><input id="pinTable-pin-40" type="radio" name="pins" value="21"> 40 - GPIO21</label></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<label> BCM GPIO</label>
|
||||
<input type="text" id="node-input-pin" style="width: 352px">
|
||||
</div>
|
||||
<div class="form-row" id="node-set-pwm">
|
||||
@ -412,6 +419,10 @@
|
||||
"23":"16", "24":"18", "10":"19", "9":"21", "25":"22", "11":"23", "8":"24", "7":"26",
|
||||
"5":"29", "6":"31", "12":"32", "13":"33", "19":"35", "16":"36", "26":"37", "20":"38", "21":"40"
|
||||
};
|
||||
var pin2bcm = { '3':'2', '5':'3', '7':'4', '8':'14', '10':'15', '11':'17', '12':'18', '13':'27',
|
||||
'15':'22', '16':'23', '18':'24', '19':'10', '21':'9', '22':'25', '23':'11', '24':'8', '26':'7',
|
||||
'29':'5', '31':'6', '32':'12', '33':'13', '35':'19', '36':'16', '37':'26', '38':'20', '40':'21'
|
||||
}
|
||||
var pinsInUse = {};
|
||||
var validPinValues = Object.values(bcm2pin);
|
||||
var isEnvVar = function (value) {
|
||||
@ -428,7 +439,7 @@
|
||||
}
|
||||
}
|
||||
var validatePin = function (value) {
|
||||
return isEnvVar(value) || (isInt(value) && validPinValues.includes(value));
|
||||
return isEnvVar(value) || (isInt(value) && value>=0 && value<=45);
|
||||
};
|
||||
RED.nodes.registerType('rpi-gpio out',{
|
||||
category: 'Raspberry Pi',
|
||||
@ -438,8 +449,9 @@
|
||||
pin: { value:"",required:true,validate:validatePin },
|
||||
set: { value:"" },
|
||||
level: { value:"0" },
|
||||
freq: {value:""},
|
||||
out: { value:"out" }
|
||||
freq: { value:""},
|
||||
out: { value:"out" },
|
||||
bcm: { value:true }
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
@ -452,12 +464,15 @@
|
||||
},
|
||||
align: "right",
|
||||
label: function() {
|
||||
if (this.out === "pwm") { return this.name || "PWM: "+this.pin; }
|
||||
else if (this.out === "ser") { return this.name || "Servo: "+this.pin; }
|
||||
if (!this.bcm) { this.pin = pin2bcm[this.pin]; this.bcm = true; }
|
||||
var p = bcm2pin[this.pin];
|
||||
var t = p ? "PIN: "+p : "GPIO: "+this.pin;
|
||||
if (this.out === "pwm") { return this.name || "PWM: "+p; }
|
||||
else if (this.out === "ser") { return this.name || "Servo: "+p; }
|
||||
else {
|
||||
var suf = "";
|
||||
if (this.set == true) { suf = (this.level === "1") ? " ¹" : " ₀"; }
|
||||
return this.name||"PIN: "+ this.pin + suf ;
|
||||
return this.name|| t + suf ;
|
||||
}
|
||||
},
|
||||
labelStyle: function() {
|
||||
|
@ -22,10 +22,15 @@ module.exports = function(RED) {
|
||||
var pinsInUse = {};
|
||||
var pinTypes = {"out":RED._("rpi-gpio.types.digout"), "tri":RED._("rpi-gpio.types.input"), "up":RED._("rpi-gpio.types.pullup"), "down":RED._("rpi-gpio.types.pulldown"), "pwm":RED._("rpi-gpio.types.pwmout")};
|
||||
|
||||
var pin2bcm = { '3':'2', '5':'3', '7':'4', '8':'14', '10':'15', '11':'17', '12':'18', '13':'27',
|
||||
'15':'22', '16':'23', '18':'24', '19':'10', '21':'9', '22':'25', '23':'11', '24':'8', '26':'7',
|
||||
'29':'5', '31':'6', '32':'12', '33':'13', '35':'19', '36':'16', '37':'26', '38':'20', '40':'21'
|
||||
}
|
||||
|
||||
function GPIOInNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.buttonState = -1;
|
||||
this.pin = n.pin;
|
||||
this.pin = (n.bcm === true) ? n.pin : pin2bcm[n.pin];
|
||||
this.intype = n.intype;
|
||||
this.read = n.read || false;
|
||||
this.debounce = Number(n.debounce || 25);
|
||||
@ -51,7 +56,7 @@ module.exports = function(RED) {
|
||||
for (var i = 0; i < d.length; i++) {
|
||||
if (d[i] === '') { return; }
|
||||
if (node.running && node.buttonState !== -1 && !isNaN(Number(d[i])) && node.buttonState !== d[i]) {
|
||||
node.send({ topic:"pi/"+node.pin, payload:Number(d[i]) });
|
||||
node.send({ topic:"gpio/"+node.pin, payload:Number(d[i]) });
|
||||
}
|
||||
node.buttonState = d[i];
|
||||
node.status({fill:"green",shape:"dot",text:d[i]});
|
||||
@ -92,7 +97,7 @@ module.exports = function(RED) {
|
||||
if (node.intype == "up") { val = 1; }
|
||||
if (node.intype == "down") { val = 0; }
|
||||
setTimeout(function() {
|
||||
node.send({ topic:"pi/"+node.pin, payload:val });
|
||||
node.send({ topic:"gpio/"+node.pin, payload:val });
|
||||
node.status({fill:"grey",shape:"dot",text:RED._("rpi-gpio.status.na",{value:val})});
|
||||
},250);
|
||||
}
|
||||
@ -113,7 +118,7 @@ module.exports = function(RED) {
|
||||
|
||||
function GPIOOutNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.pin = n.pin;
|
||||
this.pin = (n.bcm === true) ? n.pin : pin2bcm[n.pin];
|
||||
this.set = n.set || false;
|
||||
this.level = n.level || 0;
|
||||
this.freq = n.freq || 100;
|
||||
|
@ -21,7 +21,7 @@ command in your Node-RED user directory - typically `~/.node-red`
|
||||
The python library may also work with other distros running on a Pi (like Ubuntu or Debian) - you will need to install the PIGPIO package and run the following commands in order to gain full access to the GPIO pins as this ability is not part of the default distro. This is NOT necessary on Raspbian.
|
||||
|
||||
sudo apt-get install python-pip python-dev
|
||||
sudo pip install RPi.GPIO
|
||||
sudo pip install RPi.GPIO
|
||||
sudo addgroup gpio
|
||||
sudo chown root:gpio /dev/gpiomem
|
||||
sudo adduser $USER gpio
|
||||
@ -30,7 +30,7 @@ The python library may also work with other distros running on a Pi (like Ubuntu
|
||||
|
||||
## Usage
|
||||
|
||||
**Note:** the pin numbers refer the physical pin numbers on connector P1 as they are easier to locate.
|
||||
**Note:** the diagram in the configuration shows pin numbers - the BCM GPIO field allows you to enter the GPIO number directly (this allows you to use the node for other devices that have other BCM GPIO like the Pi Compute modules.)
|
||||
|
||||
### Input node
|
||||
|
||||
|
@ -1,73 +1,75 @@
|
||||
"rpi-gpio" : {
|
||||
"label" : {
|
||||
"gpiopin" : "GPIO",
|
||||
"selectpin" : "Auswahlstift",
|
||||
"resistor" : "Widerstand?",
|
||||
"readinitial" : "Anfangsstatus des Pins bei Implementierung/Neustart lesen?",
|
||||
"type" : "Typ",
|
||||
"initpin" : "Pin-Status initialisieren?",
|
||||
"debounce" : "Debounce",
|
||||
"freq" : "Frequenz",
|
||||
"button" : "Knopf",
|
||||
"pimouse" : "Pi-Maus",
|
||||
"pikeyboard" : "Pi-Tastatur",
|
||||
"left" : "Links",
|
||||
"right" : "Rechts",
|
||||
"middle" : "Mitte"
|
||||
},
|
||||
"resistor" : {
|
||||
"none" : "keine",
|
||||
"pullup" : "pullup",
|
||||
"pulldown" : "Pulldown"
|
||||
},
|
||||
"digout" : "Digitale Ausgabe",
|
||||
"pwmout" : "PWM-Ausgabe",
|
||||
"servo" : "Servo-Ausgabe",
|
||||
"initpin0" : "Anfangsstand des Pin-Niedrig (0)",
|
||||
"initpin1" : "Anfangsebene von Pin-High (1)",
|
||||
"left" : "links",
|
||||
"right" : "rechts",
|
||||
"middle" : "Mitte",
|
||||
"any" : "beliebig",
|
||||
"pinname" : "Pin",
|
||||
"alreadyuse" : "bereits im Gebrauch",
|
||||
"alreadyset" : "bereits festgelegt als",
|
||||
"tip" : {
|
||||
"pin" : "<b> Verwender Pins </b>: ",
|
||||
"in" : "Tipp: Es wird nur die digitale Eingabe unterstützt. Die Eingabe muss 0 oder 1 sein.",
|
||||
"dig" : "Tipp: Für die digitale Ausgabe muss der Wert 0 oder 1 sein.",
|
||||
"pwm" : "Tipp: Für die PWM-Ausgabe muss der Wert zwischen 0 und 100 liegen; die Einstellung der Hochfrequenz kann mehr CPU beanspruchen als erwartet.",
|
||||
"ser" : "<b> Tipp </b>: Für die Servo-Ausgabe muss ein Wert zwischen 0 und 100 eingegeben werden. 50 ist das Zentrum."
|
||||
},
|
||||
"types" : {
|
||||
"digout" : "digitale Ausgabe",
|
||||
"input" : "Eingabe",
|
||||
"pullup" : "Eingabe mit Pull-up",
|
||||
"pulldown" : "Eingabe mit Pull-down",
|
||||
"pwmout" : "PWM-Ausgabe",
|
||||
"servo" : "Servo-Ausgabe"
|
||||
},
|
||||
"status" : {
|
||||
"stopped" : "Gestoppt",
|
||||
"closed" : "geschlossen",
|
||||
"not-running" : "nicht aktiv",
|
||||
"not-available" : "nicht verfügbar",
|
||||
"na" : "N/A: __Wert__",
|
||||
"ok": "OK"
|
||||
},
|
||||
"errors" : {
|
||||
"ignorenode" : "Raspberry Pi-spezifische Nodes inaktiv",
|
||||
"version" : "Abrufen der Version von Pi fehlgeschlagen",
|
||||
"sawpitype" : "Saw-Pi-Typ",
|
||||
"libnotfound" : "Pi RPi.GPIO-Python-Bibliothek nicht gefunden",
|
||||
"alreadyset" : "GPIO-Stift __pin__ ist bereits als Typ festgelegt: __type__",
|
||||
"invalidpin" : "Ungültiger GPIO-Pin",
|
||||
"invalidinput" : "Ungültige Eingabe",
|
||||
"needtobeexecutable" : "__command__ muss ausführbar sein",
|
||||
"mustbeexecutable" : "nrgpio muss ausführbar sein",
|
||||
"commandnotfound" : "Befehl 'nrgpio' nicht gefunden",
|
||||
"commandnotexecutable" : "nrgpio-Befehl nicht ausführbar",
|
||||
"error" : "Fehler: __error__",
|
||||
"pythoncommandnotfound" : "Befehl 'nrgpio python' nicht aktiv"
|
||||
{
|
||||
"rpi-gpio": {
|
||||
"label": {
|
||||
"gpiopin": "GPIO",
|
||||
"selectpin": "Pinauswahl",
|
||||
"resistor": "Widerstand",
|
||||
"readinitial": "Initalzustand des Pins bei Übernahme/Neustart lesen",
|
||||
"type": "Typ",
|
||||
"initpin": "Pin-Zustand initialisieren",
|
||||
"debounce": "Entprellung",
|
||||
"freq": "Frequenz",
|
||||
"button": "Taste",
|
||||
"pimouse": "Pi-Maus",
|
||||
"pikeyboard": "Pi-Tastatur",
|
||||
"left": "Links",
|
||||
"right": "Rechts",
|
||||
"middle": "Mitte"
|
||||
},
|
||||
"resistor": {
|
||||
"none": "Kein",
|
||||
"pullup": "Pull-Up",
|
||||
"pulldown": "Pull-Down"
|
||||
},
|
||||
"digout": "Digitaler Ausgang",
|
||||
"pwmout": "PWM-Ausgang",
|
||||
"servo": "Servo-Ausgang",
|
||||
"initpin0": "Pin-Initalzustand low (0)",
|
||||
"initpin1": "Pin-Initalzustand high (1)",
|
||||
"left": "Links",
|
||||
"right": "Rechts",
|
||||
"middle": "Mitte",
|
||||
"any": "Beliebig",
|
||||
"pinname": "Pin",
|
||||
"alreadyuse": "bereits im Gebrauch",
|
||||
"alreadyset": "bereits festgelegt als",
|
||||
"tip": {
|
||||
"pin": "<b>Verwendete Pins:</b> ",
|
||||
"in": "<b>Tipp:</b> Es werden nur die digitale Eingänge unterstützt. Der Eingang muss 0 oder 1 sein",
|
||||
"dig": "<b>Tipp:</b> Für den digitalen Ausgang muss der Node-Eingangswert 0 oder 1 sein",
|
||||
"pwm": "<b>Tipp:</b> Für die PWM-Ausgabe muss der Node-Eingangswert zwischen 0 und 100 liegen. Hohen Frequenzen können die CPU mehr beanspruchen als erwartet.",
|
||||
"ser": "<b>Tipp:</b> Für die Servo-Ausgabe muss der Node-Eingangswert zwischen 0 und 100 eingegeben werden. 50 ist die Mitte."
|
||||
},
|
||||
"types": {
|
||||
"digout": "Digitaler Ausgang",
|
||||
"input": "Eingang",
|
||||
"pullup": "Eingang mit Pull-Up",
|
||||
"pulldown": "Eingabe mit Pull-Down",
|
||||
"pwmout": "PWM-Ausgang",
|
||||
"servo": "Servo-Ausgang"
|
||||
},
|
||||
"status": {
|
||||
"stopped": "Gestoppt",
|
||||
"closed": "Geschlossen",
|
||||
"not-running": "Nicht aktiv",
|
||||
"not-available": "Nicht verfügbar",
|
||||
"na": "Nicht anwendbar: __Wert__",
|
||||
"ok": "OK"
|
||||
},
|
||||
"errors": {
|
||||
"ignorenode": "Raspberry-Pi-spezifische Nodes inaktiv gesetzt",
|
||||
"version": "Abrufen der Version vom Pi fehlgeschlagen",
|
||||
"sawpitype": "Saw-Pi-Typ",
|
||||
"libnotfound": "RPi.GPIO-Python-Bibliothek nicht gefunden",
|
||||
"alreadyset": "GPIO-Pin __pin__ ist bereits festgelegt als Typ: __type__",
|
||||
"invalidpin": "Ungültiger GPIO-Pin",
|
||||
"invalidinput": "Ungültige Eingabe",
|
||||
"needtobeexecutable": "__command__ muss ausführbar sein",
|
||||
"mustbeexecutable": "nrgpio muss ausführbar sein",
|
||||
"commandnotfound": "nrgpio-Befehl nicht gefunden",
|
||||
"commandnotexecutable": "nrgpio-Befehl nicht ausführbar",
|
||||
"error": "Fehler: __error__",
|
||||
"pythoncommandnotfound": "nrgpio-Python-Befehl nicht aktiv"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,3 @@
|
||||
<!--
|
||||
Copyright JS Foundation and other contributors, http://js.foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/html" data-help-name="rpi-gpio in">
|
||||
<p>Raspberry Pi input node. Generates a <code>msg.payload</code> with either a
|
||||
@ -22,7 +7,7 @@
|
||||
<dt>payload <span class="property-type">number</span></dt>
|
||||
<dd>the payload will be a 1 or a 0.</dd>
|
||||
<dt>topic <span class="property-type">string</span></dt>
|
||||
<dd>the topic will be set to <code>pi/{the pin number}</code>.</dd>
|
||||
<dd>the topic will be set to <code>gpio/{the bcm spio number}</code>.</dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>You may also enable the input pullup resistor or the pulldown resistor.</p>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<dt>payload <span class="property-type">数値</span></dt>
|
||||
<dd>ペイロードには、0 または 1 が設定されます。</dd>
|
||||
<dt>topic <span class="property-type">文字列</span></dt>
|
||||
<dd>トピックには、<code>pi/{ピン番号}</code>が設定されます。</dd>
|
||||
<dd>トピックには、<code>gpio/{ピン番号}</code>が設定されます。</dd>
|
||||
</dl>
|
||||
<h3>詳細</h3>
|
||||
<p>入力のプルアップ抵抗またはプルダウン抵抗を有効にすることもできます。</p>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<dt>payload <span class="property-type">수치</span></dt>
|
||||
<dd>페이로드에는, 0 또는 1이 설정됩니다.</dd>
|
||||
<dt>topic <span class="property-type">문자열</span></dt>
|
||||
<dd>토픽에는, <code>pi/{핀 번호}</code>가 설정됩니다.</dd>
|
||||
<dd>토픽에는, <code>gpio/{핀 번호}</code>가 설정됩니다.</dd>
|
||||
</dl>
|
||||
<h3>상세</h3>
|
||||
<p>입력의 풀 업 저항 또는, 풀 다운 저항을 유효화 할 수도 있습니다.</p>
|
||||
|
@ -31,7 +31,7 @@ bounce = 25
|
||||
if len(sys.argv) > 2:
|
||||
cmd = sys.argv[1].lower()
|
||||
pin = int(sys.argv[2])
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setwarnings(False)
|
||||
|
||||
if cmd == "pwm":
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "node-red-node-pi-gpio",
|
||||
"version": "1.2.3",
|
||||
"version": "2.0.0-beta2",
|
||||
"description": "The basic Node-RED node for Pi GPIO",
|
||||
"dependencies" : {
|
||||
},
|
||||
|
15
hardware/PiLcd/locales/de/pilcd.html
Normal file
15
hardware/PiLcd/locales/de/pilcd.html
Normal file
@ -0,0 +1,15 @@
|
||||
<script type="text/html" data-help-name="rpi-lcd">
|
||||
<p>Raspberry-Pi-Ausgabe auf ein HD44780-artiges LCD mit üblicherweise 1, 2, oder 4 Schriftzeilen.</p>
|
||||
<h3>Eingangsdaten</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>payload<span class="property-type">string</span></dt>
|
||||
<dd>Anzuzeigender Text</dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>Der Node erwartet einen <code>msg.payload</code> mit der anzuzeigenden Text-Zeichenfolge (string).</p>
|
||||
<p>Die Texte für die zweite Zeile des Displays müssen mit <code>2:</code> beginnen, die dritte Zeile mit <code>3:</code> und die vierte mit <code>4:</code></p>
|
||||
<p>Um das Display zu leeren ist der Text <code>clr:</code> zu senden.</p>
|
||||
<p>Es muss selbst darauf geachtet werden, dass die Textlängen in das Displayfenster hineinpassen.</p>
|
||||
<p>Zum Betrieb wird die RPi.GPIO-Python-Bibliothek Version 0.5.8 (oder besser) benötigt.</p>
|
||||
<p><b>Hinweis</b>: Die Pinnummern beziehen sich auf die physischen Pinnummern des Steckverbinders P1, wodurch sie einfacher zu lokalisieren sind.</p>
|
||||
</script>
|
19
hardware/PiLcd/locales/de/pilcd.json
Normal file
19
hardware/PiLcd/locales/de/pilcd.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"pilcd": {
|
||||
"label": {
|
||||
"pins": "Pins"
|
||||
},
|
||||
"tip": {
|
||||
"tip": "<b>Tipp</b>: Bei Pins muss eine Komma-getrennte Liste von 6 GPIO-Anschlusspin-Nummern eingetragen werden, die mit RS, E, D4, D5, D6 und D7 des LCD verbunden sind."
|
||||
},
|
||||
"status": {
|
||||
"not-available": "Nicht verfügbar",
|
||||
"na": "Nicht anwendbar: __value__"
|
||||
},
|
||||
"errors": {
|
||||
"ignorenode": "Raspberry-Pi-spezifische Nodes inaktiv gesetzt",
|
||||
"libnotfound": "RPi.GPIO-Python-Bibliothek nicht gefunden",
|
||||
"needtobeexecutable": "__command__ muss ausführbar sein"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,11 @@
|
||||
<script type="text/html" data-help-name="rpi-lcd">
|
||||
<p>Raspberry Pi output to a HD44780 style LCD. Usually 1, 2, or 4 lines of characters.</p>
|
||||
<h3>Inputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>payload<span class="property-type">string</span></dt>
|
||||
<dd>Text to be displayed</dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>Expects a <code>msg.payload</code> with a string in it.</p>
|
||||
<p>Strings for the second line of the display must start <b>2:</b> - the third start <b>3:</b> - and the fourth <b>4:</b></p>
|
||||
<p>To clear the display send the string <b>clr:</b></p>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red-node-pilcd",
|
||||
"version" : "0.1.0",
|
||||
"version" : "0.2.0",
|
||||
"description" : "A Node-RED node for Raspberry Pi to write to HD44780 style LCD panels.",
|
||||
"dependencies" : {
|
||||
},
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name" : "node-red-node-blink1",
|
||||
"version" : "0.0.17",
|
||||
"version" : "0.0.18",
|
||||
"description" : "A Node-RED node to control a Thingm Blink(1)",
|
||||
"dependencies" : {
|
||||
"node-blink1" : "0.2.2"
|
||||
"node-blink1" : "0.5.1"
|
||||
},
|
||||
"repository" : {
|
||||
"type":"git",
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="blinkstick">
|
||||
<script type="text/html" data-template-name="blinkstick">
|
||||
<div class="form-row">
|
||||
<div class="form-row" id="node-input-row-payload">
|
||||
<label for="node-input-serial">Serial</label>
|
||||
@ -55,7 +55,7 @@
|
||||
<div class="form-tips">Expects a msg.payload with either hex "#rrggbb" or decimal "red,green,blue" string, or HTML color name.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="blinkstick">
|
||||
<script type="text/html" data-help-name="blinkstick">
|
||||
<p><i><a href="http://www.blinkstick.com" target="_new">BlinkStick</a></i> output node. Expects a <code>msg.payload</code> with one of:</p>
|
||||
<ul>
|
||||
<li>A hex string <b>"#rrggbb"</b> triple</li>
|
||||
|
50
hardware/blinkstick/blinkstick.html
Normal file
50
hardware/blinkstick/blinkstick.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/html" data-template-name="blinkstick">
|
||||
<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>
|
||||
<div class="form-tips">Expects a msg.payload with either hex #rrggbb or decimal red,green,blue.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="blinkstick">
|
||||
<p>BlinkStick output node. Expects a <b>msg.payload</b> with either a hex string #rrggbb triple or red,green,blue as three 0-255 values.
|
||||
It can also accept <i><a href="http://www.w3schools.com/html/html_colornames.asp" target="_new">standard HTML colour</a></i> names</p>
|
||||
<p><b>NOTE:</b> currently only works with a single BlinkStick. (As it uses the findFirst() function to attach).</p>
|
||||
<p>For more info see the <i><a href="http://blinkstick.com/" target="_new">BlinkStick website</a></i> or the <i><a href="https://github.com/arvydas/blinkstick-node" target="_new">node module</a></i> documentation.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('blinkstick',{
|
||||
category: 'output',
|
||||
color:"GoldenRod",
|
||||
defaults: {
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "light.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||"blinkstick";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
64
hardware/blinkstick/blinkstick.js
Normal file
64
hardware/blinkstick/blinkstick.js
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
var blinkstick = require("blinkstick");
|
||||
|
||||
Object.size = function(obj) {
|
||||
var size = 0;
|
||||
for (var key in obj) { if (obj.hasOwnProperty(key)) { size++; } }
|
||||
return size;
|
||||
};
|
||||
|
||||
function BlinkStick(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
var p1 = /^\#[A-Fa-f0-9]{6}$/
|
||||
var p2 = /[0-9]+,[0-9]+,[0-9]+/
|
||||
this.led = blinkstick.findFirst(); // maybe try findAll() (one day)
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
if (msg != null) {
|
||||
if (Object.size(node.led) !== 0) {
|
||||
try {
|
||||
if (p2.test(msg.payload)) {
|
||||
var rgb = msg.payload.split(",");
|
||||
node.led.setColor(parseInt(rgb[0])&255, parseInt(rgb[1])&255, parseInt(rgb[2])&255);
|
||||
}
|
||||
else {
|
||||
node.led.setColor(msg.payload.toLowerCase().replace(/\s+/g,''));
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
node.warn("BlinkStick missing ?");
|
||||
node.led = blinkstick.findFirst();
|
||||
}
|
||||
}
|
||||
else {
|
||||
//node.warn("No BlinkStick found");
|
||||
node.led = blinkstick.findFirst();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (Object.size(node.led) === 0) {
|
||||
node.error("No BlinkStick found");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RED.nodes.registerType("blinkstick",BlinkStick);
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name" : "node-red-node-blinkstick",
|
||||
"version" : "0.1.16",
|
||||
"version" : "0.1.7",
|
||||
"description" : "A Node-RED node to control a Blinkstick",
|
||||
"dependencies" : {
|
||||
"blinkstick" : "1.1.3"
|
||||
"blinkstick" : "1.2.0"
|
||||
},
|
||||
"repository" : {
|
||||
"type":"git",
|
||||
|
38
hardware/pigpiod/locales/de/pi-gpiod.html
Normal file
38
hardware/pigpiod/locales/de/pi-gpiod.html
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
<script type="text/html" data-help-name="pi-gpiod in">
|
||||
<p>Raspberry-Pi-Eingangs-Node.
|
||||
Generiert eine <code>msg.payload</code> mit einem Wert von 0 oder 1 in Abhängigkeit vom Status des Eingangspins.
|
||||
<a href="http://abyz.me.uk/rpi/pigpio/index.html" target="_new">pi-gpiod</a>-Daemon erforderlich.</p>
|
||||
<h3>Ausgangsdaten</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>payload<span class="property-type">number</span></dt>
|
||||
<dd>Pinstatus (0 or 1)</dd>
|
||||
<dt>topic<span class="property-type">string</span></dt>
|
||||
<dd>Pinnummer <code>pi/{the pin number}</code></dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>Es können auch die Pullup- (↑) oder Pulldown- (↓) Eingangs-Widerstände aktiviert werden.</p>
|
||||
<p>Bei Benutzung mit Docker auf dem Pi sollte die Standard-Host-IP <code>172.17.0.1</code> sein.
|
||||
Es muss ebenso <code>sudo pigpiod</code> auf dem Host gestartet werden.</p>
|
||||
<p><b>Hinweis</b>: Die Pinnummern beziehen sich auf die physischen Pinnummern des Steckverbinders P1, wodurch sie einfacher zu lokalisieren sind.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="pi-gpiod out">
|
||||
<p>Raspberry-Pi-Ausgangs-Node.
|
||||
Digital-, PWM- oder Servo-Modus unterstützt.
|
||||
<a href="http://abyz.me.uk/rpi/pigpio/index.html" target="_new">pi-gpiod</a>-Daemon erforderlich.</p>
|
||||
<h3>Eingangsdaten</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>payload<span class="property-type">number | string</span></dt>
|
||||
<dd>0,1 (Digital), 0-100 (PWM, Servo)</dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>Im digitalen Modus erwartet der Node eine <code>msg.payload</code> von entweder 0 oder 1 (oder false oder true)
|
||||
und setzt den ausgewählten physischen Pin entsprechend dem übergebenen Wert entweder auf low oder high.</p>
|
||||
<p>Der Anfangswert des Pins kann bei der Übernahme (Deploy) auf 0 oder 1 gesetzt werden.</p>
|
||||
<p>Im PWM-Modus erwartet der Node einen Eingangszahlenwert von 0 bis 100. Es kann auch eine Gleitkommazahl sein.</p>
|
||||
<p>Im Servo-Modus kann die Ausgabe gestoppt werden, indem ein <code>msg.payload</code> von <code>null</code> oder <code>""</code> übergeben wird.</p>
|
||||
<p>Bei Benutzung mit Docker auf dem Pi sollte die Standard-Host-IP <code>172.17.0.1</code> sein.
|
||||
Es muss ebenso <code>sudo pigpiod</code> auf dem Host gestartet werden.</p>
|
||||
<p><b>Hinweis</b>: Die Pinnummern beziehen sich auf die physischen Pinnummern des Steckverbinders P1, wodurch sie einfacher zu lokalisieren sind.</p>
|
||||
</script>
|
59
hardware/pigpiod/locales/de/pi-gpiod.json
Normal file
59
hardware/pigpiod/locales/de/pi-gpiod.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"pi-gpiod": {
|
||||
"label": {
|
||||
"gpiopin": "GPIO",
|
||||
"selectpin": "Pin-Auswahl",
|
||||
"host": "Host",
|
||||
"resistor": "Widerstand",
|
||||
"readinitial": "Initalzustand bei Übernahme/Neustart lesen",
|
||||
"type": "Typ",
|
||||
"initpin": "Pin-Zustand initialisieren",
|
||||
"debounce": "Entprellung",
|
||||
"limits": "Limits",
|
||||
"min": "min.",
|
||||
"max": "max.",
|
||||
"freq": "Frequenz"
|
||||
},
|
||||
"place": {
|
||||
"host": "Lokale oder entfernte IP",
|
||||
"port": "Port"
|
||||
},
|
||||
"resistor": {
|
||||
"none": "Kein",
|
||||
"pullup": "Pull-Up",
|
||||
"pulldown": "Pull-Down"
|
||||
},
|
||||
"digout": "Digitaler Ausgang",
|
||||
"pwmout": "PWM-Ausgang",
|
||||
"servo": "Servo-Ausgang",
|
||||
"initpin0": "Initalzustand low (0)",
|
||||
"initpin1": "Initalzustand high (1)",
|
||||
"pinname": "Pin",
|
||||
"tip": {
|
||||
"pin": "<b>Pins in Verwendung</b>: ",
|
||||
"in": "Nur digitaler Eingang unterstützt - Eingangszustand muss 0 oder 1 sein",
|
||||
"dig": "Digitaler Ausgang - Node-Eingangswert muss 0 oder 1 sein",
|
||||
"pwm": "PWM-Ausgang - Node-Eingangswert muss zwischen 0 und 100 sein",
|
||||
"ser": "Servo-Ausgang - Node-Eingangswert muss zwischen 0 und 100 sein. 50 ist die Mitte.<br/>Min. muss mindestens 500 µs und Max. muss 2500 µs oder weniger sein.",
|
||||
"dual": "Blaue Pins sind mehrfach verwendbar. Es ist sicherzustellen, dass keine andere Verwendung aktiviert ist, um sie als GPIO zu verwenden."
|
||||
},
|
||||
"types": {
|
||||
"digout": "Digitaler Ausgang",
|
||||
"input": "Eingang",
|
||||
"pullup": "Eingang mit Pull-Up",
|
||||
"pulldown": "Eingang mit Pull-Down",
|
||||
"pwmout": "PWM-Ausgang",
|
||||
"servo": "Servo-Ausgang"
|
||||
},
|
||||
"status": {
|
||||
"stopped": "Gestoppt",
|
||||
"closed": "Geschlossen",
|
||||
"not-running": "Nicht aktiv"
|
||||
},
|
||||
"errors": {
|
||||
"invalidpin": "Ungültiger GPIO-Pin",
|
||||
"invalidinput": "Ungültige Eingabe",
|
||||
"error": "FEHLER: __error__"
|
||||
}
|
||||
}
|
||||
}
|
36
hardware/pigpiod/locales/en-US/pi-gpiod.html
Normal file
36
hardware/pigpiod/locales/en-US/pi-gpiod.html
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
<script type="text/html" data-help-name="pi-gpiod in">
|
||||
<p>Raspberry Pi input node. Generates a <code>msg.payload</code> with either a
|
||||
0 or 1 depending on the state of the input pin.
|
||||
Requires the <a href="http://abyz.me.uk/rpi/pigpio/index.html" target="_new">pi-gpiod</a>
|
||||
daemon to be running on the host computer in order to work.</p>
|
||||
<h3>Outputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>payload<span class="property-type">number</span></dt>
|
||||
<dd>the level of the pin (0 or 1)</dd>
|
||||
<dt>topic<span class="property-type">string</span></dt>
|
||||
<dd>pin number <code>pi/{the pin number}</code></dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>You may also enable the input pullup resistor ↑ or the pulldown resistor ↓.</p>
|
||||
<p>If using with Docker on Pi then the default Host IP should be <code>172.17.0.1</code>. You will also need to run <code>sudo pigpiod</code> on the host.</p>
|
||||
<p><b>Note:</b> the pin numbers refer the physical pin numbers on connector P1 as they are easier to locate.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="pi-gpiod out">
|
||||
<p>Raspberry Pi output node. Can be used in Digital, PWM or Servo modes. Requires the
|
||||
<a href="http://abyz.me.uk/rpi/pigpio/index.html" target="_new">pi-gpiod</a> daemon to be running in order to work.</p>
|
||||
<h3>Inputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>payload<span class="property-type">number | string</span></dt>
|
||||
<dd>0,1 (Digital), 0-100 (PWM, Servo)</dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>Digital mode expects a <code>msg.payload</code> with either a 0 or 1 (or true or false),
|
||||
and will set the selected physical pin high or low depending on the value passed in.</p>
|
||||
<p>The initial value of the pin at deploy time can also be set to 0 or 1.</p>
|
||||
<p>When using PWM and Servo modes, the input value should be a number 0 - 100, and can be floating point.</p>
|
||||
<p>In Servo mode you can stop the output by sending a <code>msg.payload</code> of <code>null</code> or <code>""</code>.</p>
|
||||
<p>If using with Docker on Pi then the default Host IP should be <code>172.17.0.1</code>. You will also need to run <code>sudo pigpiod</code> on the host.</p>
|
||||
<p><b>Note</b>: the pin numbers refer the physical pin numbers on connector P1 as they are easier to locate.</p>
|
||||
</script>
|
@ -11,7 +11,8 @@
|
||||
"debounce": "Debounce",
|
||||
"limits": "Limits",
|
||||
"min": "min",
|
||||
"max": "max"
|
||||
"max": "max",
|
||||
"freq": "Frequency"
|
||||
},
|
||||
"place": {
|
||||
"host": "local or remote ip",
|
||||
@ -33,7 +34,8 @@
|
||||
"in": "Only Digital Input is supported - input must be 0 or 1.",
|
||||
"dig": "Digital output - input must be 0 or 1.",
|
||||
"pwm": "PWM output - input must be between 0 to 100.",
|
||||
"ser": "Servo output - input must be between 0 to 100. 50 is centre.<br/>Min must be 500uS or more, Max must be 2500uS or less."
|
||||
"ser": "Servo output - input must be between 0 to 100. 50 is centre.<br/>min. must be 500 us or more, max. must be 2500 us or less.",
|
||||
"dual": "Pins marked in blue are dual use. Make sure they are not enabled for their other use before using as GPIO."
|
||||
},
|
||||
"types": {
|
||||
"digout": "digital output",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "node-red-node-pi-gpiod",
|
||||
"version": "0.1.1",
|
||||
"version": "0.4.0",
|
||||
"description": "A node-red node for PiGPIOd",
|
||||
"dependencies" : {
|
||||
"js-pigpio": "*"
|
||||
|
@ -164,26 +164,9 @@
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
<div class="form-tips"><span data-i18n="[html]pi-gpiod.tip.in"></span></div>
|
||||
<div class="form-tips" id="pin-tip">Pins marked in blue are dual use. Make sure they are not enabled for
|
||||
their other use before using as GPIO.</div>
|
||||
<div class="form-tips" id="pin-tip"><span data-i18n="[html]pi-gpiod.tip.dual"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="pi-gpiod in">
|
||||
<p>Raspberry Pi input node. Generates a <code>msg.payload</code> with either a
|
||||
0 or 1 depending on the state of the input pin.
|
||||
Requires the <a href="http://abyz.me.uk/rpi/pigpio/index.html" target="_new">pi-gpiod</a>
|
||||
daemon to be running on the host computer in order to work.</p>
|
||||
<p><b>Outputs</b>
|
||||
<ul>
|
||||
<li><code>msg.payload</code> - <i>number</i> - the level of the pin (0 or 1).</li>
|
||||
<li><code>msg.topic</code> - <i>string</i> - pi/{the pin number}</li>
|
||||
</ul>
|
||||
<p><b>Details</b></p>
|
||||
<p>You may also enable the input pullup resistor ↑ or the pulldown resistor ↓.</p>
|
||||
<p>If using with Docker on Pi then the default Host IP should be <code>172.17.0.1</code>. You will also need to run <code>sudo pigpiod</code> on the host.</p>
|
||||
<p><b>Note:</b> the pin numbers refer the physical pin numbers on connector P1 as they are easier to locate.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var bcm2pin = {
|
||||
"2":"3", "3":"5", "4":"7", "14":"8", "15":"10", "17":"11", "18":"12", "27":"13", "22":"15",
|
||||
@ -383,9 +366,9 @@
|
||||
</div>
|
||||
<div class="form-row" id="node-set-minimax">
|
||||
<label> <span data-i18n="pi-gpiod.label.limits"></label>
|
||||
<span data-i18n="pi-gpiod.label.min"></span> <input type="text" id="node-input-sermin" style="width:70px;"> uS
|
||||
<span data-i18n="pi-gpiod.label.min"></span> <input type="text" id="node-input-sermin" style="width:70px;"> us
|
||||
|
||||
<span data-i18n="pi-gpiod.label.max"></span> <input type="text" id="node-input-sermax" style="width:70px;"> uS
|
||||
<span data-i18n="pi-gpiod.label.max"></span> <input type="text" id="node-input-sermax" style="width:70px;"> us
|
||||
</div>
|
||||
<div class="form-row" id="node-set-tick">
|
||||
<label> </label>
|
||||
@ -399,6 +382,28 @@
|
||||
<option value="1" data-i18n="pi-gpiod.initpin1"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row" id="node-set-freq">
|
||||
<label for="node-input-freq"> <span data-i18n="pi-gpiod.label.freq"></span></label>
|
||||
<select id="node-input-freq" style="width:80px;">
|
||||
<option value="8000">8000</option>
|
||||
<option value="4000">4000</option>
|
||||
<option value="2000">2000</option>
|
||||
<option value="1600">1600</option>
|
||||
<option value="1000">1000</option>
|
||||
<option value="800">800</option>
|
||||
<option value="500">500</option>
|
||||
<option value="400">400</option>
|
||||
<option value="320">320</option>
|
||||
<option value="250">250</option>
|
||||
<option value="200">200</option>
|
||||
<option value="160">160</option>
|
||||
<option value="80">80</option>
|
||||
<option value="50">50</option>
|
||||
<option value="40">40</option>
|
||||
<option value="20">20</option>
|
||||
<option value="10">10</option>
|
||||
</select> Hz
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-host"><i class="fa fa-globe"></i> <span data-i18n="pi-gpiod.label.host"></label>
|
||||
<input type="text" id="node-input-host" placeholder="localhost" style="width:250px;">
|
||||
@ -411,25 +416,7 @@
|
||||
<div class="form-tips" id="dig-tip"><span data-i18n="[html]pi-gpiod.tip.dig"></span></div>
|
||||
<div class="form-tips" id="pwm-tip"><span data-i18n="[html]pi-gpiod.tip.pwm"></span></div>
|
||||
<div class="form-tips" id="ser-tip"><span data-i18n="[html]pi-gpiod.tip.ser"></span></div>
|
||||
<div class="form-tips" id="pin-tip">Pins marked in blue are dual use. Make sure they are not enabled for
|
||||
their other use before using as GPIO.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="pi-gpiod out">
|
||||
<p>Raspberry Pi output node. Can be used in Digital, PWM or Servo modes. Requires the
|
||||
<a href="http://abyz.me.uk/rpi/pigpio/index.html" target="_new">pi-gpiod</a> daemon to be running in order to work.</p>
|
||||
<p><b>Inputs</b>
|
||||
<ul>
|
||||
<li><code>msg.payload</code> - <i>number | string</i> - 0,1 (Digital), 0-100 (PWM, Servo)</li>
|
||||
</ul>
|
||||
<p><b>Details</b></p>
|
||||
<p>Digital mode expects a <code>msg.payload</code> with either a 0 or 1 (or true or false),
|
||||
and will set the selected physical pin high or low depending on the value passed in.</p>
|
||||
<p>The initial value of the pin at deploy time can also be set to 0 or 1.</p>
|
||||
<p>When using PWM and Servo modes, the input value should be a number 0 - 100, and can be floating point.</p>
|
||||
<p>In Servo mode you can stop the output by sending a <code>msg.payload</code> of <code>null</code> or <code>""</code>.</p>
|
||||
<p>If using with Docker on Pi then the default Host IP should be <code>172.17.0.1</code>. You will also need to run <code>sudo pigpiod</code> on the host.</p>
|
||||
<p><b>Note</b>: the pin numbers refer the physical pin numbers on connector P1 as they are easier to locate.</p>
|
||||
<div class="form-tips" id="pin-tip"><span data-i18n="[html]pi-gpiod.tip.dual"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -450,7 +437,8 @@
|
||||
level: { value:"0" },
|
||||
out: { value:"out" },
|
||||
sermin: { value:"1000" },
|
||||
sermax: { value:"2000" }
|
||||
sermax: { value:"2000" },
|
||||
freq: { value:"800" }
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
@ -478,29 +466,32 @@
|
||||
|
||||
var hidestate = function () {
|
||||
if ($("#node-input-out").val() === "pwm") {
|
||||
$('#node-set-freq').show();
|
||||
$('#node-set-tick').hide();
|
||||
$('#node-set-state').hide();
|
||||
$('#node-set-minimax').hide();
|
||||
$('#node-input-set').prop('checked', false);
|
||||
$("#dig-tip").hide();
|
||||
$("#pwm-tip").show();
|
||||
$("#ser-tip").hide();
|
||||
$('#dig-tip').hide();
|
||||
$('#pwm-tip').show();
|
||||
$('#ser-tip').hide();
|
||||
}
|
||||
else if ($("#node-input-out").val() === "ser") {
|
||||
$('#node-set-freq').hide();
|
||||
$('#node-set-tick').hide();
|
||||
$('#node-set-state').hide();
|
||||
$('#node-set-minimax').show();
|
||||
$('#node-input-set').prop('checked', false);
|
||||
$("#dig-tip").hide();
|
||||
$("#pwm-tip").hide();
|
||||
$("#ser-tip").show();
|
||||
$('#dig-tip').hide();
|
||||
$('#pwm-tip').hide();
|
||||
$('#ser-tip').show();
|
||||
}
|
||||
else {
|
||||
$('#node-set-freq').hide();
|
||||
$('#node-set-tick').show();
|
||||
$('#node-set-minimax').hide();
|
||||
$("#dig-tip").show();
|
||||
$("#pwm-tip").hide();
|
||||
$("#ser-tip").hide();
|
||||
$('#dig-tip').show();
|
||||
$('#pwm-tip').hide();
|
||||
$('#ser-tip').hide();
|
||||
}
|
||||
};
|
||||
$("#node-input-out").change(function () { hidestate(); });
|
||||
|
@ -86,6 +86,7 @@ module.exports = function(RED) {
|
||||
this.set = n.set || false;
|
||||
this.level = parseInt(n.level || 0);
|
||||
this.out = n.out || "out";
|
||||
this.freq = parseInt(n.freq) || 800;
|
||||
this.sermin = Number(n.sermin)/100;
|
||||
this.sermax = Number(n.sermax)/100;
|
||||
if (this.sermin > this.sermax) {
|
||||
@ -120,6 +121,7 @@ module.exports = function(RED) {
|
||||
PiGPIO.write(node.pin, out);
|
||||
}
|
||||
if (node.out === "pwm") {
|
||||
PiGPIO.set_PWM_frequency(node.pin, node.freq);
|
||||
PiGPIO.set_PWM_dutycycle(node.pin, parseInt(out * 2.55));
|
||||
}
|
||||
if (node.out === "ser") {
|
||||
|
12
hardware/sensehat/locales/de/sensehat.json
Normal file
12
hardware/sensehat/locales/de/sensehat.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"sensehat": {
|
||||
"label": {
|
||||
"outputs": "Ausgänge",
|
||||
"motionEvents": "Bewegungsereignisse",
|
||||
"motionEventsExamples": "Beschleunigungsmesser, Gyroskop, Magnetometer, Kompass",
|
||||
"environmentEvents": "Umgebungsereignisse",
|
||||
"environmentEventsExamples": "Temperatur, Luftfeuchtigkeit, Luftdruck",
|
||||
"joystickEvents": "Joystick-Ereignisse"
|
||||
}
|
||||
}
|
||||
}
|
100
hardware/sensehat/locales/en-US/sensehat.html
Normal file
100
hardware/sensehat/locales/en-US/sensehat.html
Normal file
@ -0,0 +1,100 @@
|
||||
|
||||
<script type="text/html" data-help-name="rpi-sensehat in">
|
||||
<p>Raspberry Pi Sense HAT input node.</p>
|
||||
<p>This node sends readings from the various sensors on the Sense HAT,
|
||||
grouped into three sets; motion events, environment events and joystick events.</p>
|
||||
<p><b>Motion events</b></p>
|
||||
<p>Motion events include readings from the accelerometer, gyroscope and magnetometer,
|
||||
as well as the current compass heading. They are sent at a rate of approximately 10
|
||||
per second. The <code>topic</code> is set to <code>motion</code> and the
|
||||
<code>payload</code> is an object with the following values:</p>
|
||||
<ul>
|
||||
<li><code>acceleration.x/y/z</code> : the acceleration intensity in Gs</li>
|
||||
<li><code>gyroscope.x/y/z</code> : the rotational intensity in radians/s</li>
|
||||
<li><code>orientation.roll/pitch/yaw</code> : the angle of the axis in degrees</li>
|
||||
<li><code>compass</code> : the direction of North in degrees</li>
|
||||
</ul>
|
||||
<p><b>Environment events</b></p>
|
||||
<p>Environment events include readings from the temperature, humidity and pressure
|
||||
sensors. They are sent at a rate of approximately 1 per second. The <code>topic</code>
|
||||
is set to <code>environment</code> and the <code>payload</code> is an object
|
||||
with the following values:</p>
|
||||
<ul>
|
||||
<li><code>temperature</code> : degrees Celsius</li>
|
||||
<li><code>humidity</code> : percentage of relative humidity</li>
|
||||
<li><code>pressure</code> : Millibars</li>
|
||||
</ul>
|
||||
<p><b>Joystick events</b></p>
|
||||
<p>Joystick events are sent when the Sense HAT joystick is interacted with. The
|
||||
<code>topic</code> is set to <code>joystick</code> and the <code>payload</code>
|
||||
is an object with the following values:</p>
|
||||
<ul>
|
||||
<li><code>key</code> : one of <code>UP</code>, <code>DOWN</code>, <code>LEFT</code>, <code>RIGHT</code>, <code>ENTER</code></li>
|
||||
<li><code>state</code> : the state of the key:
|
||||
<ul>
|
||||
<li><code>0</code> : the key has been released</li>
|
||||
<li><code>1</code> : the key has been pressed</li>
|
||||
<li><code>2</code> : the key is being held down</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="rpi-sensehat out">
|
||||
<p>Raspberry Pi Sense HAT output node.</p>
|
||||
<p>This node sends commands to the 8x8 LED display on the Sense HAT.</p>
|
||||
<p>Commands are sent to the node in <code>msg.payload</code>. Multiple commands can
|
||||
be sent in a single message by separating them with newline (\n) characters. You must
|
||||
use a function node or a change node (jsonata expression) when using the newline (\n)
|
||||
character to create a payload containing multiple commands.<p>
|
||||
|
||||
<p><b>Set the colour of individual pixels</b></p>
|
||||
<p>Format: <code><x>,<y>,<colour></code>
|
||||
<p><code>x</code> and <code>y</code> must either be a value from 0 to 7, a
|
||||
<code>*</code> to indicate the entire row or column, or a range such as <code>3-6</code>.</p>
|
||||
<p><code>colour</code> must be one of:
|
||||
<ul>
|
||||
<li>the well-known <a href="https://en.wikipedia.org/wiki/Web_colors" target="_new">HTML colour names</a>
|
||||
- eg <code>red</code> or <code>aquamarine</code>,</li>
|
||||
<li>the <a href="http://cheerlights.com/cheerlights-api/">CheerLights colour names</a>,</li>
|
||||
<li>a HEX colour value - eg <code>#aa9900</code></li>
|
||||
<li>an RGB triple - <code>190,255,0</code></li>
|
||||
<li>or simply <code>off</code></li>
|
||||
</ul>
|
||||
|
||||
<p><i>Examples</i></p>
|
||||
<p>To set the entire screen to red:</p>
|
||||
<p><code>*,*,red</code></p>
|
||||
<p>To set the four corners of the display to red, green (#00ff00), yellow and blue (0,0,255):</p>
|
||||
<p><code>0,0,red,0,7,#00ff00,7,7,yellow,7,0,0,0,255</code></p>
|
||||
<p>To set a 3-pixel wide column to purple:</p>
|
||||
<p><code>4-6,*,purple</code></p>
|
||||
|
||||
<p><b>Rotate the screen</b></p>
|
||||
<p>Format: <code>R<angle></code></p>
|
||||
<p><code>angle</code> must be 0, 90, 180 or 270.</p>
|
||||
<p>Example: <code>R180</code></p>
|
||||
|
||||
<p><b>Flip the screen</b></p>
|
||||
<p>Format: <code>F<axis></code></p>
|
||||
<p><code>axis</code> must be either <code>H</code> or <code>V</code> to flip on
|
||||
the horizontal or vertical axis respectively.</p>
|
||||
<p>Example: <code>FV</code></p>
|
||||
|
||||
<p><b>Scroll a message</b></p>
|
||||
<p>If <code>msg.payload</code> is not recognised as any of the above commands,
|
||||
it is treated as a text message to be scrolled across the screen.</p>
|
||||
<p>If the text is a single character, it will be displayed without scrolling.
|
||||
To scroll a single character, append a blank space after it - <code>"A "</code>.</p>
|
||||
<p>The following message properties can be used to customise the appearance:</p>
|
||||
<ul>
|
||||
<li><code>msg.color</code> - the colour of the text, default: <code>white</code></li>
|
||||
<li><code>msg.background</code> - the colour of the background, default: <code>off</code></li>
|
||||
<li><code>msg.speed</code> - the scroll speed. A value in the range 1 (slower) to 5 (faster), default: <code>3</code></li>
|
||||
</ul>
|
||||
|
||||
<p><b>Set the screen brightness</b></p>
|
||||
<p>Format: <code>D<level></code></p>
|
||||
<p><code>level</code> must be 0 (low) or 1 (high).</p>
|
||||
<p>Example: <code>D1</code></p>
|
||||
</script>
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red-node-pi-sense-hat",
|
||||
"version" : "0.0.18",
|
||||
"version" : "0.1.0",
|
||||
"description" : "A Node-RED node to interact with a Raspberry Pi Sense HAT",
|
||||
"repository" : {
|
||||
"type":"git",
|
||||
|
@ -1,132 +1,33 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="rpi-sensehat in">
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-arrow-right"></i> <span data-i18n="sensehat.label.outputs"></label>
|
||||
<label style="width: auto" for="node-input-motion"><input style="vertical-align: top; width: auto; margin-right: 5px;" type="checkbox" id="node-input-motion"> <span data-i18n="sensehat.label.motionEvents"></label>
|
||||
<div style="padding-left: 125px; margin-top: -5px; color: #bbb;" data-i18n="sensehat.label.motionEventsExamples"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label></label>
|
||||
<label style="width: auto" for="node-input-env"><input style="vertical-align: top; width: auto; margin-right: 5px;" type="checkbox" id="node-input-env"> <span data-i18n="sensehat.label.environmentEvents"></label>
|
||||
<div style="padding-left: 125px; margin-top: -5px; color: #bbb;" data-i18n="sensehat.label.environmentEventsExamples"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label></label>
|
||||
<label style="width: auto" for="node-input-stick"><input style="vertical-align: top; width: auto; margin-right: 5px;" type="checkbox" id="node-input-stick"> <span data-i18n="sensehat.label.joystickEvents"></label>
|
||||
</div>
|
||||
<script type="text/html" data-template-name="rpi-sensehat in">
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-arrow-right"></i> <span data-i18n="sensehat.label.outputs"></label>
|
||||
<label style="width: auto" for="node-input-motion"><input style="vertical-align: top; width: auto; margin-right: 5px;" type="checkbox" id="node-input-motion"> <span data-i18n="sensehat.label.motionEvents"></label>
|
||||
<div style="padding-left: 125px; margin-top: -5px; color: #bbb;" data-i18n="sensehat.label.motionEventsExamples"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label></label>
|
||||
<label style="width: auto" for="node-input-env"><input style="vertical-align: top; width: auto; margin-right: 5px;" type="checkbox" id="node-input-env"> <span data-i18n="sensehat.label.environmentEvents"></label>
|
||||
<div style="padding-left: 125px; margin-top: -5px; color: #bbb;" data-i18n="sensehat.label.environmentEventsExamples"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label></label>
|
||||
<label style="width: auto" for="node-input-stick"><input style="vertical-align: top; width: auto; margin-right: 5px;" type="checkbox" id="node-input-stick"> <span data-i18n="sensehat.label.joystickEvents"></label>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="rpi-sensehat out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
<script type="text/html" data-template-name="rpi-sensehat out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="rpi-sensehat in">
|
||||
<p>Raspberry Pi Sense HAT input node.</p>
|
||||
<p>This node sends readings from the various sensors on the Sense HAT,
|
||||
grouped into three sets; motion events, environment events and joystick events.</p>
|
||||
<p><b>Motion events</b></p>
|
||||
<p>Motion events include readings from the accelerometer, gyroscope and magnetometer,
|
||||
as well as the current compass heading. They are sent at a rate of approximately 10
|
||||
per second. The <code>topic</code> is set to <code>motion</code> and the
|
||||
<code>payload</code> is an object with the following values:</p>
|
||||
<ul>
|
||||
<li><code>acceleration.x/y/z</code> : the acceleration intensity in Gs</li>
|
||||
<li><code>gyroscope.x/y/z</code> : the rotational intensity in radians/s</li>
|
||||
<li><code>orientation.roll/pitch/yaw</code> : the angle of the axis in degrees</li>
|
||||
<li><code>compass</code> : the direction of North in degrees</li>
|
||||
</ul>
|
||||
<p><b>Environment events</b></p>
|
||||
<p>Environment events include readings from the temperature, humidity and pressure
|
||||
sensors. They are sent at a rate of approximately 1 per second. The <code>topic</code>
|
||||
is set to <code>environment</code> and the <code>payload</code> is an object
|
||||
with the following values:</p>
|
||||
<ul>
|
||||
<li><code>temperature</code> : degrees Celsius</li>
|
||||
<li><code>humidity</code> : percentage of relative humidity</li>
|
||||
<li><code>pressure</code> : Millibars</li>
|
||||
</ul>
|
||||
<p><b>Joystick events</b></p>
|
||||
<p>Joystick events are sent when the Sense HAT joystick is interacted with. The
|
||||
<code>topic</code> is set to <code>joystick</code> and the <code>payload</code>
|
||||
is an object with the following values:</p>
|
||||
<ul>
|
||||
<li><code>key</code> : one of <code>UP</code>, <code>DOWN</code>, <code>LEFT</code>, <code>RIGHT</code>, <code>ENTER</code></li>
|
||||
<li><code>state</code> : the state of the key:
|
||||
<ul>
|
||||
<li><code>0</code> : the key has been released</li>
|
||||
<li><code>1</code> : the key has been pressed</li>
|
||||
<li><code>2</code> : the key is being held down</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="rpi-sensehat out">
|
||||
<p>Raspberry Pi Sense HAT output node.</p>
|
||||
<p>This node sends commands to the 8x8 LED display on the Sense HAT.</p>
|
||||
<p>Commands are sent to the node in <code>msg.payload</code>. Multiple commands can
|
||||
be sent in a single message by separating them with newline (\n) characters. You must
|
||||
use a function node or a change node (jsonata expression) when using the newline (\n)
|
||||
character to create a payload containing multiple commands.<p>
|
||||
|
||||
<p><b>Set the colour of individual pixels</b></p>
|
||||
<p>Format: <code><x>,<y>,<colour></code>
|
||||
<p><code>x</code> and <code>y</code> must either be a value from 0 to 7, a
|
||||
<code>*</code> to indicate the entire row or column, or a range such as <code>3-6</code>.</p>
|
||||
<p><code>colour</code> must be one of:
|
||||
<ul>
|
||||
<li>the well-known <a href="https://en.wikipedia.org/wiki/Web_colors" target="_new">HTML colour names</a>
|
||||
- eg <code>red</code> or <code>aquamarine</code>,</li>
|
||||
<li>the <a href="http://cheerlights.com/cheerlights-api/">CheerLights colour names</a>,</li>
|
||||
<li>a HEX colour value - eg <code>#aa9900</code></li>
|
||||
<li>an RGB triple - <code>190,255,0</code></li>
|
||||
<li>or simply <code>off</code></li>
|
||||
</ul>
|
||||
|
||||
<p><i>Examples</i></p>
|
||||
<p>To set the entire screen to red:</p>
|
||||
<p><code>*,*,red</code></p>
|
||||
<p>To set the four corners of the display to red, green (#00ff00), yellow and blue (0,0,255):</p>
|
||||
<p><code>0,0,red,0,7,#00ff00,7,7,yellow,7,0,0,0,255</code></p>
|
||||
<p>To set a 3-pixel wide column to purple:</p>
|
||||
<p><code>4-6,*,purple</code></p>
|
||||
|
||||
<p><b>Rotate the screen</b></p>
|
||||
<p>Format: <code>R<angle></code></p>
|
||||
<p><code>angle</code> must be 0, 90, 180 or 270.</p>
|
||||
<p>Example: <code>R180</code></p>
|
||||
|
||||
<p><b>Flip the screen</b></p>
|
||||
<p>Format: <code>F<axis></code></p>
|
||||
<p><code>axis</code> must be either <code>H</code> or <code>V</code> to flip on
|
||||
the horizontal or vertical axis respectively.</p>
|
||||
<p>Example: <code>FV</code></p>
|
||||
|
||||
<p><b>Scroll a message</b></p>
|
||||
<p>If <code>msg.payload</code> is not recognised as any of the above commands,
|
||||
it is treated as a text message to be scrolled across the screen.</p>
|
||||
<p>If the text is a single character, it will be displayed without scrolling.
|
||||
To scroll a single character, append a blank space after it - <code>"A "</code>.</p>
|
||||
<p>The following message properties can be used to customise the appearance:</p>
|
||||
<ul>
|
||||
<li><code>msg.color</code> - the colour of the text, default: <code>white</code></li>
|
||||
<li><code>msg.background</code> - the colour of the background, default: <code>off</code></li>
|
||||
<li><code>msg.speed</code> - the scroll speed. A value in the range 1 (slower) to 5 (faster), default: <code>3</code></li>
|
||||
</ul>
|
||||
|
||||
<p><b>Set the screen brightness</b></p>
|
||||
<p>Format: <code>D<level></code></p>
|
||||
<p><code>level</code> must be 0 (low) or 1 (high).</p>
|
||||
<p>Example: <code>D1</code></p>
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('rpi-sensehat in',{
|
||||
category: 'Raspberry Pi',
|
||||
|
@ -73,16 +73,39 @@ And a lightbulb can look like this:
|
||||
}
|
||||
```
|
||||
|
||||
Insight
|
||||
An Insight socket output can look like this:
|
||||
|
||||
```
|
||||
{
|
||||
"raw": "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">\n<e:property>\n<BinaryState>8|1454271649|301|834|56717|1209600|8|1010|638602|12104165</BinaryState>\n</e:property>\n</e:propertyset>\n\n\r",
|
||||
"state": "8",
|
||||
"power": 1.01,
|
||||
"onSince": 1611179325,
|
||||
"onFor": 2545,
|
||||
"onToday": 17432,
|
||||
"onTotal": 47939,
|
||||
"averagePower": 13,
|
||||
"power": 3.205,
|
||||
"energyToday": 3596536,
|
||||
"energyTotal": 9966151
|
||||
"sid": "uuid:ea808ecc-1dd1-11b2-9579-8e5c117d479e",
|
||||
"type": "socket",
|
||||
"name": "WeMo Insight",
|
||||
"id": "221450K1200F5C"
|
||||
}
|
||||
```
|
||||
Some information about those power parameters:
|
||||
+ `state`: Whether the device is currently ON or OFF (1 or 0).
|
||||
+ `onSince`: The date and time when the device was last turned on or off (as a Unix timestamp).
|
||||
+ `onFor`: How long the device was last ON for (seconds).
|
||||
+ `onToday`: How long the device has been ON today (seconds).
|
||||
+ `onTotal`: How long the device has been ON total (seconds).
|
||||
+ `timespan`: Timespan over which onTotal is relevant (seconds). Typically 2 weeks except when first started up.
|
||||
+ `averagePower`: Average power consumption (Watts).
|
||||
+ `power`: Current power consumption (Watts).
|
||||
+ `energyToday`: Energy used today (Watt-hours, or Wh).
|
||||
+ `energyTotal`: Energy used in total (Wh).
|
||||
+ `standbyLimit`: Minimum energy usage to register the insight as switched on ( milliwats, default 8000mW, configurable via WeMo App).
|
||||
|
||||
## Lookup Node
|
||||
|
||||
This node queries the current state of a device, when an input message is injected. The output is very similar to that of the Input node.
|
||||
|
@ -29,9 +29,26 @@
|
||||
<li>Light Groups</li>
|
||||
<li>Motion Detector</li>
|
||||
</ul>
|
||||
<p>Sockets will generate msg.payload with values of 0/1/8 for off or on
|
||||
(8 is on but at standby load for insight sockets), lightswill return an
|
||||
object like this:</p>
|
||||
<p>Sockets will generate msg.payload with values of 0 or 1 (for off or on).</p>
|
||||
<p>Insight sockets will return an object like this (where state can also be 8 at standby):</p>
|
||||
<pre>
|
||||
{
|
||||
state: "1"
|
||||
onSince: 1611180205
|
||||
onFor: 853
|
||||
onToday: 18284
|
||||
onTotal: 48785
|
||||
averagePower: 12
|
||||
power: 0
|
||||
energyToday: 3772853
|
||||
energyTotal: 10142468
|
||||
sid: "uuid:adebe0c4-1dd1-11b2-8779-d6b6d5a8a932"
|
||||
type: "socket"
|
||||
name: "WeMo Insight"
|
||||
id: "221536K12000B4"
|
||||
}
|
||||
</pre>
|
||||
<p>Lights will return an object like this:</p>
|
||||
<pre>
|
||||
{
|
||||
name: 'Bedroom light',
|
||||
@ -164,7 +181,23 @@
|
||||
|
||||
<script type="text/x-red" data-help-name="wemo lookup">
|
||||
<p>This node queries the current state of a device</p>
|
||||
<p>For lights it return a msg.payload that looks like this:</p>
|
||||
<p>For sockets it returns a msg.payload that looks like this:</p>
|
||||
<pre>{
|
||||
state: 0
|
||||
}</pre>
|
||||
<p>For insight sockets it returns a msg.payload that contains extra power parameters:</p>
|
||||
<pre>{
|
||||
state: 0,
|
||||
onSince: 1611179325,
|
||||
onFor: 2545,
|
||||
onToday: 17432,
|
||||
onTotal: 47939,
|
||||
averagePower: 13,
|
||||
power: 3.205,
|
||||
energyToday: 3596536,
|
||||
energyTotal: 9966151
|
||||
}</pre>
|
||||
<p>For lights it returns a msg.payload that looks like this:</p>
|
||||
<pre>{
|
||||
available: true,
|
||||
state: 0,
|
||||
|
@ -125,7 +125,7 @@ module.exports = function(RED) {
|
||||
|
||||
callback_url += 'wemoNG/notification';
|
||||
|
||||
console.log('Callback URL = %s',callback_url);
|
||||
// console.log('Callback URL = %s',callback_url);
|
||||
|
||||
var subscribeOptions = {
|
||||
host: device.ip,
|
||||
@ -152,6 +152,14 @@ module.exports = function(RED) {
|
||||
}
|
||||
});
|
||||
|
||||
sub_request.on('error', function(){
|
||||
// devie probably offline
|
||||
// try again after a minute
|
||||
setTimeout( function() {
|
||||
subscribe(node)
|
||||
}, 60000)
|
||||
})
|
||||
|
||||
sub_request.end();
|
||||
}
|
||||
}
|
||||
@ -221,12 +229,21 @@ module.exports = function(RED) {
|
||||
node.status({fill: 'green',shape: 'dot',text: 'found'});
|
||||
}
|
||||
|
||||
node.on('input', function(msg) {
|
||||
node.on('input', function(msg, send, done){
|
||||
var dev = wemo.get(node.dev);
|
||||
|
||||
send = send || function() { node.send.apply(node,arguments) }
|
||||
|
||||
if (!dev) {
|
||||
//need to show that dev not currently found
|
||||
console.log('no device found');
|
||||
// console.log('no device found');
|
||||
|
||||
if (done) {
|
||||
done("Device not discovered yet")
|
||||
} else {
|
||||
node.error("Device not discovered yet", msg)
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -246,7 +263,7 @@ module.exports = function(RED) {
|
||||
} else if (typeof msg.payload === 'object') {
|
||||
//object need to get complicated here
|
||||
if (msg.payload.hasOwnProperty('state') && typeof msg.payload.state === 'number') {
|
||||
if (dev.type === 'socket') {
|
||||
if (dev.type === 'socket' || dev.type === 'socket_insight') {
|
||||
if (msg.payload.state >= 0 && msg.payload.state < 2) {
|
||||
on = msg.payload.state;
|
||||
}
|
||||
@ -278,7 +295,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
|
||||
if (dev.type == 'socket') {
|
||||
if (dev.type == 'socket' || dev.type == 'socket_insight') {
|
||||
//console.log("socket");
|
||||
wemo.toggleSocket(dev, on);
|
||||
} else if (dev.type === 'light') {
|
||||
@ -325,7 +342,10 @@ module.exports = function(RED) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'socket': {
|
||||
case 'socket':
|
||||
case 'socket_insight': {
|
||||
// For backwards compatibility, always send type 'socket'
|
||||
notification.type = 'socket';
|
||||
node.send(msg);
|
||||
break;
|
||||
}
|
||||
@ -395,12 +415,19 @@ module.exports = function(RED) {
|
||||
node.status({fill: 'green',shape: 'dot',text: 'found'});
|
||||
}
|
||||
|
||||
node.on('input', function(msg) {
|
||||
node.on('input', function(msg, send, done) {
|
||||
var dev = wemo.get(node.dev);
|
||||
|
||||
send = send || function() { node.send.apply(node,arguments) }
|
||||
|
||||
if (!dev) {
|
||||
//need to show that dev not currently found
|
||||
console.log('no device found');
|
||||
console.log('Device not discovered yet');
|
||||
if (done) {
|
||||
done("Device not discovered yet")
|
||||
} else {
|
||||
node.error("Device not discovered yet",msg)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -424,17 +451,55 @@ module.exports = function(RED) {
|
||||
delete status.capabilities;
|
||||
// }
|
||||
msg.payload = status;
|
||||
node.send(msg);
|
||||
send(msg);
|
||||
if (done) {
|
||||
done()
|
||||
}
|
||||
}).catch(function(err){
|
||||
if (done) {
|
||||
done(err)
|
||||
} else {
|
||||
node.error(err,msg)
|
||||
}
|
||||
});
|
||||
} else if (dev.type === 'socket_insight') {
|
||||
console.log("socket_insight");
|
||||
// insight socket: ask both current switch status AND power measurements
|
||||
wemo.getInsightParams(dev)
|
||||
.then(function(insightParameters) {
|
||||
msg.payload = insightParameters;
|
||||
// 'state' should be a number for backwards compatibility
|
||||
msg.payload.state = parseInt(msg.payload.state);
|
||||
send(msg);
|
||||
if (done) {
|
||||
done()
|
||||
}
|
||||
}).catch(function(err){
|
||||
if (done) {
|
||||
done(err)
|
||||
} else {
|
||||
node.error(err,msg)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log("socket");
|
||||
//socket
|
||||
//console.log("socket");
|
||||
// classic socket: no power measurement, so only request current switch status
|
||||
wemo.getSocketStatus(dev)
|
||||
.then(function(status) {
|
||||
msg.payload = {
|
||||
state: status
|
||||
};
|
||||
node.send(msg);
|
||||
send(msg);
|
||||
if (done) {
|
||||
done()
|
||||
}
|
||||
})
|
||||
.catch(function(err){
|
||||
if (done) {
|
||||
done(err)
|
||||
} else {
|
||||
node.error(err,msg)
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -457,9 +522,13 @@ module.exports = function(RED) {
|
||||
'sid': req.headers.sid
|
||||
};
|
||||
//console.log("Incoming Event %s", req.body.toString());
|
||||
wemo.parseEvent(req.body.toString()).then(function(evt) {
|
||||
wemo.parseEvent(req.body.toString())
|
||||
.then(function(evt) {
|
||||
evt.sid = notification.sid;
|
||||
wemo.emit('event',evt);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
});
|
||||
res.send('');
|
||||
});
|
||||
|
@ -69,6 +69,17 @@ var getSocketState = {
|
||||
].join('\n')
|
||||
}
|
||||
|
||||
var getInsightParameters = {
|
||||
method: 'POST',
|
||||
path: '/upnp/control/insight1',
|
||||
action: '"urn:Belkin:service:insight:1#GetInsightParams"',
|
||||
body: [
|
||||
postbodyheader,
|
||||
'<u:GetInsightParams xmlns:u="urn:Belkin:service:insight:1">',
|
||||
'</u:GetInsightParams>',
|
||||
postbodyfooter
|
||||
].join('\n')
|
||||
}
|
||||
|
||||
var setdevstatus = {};
|
||||
setdevstatus.path = '/upnp/control/bridge1';
|
||||
@ -109,6 +120,47 @@ var WeMoNG = function () {
|
||||
|
||||
}
|
||||
|
||||
function addInsightParams(insightParms, msg) {
|
||||
var params = insightParms.split("|");
|
||||
|
||||
// Whether the device is ON or OFF (1 or 0)
|
||||
msg.state = params[0];
|
||||
|
||||
// The date and time when the device was last turned on or off (as a Unix timestamp)
|
||||
msg.onSince = parseInt(params[1]);
|
||||
|
||||
// How long the device was last ON for (seconds)
|
||||
msg.onFor = parseInt(params[2]);
|
||||
|
||||
// How long the device has been ON today (seconds)
|
||||
msg.onToday = parseInt(params[3]);
|
||||
|
||||
// How long the device has been ON total (seconds)
|
||||
msg.onTotal = parseInt(params[4]);
|
||||
|
||||
// Timespan over which onTotal is relevant (seconds). Typically 2 weeks except when first started up.
|
||||
//msg.timespan = parseInt(params[5]);
|
||||
|
||||
// Average power consumption (Watts)
|
||||
msg.averagePower = parseInt(params[6]);
|
||||
|
||||
// Current power consumption (Watts). Conversion required because the value is delivered in milliWatts.
|
||||
// It is called 'power' (instead of currentPower) for backwards compatibility ...
|
||||
msg.power = params[7]/1000;
|
||||
|
||||
// Energy used today (Watt-hours, or Wh)
|
||||
msg.energyToday = parseInt(params[8]);
|
||||
|
||||
// Energy used in total (Wh)
|
||||
msg.energyTotal = parseFloat(params[9]);
|
||||
|
||||
// The 10-th parameter is not always available
|
||||
if (params[10]) {
|
||||
// Minimum energy usage to register the insight as switched on ( milliwats, default 8000mW, configurable via WeMo App)
|
||||
msg.standbyLimit = parseInt(params[10]);
|
||||
}
|
||||
}
|
||||
|
||||
util.inherits(WeMoNG, events.EventEmitter);
|
||||
|
||||
WeMoNG.prototype.start = function start() {
|
||||
@ -219,11 +271,31 @@ WeMoNG.prototype.start = function start() {
|
||||
post_request.abort();
|
||||
});
|
||||
|
||||
post_request.on('error', function(err){
|
||||
// should log err
|
||||
//console.log(err);
|
||||
})
|
||||
|
||||
post_request.write(util.format(getenddevs.body, udn));
|
||||
post_request.end();
|
||||
|
||||
} else if (device.deviceType.indexOf('urn:Belkin:device:insight') != -1) {
|
||||
// Insight socket (with power measurement)
|
||||
var socket = {
|
||||
"ip": location.hostname,
|
||||
"port": location.port,
|
||||
"name": device.friendlyName,
|
||||
"type": "socket_insight",
|
||||
"device": device
|
||||
};
|
||||
if (!_wemo.devices[device.serialNumber]) {
|
||||
_wemo.devices[device.serialNumber] = socket;
|
||||
_wemo.emit('discovered',device.serialNumber);
|
||||
} else {
|
||||
_wemo.devices[device.serialNumber] = socket;
|
||||
}
|
||||
} else if (device.deviceType.indexOf('urn:Belkin:device') != -1) {
|
||||
//socket
|
||||
// classic socket (without power measurement)
|
||||
var socket = {
|
||||
"ip": location.hostname,
|
||||
"port": location.port,
|
||||
@ -291,12 +363,12 @@ WeMoNG.prototype.toggleSocket = function toggleSocket(socket, on) {
|
||||
});
|
||||
|
||||
post_request.on('error', function (e) {
|
||||
console.log(e);
|
||||
console.log("%j", postoptions);
|
||||
// console.log(e);
|
||||
// console.log("%j", postoptions);
|
||||
});
|
||||
|
||||
post_request.on('timeout', function () {
|
||||
console.log("Timeout");
|
||||
// console.log("Timeout");
|
||||
post_request.abort();
|
||||
});
|
||||
|
||||
@ -341,21 +413,21 @@ WeMoNG.prototype.getSocketStatus = function getSocketStatus(socket) {
|
||||
status = parseInt(status);
|
||||
def.resolve(status);
|
||||
} else {
|
||||
def.reject();
|
||||
def.reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
post_request.on('error', function (e) {
|
||||
console.log(e);
|
||||
console.log("%j", postoptions);
|
||||
def.reject();
|
||||
// console.log(e);
|
||||
// console.log("%j", postoptions);
|
||||
def.reject(e);
|
||||
});
|
||||
|
||||
post_request.on('timeout', function(){
|
||||
post_request.abort();
|
||||
def.reject();
|
||||
def.reject("timeout");
|
||||
});
|
||||
|
||||
post_request.write(getSocketState.body);
|
||||
@ -364,6 +436,57 @@ WeMoNG.prototype.getSocketStatus = function getSocketStatus(socket) {
|
||||
return def.promise;
|
||||
};
|
||||
|
||||
WeMoNG.prototype.getInsightParams = function getInsightParams(socket) {
|
||||
var postoptions = {
|
||||
host: socket.ip,
|
||||
port: socket.port,
|
||||
path: getInsightParameters.path,
|
||||
method: getInsightParameters.method,
|
||||
headers: {
|
||||
'SOAPACTION': getInsightParameters.action,
|
||||
'Content-Type': 'text/xml; charset="utf-8"',
|
||||
'Accept': ''
|
||||
}
|
||||
}
|
||||
|
||||
var def = Q.defer();
|
||||
|
||||
var post_request = http.request(postoptions, function(res){
|
||||
var data = "";
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', function(chunk){
|
||||
data += chunk;
|
||||
});
|
||||
|
||||
res.on('end', function(){
|
||||
xml2js.parseString(data, function(err, result){
|
||||
if (!err) {
|
||||
var params = result["s:Envelope"]["s:Body"][0]["u:GetInsightParamsResponse"][0].InsightParams[0];
|
||||
var msg = {};
|
||||
addInsightParams(params, msg);
|
||||
def.resolve(msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
post_request.on('error', function (e) {
|
||||
// console.log(e);
|
||||
// console.log("%j", postoptions);
|
||||
def.reject(e);
|
||||
});
|
||||
|
||||
post_request.on('timeout', function(){
|
||||
post_request.abort();
|
||||
def.reject("timeout");
|
||||
});
|
||||
|
||||
post_request.write(getInsightParameters.body);
|
||||
post_request.end();
|
||||
|
||||
return def.promise;
|
||||
};
|
||||
|
||||
WeMoNG.prototype.getLightStatus = function getLightStatus(light) {
|
||||
var postoptions = {
|
||||
host: light.ip,
|
||||
@ -403,28 +526,28 @@ WeMoNG.prototype.getLightStatus = function getLightStatus(light) {
|
||||
};
|
||||
def.resolve(obj);
|
||||
} else {
|
||||
def.reject();
|
||||
console.log("err");
|
||||
def.reject(err);
|
||||
// console.log("err");
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.log("err");
|
||||
def.reject();
|
||||
// console.log("err");
|
||||
def.reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
post_request.on('error', function (e) {
|
||||
console.log(e);
|
||||
console.log("%j", postoptions);
|
||||
def.reject();
|
||||
// console.log(e);
|
||||
// console.log("%j", postoptions);
|
||||
def.reject(e);
|
||||
});
|
||||
|
||||
post_request.on('timeout', function () {
|
||||
console.log("Timeout");
|
||||
post_request.abort();
|
||||
// console.log("Timeout");
|
||||
post_request.abort("timeout");
|
||||
def.reject();
|
||||
});
|
||||
|
||||
@ -460,12 +583,12 @@ WeMoNG.prototype.setStatus = function setStatus(light, capability, value) {
|
||||
});
|
||||
|
||||
post_request.on('error', function (e) {
|
||||
console.log(e);
|
||||
console.log("%j", postoptions);
|
||||
// console.log(e);
|
||||
// console.log("%j", postoptions);
|
||||
});
|
||||
|
||||
post_request.on('timeout', function () {
|
||||
console.log("Timeout");
|
||||
// console.log("Timeout");
|
||||
post_request.abort();
|
||||
});
|
||||
|
||||
@ -494,15 +617,14 @@ WeMoNG.prototype.parseEvent = function parseEvent(evt) {
|
||||
msg.value = res['StateEvent']['Value'][0];
|
||||
def.resolve(msg);
|
||||
} else {
|
||||
def.reject();
|
||||
def.reject(err);
|
||||
}
|
||||
});
|
||||
} else if (prop.hasOwnProperty('BinaryState')) {
|
||||
msg.state = prop['BinaryState'][0];
|
||||
if (msg.state.length > 1) {
|
||||
var parts = msg.state.split('|');
|
||||
msg.state = parts[0];
|
||||
msg.power = parts[7]/1000;
|
||||
// Add all the insight params to the msg
|
||||
addInsightParams(msg.state, msg);
|
||||
}
|
||||
|
||||
def.resolve(msg);
|
||||
@ -512,7 +634,7 @@ WeMoNG.prototype.parseEvent = function parseEvent(evt) {
|
||||
}
|
||||
} else {
|
||||
//error
|
||||
def.reject();
|
||||
def.reject(err);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "node-red-node-wemo",
|
||||
"version": "0.1.18",
|
||||
"version": "0.2.1",
|
||||
"description": "Input and Output nodes for Belkin WeMo devices",
|
||||
"repository": "https://github.com/node-red/node-red-nodes/tree/master/hardware",
|
||||
"main": "WeMoNG.js",
|
||||
@ -12,11 +12,16 @@
|
||||
"wemo",
|
||||
"belkin"
|
||||
],
|
||||
"author": {
|
||||
"email": "hardillb@gmail.com",
|
||||
"name": "Benjamin Hardill",
|
||||
"url": "http://www.hardill.me.uk/wordpress/"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"email": "hardillb@gmail.com",
|
||||
"name": "Benjamin Hardill",
|
||||
"url": "http://www.hardill.me.uk/wordpress/"
|
||||
},
|
||||
{
|
||||
"name": "Bart Butenaers"
|
||||
}
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"node-ssdp": "~3.2.5",
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="emoncms">
|
||||
<script type="text/html" data-template-name="emoncms">
|
||||
<div class="form-row">
|
||||
<label for="node-input-emonServer"><i class="fa fa-globe"></i> Emoncms server</label>
|
||||
<input type="text" id="node-input-emonServer">
|
||||
@ -21,10 +21,9 @@
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Emoncms">
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="emoncms">
|
||||
<script type="text/html" data-help-name="emoncms">
|
||||
<p>Posts data to Emoncms.</p>
|
||||
<p>The <code>msg.payload</code> can contain either a comma separated list of name
|
||||
value pairs (legacy) e.g. <pre>name:value,...</pre> or a comma separated list of values (CSV) e.g. <pre>1,2,...</pre>
|
||||
@ -33,7 +32,7 @@
|
||||
<p>The node must be specified either by the <i>Node</i> element or if left blank by <code>msg.nodegroup</code></p>
|
||||
<p>Data Type must be one of <pre>legacy, json, fulljson, CSV</pre></p>
|
||||
<p>Insertion time can be set by using <code>msg.time</code>.
|
||||
This can either be a valid ISO 8601 format or seconds since 1970. Not setting a time or setting an incorrect
|
||||
This can either be a valid ISO 8601 format or seconds since 1970. Not setting a time or setting an incorrect
|
||||
time format will result in data being pushed to Emoncms without the time element.</p>
|
||||
<p>The output node contains the server response</p>
|
||||
</script>
|
||||
@ -66,7 +65,8 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="emoncms in">
|
||||
|
||||
<script type="text/html" data-template-name="emoncms in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-emonServer"><i class="fa fa-globe"></i> Emoncms server</label>
|
||||
<input type="text" id="node-input-emonServer">
|
||||
@ -81,9 +81,11 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="emoncms in">
|
||||
<script type="text/html" data-help-name="emoncms in">
|
||||
<p>Fetches data from emoncms.</p>
|
||||
<p>The <code>msg.payload</code> contains last emoncms feed value
|
||||
<p>The <code>msg.topic</code> contains the name of the Feed</p>
|
||||
<p>The <code>msg.payload</code> contains last emoncms feed value</p>
|
||||
<p>The <code>msg.feed_data</code> contains all the feed data</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -109,18 +111,7 @@
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/x-red" data-template-name="emoncms-server">
|
||||
<script type="text/html" data-template-name="emoncms-server">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-server"><i class="fa fa-globe"></i> Base URL</label>
|
||||
<input type="text" id="node-config-input-server">
|
||||
@ -133,7 +124,7 @@
|
||||
<label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-config-input-name">
|
||||
</div>
|
||||
<div class="form-tips">The <b>Base URL</b> is the URL to the Emoncms root directory.</div>
|
||||
<div class="form-tips">The <b>Base URL</b> is the URL to the Emoncms root directory.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
@ -160,7 +160,7 @@ module.exports = function(RED) {
|
||||
if (this.baseurl.substring(0,5) === "https") { http = require("https"); }
|
||||
else { http = require("http"); }
|
||||
this.on("input", function(msg) {
|
||||
this.url = this.baseurl + '/feed/value.json';
|
||||
this.url = this.baseurl + '/feed/aget.json';
|
||||
this.url += '&apikey='+this.apikey;
|
||||
var feedid = this.feedid || msg.feedid;
|
||||
if (feedid !== "") {
|
||||
@ -169,14 +169,17 @@ module.exports = function(RED) {
|
||||
http.get(this.url, function(res) {
|
||||
msg.rc = res.statusCode;
|
||||
msg.payload = "";
|
||||
msg.feed_data = "";
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', function(chunk) {
|
||||
msg.payload += chunk;
|
||||
msg.feed_data += chunk;
|
||||
});
|
||||
res.on('end', function() {
|
||||
if (msg.rc === 200) {
|
||||
try {
|
||||
msg.payload = JSON.parse(msg.payload);
|
||||
msg.feed_data = JSON.parse(msg.feed_data);
|
||||
msg.topic = msg.feed_data.name;
|
||||
msg.payload = msg.feed_data.value;
|
||||
}
|
||||
catch(err) {
|
||||
// Failed to parse, pass it on
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red-node-emoncms",
|
||||
"version" : "0.2.1",
|
||||
"version" : "0.3.0",
|
||||
"description" : "A Node-RED node to fetch/post data to/from emoncms",
|
||||
"dependencies" : {
|
||||
},
|
||||
|
@ -4,6 +4,14 @@
|
||||
<label for="node-input-host"><i class="fa fa-dot-circle-o"></i> <span data-i18n="ping.label.target"></span></label>
|
||||
<input type="text" id="node-input-host" placeholder="192.168.0.1, www.google.com">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-protocol"><i class="fa fa-gear"></i> <span data-i18n="ping.label.protocol"></label>
|
||||
<select type="text" id="node-input-protocol" style="width: 70%">
|
||||
<option value="Automatic" data-i18n="ping.label.protocol_option.auto"></option>
|
||||
<option value="IPv4" data-i18n="ping.label.protocol_option.ipv4"></option>
|
||||
<option value="IPv6" data-i18n="ping.label.protocol_option.ipv6"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-mode"><i class="fa fa-wrench"></i> <span data-i18n="ping.label.mode"></label>
|
||||
<select type="text" id="node-input-mode" style="width: 70%">
|
||||
@ -54,6 +62,7 @@ var timerParameterValidator = function(node,v){
|
||||
category: "network-input",
|
||||
color:"#fdf0c2",
|
||||
defaults: {
|
||||
protocol: {value:"Automatic"},
|
||||
mode: {value:"timed"},
|
||||
name: {value:""},
|
||||
host: {value:"", validate: function(v){
|
||||
|
@ -6,7 +6,7 @@ module.exports = function(RED) {
|
||||
|
||||
function doPing(node, host, arrayMode) {
|
||||
const defTimeout = 5000;
|
||||
var ex, hostOptions, commandLineOptions;
|
||||
var ex, ex6, hostOptions, commandLineOptions;
|
||||
if (typeof host === "string") {
|
||||
hostOptions = {
|
||||
host: host,
|
||||
@ -25,19 +25,42 @@ module.exports = function(RED) {
|
||||
if (arrayMode) {
|
||||
msg.ping = hostOptions
|
||||
}
|
||||
|
||||
var cmd = "ping";
|
||||
//User Selected Protocol
|
||||
if (plat == "linux" || plat == "android") {
|
||||
commandLineOptions = ["-n", "-w", timeoutS, "-c", "1"]
|
||||
if (node.protocol === "IPv4") {
|
||||
commandLineOptions = ["-n", "-4", "-w", timeoutS, "-c", "1"]; //IPv4
|
||||
} else if (node.protocol === "IPv6") {
|
||||
commandLineOptions = ["-n", "-6", "-w", timeoutS, "-c", "1"]; //IPv6
|
||||
} else {
|
||||
commandLineOptions = ["-n", "-w", timeoutS, "-c", "1"]; //Automatic
|
||||
}
|
||||
} else if (plat.match(/^win/)) {
|
||||
commandLineOptions = ["-n", "1", "-w", hostOptions.timeout]
|
||||
if (node.protocol === "IPv4") {
|
||||
commandLineOptions = ["-n", "1", "-4", "-w", hostOptions.timeout]; //IPv4
|
||||
} else if (node.protocol === "IPv6") {
|
||||
commandLineOptions = ["-n", "1", "-6", "-w", hostOptions.timeout]; //IPv6
|
||||
} else {
|
||||
commandLineOptions = ["-n", "1", "-w", hostOptions.timeout]; //Automatic
|
||||
}
|
||||
} else if (plat == "darwin" || plat == "freebsd") {
|
||||
commandLineOptions = ["-n", "-t", timeoutS, "-c", "1"]
|
||||
if (node.protocol === "IPv4") {
|
||||
commandLineOptions = ["-n", "-t", timeoutS, "-c", "1"]; //IPv4
|
||||
} else if (node.protocol === "IPv6") {
|
||||
cmd = "ping6";
|
||||
commandLineOptions = ["-n", "-t", timeoutS, "-c", "1"]; //IPv6
|
||||
} else {
|
||||
commandLineOptions = ["-n", "-t", timeoutS, "-c", "1"]; //Automatic
|
||||
}
|
||||
|
||||
} else {
|
||||
node.error("Sorry - your platform - "+plat+" - is not recognised.", msg);
|
||||
return; //dont pass go - just return!
|
||||
}
|
||||
|
||||
//spawn with timeout in case of os issue
|
||||
ex = spawn("ping", [...commandLineOptions, hostOptions.host]);
|
||||
ex = spawn(cmd, [...commandLineOptions, hostOptions.host]);
|
||||
|
||||
//monitor every spawned process & SIGINT if too long
|
||||
var spawnTout = setTimeout(() => {
|
||||
@ -53,6 +76,27 @@ module.exports = function(RED) {
|
||||
var fail = false;
|
||||
//var regex = /from.*time.(.*)ms/;
|
||||
var regex = /=.*[<|=]([0-9]*).*TTL|ttl..*=([0-9\.]*)/;
|
||||
|
||||
var tryPing6 = false;
|
||||
//catch error msg from ping
|
||||
ex.stderr.setEncoding('utf8');
|
||||
ex.stderr.on("data", function (data) {
|
||||
if (!data.includes('Usage')) { // !data: only get the error and not how to use the ping command
|
||||
if (data.includes('invalid') && data.includes('6')) { //if IPv6 not supported in version of ping try ping6
|
||||
tryPing6 = true;
|
||||
}
|
||||
else if (data.includes('Network is unreachable')) {
|
||||
node.status({shape:"ring",fill:"red"});
|
||||
node.error(data + " Please check that your service provider or network device has IPv6 enabled", msg);
|
||||
node.hadErr = true;
|
||||
}
|
||||
else {
|
||||
node.status({shape:"ring",fill:"grey"});
|
||||
node.hadErr = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ex.stdout.on("data", function (data) {
|
||||
line += data.toString();
|
||||
});
|
||||
@ -72,23 +116,94 @@ module.exports = function(RED) {
|
||||
}
|
||||
});
|
||||
ex.on("close", function (code) {
|
||||
if (fail) { fail = false; return; }
|
||||
var m = regex.exec(line)||"";
|
||||
if (m !== "") {
|
||||
if (m[1]) { res = Number(m[1]); }
|
||||
if (m[2]) { res = Number(m[2]); }
|
||||
if (tryPing6 === false) {
|
||||
if (fail) { fail = false; return; }
|
||||
var m = regex.exec(line)||"";
|
||||
if (m !== "") {
|
||||
if (m[1]) { res = Number(m[1]); }
|
||||
if (m[2]) { res = Number(m[2]); }
|
||||
}
|
||||
if (code === 0) { msg.payload = res }
|
||||
try { node.send(msg); }
|
||||
catch(e) {console.warn(e)}
|
||||
|
||||
}
|
||||
else {
|
||||
//fallback to ping6 for OS's that have not updated/out of date
|
||||
if (plat == "linux" || plat == "android") {
|
||||
commandLineOptions = ["-n", "-w", timeoutS, "-c", "1"];
|
||||
} else if (plat == "darwin" || plat == "freebsd") {
|
||||
commandLineOptions = ["-n", "-c", "1"] //NOTE: -X / timeout does not work on mac OSX and most freebsd systems
|
||||
} else {
|
||||
node.error("Sorry IPv6 on your platform - "+plat+" - is not supported.", msg);
|
||||
}
|
||||
//spawn with timeout in case of os issue
|
||||
ex6 = spawn("ping6", [...commandLineOptions, hostOptions.host]);
|
||||
|
||||
//monitor every spawned process & SIGINT if too long
|
||||
var spawnTout = setTimeout(() => {
|
||||
node.log(`ping6 - Host '${hostOptions.host}' process timeout - sending SIGINT`)
|
||||
try {
|
||||
if (ex6 && ex6.pid) { ex6.kill("SIGINT"); }
|
||||
}
|
||||
catch(e) {console.warn(e); }
|
||||
}, hostOptions.timeout+1000); //add 1s for grace
|
||||
|
||||
//catch error msg from ping6
|
||||
ex6.stderr.setEncoding('utf8');
|
||||
ex6.stderr.on("data", function (data) {
|
||||
if (!data.includes('Usage')) { // !data: only get the error and not how to use the ping6 command
|
||||
if (data.includes('Network is unreachable')) {
|
||||
node.error(data + " Please check that your service provider or network device has IPv6 enabled", msg);
|
||||
node.status({shape:"ring",fill:"red"});
|
||||
}
|
||||
else {
|
||||
node.status({shape:"ring",fill:"grey"});
|
||||
}
|
||||
node.hadErr = true;
|
||||
}
|
||||
});
|
||||
|
||||
ex6.stdout.on("data", function (data) {
|
||||
line += data.toString();
|
||||
});
|
||||
ex6.on("exit", function (err) {
|
||||
clearTimeout(spawnTout);
|
||||
});
|
||||
ex6.on("error", function (err) {
|
||||
fail = true;
|
||||
if (err.code === "ENOENT") {
|
||||
node.error(err.code + " ping6 command not found", msg);
|
||||
}
|
||||
else if (err.code === "EACCES") {
|
||||
node.error(err.code + " can't run ping6 command", msg);
|
||||
}
|
||||
else {
|
||||
node.error(err.code, msg);
|
||||
}
|
||||
});
|
||||
ex6.on("close", function (code) {
|
||||
if (fail) { fail = false; return; }
|
||||
var m = regex.exec(line)||"";
|
||||
if (m !== "") {
|
||||
if (m[1]) { res = Number(m[1]); }
|
||||
if (m[2]) { res = Number(m[2]); }
|
||||
}
|
||||
if (code === 0) { msg.payload = res }
|
||||
try { node.send(msg); }
|
||||
catch(e) {console.warn(e)}
|
||||
});
|
||||
}
|
||||
if (code === 0) { msg.payload = res }
|
||||
try { node.send(msg); }
|
||||
catch(e) {console.warn(e)}
|
||||
});
|
||||
}
|
||||
|
||||
function PingNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.protocol = n.protocol||'Automatic';
|
||||
this.mode = n.mode;
|
||||
this.host = n.host;
|
||||
this.timer = n.timer * 1000;
|
||||
this.hadErr = false;
|
||||
var node = this;
|
||||
|
||||
function generatePingList(str) {
|
||||
@ -102,6 +217,7 @@ module.exports = function(RED) {
|
||||
clearPingInterval();
|
||||
} else if (node.timer) {
|
||||
node.tout = setInterval(function() {
|
||||
if (node.hadErr) { node.hadErr = false; node.status({}); }
|
||||
let pingables = generatePingList(node.host);
|
||||
for (let index = 0; index < pingables.length; index++) {
|
||||
const element = pingables[index];
|
||||
@ -112,6 +228,7 @@ module.exports = function(RED) {
|
||||
|
||||
this.on("input", function (msg) {
|
||||
let node = this;
|
||||
if (node.hadErr) { node.hadErr = false; node.status({}); }
|
||||
let payload = node.host || msg.payload;
|
||||
if (typeof payload == "string") {
|
||||
let pingables = generatePingList(payload)
|
||||
@ -132,4 +249,4 @@ module.exports = function(RED) {
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("ping",PingNode);
|
||||
}
|
||||
}
|
||||
|
15
io/ping/locales/de/88-ping.json
Normal file
15
io/ping/locales/de/88-ping.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"ping": {
|
||||
"ping": "ping",
|
||||
"label": {
|
||||
"target": "Ziel",
|
||||
"ping": "Ping (S)",
|
||||
"mode": "Modus",
|
||||
"mode_option": {
|
||||
"timed": "Zeitgesteuert",
|
||||
"triggered": "Getriggert"
|
||||
},
|
||||
"tip": "Hinweis: Ziel-Eintrag leer lassen, damit über msg.payload der Hosts dynamisch gesetzt werden kann"
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,19 @@
|
||||
<p>Returns <b>false</b> if no response received, or if the host is unresolveable.</p>
|
||||
<p>Default ping is every 20 seconds but can be configured.</p>
|
||||
|
||||
<h4>Protocol...</h4>
|
||||
<ul>
|
||||
<li><b>Automatic</b><br>
|
||||
<P>Will use any Protocol, IPv4 or IPv6, to reach host; based on your operating system network settings</P>
|
||||
</li>
|
||||
<li><b>IPv4</b><br>
|
||||
<P>Forces use of IPv4 to reach host. Will fail if no route availibe</P>
|
||||
</li>
|
||||
<li><b>IPv6</b><br>
|
||||
<P>Forces use of IPv6 to reach host. Will fail if no route availibe</P>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Mode...</h4>
|
||||
<ul>
|
||||
<li><b>Timed</b><br>
|
||||
|
@ -9,6 +9,12 @@
|
||||
"timed": "Timed",
|
||||
"triggered": "Triggered"
|
||||
},
|
||||
"protocol": "Protocol",
|
||||
"protocol_option": {
|
||||
"auto": "Automatic",
|
||||
"ipv4": "IPv4",
|
||||
"ipv6": "IPv6"
|
||||
},
|
||||
"tip": "Note: Leave Target field blank to allow msg.payload to set hosts dynamically."
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,19 @@
|
||||
<p>ホスト名が解決できなかったり、レスポンスが得られなければ、<b>false</b>を返します。</p>
|
||||
<p>デフォルトでは20秒ごとにpingを送りますが、設定で変更できます。</p>
|
||||
|
||||
<h4>Protocol...</h4>
|
||||
<ul>
|
||||
<li><b>Automatic</b><br>
|
||||
<P>Will use any Protocol, IPv4 or IPv6, to reach host; based on your operating system network settings</P>
|
||||
</li>
|
||||
<li><b>IPv4</b><br>
|
||||
<P>Forces use of IPv4 to reach host. Will fail if no route availibe</P>
|
||||
</li>
|
||||
<li><b>IPv6</b><br>
|
||||
<P>Forces use of IPv6 to reach host. Will fail if no route availibe</P>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>モード...</h4>
|
||||
<ul>
|
||||
<li><b>時間</b><br>
|
||||
@ -25,7 +38,7 @@
|
||||
<li><b>トリガー</b><br>
|
||||
<p><code>トリガー</code>モードでは、入力ワイヤを結線し、<code>msg</code>入力によってping処理を起動します。
|
||||
<p><code>ターゲット</code>フィールドに入力した値はホスト名もしくはIPアドレスとして使用します。 ターゲットはホスト名/IPアドレスをカンマで区切ったものです。例: <code>"192.168.0.1"</code> あるいは <code>"192.168.0.1, www.google.com"</code></p>
|
||||
|
||||
|
||||
<p><code>ターゲット</code>を空にした場合、カンマ区切り文字列、もしくは、ホストの配列を<code>msg.payload</code>に指定します。
|
||||
<ul>
|
||||
<li><code>文字列</code> - カンマ区切りのホスト名/IPアドレス 例: <code>"192.168.0.1"</code> あるいは <code>"192.168.0.1, www.google.com"</code> </li>
|
||||
@ -33,12 +46,12 @@
|
||||
<li>配列ペイロードの例: <pre>[
|
||||
"192.168.0.99",
|
||||
{
|
||||
"host":"192.168.0.1",
|
||||
"host":"192.168.0.1",
|
||||
"name":"ルータ"
|
||||
},
|
||||
},
|
||||
{
|
||||
"host":"myapiserver.com",
|
||||
"name":"拡張API",
|
||||
"host":"myapiserver.com",
|
||||
"name":"拡張API",
|
||||
"timeout": 20000,
|
||||
"support":"support@myapiserver.com"
|
||||
}
|
||||
|
@ -9,6 +9,12 @@
|
||||
"timed": "時間",
|
||||
"triggered": "トリガー"
|
||||
},
|
||||
"protocol": "プロトコル",
|
||||
"protocol_option": {
|
||||
"auto": "自動の",
|
||||
"ipv4": "IPv4",
|
||||
"ipv6": "IPv6"
|
||||
},
|
||||
"tip": "注: msg.payloadでホスト名を動的に指定する場合は、ターゲットフィールドを空にします。"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red-node-ping",
|
||||
"version" : "0.2.2",
|
||||
"version" : "0.3.1",
|
||||
"description" : "A Node-RED node to ping a remote server, for use as a keep-alive check.",
|
||||
"dependencies" : {
|
||||
},
|
||||
|
@ -10,17 +10,6 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="serial in">
|
||||
<p>Reads data from a local serial port.</p>
|
||||
<p>Can either <ul><li>wait for a "split" character (default \n). Also accepts hex notation (0x0d).</li>
|
||||
<li>Wait for a timeout in milliseconds from the first character received</li>
|
||||
<li>Wait to fill a fixed sized buffer</li></ul></p>
|
||||
<p>It then outputs <code>msg.payload</code> as either a UTF8 ascii string or a binary Buffer object.</p>
|
||||
<p><code>msg.port</code> is set to the name of the port selected.</p>
|
||||
<p>If no split character is specified, or a timeout or buffer size of 0, then a stream of single characters
|
||||
is sent - again either as ascii chars or size 1 binary buffers.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('serial in',{
|
||||
category: 'network',
|
||||
@ -54,14 +43,6 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="serial out">
|
||||
<p>Provides a connection to an outbound serial port.</p>
|
||||
<p>Only the <code>msg.payload</code> is sent.</p>
|
||||
<p>Optionally the baudrate can be changed using <code>msg.baudrate</code></p>
|
||||
<p>Optionally the new line character used to split the input can be appended to every message sent out to the serial port.</p>
|
||||
<p>Binary payloads can be sent by using a Buffer object.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('serial out',{
|
||||
category: 'network',
|
||||
@ -95,33 +76,6 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="serial request">
|
||||
<p>Provides a connection to a request/response serial port.</p>
|
||||
<p>This node behaves as a tightly coupled combination of <code>serial in</code> and <code>serial out</code> nodes,
|
||||
with which it shares the configuration.</p>
|
||||
<p>Send the request message in <code>msg.payload</code> as you would do with a <code>serial out</code> node.
|
||||
The message will be forwarded to the serial port following a strict FIFO (First In, First Out) queue, waiting for a single response before transmitting the next request.
|
||||
Once a response is received (with the same logic of a <code>serial in</code> node), or after a timeout occurs, a message is sent to the output (see Outputs below),
|
||||
with <code>msg.payload</code> containing the received response (or missing in case if timeout) and all other fields preserved.</p>
|
||||
<p>For consistency with the <code>serial in</code> node, <code>msg.port</code> is set to the name of the port selected.</p>
|
||||
<h3>Inputs</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<code>msg.timeout</code> is the timeout (in ms) after which the incoming message is propagated to the output with <code>msg.status</code> set to <code>"ERR_TIMEOUT"</code> and missing payload.
|
||||
If not present, the default value is 10000 (10s).
|
||||
</li>
|
||||
<li><code>msg.count</code> if set this will override the configured number of characters as long as it is less than the number configured.</li>
|
||||
<li><code>msg.waitfor</code> single character, escape code, or hex code. If set, the node will wait until it matches that character in the stream and then start the output.</li>
|
||||
<li>Optionally the baudrate can be changed using <code>msg.baudrate</code></li>
|
||||
</ul>
|
||||
<h3>Outputs</h3>
|
||||
<ul>
|
||||
<li><code>msg.payload</code> is the response. If no response occured, this field is removed.</li>
|
||||
<li><code>msg.status</code> is <code>"OK"</code> in case a response is received, or <code>"ERR_TIMEOUT"</code> if a timeout occurs.</li>
|
||||
<li>Any other field coming from the input will be preserved.</li>
|
||||
</ul>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('serial request',{
|
||||
category: 'network',
|
||||
@ -272,16 +226,6 @@
|
||||
<div class="form-tips" id="tip-count" hidden><span data-i18n="serial.tip.count"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="serial-port">
|
||||
<p>Provides configuration options for a serial port.</p>
|
||||
<p>The search button should return a list of available serial ports to choose from, or you
|
||||
can type in the location if known.</p>
|
||||
<p>The DTR, RTS, CTS and DSR switches can be used to permanently pull the corresponding flow control pin high or low, e.g. in order to power devices via those pins.</p>
|
||||
<p>The node can optionally wait until it matches a pre-defined character.
|
||||
The data can then be split on a fixed character, after a timeout, or after a fixed number of characters.</p>
|
||||
<p>If using a character, it can be specified as either the character, the escaped shortcut (e.g. \n), or the hex code (e.g. 0x0d).</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('serial-port',{
|
||||
category: 'config',
|
||||
|
@ -72,7 +72,7 @@ module.exports = function(RED) {
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.error(RED._("serial.errors.missing-conf"));
|
||||
this.error(RED._("serial.errors.missing-conf"), {});
|
||||
}
|
||||
|
||||
this.on("close", function(done) {
|
||||
@ -109,7 +109,7 @@ module.exports = function(RED) {
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.error(RED._("serial.errors.missing-conf"));
|
||||
this.error(RED._("serial.errors.missing-conf"), {});
|
||||
}
|
||||
|
||||
this.on("close", function(done) {
|
||||
@ -186,7 +186,7 @@ module.exports = function(RED) {
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.error(RED._("serial.errors.missing-conf"));
|
||||
this.error(RED._("serial.errors.missing-conf"), {});
|
||||
}
|
||||
|
||||
this.on("close", function(done) {
|
||||
@ -347,7 +347,7 @@ module.exports = function(RED) {
|
||||
if (err) {
|
||||
if (err.toString() !== olderr) {
|
||||
olderr = err.toString();
|
||||
RED.log.error(RED._("serial.errors.error",{port:port,error:olderr}));
|
||||
RED.log.error(RED._("serial.errors.error",{port:port,error:olderr}), {});
|
||||
}
|
||||
obj.tout = setTimeout(function() {
|
||||
setupSerial();
|
||||
@ -355,7 +355,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
});
|
||||
obj.serial.on('error', function(err) {
|
||||
RED.log.error(RED._("serial.errors.error",{port:port,error:err.toString()}));
|
||||
RED.log.error(RED._("serial.errors.error",{port:port,error:err.toString()}), {});
|
||||
obj._emitter.emit('closed');
|
||||
if (obj.tout) { clearTimeout(obj.tout); }
|
||||
obj.tout = setTimeout(function() {
|
||||
@ -366,7 +366,7 @@ module.exports = function(RED) {
|
||||
if (!obj._closing) {
|
||||
if (olderr !== "unexpected") {
|
||||
olderr = "unexpected";
|
||||
RED.log.error(RED._("serial.errors.unexpected-close",{port:port}));
|
||||
RED.log.error(RED._("serial.errors.unexpected-close",{port:port}), {});
|
||||
}
|
||||
obj._emitter.emit('closed');
|
||||
if (obj.tout) { clearTimeout(obj.tout); }
|
||||
@ -472,7 +472,7 @@ module.exports = function(RED) {
|
||||
connections[port]._closing = true;
|
||||
try {
|
||||
connections[port].close(function() {
|
||||
RED.log.info(RED._("serial.errors.closed",{port:port}));
|
||||
RED.log.info(RED._("serial.errors.closed",{port:port}), {});
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
73
io/serialport/locales/de/25-serial.json
Normal file
73
io/serialport/locales/de/25-serial.json
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
"serial": {
|
||||
"status": {
|
||||
"waiting": "Wartend",
|
||||
"timeout": "Zeitablauf"
|
||||
},
|
||||
"label": {
|
||||
"serialport": "Serieller Port",
|
||||
"settings": "Einstellungen",
|
||||
"baudrate": "Baudrate",
|
||||
"databits": "Datenbits",
|
||||
"parity": "Parität",
|
||||
"stopbits": "Stoppbits",
|
||||
"input": "Empfang",
|
||||
"split": "Aufteilung",
|
||||
"deliver": "und Ausgabe",
|
||||
"output": "Versand",
|
||||
"request": "Anforderung",
|
||||
"responsetimeout": "Standardwert Antwort-Zeitablauf",
|
||||
"ms": "ms",
|
||||
"serial": "seriell",
|
||||
"none": "none",
|
||||
"start": "Optional Warten auf das Startzeichen",
|
||||
"startor": ", dann"
|
||||
},
|
||||
"placeholder": {
|
||||
"serialport": "z. B. /dev/ttyUSB0/"
|
||||
},
|
||||
"parity": {
|
||||
"none": "Keine",
|
||||
"even": "Gerade",
|
||||
"mark": "Mark",
|
||||
"odd": "Ungerade",
|
||||
"space": "Space"
|
||||
},
|
||||
"linestates": {
|
||||
"none": "Auto",
|
||||
"high": "High",
|
||||
"low": "Low"
|
||||
},
|
||||
"split": {
|
||||
"character": "anhand Zeichen",
|
||||
"timeout": "nach Zeitablauf von",
|
||||
"silent": "nach Ruhezeit von",
|
||||
"lengths": "in feste Längen von"
|
||||
},
|
||||
"output": {
|
||||
"ascii": "als ASCII-Strings",
|
||||
"binary": "binäre Buffer"
|
||||
},
|
||||
"addsplit": "Zeichen zu Ausgangsnachrichten hinzufügen",
|
||||
"tip": {
|
||||
"responsetimeout": "Tipp: Der Standardwert des Antwort-Zeitablaufs (default response timeout) kann durch Setzen von msg.timeout überschrieben werden",
|
||||
"split": "Tipp: Das Aufteilungszeichen wird benutzt, um die empfangenen Daten in einzelne Nachrichten aufzuteilen. Es werden Zeichen ($), Escape-Codes (\\n) oder Hex-Codes (0x03) akzeptiert.",
|
||||
"silent": "Tipp: Im Ruhezeit-Modus wird die Ruhezeitmessung bei jedem neu empfangenen Zeichen neu gestartet",
|
||||
"timeout": "Tipp: Im Zeitablauf-Modus startet die Zeitmessung mit Empfang des ersten Zeichens",
|
||||
"count": "Tipp: Im Modus der festen Längen kann msg.count die vorgegebene Anzahl überschreiben, sofern dieser Wert kleiner ist",
|
||||
"waitfor": "Tipp: Optional. Leer lassen, um alle Daten zu empfangen. Es werden Zeichen ($), Escape-Codes (\\n) oder Hex-Codes (0x03) akzeptiert." ,
|
||||
"addchar": "Tipp: Dieses Zeichen wird jeder über den seriellen Port gesendeten Nachricht hinzugefügt. Üblicherweise \\r oder \\n."
|
||||
},
|
||||
"onopen": "Seriellen Port __port__ geöffnet mit __baud__ Baud, __config__",
|
||||
"errors": {
|
||||
"missing-conf": "Fehlende serielle Konfiguration",
|
||||
"serial-port": "Serieller Port",
|
||||
"error": "Serieller Port __port__ Fehler: __error__",
|
||||
"unexpected-close": "Serieller Port __port__ unerwartet geschlossen",
|
||||
"disconnected": "Serieller Port __port__ getrennt",
|
||||
"closed": "Serieller Port __port__ geschlossen",
|
||||
"list": "Port-Auflistung fehlgeschlagen. Bitte manuell eintragen.",
|
||||
"badbaudrate": "Ungültige Baudrate"
|
||||
}
|
||||
}
|
||||
}
|
56
io/serialport/locales/en-US/25-serial.html
Normal file
56
io/serialport/locales/en-US/25-serial.html
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
<script type="text/html" data-help-name="serial in">
|
||||
<p>Reads data from a local serial port.</p>
|
||||
<p>Can either <ul><li>wait for a "split" character (default \n). Also accepts hex notation (0x0d).</li>
|
||||
<li>Wait for a timeout in milliseconds from the first character received</li>
|
||||
<li>Wait to fill a fixed sized buffer</li></ul></p>
|
||||
<p>It then outputs <code>msg.payload</code> as either a UTF8 ascii string or a binary Buffer object.</p>
|
||||
<p><code>msg.port</code> is set to the name of the port selected.</p>
|
||||
<p>If no split character is specified, or a timeout or buffer size of 0, then a stream of single characters
|
||||
is sent - again either as ascii chars or size 1 binary buffers.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="serial out">
|
||||
<p>Provides a connection to an outbound serial port.</p>
|
||||
<p>Only the <code>msg.payload</code> is sent.</p>
|
||||
<p>Optionally the baudrate can be changed using <code>msg.baudrate</code></p>
|
||||
<p>Optionally the new line character used to split the input can be appended to every message sent out to the serial port.</p>
|
||||
<p>Binary payloads can be sent by using a Buffer object.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="serial request">
|
||||
<p>Provides a connection to a request/response serial port.</p>
|
||||
<p>This node behaves as a tightly coupled combination of <code>serial in</code> and <code>serial out</code> nodes,
|
||||
with which it shares the configuration.</p>
|
||||
<p>Send the request message in <code>msg.payload</code> as you would do with a <code>serial out</code> node.
|
||||
The message will be forwarded to the serial port following a strict FIFO (First In, First Out) queue, waiting for a single response before transmitting the next request.
|
||||
Once a response is received (with the same logic of a <code>serial in</code> node), or after a timeout occurs, a message is sent to the output (see Outputs below),
|
||||
with <code>msg.payload</code> containing the received response (or missing in case if timeout) and all other fields preserved.</p>
|
||||
<p>For consistency with the <code>serial in</code> node, <code>msg.port</code> is set to the name of the port selected.</p>
|
||||
<h3>Inputs</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<code>msg.timeout</code> is the timeout (in ms) after which the incoming message is propagated to the output with <code>msg.status</code> set to <code>"ERR_TIMEOUT"</code> and missing payload.
|
||||
If not present, the default value is 10000 (10s).
|
||||
</li>
|
||||
<li><code>msg.count</code> if set this will override the configured number of characters as long as it is less than the number configured.</li>
|
||||
<li><code>msg.waitfor</code> single character, escape code, or hex code. If set, the node will wait until it matches that character in the stream and then start the output.</li>
|
||||
<li>Optionally the baudrate can be changed using <code>msg.baudrate</code></li>
|
||||
</ul>
|
||||
<h3>Outputs</h3>
|
||||
<ul>
|
||||
<li><code>msg.payload</code> is the response. If no response occured, this field is removed.</li>
|
||||
<li><code>msg.status</code> is <code>"OK"</code> in case a response is received, or <code>"ERR_TIMEOUT"</code> if a timeout occurs.</li>
|
||||
<li>Any other field coming from the input will be preserved.</li>
|
||||
</ul>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="serial-port">
|
||||
<p>Provides configuration options for a serial port.</p>
|
||||
<p>The search button should return a list of available serial ports to choose from, or you
|
||||
can type in the location if known.</p>
|
||||
<p>The DTR, RTS, CTS and DSR switches can be used to permanently pull the corresponding flow control pin high or low, e.g. in order to power devices via those pins.</p>
|
||||
<p>The node can optionally wait until it matches a pre-defined character.
|
||||
The data can then be split on a fixed character, after a timeout, or after a fixed number of characters.</p>
|
||||
<p>If using a character, it can be specified as either the character, the escaped shortcut (e.g. \n), or the hex code (e.g. 0x0d).</p>
|
||||
</script>
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name" : "node-red-node-serialport",
|
||||
"version" : "0.11.1",
|
||||
"version" : "0.13.0",
|
||||
"description" : "Node-RED nodes to talk to serial ports",
|
||||
"dependencies" : {
|
||||
"serialport" : "^9.0.2"
|
||||
"serialport" : "^9.0.7"
|
||||
},
|
||||
"repository" : {
|
||||
"type":"git",
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="stomp in">
|
||||
<script type="text/html" data-template-name="stomp in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-server" style="width: 110px;"><i class="fa fa-bookmark"></i> Server</label>
|
||||
<input type="text" id="node-input-server">
|
||||
@ -14,7 +14,7 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="stomp in">
|
||||
<script type="text/html" data-help-name="stomp in">
|
||||
<p>Connects to a server using the Stomp protocol to receive messages.</p>
|
||||
<p>If the message received is JSON <code>msg.payload</code> will be parsed into an
|
||||
object. If not it will be the raw data.</p>
|
||||
@ -47,7 +47,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="stomp out">
|
||||
<script type="text/html" data-template-name="stomp out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-server" style="width: 110px;"><i class="fa fa-bookmark"></i> Server</label>
|
||||
<input type="text" id="node-input-server">
|
||||
@ -64,7 +64,7 @@
|
||||
property of the message.</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="stomp out">
|
||||
<script type="text/html" data-help-name="stomp out">
|
||||
<p>Connects to an Stomp capable server to send messages.</p>
|
||||
<p>The <b>Destination</b> field is optional. If set it overrides the <code>msg.topic</code>
|
||||
property of the message.</p>
|
||||
@ -99,7 +99,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="stomp-server">
|
||||
<script type="text/html" data-template-name="stomp-server">
|
||||
<div class="form-row node-input-server">
|
||||
<label for="node-config-input-server"><i class="fa fa-bookmark"></i> Server</label>
|
||||
<input class="input-append-left" type="text" id="node-config-input-server" placeholder="localhost" style="width: 45%;" >
|
||||
|
24
parsers/base64/locales/de/70-base64.json
Normal file
24
parsers/base64/locales/de/70-base64.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"base64": {
|
||||
"base64": "base64",
|
||||
"label": {
|
||||
"action": "Aktion"
|
||||
},
|
||||
"convert": {
|
||||
"buffer": "Konvertierung Buffer <-> Base64",
|
||||
"encode": "Kodierung als Base64",
|
||||
"decode": "Konvertierung Base64 zu String"
|
||||
},
|
||||
"log": {
|
||||
"nonbase64encode": "Kein Base64-String - möglicherweise soll es kodiert werden..."
|
||||
},
|
||||
"warn": {
|
||||
"cannothandle": "Dieser Node kann nur Strings oder Buffer verarbeiten",
|
||||
"noproperty": "Keine Eigenschaft zur Verarbeitung gefunden"
|
||||
},
|
||||
"error": {
|
||||
"invalid": "Ungültiger Base64-String",
|
||||
"nonbase64": "Kein Base64-String"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red-node-base64",
|
||||
"version" : "0.2.1",
|
||||
"version" : "0.3.0",
|
||||
"description" : "A Node-RED node to pack and unpack objects to base64 format",
|
||||
"dependencies" : {
|
||||
},
|
||||
|
@ -126,6 +126,14 @@
|
||||
<label for="node-input-useSSL"><i class="fa fa-lock"></i> <span data-i18n="email.label.useSSL"></span></label>
|
||||
<input type="checkbox" id="node-input-useSSL" style="width: auto;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-autotls"><i class="fa fa-lock"></i> <span data-i18n="email.label.autotls"></label>
|
||||
<select type="text" id="node-input-autotls" style="width: 150px;">
|
||||
<option value="never" data-i18n="email.label.never"></option>
|
||||
<option value="required" data-i18n="email.label.required"></option>
|
||||
<option value="always" data-i18n="email.label.always"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-server"><i class="fa fa-globe"></i> <span data-i18n="email.label.server"></span></label>
|
||||
<input type="text" id="node-input-server" placeholder="imap.gmail.com">
|
||||
@ -202,10 +210,12 @@
|
||||
$("#node-input-protocol").change(function() {
|
||||
var protocol = $("#node-input-protocol").val();
|
||||
if (protocol === "IMAP") {
|
||||
$(".node-input-autotls").show();
|
||||
$(".node-input-box").show();
|
||||
$(".node-input-disposition").show();
|
||||
$(".node-input-criteria").show();
|
||||
} else {
|
||||
$(".node-input-autotls").hide();
|
||||
$(".node-input-box").hide();
|
||||
$(".node-input-disposition").hide();
|
||||
$(".node-input-criteria").hide();
|
||||
@ -225,6 +235,7 @@
|
||||
protocol: {value: "IMAP", required:true}, // Which protocol to use to connect to the mail server ("IMAP" or "POP3")
|
||||
server: {value:"imap.gmail.com",required:true},
|
||||
useSSL: {value: true},
|
||||
autotls: {value: "never"},
|
||||
port: {value:"993",required:true},
|
||||
box: {value:"INBOX"}, // For IMAP, The mailbox to process
|
||||
disposition: { value: "Read" }, // For IMAP, the disposition of the read email
|
||||
@ -265,6 +276,10 @@
|
||||
$("#node-input-criteria").val("UNSEEN");
|
||||
this.criteria = "UNSEEN";
|
||||
}
|
||||
if (typeof this.autotls === 'undefined') {
|
||||
$("#node-input-autotls").val("never");
|
||||
this.autotls = "never";
|
||||
}
|
||||
if ($("#node-input-fetch").val() === null) { $("#node-input-fetch").val("auto"); }
|
||||
$("#node-input-fetch").change(function() {
|
||||
if ($("#node-input-fetch").val() === "trigger") {
|
||||
|
@ -119,9 +119,16 @@ module.exports = function(RED) {
|
||||
else {
|
||||
var payload = RED.util.ensureString(msg.payload);
|
||||
sendopts.text = payload; // plaintext body
|
||||
if (/<[a-z][\s\S]*>/i.test(payload)) { sendopts.html = payload; } // html body
|
||||
if (msg.attachments && Array.isArray(msg.attachments)) {
|
||||
sendopts.attachments = msg.attachments;
|
||||
if (/<[a-z][\s\S]*>/i.test(payload)) {
|
||||
sendopts.html = payload; // html body
|
||||
if (msg.hasOwnProperty("plaintext")) {
|
||||
var plaintext = RED.util.ensureString(msg.plaintext);
|
||||
sendopts.text = plaintext; // plaintext body - specific plaintext version
|
||||
}
|
||||
}
|
||||
if (msg.attachments) {
|
||||
if (!Array.isArray(msg.attachments)) { sendopts.attachments = [ msg.attachments ]; }
|
||||
else { sendopts.attachments = msg.attachments; }
|
||||
for (var a=0; a < sendopts.attachments.length; a++) {
|
||||
if (sendopts.attachments[a].hasOwnProperty("content")) {
|
||||
if (typeof sendopts.attachments[a].content !== "string" && !Buffer.isBuffer(sendopts.attachments[a].content)) {
|
||||
@ -182,6 +189,7 @@ module.exports = function(RED) {
|
||||
this.inport = n.port || (globalkeys && globalkeys.port) || "993";
|
||||
this.box = n.box || "INBOX";
|
||||
this.useSSL= n.useSSL;
|
||||
this.autotls= n.autotls;
|
||||
this.protocol = n.protocol || "IMAP";
|
||||
this.disposition = n.disposition || "None"; // "None", "Delete", "Read"
|
||||
this.criteria = n.criteria || "UNSEEN"; // "ALL", "ANSWERED", "FLAGGED", "SEEN", "UNANSWERED", "UNFLAGGED", "UNSEEN"
|
||||
@ -484,6 +492,7 @@ module.exports = function(RED) {
|
||||
host: node.inserver,
|
||||
port: node.inport,
|
||||
tls: node.useSSL,
|
||||
autotls: node.autotls,
|
||||
tlsOptions: { rejectUnauthorized: false },
|
||||
connTimeout: tout,
|
||||
authTimeout: tout
|
||||
@ -506,7 +515,11 @@ module.exports = function(RED) {
|
||||
if (this.interval_id != null) {
|
||||
clearTimeout(this.interval_id);
|
||||
}
|
||||
if (imap) { imap.destroy(); }
|
||||
if (imap) {
|
||||
imap.end();
|
||||
setTimeout(function() { imap.destroy(); },1000);
|
||||
node.status({});
|
||||
}
|
||||
});
|
||||
|
||||
function setInputRepeatTimeout() {
|
||||
|
@ -3,7 +3,6 @@ node-red-node-email
|
||||
|
||||
<a href="http://nodered.org" target="info">Node-RED</a> nodes to send and receive simple emails.
|
||||
|
||||
|
||||
Pre-requisite
|
||||
-------------
|
||||
|
||||
@ -12,13 +11,10 @@ getting an application password if you have two-factor authentication enabled.
|
||||
|
||||
**Note :** Version 1.x of this node requires **Node.js v8** or newer.
|
||||
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
Version 0.x of this node is usually installed by default by Node-RED.
|
||||
As long as you have at least version 0.19.x of Node-RED you can install the new version
|
||||
by using the `Menu - Manage Palette` option, or running the following command in your
|
||||
You can install by using the `Menu - Manage Palette` option, or running the following command in your
|
||||
Node-RED user directory - typically `~/.node-red`
|
||||
|
||||
cd ~/.node-red
|
||||
@ -35,9 +31,9 @@ Usage
|
||||
|
||||
Nodes to send and receive simple emails.
|
||||
|
||||
### Input
|
||||
### Input node
|
||||
|
||||
Repeatedly gets emails from an IMAP or POP3 server and forwards them onwards as messages if not already seen.
|
||||
Fetches emails from an IMAP or POP3 server and forwards them onwards as messages if not already seen.
|
||||
|
||||
The subject is loaded into `msg.topic` and `msg.payload` is the plain text body.
|
||||
If there is text/html then that is returned in `msg.html`. `msg.from` and
|
||||
@ -46,24 +42,19 @@ If there is text/html then that is returned in `msg.html`. `msg.from` and
|
||||
Additionally `msg.header` contains the complete header object including
|
||||
**to**, **cc** and other potentially useful properties.
|
||||
|
||||
**Note:** this node *only* gets the most recent single email from the inbox,
|
||||
so set the repeat (polling) time appropriately.
|
||||
|
||||
Uses the *imap* npm module.
|
||||
|
||||
### Output
|
||||
### Output node
|
||||
|
||||
Sends the `msg.payload` as an email, with a subject of `msg.topic`.
|
||||
|
||||
The default message recipient can be configured in the node, if it is left
|
||||
blank it should be set using the `msg.to` property of the incoming message.
|
||||
|
||||
The email *from* can be set using `msg.from` but not all mail services allow
|
||||
this unless `msg.from` is also a valid userid or email address associated with
|
||||
the password. Note: if `userid` or msg.from does not contain a valid email
|
||||
address (userxx@some_domain.com), you may see (No Sender) in the email.
|
||||
The email *from* can be set using `msg.from` but not all mail services allow
|
||||
this unless `msg.from` is also a valid userid or email address associated with
|
||||
the password. Note: if `userid` or msg.from does not contain a valid email
|
||||
address (userxx@some_domain.com), you may see *(No Sender)* in the email.
|
||||
|
||||
The payload can be html format.
|
||||
The payload can be html format. You can also specify `msg.plaintext` if the main payload is html.
|
||||
|
||||
If the payload is a binary buffer then it will be converted to an attachment.
|
||||
|
||||
|
70
social/email/locales/de/61-email.html
Normal file
70
social/email/locales/de/61-email.html
Normal file
@ -0,0 +1,70 @@
|
||||
<script type="text/html" data-help-name="e-mail">
|
||||
<p>Versand von <code>msg.payload</code> als E-Mail mit <code>msg.topic</code> als Subjekt.</p>
|
||||
<p>Der Standard-Nachrichtenempfänger kann im Node vorgegeben werden.
|
||||
Wenn nicht angegeben, muss der Nachrichtenempfänger über die <code>msg.to</code>-Eigenschaft
|
||||
der eingehenden Nachricht übergeben werden.
|
||||
Ebenso können einige oder alle vorgegeben werden von: <code>msg.cc</code>, <code>msg.bcc</code>, <code>msg.replyTo</code>,
|
||||
<code>msg.inReplyTo</code>, <code>msg.references</code>, <code>msg.headers</code> oder <code>msg.priority</code>-Eigenschaften.</p>
|
||||
<p>Es kann optional auch <code>msg.from</code> in den Nutzdaten (Payload) vorgegeben werden,
|
||||
was die eingestellte <code>Benutzer-ID</code> überschreiben würde.</p>
|
||||
<h3>Gmail-Benutzer</h3>
|
||||
<p>Beim Zugriff auf Gmail kann es nötig sein, entweder <a target="_new" href="https://support.google.com/mail/answer/185833?hl=de">ein App-Passwort</a> zu aktivieren oder den <a target="_new" href="https://support.google.com/accounts/answer/6010255?hl=de">Zugriff aufs Google-Konto durch weniger sichere Apps</a> über die Google-Konto-Einstellungen zu erlauben.</p>
|
||||
<h3>Details</h3>
|
||||
<p>Die Nachricht in <code>msg.payload</code> kann als HTML formatiert sein.
|
||||
Ein separater, davon abweichender Plaintext kann in <code>msg.plaintext</code> angegeben werden. Ansonsten wird auch <code>msg.payload</code> verwendet.
|
||||
<code>msg.plaintext</code> wird ignoriert, wenn <code>msg.payload</code> kein HTML enthält.</p>
|
||||
<p>Wenn <code>msg.payload</code> ein binärer Buffer ist, so wird sie in einen Nachrichten-Dateianhang (attachment) konvertiert.
|
||||
Der Dateiname sollte mittels <code>msg.filename</code> angegeben werden.
|
||||
Optional kann <code>msg.description</code> als Nachrichtentext hinzugefügt werden.</p>
|
||||
<p>Alternativ kann auch <code>msg.attachments</code> übergeben werden, welches ein Datenfeld (array) mit einen oder mehreren
|
||||
Dateianhängen im <a href="https://nodemailer.com/message/attachments/" target="_new">nodemailer</a>-Format enthält.</p>
|
||||
<p>Falls vom Empfänger benötigt, kann zusätzlich über <code>msg.envelope</code> ein Objekt übergeben werden, welches typischerweise zusätzliche <code>from</code>- und <code>to</code>-Eigenschaften enthält.</p>
|
||||
<p>Wenn ein selbstausgestelltes Zertifikates vorliegt, kann sich Nodemailer darüber beschweren und das Senden der Nachricht ablehnen.
|
||||
In diesem Fall kann versucht werden TLS abzuschalten.</p>
|
||||
<p><b>Hinweis</b>: Verwendet SMTP mit SSL über Port 465.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="e-mail in">
|
||||
<p>Regelmäßiger Abruf von E-Mails von einem POP3- oder IMAP-Server und Weiterleitung der Nachricht, falls diese noch nicht angezeigt wurde.</p>
|
||||
<p>Der Subjekttext wird in <code>msg.topic</code> und der Klartextinhalt in <code>msg.payload</code> abgelegt.
|
||||
Wenn text/html vorliegt, dann wird dieser in <code>msg.html</code> abgelegt.
|
||||
<code>msg.from</code> und <code>msg.date</code> sind ebenfalls für die weitere Nutzung gesetzt.</p>
|
||||
<p>Zusätzlich enthält <code>msg.header</code> den kompletten Mailkopf (Header) als Objekt mit
|
||||
<i>to</i>, <i>cc</i> und anderen eventuell nützlichen Eigenschaften.</p>
|
||||
<p>Der Node kann optional die Nachricht als gelesen markieren (Standard-Einstellung), sie löschen oder sie als unmarkiert belassen.</p>
|
||||
<p>Verwendet wird das <a href="https://github.com/mscdex/node-imap/blob/master/README.md" target="_new">node-imap-Modul</a> -
|
||||
siehe dort für Informationen über das <code>msg.criteria</code>-Format, falls benötigt.</p>
|
||||
<p>Alle Dateianhänge mitgeliefert in eingehenden E-Mails können in der <code>msg.attachments</code>-Eigenschaft gefunden werden.
|
||||
Es wird dann ein Datenfeld (Array) von Objekten übergeben, wo jedes Objekt ein einzelner Dateianhang (attachment) darstellt.
|
||||
Das Objektformat ist:</p>
|
||||
<pre>
|
||||
{
|
||||
contentType: // Die MIME-Inhaltsbeschreibung (MIME content description)
|
||||
fileName: // Ein vorgeschlagener Dateiname, der diesem Anhang zugeordnet ist
|
||||
transferEncoding: // Wie wurde der ursprüngliche E-Mail-Anhang verschlüsselt?
|
||||
contentDisposition: // Unbekannt
|
||||
generatedFileName: // Ein vorgeschlagener Dateiname, der diesem Anhang zugeordnet ist
|
||||
contentId: // Eine eindeutige generierte ID für diesen Anhang
|
||||
checksum: // Eine Prüfsumme gegen die Daten
|
||||
length: // Datengröße in Bytes
|
||||
content: // Der tatsächliche Inhalt der in einem Node.js-Pufferobjekt enthaltenen Daten
|
||||
// Wir können dies in eine base64-Datenzeichenfolge mit content.toString('base64') umwandeln
|
||||
}
|
||||
</pre>
|
||||
<p><b>Hinweis</b>: Bei POP3 sind die Standard-Portnummern 110 für ungesichertes TCP und 995 für SSL. Bei IMAP 143 für ungesichertes TCP und 993 für SSL.</p>
|
||||
<p><b>Hinweis</b>: Mit der Option 'STARTTLS' kann eine bestehende ungesicherte Verbindung zu einer gesicherten geupgraded werden. Die Einstellung 'immer' versucht dies immer, 'wenn erforderlich' wenn es erforderlich ist, und 'nie' gar nicht.</p>
|
||||
<p><b>Hinweis</b>: Das maximale Aktualisierungsintervall ist 2147483 Sekunden (24,8 Tage).</p>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="e-mail mta">
|
||||
<p>Mail Transfer Agent - Portüberwachung für eingehende SMTP-Mails.</p>
|
||||
<p><b>Hinweis</b>: "NICHT für Produktivbetrieb", da keine Sicherheitsfunktionen eingebaut sind!
|
||||
Dies dient hauptsächlich zum lokalen Testen des Versands ausgehender E-Mails,
|
||||
kann jedoch bei Bedarf verwendet werden als Mail-Weiterleitung an einen echten E-Mail-Dienst.</p>
|
||||
<p>Um Ports unter 1024 (z.B. 25 or 465) zu benutzen, könnten höhere Zugriffsrechte nötig sein.
|
||||
Auf Linux-Systemen kann dieses erreicht werden durch Starten von
|
||||
<pre>sudo setcap 'cap_net_bind_service=+eip' $(which node)</pre>
|
||||
und Neustart von Node-RED.
|
||||
Es ist zu beachten, dass dadurch alle Knotenanwendungen auf alle Ports zugreifen können.</p>
|
||||
</script>
|
71
social/email/locales/de/61-email.json
Normal file
71
social/email/locales/de/61-email.json
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"email": {
|
||||
"email": "email",
|
||||
"label": {
|
||||
"getmail":"Mailempfang",
|
||||
"auto": "automatisch",
|
||||
"trigger": "wenn getriggert",
|
||||
"to": "An",
|
||||
"server": "Server",
|
||||
"port": "Port",
|
||||
"useSecureConnection": "Sichere Verbindung verwenden",
|
||||
"userid": "Benutzer-ID",
|
||||
"password": "Passwort",
|
||||
"repeat": "alle",
|
||||
"seconds": "Sekunden",
|
||||
"folder": "Verzeichnis",
|
||||
"protocol": "Protokoll",
|
||||
"useSSL": "SSL",
|
||||
"useTLS": "TLS",
|
||||
"disposition": "Behandlung",
|
||||
"none": "Keine",
|
||||
"read": "Gelesen markieren",
|
||||
"delete": "Löschen",
|
||||
"criteria": "Kriterium",
|
||||
"criteriaFromMsg": "Gesetzt durch msg.criteria",
|
||||
"all": "Alle",
|
||||
"answered": "Beantwortet",
|
||||
"flagged": "Markiert",
|
||||
"seen": "Gesichtet",
|
||||
"unanswered": "Unbeantwortet",
|
||||
"unflagged": "Unmarkiert",
|
||||
"unseen": "Ungesehen",
|
||||
"autotls": "STARTTLS?",
|
||||
"never": "nie",
|
||||
"required": "wenn erforderlich",
|
||||
"always": "immer"
|
||||
},
|
||||
"default-message": "__description__\n\nDatei von Node-RED ist angehängt: __filename__",
|
||||
"tip": {
|
||||
"cred": "<b>Hinweis</b>: Berechtigungen von globaler emailkeys.js-Datei kopiert",
|
||||
"recent": "Tipp: Es wird nur die letzte E-Mail abgerufen",
|
||||
"mta": "<b>Hinweis</b>: Um Ports unter 1024 zu verwenden könnten höhere (root) Rechte benötigt werden. Siehe Hilfe-Seitenleiste."
|
||||
},
|
||||
"status": {
|
||||
"messagesent": "Nachricht gesendet: __response__",
|
||||
"fetching": "Rufe ab",
|
||||
"foldererror": "Fehler bei Verzeichnisabruf",
|
||||
"messageerror": "Fehler bei Nachrichtenabruf",
|
||||
"message": "Nachricht #__number__",
|
||||
"newemail": "Neue E-Mail empfangen: __topic__",
|
||||
"duplicate": "Duplikat nicht gesendet: __topic__",
|
||||
"inboxzero": "Posteingang leer",
|
||||
"sending": "Sende",
|
||||
"sendfail": "Senden fehlgeschlagen",
|
||||
"parseerror": "Analyse der Nachricht fehlgeschlagen",
|
||||
"connecterror": "Verbindungsfehler"
|
||||
},
|
||||
"errors": {
|
||||
"nouserid": "Kein E-Mail-Benutzer-ID angegeben",
|
||||
"nopassword": "Kein E-Mail-Passwort angegeben",
|
||||
"nocredentials": "Keine E-Mail-Berechtigungen gefunden. Siehe Info-Anzeige.",
|
||||
"nosmtptransport": "Kein SMTP-Transport. Siehe Info-Anzeige.",
|
||||
"nopayload": "Keine sendbaren Nutzdaten (Payload)",
|
||||
"fetchfail": "Verzeichnisabruf fehlgeschlagen: __folder__",
|
||||
"parsefail": "Analyse der Nachricht fehlgeschlagen",
|
||||
"messageerror": "Nachrichtenabruf fehlgeschlagen: __error__",
|
||||
"refreshtoolarge": "Abrufintervall ist zu groß. Max. Limit sind 2147483 Sekunden.",
|
||||
"invalidattachment": "Ungültiger Anhang-Inhalt. Es muss ein String oder ein Buffer sein."
|
||||
}
|
||||
}
|
||||
}
|
@ -6,22 +6,24 @@
|
||||
<code>msg.inReplyTo</code>, <code>msg.references</code>, <code>msg.headers</code>, or <code>msg.priority</code> properties.</p>
|
||||
<p>You may optionally set <code>msg.from</code> in the payload which will override the <code>userid</code>
|
||||
default value.</p>
|
||||
<h3>GMail users</h3>
|
||||
<p>If you are accessing GMail you may need to either enable <a target="_new" href="https://support.google.com/mail/answer/185833?hl=en">an application password</a>,
|
||||
<h3>Gmail users</h3>
|
||||
<p>If you are accessing Gmail you may need to either enable <a target="_new" href="https://support.google.com/mail/answer/185833?hl=en">an application password</a>,
|
||||
or enable <a target="_new" href="https://support.google.com/accounts/answer/6010255?hl=en">less secure access</a> via your Google account settings.</p>
|
||||
<h3>Details</h3>
|
||||
<p>The payload can be html format.</p>
|
||||
<p>The payload can be html format. You may supply a separate plaintext version using <code>msg.plaintext</code>.
|
||||
If you don't and <code>msg.payload</code> contains html, it will also be used for the plaintext.
|
||||
<code>msg.plaintext</code> will be ignored if <code>msg.payload</code> doesn't contain html.</p>
|
||||
<p>If the payload is a binary buffer then it will be converted to an attachment.
|
||||
The filename should be set using <code>msg.filename</code>. Optionally <code>msg.description</code> can be added for the body text.</p>
|
||||
<p>Alternatively you may provide <code>msg.attachments</code> which should contain an array of one or
|
||||
more attachments in <a href="https://nodemailer.com/message/attachments/" target="_new">nodemailer</a> format.</p>
|
||||
<p>If required by your recipient you may also pass in a <code>msg.envelope</code> object, typically containing extra from and to properties.</p>
|
||||
<p>If you have own signed certificates, Nodemailer can complain about that and refuse sending the message. In this case you can try switching off TLS.</p>
|
||||
<p>Note: uses SMTP with SSL to port 465.</p>
|
||||
<p><b>Note</b>: uses SMTP with SSL to port 465.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="e-mail in">
|
||||
<p>Repeatedly gets emails from an IMAP server and forwards on as a msg if not already seen.</p>
|
||||
<p>Repeatedly gets emails from a POP3 or IMAP server and forwards on as a msg if not already seen.</p>
|
||||
<p>The subject is loaded into <code>msg.topic</code> and <code>msg.payload</code> is the plain text body.
|
||||
If there is text/html then that is returned in <code>msg.html</code>. <code>msg.from</code> and <code>msg.date</code> are also set if you need them.</p>
|
||||
<p>Additionally <code>msg.header</code> contains the complete header object including
|
||||
@ -29,10 +31,8 @@
|
||||
<p>It can optionally mark the message as Read (default), Delete it, or leave unmarked (None).</p>
|
||||
<p>Uses the <a href="https://github.com/mscdex/node-imap/blob/master/README.md" target="_new">node-imap module</a> - see that page for
|
||||
information on the <code>msg.criteria</code> format if needed.</p>
|
||||
<p><b>Note</b>: uses IMAP with SSL to port 993.</p>
|
||||
<p>Any attachments supplied in the incoming email can be found in the <code>msg.attachments</code> property. This will be an array of objects where
|
||||
each object represents a specific attachments. The format of the object is:</p>
|
||||
|
||||
<pre>
|
||||
{
|
||||
contentType: // The MIME content description
|
||||
@ -47,13 +47,14 @@
|
||||
// We can turn this into a base64 data string with content.toString('base64')
|
||||
}
|
||||
</pre>
|
||||
<p>For POP3, the default port numbers are 110 for plain TCP and 995 for SSL. For IMAP the port numbers are 143 for plain TCP and 993 for SSL.</p>
|
||||
<p>The maximum refresh interval is 2147483 seconds (24.8 days).</p>
|
||||
<p><b>Note</b>: For POP3, the default port numbers are 110 for plain TCP and 995 for SSL. For IMAP the port numbers are 143 for plain TCP and 993 for SSL.</p>
|
||||
<p><b>Note</b>: With option 'STARTTLS' an established plain connection is upgraded to an encrypted one. Set to 'always' to always attempt connection upgrades via STARTTLS, 'required' only if upgrading is required, or 'never' to never attempt upgrading.</p>
|
||||
<p><b>Note</b>: The maximum refresh interval is 2147483 seconds (24.8 days).</p>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="e-mail mta">
|
||||
<p>Mail Transfer Agent - listens on a port for incoming SMTP mail.</p>
|
||||
<p>Mail Transfer Agent - listens on a port for incoming SMTP mails.</p>
|
||||
<p><b>Note</b>: "NOT for production use" as there is no security built in.
|
||||
This is primarily for local testing of outbound mail sending, but could be used
|
||||
as a mail forwarder to a real email service if required.</p>
|
||||
|
@ -29,7 +29,11 @@
|
||||
"seen": "Seen",
|
||||
"unanswered": "Unanswered",
|
||||
"unflagged": "Unflagged",
|
||||
"unseen": "Unseen"
|
||||
"unseen": "Unseen",
|
||||
"autotls": "Start TLS?",
|
||||
"never": "never",
|
||||
"required": "if required",
|
||||
"always": "always"
|
||||
},
|
||||
"default-message": "__description__\n\nFile from Node-RED is attached: __filename__",
|
||||
"tip": {
|
||||
|
@ -16,7 +16,11 @@
|
||||
"none": "なし",
|
||||
"read": "既読",
|
||||
"delete": "削除",
|
||||
"criteriaFromMsg": "- msg.criteriaから使用 -"
|
||||
"criteriaFromMsg": "- msg.criteriaから使用 -",
|
||||
"autotls": "TLSを開始?",
|
||||
"never": "なし",
|
||||
"always": "常時",
|
||||
"required": "必要な場合"
|
||||
},
|
||||
"default-message": "__description__\n\nNode-REDからファイルが添付されました: __filename__",
|
||||
"tip": {
|
||||
|
@ -1,14 +1,21 @@
|
||||
{
|
||||
"name": "node-red-node-email",
|
||||
"version": "1.8.3",
|
||||
"version": "1.12.0",
|
||||
"description": "Node-RED nodes to send and receive simple emails.",
|
||||
"dependencies": {
|
||||
"imap": "^0.8.19",
|
||||
"poplib": "^0.1.7",
|
||||
"mailparser": "^3.0.1",
|
||||
"nodemailer": "~6.4.17",
|
||||
"mailparser": "^3.2.0",
|
||||
"nodemailer": "~6.5.0",
|
||||
"smtp-server": "^3.8.0"
|
||||
},
|
||||
"bundledDependencies": [
|
||||
"imap",
|
||||
"poplib",
|
||||
"mailparser",
|
||||
"nodemailer",
|
||||
"smtp-server"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/node-red/node-red-nodes/tree/master/social/email"
|
||||
|
@ -1,4 +1,4 @@
|
||||
<script type="text/x-red" data-template-name="feedparse">
|
||||
<script type="text/html" data-template-name="feedparse">
|
||||
<div class="form-row">
|
||||
<label for="node-input-url"><i class="fa fa-globe"></i> <span data-i18n="feedparse.label.feedurl"></span></label>
|
||||
<input type="text" id="node-input-url">
|
||||
|
15
social/feedparser/locales/de/32-feedparse.html
Normal file
15
social/feedparser/locales/de/32-feedparse.html
Normal file
@ -0,0 +1,15 @@
|
||||
<script type="text/html" data-help-name="feedparse">
|
||||
<p>Überwacht einen RSS/atom-Feed auf neue Einträge.</p>
|
||||
<h3>Outputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>topic <span class="property-type">string</span></dt>
|
||||
<dd>Der originale Artikel-Link</dd>
|
||||
<dt>payload <span class="property-type">string</span></dt>
|
||||
<dd>Beschreibung</dd>
|
||||
<dt>article <span class="property-type">object</span></dt>
|
||||
<dd>Komplettes Artikel-Objekt</dd>
|
||||
</dl>
|
||||
<p>Die <code>msg.article</code>-Eigenschaft enthält das komplette Artikel-Objekt,
|
||||
welches Eigenschaften wie <code>.title</code>, <code>.summary</code>, <code>.date</code> usw. enthält.</p>
|
||||
<p>Das Aktualisierungsintervall kann nicht größer als 35790 Minuten sein (ca. 24,8 Tage).
|
||||
</script>
|
15
social/feedparser/locales/de/32-feedparse.json
Normal file
15
social/feedparser/locales/de/32-feedparse.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"feedparse": {
|
||||
"feedparse": "feedparser",
|
||||
"label": {
|
||||
"feedurl": "Feed-URL",
|
||||
"refresh": "Aktualisierung",
|
||||
"minutes": "Minuten"
|
||||
},
|
||||
"errors": {
|
||||
"badstatuscode": "Fehler - Fehlerhafter Statuscode",
|
||||
"invalidurl": "Ungültige URL",
|
||||
"invalidinterval": "Aktualisierungsintervall zu groß"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,15 @@
|
||||
<script type="text/html" data-help-name="feedparse">
|
||||
<p>Monitors an RSS/atom feed for new entries.</p>
|
||||
<p>The <code>msg.topic</code> contains the original article link. The <code>msg.payload</code>
|
||||
contains the description, and <code>msg.article</code> contains the complete article object,
|
||||
which has properties such as <code>.title</code>, <code>.summary</code>, <code>.date</code> and so on.</p>
|
||||
<p>The Refresh interval cannot be greater than 35790 minutes (approx 24.8 days).
|
||||
<h3>Outputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>topic <span class="property-type">string</span></dt>
|
||||
<dd>Original article link</dd>
|
||||
<dt>payload <span class="property-type">string</span></dt>
|
||||
<dd>Description</dd>
|
||||
<dt>article <span class="property-type">object</span></dt>
|
||||
<dd>Complete article object</dd>
|
||||
</dl>
|
||||
<p>The <code>msg.article</code> property contains the complete article object,
|
||||
which has properties such as <code>.title</code>, <code>.summary</code>, <code>.date</code> and so on.</p>
|
||||
<p>The refresh interval cannot be greater than 35790 minutes (approx 24.8 days).
|
||||
</script>
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "node-red-node-feedparser",
|
||||
"version": "0.1.16",
|
||||
"version": "0.2.1",
|
||||
"description": "A Node-RED node to get RSS Atom feeds.",
|
||||
"dependencies": {
|
||||
"feedparser": "^2.2.10",
|
||||
"request": "^2.88.0"
|
||||
"request": "^2.88.2"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="irc in">
|
||||
<script type="text/html" data-template-name="irc in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-ircserver"><i class="fa fa-globe"></i> <span data-i18n="irc.label.ircserver"></span></label>
|
||||
<input type="text" id="node-input-ircserver">
|
||||
@ -15,64 +15,6 @@
|
||||
<div class="form-tips"><span data-i18n="[html]irc.tip.in"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="irc in">
|
||||
<p>Connects to a channel on an IRC server.</p>
|
||||
<p>You may join multiple channels by comma separating a list - #chan1,#chan2,#etc.</p>
|
||||
<p>Any messages on that channel will appear on the <code>msg.payload</code> at the output,
|
||||
while <code>msg.topic</code> will contain who it is from.
|
||||
<code>msg.to</code> contains either the name of the channel or PRIV in the case of a pm.</p>
|
||||
<p>The second output provides a <code>msg.payload</code> that has any status messages such as joins, parts, kicks etc.</p>
|
||||
<p>The type of the status message is set as <code>msg.payload.type</code>.</p>
|
||||
<p>The possible status types are: <br />
|
||||
<table border="1" cellpadding="1" cellspacing="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Type</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>message</td>
|
||||
<td>message is sent into the channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pm</td>
|
||||
<td>private message to the bot</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>join</td>
|
||||
<td>a user joined the channel (also triggered when the bot joins a channel)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>invite</td>
|
||||
<td>the bot is being invited to a channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>part</td>
|
||||
<td>a user leaves a channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>quit</td>
|
||||
<td>a user quits a channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>kick</td>
|
||||
<td>a user is kicked from a channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>topic</td>
|
||||
<td>a topic has been changed on a joined channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>names</td>
|
||||
<td>retrieves the list of users when the bot joins a channel</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('irc in',{
|
||||
category: 'social-input',
|
||||
@ -107,8 +49,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/x-red" data-template-name="irc out">
|
||||
<script type="text/html" data-template-name="irc out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-ircserver"><i class="fa fa-globe"></i> <span data-i18n="irc.label.ircserver"></span></label>
|
||||
<input type="text" id="node-input-ircserver">
|
||||
@ -132,15 +73,6 @@
|
||||
<div class="form-tips"><span data-i18n="[html]irc.tip.out"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="irc out">
|
||||
<p>Sends messages to a channel on an IRC server</p>
|
||||
<p>You can send just the <code>msg.payload</code>, or the complete <code>msg</code> object to the selected channel,
|
||||
or you can select to use <code>msg.topic</code> to send the <code>msg.payload</code> to a specific user (private message) or channel.</p>
|
||||
<p>If multiple output channels are listed (eg. #chan1,#chan2), then the message will be sent to all of them.</p>
|
||||
<p><b>Note:</b> you can only send to channels you have previously joined so they MUST be specified in the node - even if you then decide to use a subset in msg.topic</p>
|
||||
<p>You may send RAW commands using <code>msg.raw</code> - This must contain an array of parameters - eg. <pre>["privmsg","#nodered","Hello world"]</pre></p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('irc out',{
|
||||
category: 'social-output',
|
||||
@ -171,8 +103,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/x-red" data-template-name="irc-server">
|
||||
<script type="text/html" data-template-name="irc-server">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-server"><i class="fa fa-globe"></i> <span data-i18n="irc.label.ircserver"></span></label>
|
||||
<input type="text" id="node-config-input-server" placeholder="irc.freenode.net" style="width: 45%;" >
|
||||
|
44
social/irc/locales/de/91-irc.json
Normal file
44
social/irc/locales/de/91-irc.json
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"irc": {
|
||||
"label": {
|
||||
"ircserver": "IRC-Server",
|
||||
"channel": "Kanal",
|
||||
"action": "Aktion",
|
||||
"port": "Port",
|
||||
"ssl": "Sichere SSL-Verbindung",
|
||||
"self": "Selbstausgestellte Zertifikate erlauben",
|
||||
"nickname": "Nickname",
|
||||
"username": "Benutzername",
|
||||
"password": "Passwort"
|
||||
},
|
||||
"placeholder": {
|
||||
"ifreq": "wenn vom Server benötigt"
|
||||
},
|
||||
"payload": "Sende Nutzdaten (Payload) an Kanäle",
|
||||
"topic": "Benutze msg.topic um Nicknamen oder Kanäle vorzugeben",
|
||||
"msg": "Sende komplettes msg-Objekt an Kanäle",
|
||||
"tip": {
|
||||
"in": "Der beizutretende Kanal muss mit einer # (Raute) beginnen.<br/>Bei mehreren Kanälen müssen diese mit Kommas getrennt angegeben werden. Z. B. #chan1,#chan2,etc.",
|
||||
"out": "Der beizutretende Kanal muss mit einer # (Raute) beginnen.<br/>Beim Senden eines kompletten Objekt wird es zuvor in Strings umgewandelt."
|
||||
},
|
||||
"errors": {
|
||||
"connect": "Verbinde",
|
||||
"err": "Fehler",
|
||||
"net": "NET",
|
||||
"connected": "Verbunden",
|
||||
"online": "Online",
|
||||
"joined": "Beigetreten",
|
||||
"ping": "Ping von",
|
||||
"quit": "Quit",
|
||||
"restart": "Neustart",
|
||||
"connectionlost": "Verbindung verloren?",
|
||||
"hasjoined": "ist beigetreten",
|
||||
"sentinvite": "Sende Einladung an",
|
||||
"hasleft": "ist ausgetreten",
|
||||
"hasquit": "hat beendet (quit)",
|
||||
"kickedfrom": "wurde gekickt von",
|
||||
"rawcommand": "Rohbefehl",
|
||||
"topicnotset": "msg.topic nicht gesetzt"
|
||||
}
|
||||
}
|
||||
}
|
67
social/irc/locales/en-US/91-irc.html
Normal file
67
social/irc/locales/en-US/91-irc.html
Normal file
@ -0,0 +1,67 @@
|
||||
|
||||
<script type="text/x-red" data-help-name="irc in">
|
||||
<p>Connects to a channel on an IRC server.</p>
|
||||
<p>You may join multiple channels by comma separating a list - #chan1,#chan2,#etc.</p>
|
||||
<p>Any messages on that channel will appear on the <code>msg.payload</code> at the output,
|
||||
while <code>msg.topic</code> will contain who it is from.
|
||||
<code>msg.to</code> contains either the name of the channel or PRIV in the case of a pm.</p>
|
||||
<p>The second output provides a <code>msg.payload</code> that has any status messages such as joins, parts, kicks etc.</p>
|
||||
<p>The type of the status message is set as <code>msg.payload.type</code>.</p>
|
||||
<p>The possible status types are: <br />
|
||||
<table border="1" cellpadding="1" cellspacing="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Type</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>message</td>
|
||||
<td>message is sent into the channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>pm</td>
|
||||
<td>private message to the bot</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>join</td>
|
||||
<td>a user joined the channel (also triggered when the bot joins a channel)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>invite</td>
|
||||
<td>the bot is being invited to a channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>part</td>
|
||||
<td>a user leaves a channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>quit</td>
|
||||
<td>a user quits a channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>kick</td>
|
||||
<td>a user is kicked from a channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>topic</td>
|
||||
<td>a topic has been changed on a joined channel</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>names</td>
|
||||
<td>retrieves the list of users when the bot joins a channel</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="irc out">
|
||||
<p>Sends messages to a channel on an IRC server</p>
|
||||
<p>You can send just the <code>msg.payload</code>, or the complete <code>msg</code> object to the selected channel,
|
||||
or you can select to use <code>msg.topic</code> to send the <code>msg.payload</code> to a specific user (private message) or channel.</p>
|
||||
<p>If multiple output channels are listed (eg. #chan1,#chan2), then the message will be sent to all of them.</p>
|
||||
<p><b>Note:</b> you can only send to channels you have previously joined so they MUST be specified in the node - even if you then decide to use a subset in msg.topic</p>
|
||||
<p>You may send RAW commands using <code>msg.raw</code> - This must contain an array of parameters - eg. <pre>["privmsg","#nodered","Hello world"]</pre></p>
|
||||
</script>
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name" : "node-red-node-irc",
|
||||
"version" : "0.0.8",
|
||||
"version" : "0.1.0",
|
||||
"description" : "A Node-RED node to talk to an IRC server",
|
||||
"dependencies" : {
|
||||
"irc" : "~0.4.0"
|
||||
"irc" : "^0.5.2"
|
||||
},
|
||||
"repository" : {
|
||||
"type":"git",
|
||||
|
@ -10,13 +10,6 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="nnotify">
|
||||
<p>Uses node-notifier to provide a desktop popup containing the <code>msg.payload</code>. Only useful on the local machine.</p>
|
||||
<p>Optionally uses <code>msg.topic</code> as the title, and <code>msg.icon</code> as the full path to an icon file to display.</p>
|
||||
<p>Uses node-notifier so should work cross platform but may need to intall pre-reqs... see <i><a href="https://www.npmjs.com/package/node-notifier" target="_new">this link.</a></i></p>
|
||||
<p>If installing on Windows you MUST read the install instructions... or it WILL NOT work.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('nnotify',{
|
||||
category: 'output',
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user