1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Merge branch 'master' of git://github.com/node-red/node-red into multipart_stream

This commit is contained in:
bartbutenaers 2017-04-04 22:05:22 +02:00
commit 53c1fb6e57
14 changed files with 1996 additions and 4074 deletions

View File

@ -110,6 +110,7 @@
'$append':{ args:['array','array'] }, '$append':{ args:['array','array'] },
'$average':{ args:['value'] }, '$average':{ args:['value'] },
'$boolean':{ args:['value'] }, '$boolean':{ args:['value'] },
'$contains':{ args:['str','pattern']},
'$count':{ args:['array'] }, '$count':{ args:['array'] },
'$exists':{ args:['value'] }, '$exists':{ args:['value'] },
'$join':{ args:['array','separator'] }, '$join':{ args:['array','separator'] },
@ -117,12 +118,14 @@
'$length':{ args:['string'] }, '$length':{ args:['string'] },
'$lookup':{ args:['object','key'] }, '$lookup':{ args:['object','key'] },
'$lowercase':{ args:['string'] }, '$lowercase':{ args:['string'] },
'$match':{ args:['str','pattern','limit']},
'$map':{ args:[] }, '$map':{ args:[] },
'$max':{ args:['array'] }, '$max':{ args:['array'] },
'$min':{ args:['array'] }, '$min':{ args:['array'] },
'$not':{ args:['value'] }, '$not':{ args:['value'] },
'$number':{ args:['value'] }, '$number':{ args:['value'] },
'$reduce':{ args:[] }, '$reduce':{ args:[] },
'$replace':{ args:['str','pattern','replacement','limit']},
'$split':{ args:['string','separator','limit'] }, '$split':{ args:['string','separator','limit'] },
'$spread':{ args:['object'] }, '$spread':{ args:['object'] },
'$string':{ args:['value'] }, '$string':{ args:['value'] },
@ -130,6 +133,7 @@
'$substringAfter':{ args:['string','chars'] }, '$substringAfter':{ args:['string','chars'] },
'$substringBefore':{ args:['string','chars'] }, '$substringBefore':{ args:['string','chars'] },
'$sum':{ args:['array'] }, '$sum':{ args:['array'] },
'$trim': { args:['str'] },
'$uppercase':{ args:['string'] } '$uppercase':{ args:['string'] }
} }
jsonata.getFunctionSnippet = function(fn) { jsonata.getFunctionSnippet = function(fn) {

View File

@ -1,11 +1,11 @@
define("ace/snippets/jsonata",["require","exports","module"], function(require, exports, module) { define("ace/snippets/jsonata",["require","exports","module"], function(require, exports, module) {
"use strict"; "use strict";
var snippetText = ""; var snippetText = "";
for (var fn in jsonata.functions) { for (var fn in jsonata.functions) {
if (jsonata.functions.hasOwnProperty(fn)) { if (jsonata.functions.hasOwnProperty(fn)) {
snippetText += "# "+fn+"\nsnippet "+fn+"\n\t"+jsonata.getFunctionSnippet(fn)+"\n" snippetText += "# "+fn+"\nsnippet "+fn+"\n\t"+jsonata.getFunctionSnippet(fn)+"\n"
} }
} }
exports.snippetText = snippetText; exports.snippetText = snippetText;
exports.scope = "jsonata"; exports.scope = "jsonata";
}); });

File diff suppressed because one or more lines are too long

View File

@ -193,6 +193,10 @@
</select> </select>
</div> </div>
<br/> <br/>
<div class="form-row" id="node-set-freq">
<label for="node-input-freq"> <span data-i18n="rpi-gpio.label.freq"></span></label>
<input type="text" id="node-input-freq" placeholder="100">
</div>
<div class="form-row"> <div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
@ -210,6 +214,7 @@
<p>When using PWM mode - expects an input value of a number 0 - 100. It can be floating point.</p> <p>When using PWM mode - expects an input value of a number 0 - 100. It can be floating point.</p>
<p>PWM mode can be used to drive a servo using input values between 10 and 20 only. <p>PWM mode can be used to drive a servo using input values between 10 and 20 only.
The GPIO2 pin is best for this as it uses hardware to do the PWM.</p> The GPIO2 pin is best for this as it uses hardware to do the PWM.</p>
<p>Setting high PWM frequency might occupy more CPU than expected (default is 100Hz)</p>
<p>Requires the RPi.GPIO python library version 0.5.10 (or better) in order to work.</p> <p>Requires the RPi.GPIO python library version 0.5.10 (or better) in order to work.</p>
<p><b>Note:</b> we are using the actual physical pin numbers on connector P1 as they are easier to locate.</p> <p><b>Note:</b> we are using the actual physical pin numbers on connector P1 as they are easier to locate.</p>
</script> </script>
@ -224,6 +229,7 @@
pin: { value:"",required:true,validate:RED.validators.number() }, pin: { value:"",required:true,validate:RED.validators.number() },
set: { value:"" }, set: { value:"" },
level: { value:"0" }, level: { value:"0" },
freq: {value:""},
out: { value:"out" } out: { value:"out" }
}, },
inputs:1, inputs:1,
@ -297,11 +303,13 @@
$('#node-input-set').prop('checked', false); $('#node-input-set').prop('checked', false);
$("#dig-tip").hide(); $("#dig-tip").hide();
$("#pwm-tip").show(); $("#pwm-tip").show();
$('#node-set-freq').show();
} }
else { else {
$('#node-set-tick').show(); $('#node-set-tick').show();
$("#dig-tip").show(); $("#dig-tip").show();
$("#pwm-tip").hide(); $("#pwm-tip").hide();
$('#node-set-freq').hide();
} }
}; };
$("#node-input-out").change(function () { hidestate(); }); $("#node-input-out").change(function () { hidestate(); });

