node-red-contrib-miio-roborock
Version:
Roborock connectivity nodes for node-red
317 lines (269 loc) • 13.7 kB
HTML
<script type="text/x-red" data-template-name="miio-roborock-command">
<link rel="stylesheet" href="miio-roborock/static/css/multiple-select.css" type="text/css" />
<link rel="stylesheet" href="miio-roborock/static/css/common.css" type="text/css" />
<div class="form-row">
<label for="node-input-name" class="l-width"><i class="icon-tag"></i> <span data-i18n="label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]placeholder.name">
</div>
<div class="form-row">
<label for="node-input-server" class="l-width"><i class="fa fa-globe"></i> <span data-i18n="label.server"></span></label>
<input type="text" id="node-input-server">
</div>
<div class="form-row">
<label for="node-input-command" class="l-width"><i class="fa fa-tasks"></i> <span data-i18n="label.command"></span></label>
<input type="text" id="node-input-command" style="width:70%">
<input type="hidden" id="node-input-commandType">
</div>
<div class="form-row">
<label for="node-input-payload" class="l-width"><i class="fa fa-envelope"></i> <span data-i18n="label.payload"></span></label>
<input type="text" id="node-input-payload" style="width:70%">
<input type="hidden" id="node-input-payloadType">
</div>
<div class="form-row node-input-rule-container-row">
<ol id="node-input-rule-container"></ol>
</div>
<hr>
<!--app_zoned_clean-->
<div class="form-row command_options command_options__app_zoned_clean">
<label for="node-input-coordinates" class="l-width" style="vertical-align:top;"><span data-i18n="label.coordinates"></span></label>
<textarea id="node-input-coordinates" style="width:70%;min-height:70px;height:95px;resize:vertical;"></textarea>
<hr>
</div>
<!--set_custom_mode-->
<div class="form-row command_options command_options__set_custom_mode">
<label for="node-input-fan_speed" class="l-width"><span data-i18n="label.fan_speed_percent"></span></label>
<input type="number" id="node-input-fan_speed" data-i18n="[placeholder]placeholder.fan_speed">
<hr>
</div>
<!--dnld_install_sound-->
<div class="form-row command_options command_options__dnld_install_sound">
<label for="node-input-voice_pack" class="l-width"><span data-i18n="label.voice_pack"></span></label>
<select id="node-input-voice_pack" class="s-width"></select>
<hr>
</div>
<div class="form-row homekit_options">
<label for='node-input-homekit_stop_to_dock' class="l-width"><i class='fa fa-share-square'></i> <span data-i18n="label.homekit_stop"></span></label>
<input type="checkbox" id="node-input-homekit_stop_to_dock" checked="checked" style="display: inline-block; width: auto; vertical-align: top;"> <span data-i18n="label.homekit_stop_help"></span></input>
<hr>
</div>
<div id="node-input-command-tips-wr">
<!--app_zoned_clean-->
<div class="form-tips command_tips command_tips__app_zoned_clean">
A zone consists of a list of 5 integer values. The first four define the rectangle in map coordinates and the last integer defines the times this zone should be cleaned.<br>
<b>Example:</b><br><code>[<br> [26234,26042,27284,26642,1],<br> [26234,26042,27284,26642,1]<br>]</code>
</div>
<!--set_custom_mode-->
<div class="form-tips command_tips command_tips__set_custom_mode">
This command sets the fan level during the cleaning process. <br>
<b>Example:</b><br><code>50</code>
</div>
<div id="node-input-command-tips" class="form-tips"></div>
</div>
<br><br>
</script>
<script type='text/javascript'>
RED.nodes.registerType('miio-roborock-command', {
category: 'Xiaomi',
color: '#FF233F',
defaults: {
name: {
value: ""
},
server: {
type: "miio-roborock-server",
required: true
},
command_name: {
value: null
},
command: {
value: 'find_me',
},
commandType: {
value: 'vacuum_cmd',
},
payload: {
value: 'payload',
},
payloadType: {
value: 'msg',
},
coordinates: {
value: null,
},
fan_speed: {
value: 100,
},
voice_pack: {
value: null,
},
homekit_stop_to_dock: {
value: false,
}
},
inputs: 1,
outputs: 1,
outputLabels: ["result"],
paletteLabel: 'Roborock: command',
icon: "roborock.png",
label: function () {
var label = 'Roborock: command';
if (this.name) {
label = this.name;
} else if (typeof(this.command_name) == 'string' && this.command_name.length) {
label = this.command_name;
}
return label;
},
oneditprepare: function () {
var node = this;
var $commandInput = $('#node-input-command');
var $commandTypeInput = $('#node-input-commandType');
var $payloadInput = $('#node-input-payload');
var $payloadTypeInput = $('#node-input-payloadType');
// $eventTypesSelect.children().remove();
$.getJSON('miio-roborock/getCommands', {
nodeID: node.id
}).done(function (data, textStatus, jqXHR) {
try {
node.commands = data;
var commands = [];
$.each(data, function(index, value) {
commands.push({'value':index, 'label':RED._("node-red-contrib-miio-roborock/command:commands."+index)});
});
var topicTypes = {
value: 'vacuum_cmd',
label: 'mi',
icon: 'icons/node-red-contrib-miio-roborock/roborock-color.png',
options: commands
};
$commandInput.typedInput({
types: [
topicTypes,
{value:'homekit_cmd',label:'homekit',icon: 'icons/node-red-contrib-miio-roborock/homekit-logo.png',options:['homekit']},
'str', 'msg', {value:'object',label:'object',options:['json']}],
default: 'msg',
value: 'topic',
typeField: $commandTypeInput,
});
$commandTypeInput.val(node.commandType);
var payloadTypes = {
value: 'vacuum_payload',
label: 'mi',
icon: 'icons/node-red-contrib-miio-roborock/roborock-color.png',
options: [{'value':'arguments', 'label':'Enter arguments'}]
};
$payloadInput.typedInput({
types: [payloadTypes, 'msg', 'flow', 'global', 'str', 'num', 'date'],
default: 'msg',
value: 'payload',
typeField: $payloadTypeInput,
});
$payloadTypeInput.val(node.payloadType);
voicePackInit();
$commandInput.on('change', function(type, value) {
// console.log('====>$commandInput');
onChange();
});
$payloadInput.on('change', function(type, value) {
// console.log('====>$payloadInput');
onChange();
});
onChange();
function onChange() {
var $commandInput = $('#node-input-command');
var command = $commandInput.val();
var $commandTypeInput = $('#node-input-commandType');
var $payloadInput = $('#node-input-payload');
var $payloadRow = $payloadInput.closest('.form-row');
var $payloadTypeInput = $('#node-input-payloadType');
// console.log('$commandInput: ', $commandInput.val());
// console.log('$commandTypeInput: ', $commandTypeInput.val());
// console.log('$payloadInput: ', $payloadInput.val());
// console.log('$payloadTypeInput: ', $payloadTypeInput.val());
//show payload row
if ($commandTypeInput.val() === 'vacuum_cmd') {
if (node.commands[command].args) {
$payloadRow.show();
} else {
$payloadRow.hide();
}
} else {
$payloadRow.show();
$payloadInput.typedInput('width'); //small hack
}
//show homekit options
$('.homekit_options').toggle($commandTypeInput.val() === 'homekit_cmd');
//show arguments
$('.command_options').hide();
if ($payloadTypeInput.val() === 'vacuum_payload' && $payloadInput.val() === 'arguments') {
// if ($commandTypeInput.val() === 'vacuum_cmd') {
$('.command_options__'+command).show();
}
//show tips
var $tips = $('#node-input-command-tips');
var $tipsWr = $('#node-input-command-tips-wr');
$('.command_tips').hide();
$tips.hide();
$tipsWr.hide();
if ($commandTypeInput.val() === 'vacuum_cmd') {
$tipsWr.show();
$('.command_tips__'+command).show();
var link = node.commands[command].link;
if (link) {
$tips.html('<b>' + RED._("node-red-contrib-miio-roborock/command:tips.read_docs") + '</b>: <a target="_blank" href="' + link + '">' + data[command]['name'] + '</a>');
$tips.show();
}
}
}
function voicePackInit() {
// Initialize bootstrap multiselect form
$voicePacksSelect = $('#node-input-voice_pack');
$voicePacksSelect.multipleSelect({
maxHeight: 300,
dropWidth: 320,
width: 320,
single: !(typeof $(this).attr('multiple') !== typeof undefined && $(this).attr('multiple') !== false),
filter: true,
});
$voicePacksSelect.children().remove();
$.getJSON('miio-roborock/getVoices', {
controllerID: node.server
}).done(function (data, textStatus, jqXHR) {
try {
var groupHtml = '';
var currentGroup = null;
$.each(data, function(index, value) {
if (value.lang !== currentGroup) {
groupHtml = $('<optgroup/>', { label: RED._("node-red-contrib-miio-roborock/command:languages."+value.lang) });
groupHtml.appendTo($voicePacksSelect);
currentGroup = value.lang;
}
$('<option value="' + index +'">'+value.name+' (ver: '+value.ver+')</option>').appendTo(groupHtml);
});
$voicePacksSelect.multipleSelect('enable');
$voicePacksSelect.val(node.voice_pack);
$voicePacksSelect.multipleSelect('refresh'); //rebuild
} catch (error) {
console.error('Error #4544');
console.log(error);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
$voicePacksSelect.multipleSelect('disable');
$voicePacksSelect.multipleSelect('refresh');
});
}
} catch (error) {
console.error('Error #4535');
console.log(error);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
});
},
oneditsave: function () {
var commandCode = $('#node-input-command').val();
var commandLabel = $('.red-ui-typedInput-options [value='+commandCode+']').text();
this.command_name = commandLabel?commandLabel:null;
}
});
</script>