View File

@ -137,6 +137,7 @@ module.exports = function(RED) {
this.pin = n.pin; this.pin = n.pin;
this.set = n.set || false; this.set = n.set || false;
this.level = n.level || 0; this.level = n.level || 0;
this.freq = n.freq || 100;
this.out = n.out || "out"; this.out = n.out || "out";
var node = this; var node = this;
if (!pinsInUse.hasOwnProperty(this.pin)) { if (!pinsInUse.hasOwnProperty(this.pin)) {
@ -173,7 +174,7 @@ module.exports = function(RED) {
node.child = spawn(gpioCommand, [node.out,node.pin,node.level]); node.child = spawn(gpioCommand, [node.out,node.pin,node.level]);
node.status({fill:"green",shape:"dot",text:node.level}); node.status({fill:"green",shape:"dot",text:node.level});
} else { } else {
node.child = spawn(gpioCommand, [node.out,node.pin]); node.child = spawn(gpioCommand, [node.out,node.pin,node.freq]);
node.status({fill:"green",shape:"dot",text:"common.status.ok"}); node.status({fill:"green",shape:"dot",text:"common.status.ok"});
} }
node.running = true; node.running = true;

View File

@ -35,8 +35,13 @@ if len(sys.argv) > 2:
if cmd == "pwm": if cmd == "pwm":
#print "Initialised pin "+str(pin)+" to PWM" #print "Initialised pin "+str(pin)+" to PWM"
try:
freq = int(sys.argv[3])
except:
freq = 100
GPIO.setup(pin,GPIO.OUT) GPIO.setup(pin,GPIO.OUT)
p = GPIO.PWM(pin, 100) p = GPIO.PWM(pin, freq)
p.start(0) p.start(0)
while True: while True:

View File

@ -35,7 +35,7 @@
</script> </script>
<script type="text/x-red" data-help-name="mqtt in"> <script type="text/x-red" data-help-name="mqtt in">
<p>Connects to a broker and subscribes to the specified topic.</p> <p>Connects to a MQTT broker and subscribes to the specified topic.</p>
<p>Outputs a message with the properties:</p> <p>Outputs a message with the properties:</p>
<ul> <ul>
<li><code>msg.topic</code></li> <li><code>msg.topic</code></li>
@ -107,6 +107,7 @@
<p>Connects to a MQTT broker and publishes messages.</p> <p>Connects to a MQTT broker and publishes messages.</p>
<p><code>msg.payload</code> is used as the payload of the published message. <p><code>msg.payload</code> is used as the payload of the published message.
If it contains an Object it will be converted to JSON before being sent. If it contains an Object it will be converted to JSON before being sent.
If it contains a binary Buffer the message will be published as-is.
</p> </p>
<p>The topic used can be configured in the node or, if left blank, can be set <p>The topic used can be configured in the node or, if left blank, can be set
by <code>msg.topic</code>.</p> by <code>msg.topic</code>.</p>
@ -147,9 +148,9 @@
<div id="mqtt-broker-tab-connection" style="display:none"> <div id="mqtt-broker-tab-connection" style="display:none">
<div class="form-row node-input-broker"> <div class="form-row node-input-broker">
<label for="node-config-input-broker"><i class="fa fa-globe"></i> <span data-i18n="mqtt.label.broker"></span></label> <label for="node-config-input-broker"><i class="fa fa-globe"></i> <span data-i18n="mqtt.label.broker"></span></label>
<input class="input-append-left" type="text" id="node-config-input-broker" placeholder="e.g. localhost" style="width: 40%;" > <input class="input-append-left" type="text" id="node-config-input-broker" placeholder="e.g. localhost" style="width:40%;" >
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> <span data-i18n="mqtt.label.port"></span></label> <label for="node-config-input-port" style="margin-left:20px; width:35px; "> <span data-i18n="mqtt.label.port"></span></label>
<input type="text" id="node-config-input-port" data-i18n="[placeholder]mqtt.label.port" style="width:45px"> <input type="text" id="node-config-input-port" data-i18n="[placeholder]mqtt.label.port" style="width:55px">
</div> </div>
<div class="form-row"> <div class="form-row">
<input type="checkbox" id="node-config-input-usetls" style="display: inline-block; width: auto; vertical-align: top;"> <input type="checkbox" id="node-config-input-usetls" style="display: inline-block; width: auto; vertical-align: top;">
@ -299,7 +300,7 @@
id: "mqtt-broker-tab-will", id: "mqtt-broker-tab-will",
label: this._("mqtt.tabs-label.will") label: this._("mqtt.tabs-label.will")
}); });
setTimeout(function() { tabs.resize()},0); setTimeout(function() { tabs.resize(); },0);
if (typeof this.cleansession === 'undefined') { if (typeof this.cleansession === 'undefined') {
this.cleansession = true; this.cleansession = true;
$("#node-config-input-cleansession").prop("checked",true); $("#node-config-input-cleansession").prop("checked",true);

View File

@ -66,16 +66,16 @@ module.exports = function(RED) {
// If the config node is missing certain options (it was probably deployed prior to an update to the node code), // If the config node is missing certain options (it was probably deployed prior to an update to the node code),
// select/generate sensible options for the new fields // select/generate sensible options for the new fields
if (typeof this.usetls === 'undefined'){ if (typeof this.usetls === 'undefined') {
this.usetls = false; this.usetls = false;
} }
if (typeof this.compatmode === 'undefined'){ if (typeof this.compatmode === 'undefined') {
this.compatmode = true; this.compatmode = true;
} }
if (typeof this.verifyservercert === 'undefined'){ if (typeof this.verifyservercert === 'undefined') {
this.verifyservercert = false; this.verifyservercert = false;
} }
if (typeof this.keepalive === 'undefined'){ if (typeof this.keepalive === 'undefined') {
this.keepalive = 60; this.keepalive = 60;
} else if (typeof this.keepalive === 'string') { } else if (typeof this.keepalive === 'string') {
this.keepalive = Number(this.keepalive); this.keepalive = Number(this.keepalive);
@ -110,7 +110,7 @@ module.exports = function(RED) {
this.options.keepalive = this.keepalive; this.options.keepalive = this.keepalive;
this.options.clean = this.cleansession; this.options.clean = this.cleansession;
this.options.reconnectPeriod = RED.settings.mqttReconnectTime||5000; this.options.reconnectPeriod = RED.settings.mqttReconnectTime||5000;
if (this.compatmode == "true" || this.compatmode === true){ if (this.compatmode == "true" || this.compatmode === true) {
this.options.protocolId = 'MQIsdp'; this.options.protocolId = 'MQIsdp';
this.options.protocolVersion = 3; this.options.protocolVersion = 3;
} }
@ -140,14 +140,14 @@ module.exports = function(RED) {
var node = this; var node = this;
this.users = {}; this.users = {};
this.register = function(mqttNode){ this.register = function(mqttNode) {
node.users[mqttNode.id] = mqttNode; node.users[mqttNode.id] = mqttNode;
if (Object.keys(node.users).length === 1) { if (Object.keys(node.users).length === 1) {
node.connect(); node.connect();
} }
}; };
this.deregister = function(mqttNode,done){ this.deregister = function(mqttNode,done) {
delete node.users[mqttNode.id]; delete node.users[mqttNode.id];
if (node.closing) { if (node.closing) {
return done(); return done();
@ -266,7 +266,7 @@ module.exports = function(RED) {
} }
if (Object.keys(sub).length === 0) { if (Object.keys(sub).length === 0) {
delete node.subscriptions[topic]; delete node.subscriptions[topic];
if (node.connected){ if (node.connected) {
node.client.unsubscribe(topic); node.client.unsubscribe(topic);
} }
} }
@ -287,7 +287,7 @@ module.exports = function(RED) {
qos: msg.qos || 0, qos: msg.qos || 0,
retain: msg.retain || false retain: msg.retain || false
}; };
node.client.publish(msg.topic, msg.payload, options, function (err){return}); node.client.publish(msg.topic, msg.payload, options, function(err) {return});
} }
}; };
@ -298,7 +298,7 @@ module.exports = function(RED) {
done(); done();
}); });
this.client.end(); this.client.end();
} else if (this.connecting) { } else if (this.connecting || node.client.reconnecting) {
node.client.end(); node.client.end();
done(); done();
} else { } else {

View File

@ -649,7 +649,8 @@
"pikeyboard": "Pi Keyboard", "pikeyboard": "Pi Keyboard",
"left": "Left", "left": "Left",
"right": "Right", "right": "Right",
"middle": "Middle" "middle": "Middle",
"freq": "Frequency (Hz)"
}, },
"resistor": { "resistor": {
"none": "none", "none": "none",
@ -671,7 +672,7 @@
"pin": "<b>Pins in Use</b>: ", "pin": "<b>Pins in Use</b>: ",
"in": "Tip: Only Digital Input is supported - input must be 0 or 1.", "in": "Tip: Only Digital Input is supported - input must be 0 or 1.",
"dig": "Tip: For digital output - input must be 0 or 1.", "dig": "Tip: For digital output - input must be 0 or 1.",
"pwm": "Tip: For PWM output - input must be between 0 to 100." "pwm": "Tip: For PWM output - input must be between 0 to 100; setting high frequency might occupy more CPU than expected."
}, },
"types": { "types": {
"digout": "digital output", "digout": "digital output",

View File

@ -35,14 +35,14 @@
"cors":"2.8.1", "cors":"2.8.1",
"cron":"1.2.1", "cron":"1.2.1",
"express": "4.14.0", "express": "4.14.0",
"follow-redirects":"1.2.1", "follow-redirects":"1.2.2",
"fs-extra": "1.0.0", "fs-extra": "1.0.0",
"fs.notify":"0.0.4", "fs.notify":"0.0.4",
"i18next":"1.10.6", "i18next":"1.10.6",
"is-utf8":"0.2.1", "is-utf8":"0.2.1",
"js-yaml": "3.7.0", "js-yaml": "3.7.0",
"json-stringify-safe":"5.0.1", "json-stringify-safe":"5.0.1",
"jsonata":"1.0.10", "jsonata":"1.1.1",
"media-typer": "0.3.0", "media-typer": "0.3.0",
"mqtt": "2.2.1", "mqtt": "2.2.1",
"mustache": "2.3.0", "mustache": "2.3.0",

View File

@ -16,30 +16,12 @@
var fs = require('fs'); var fs = require('fs');
var path = require('path'); var path = require('path');
var i18n; var i18n;
var supportedLangs = [];
var apiLocalDir = path.resolve(path.join(__dirname,"locales"));
var initSupportedLangs = function() {
fs.readdir(apiLocalDir, function(err,files) {
if(!err) {
supportedLangs = files;
}
});
}
function determineLangFromHeaders(acceptedLanguages){ function determineLangFromHeaders(acceptedLanguages){
var lang = i18n.defaultLang; var lang = i18n.defaultLang;
acceptedLanguages = acceptedLanguages || []; acceptedLanguages = acceptedLanguages || [];
for (var i=0;i<acceptedLanguages.length;i++){ if (acceptedLanguages.length >= 1) {
if (supportedLangs.indexOf(acceptedLanguages[i]) !== -1){ lang = acceptedLanguages[0];
lang = acceptedLanguages[i];
break;
// check the language without the country code
} else if (supportedLangs.indexOf(acceptedLanguages[i].split("-")[0]) !== -1) {
lang = acceptedLanguages[i].split("-")[0];
break;
}
} }
return lang; return lang;
} }
@ -47,7 +29,6 @@ function determineLangFromHeaders(acceptedLanguages){
module.exports = { module.exports = {
init: function(runtime) { init: function(runtime) {
i18n = runtime.i18n; i18n = runtime.i18n;
initSupportedLangs();
}, },
get: function(req,res) { get: function(req,res) {
var namespace = req.params[0]; var namespace = req.params[0];

View File

@ -27,14 +27,30 @@
"args": "str", "args": "str",
"desc": "Returns a string with all the characters of `str` converted to lowercase." "desc": "Returns a string with all the characters of `str` converted to lowercase."
}, },
"$trim": {
"args": "str",
"desc": "Normalizes and trims all whitespace characters in str by applying the following steps:\n\n - All tabs, carriage returns, and line feeds are replaced with spaces.\n- Contiguous sequences of spaces are reduced to a single space.\n- Trailing and leading spaces are removed.\n\n If `str` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `str`. An error is thrown if `str` is not a string."
},
"$contains": {
"args": "str, pattern",
"desc": "Returns `true` if `str` is matched by `pattern`, otherwise it returns `false`. If `str` is not specified (i.e. this function is invoked with one argument), then the context value is used as the value of `str`. The `pattern` parameter can either be a string or a regular expression."
},
"$split": { "$split": {
"args": "str[, separator][, limit]", "args": "str[, separator][, limit]",
"desc": "Splits the `str` parameter into an array of substrings. It is an error if `str` is not a string. The optional `separator` parameter specifies the characters within the `str` about which it should be split. If `separator` is not specified, then the empty string is assumed, and `str` will be split into an array of single characters. It is an error if `separator` is not a string. The optional `limit` parameter is a number that specifies the maximum number of substrings to include in the resultant array. Any additional substrings are discarded. If `limit` is not specified, then `str` is fully split with no limit to the size of the resultant array. It is an error if `limit` is not a non-negative number." "desc": "Splits the `str` parameter into an array of substrings. It is an error if `str` is not a string. The optional `separator` parameter specifies the characters within the `str` about which it should be split as either a string or regular expression. If `separator` is not specified, then the empty string is assumed, and `str` will be split into an array of single characters. It is an error if `separator` is not a string. The optional `limit` parameter is a number that specifies the maximum number of substrings to include in the resultant array. Any additional substrings are discarded. If `limit` is not specified, then `str` is fully split with no limit to the size of the resultant array. It is an error if `limit` is not a non-negative number."
}, },
"$join": { "$join": {
"args": "array[, separator]", "args": "array[, separator]",
"desc": "Joins an array of component strings into a single concatenated string with each component string separated by the optional `separator` parameter. It is an error if the input `array` contains an item which isn't a string. If `separator` is not specified, then it is assumed to be the empty string, i.e. no `separator` between the component strings. It is an error if `separator` is not a string." "desc": "Joins an array of component strings into a single concatenated string with each component string separated by the optional `separator` parameter. It is an error if the input `array` contains an item which isn't a string. If `separator` is not specified, then it is assumed to be the empty string, i.e. no `separator` between the component strings. It is an error if `separator` is not a string."
}, },
"$match": {
"args": "str, pattern [, limit]",
"desc": "Applies the `str` string to the `pattern` regular expression and returns an array of objects, with each object containing information about each occurrence of a match withing `str`."
},
"$replace": {
"args": "str, pattern, replacement [, limit]",
"desc": "Finds occurrences of `pattern` within `str` and replaces them with `replacement`. "
},
"$number": { "$number": {
@ -57,11 +73,11 @@
"args": "array", "args": "array",
"desc": "Returns the mean value of an `array` of numbers. It is an error if the input `array` contains an item which isn't a number." "desc": "Returns the mean value of an `array` of numbers. It is an error if the input `array` contains an item which isn't a number."
}, },
"$boolean": { "$boolean": {
"args": "arg", "args": "arg",
"desc": "Casts the argument to a Boolean using the following rules:\n\n - `Boolean` : unchanged\n - `string`: empty : `false`\n - `string`: non-empty : `true`\n - `number`: `0` : `false`\n - `number`: non-zero : `true`\n - `null` : `false`\n - `array`: empty : `false`\n - `array`: contains a member that casts to `true` : `true`\n - `array`: all members cast to `false` : `false`\n - `object`: empty : `false`\n - `object`: non-empty : `true`\n - `function` : `false`" "desc": "Casts the argument to a Boolean using the following rules:\n\n - `Boolean` : unchanged\n - `string`: empty : `false`\n - `string`: non-empty : `true`\n - `number`: `0` : `false`\n - `number`: non-zero : `true`\n - `null` : `false`\n - `array`: empty : `false`\n - `array`: contains a member that casts to `true` : `true`\n - `array`: all members cast to `false` : `false`\n - `object`: empty : `false`\n - `object`: non-empty : `true`\n - `function` : `false`"
}, },
"$not": { "$not": {
"args": "arg", "args": "arg",
"desc": "Returns Boolean NOT on the argument. `arg` is first cast to a boolean" "desc": "Returns Boolean NOT on the argument. `arg` is first cast to a boolean"
@ -70,6 +86,7 @@
"args": "arg", "args": "arg",
"desc": "Returns Boolean `true` if the `arg` expression evaluates to a value, or `false` if the expression does not match anything (e.g. a path to a non-existent field reference)." "desc": "Returns Boolean `true` if the `arg` expression evaluates to a value, or `false` if the expression does not match anything (e.g. a path to a non-existent field reference)."
}, },
"$count": { "$count": {
"args": "array", "args": "array",
"desc": "Returns the number of items in the array" "desc": "Returns the number of items in the array"

View File

@ -45,7 +45,7 @@
"examples": "サンプル", "examples": "サンプル",
"subflows": "サブフロー", "subflows": "サブフロー",
"createSubflow": "サブフローを作成", "createSubflow": "サブフローを作成",
"selectionToSubflow": "サブフローの選択", "selectionToSubflow": "選択部分をサブフロー化",
"flows": "フロー", "flows": "フロー",
"add": "フローを新規追加", "add": "フローを新規追加",
"rename": "フロー名を変更", "rename": "フロー名を変更",