node-red-contrib-hikvision-ultimate
Version:
A native set of nodes for Hikvision (and compatible) Cameras, Alarms, Radars, NVR, Doorbells, etc.
231 lines (201 loc) • 7.07 kB
HTML
<script type="text/javascript">
RED.nodes.registerType('hikvisionUltimateSpeaker', {
category: 'Hikvision Ultimate',
color: '#C0C0C0',
defaults: {
name: { value: "" },
topic: { value: "" },
server: { type: "Speaker-config", required: true },
customAudioID: { value: "" },
volume: { value: "2" }
},
inputs: 1,
outputs: 2,
outputLabels: function (i) {
var ret = "";
switch (i) {
case 0:
return "Play";
break;
case 1:
return "Error";
break;
case 2
:
return "";
break;
default:
break;
}
},
icon: "bridge.svg",
label:
function () {
var label = "Speaker"
if (this.name !== undefined && this.name.length > 0) {
label = this.name;
}
return label;
},
paletteLabel: function () {
return "Speaker";
},
oneditprepare: function () {
let node = this;
const $serverField = $("#node-input-server");
const $audioSelect = $("#node-input-customAudioID");
const $playButton = $("#testFile");
const $volume = $("#node-input-volume");
let isPlaying = false;
function updateButtonState() {
if (!$serverField.val() || !$audioSelect.val()) {
$playButton.prop("disabled", true).val("Play");
isPlaying = false;
return;
}
$playButton.prop("disabled", false).val(isPlaying ? "Stop" : "Play");
}
function resetPlayingState() {
isPlaying = false;
updateButtonState();
}
function refreshAudioList() {
$audioSelect.empty();
resetPlayingState();
try {
const configId = $serverField.val();
if (!configId) {
return;
}
const configNode = RED.nodes.node(configId);
if (!configNode) {
return;
}
$.getJSON("hikvisionUltimateGetSpeakerFiles?nodeID=" + configNode.id, {}).done(function (data) {
if (!Array.isArray(data) || data.length === 0) {
return;
}
$.each(data, function (i, item) {
$audioSelect.append($("<option>").val(item.customAudioID.toString()).text(item.customAudioName + " #" + item.customAudioID))
});
const desiredId = node.customAudioID ? node.customAudioID.toString() : data[0].customAudioID.toString();
$audioSelect.val(desiredId);
if (!node.customAudioID) {
node.customAudioID = desiredId;
}
updateButtonState();
}).fail(function () {
resetPlayingState();
});
} catch (error) {
resetPlayingState();
}
}
// File to be played
$("#node-input-server").change(function () {
refreshAudioList();
});
$audioSelect.on("change", function () {
resetPlayingState();
});
// Volume
$volume.empty();
for (let index = 1; index < 100; index++) {
$volume.append($("<option>").val(index.toString()).text(index + "%"))
}
$volume.val(this.volume);
$playButton.click(function () {
const serverId = $serverField.val();
const audioId = $audioSelect.val();
if (!serverId || !audioId) {
RED.notify("Select a speaker and an audio before playing.", { type: "warning" });
return;
}
const action = isPlaying ? "stop" : "play";
const paramsObj = {
nodeID: serverId,
customAudioID: audioId,
action
};
if (action === "play") {
paramsObj.volume = $volume.val() || "2";
}
$playButton.prop("disabled", true).val(action === "play" ? "Wait..." : "Stopping...");
$.getJSON("hikvisionUltimateSpeakerTest?" + $.param(paramsObj), (data) => {
isPlaying = action === "play";
updateButtonState();
}).fail(function (jqXHR) {
resetPlayingState();
const message = (jqXHR && jqXHR.responseJSON && jqXHR.responseJSON.error) || "Impossibile riprodurre il file. Verifica la configurazione dello Speaker.";
RED.notify(message,
{
modal: false,
fixed: false,
type: 'warning'
})
});
});
updateButtonState();
refreshAudioList();
},
oneditsave: function () {
if ($("#node-input-name").val() === undefined || $("#node-input-name").val() === '') {
$("#node-input-name").val($("#node-input-customAudioID option:selected").text());
}
}
});
</script>
<script type="text/html" data-template-name="hikvisionUltimateSpeaker">
<div class="form-row">
<b>Speaker node</b>
<br/>
<br/>
<label for="node-input-server">Server</label>
<input type="text" id="node-input-server" />
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-topic"><i class="fa fa-tasks"></i> Node topic</label>
<input type="text" id="node-input-topic" placeholder="Node's own topic">
</div>
<div class="form-row">
<label for="node-input-customAudioID"><i class="fa fa-tasks"></i> File</label>
<div style="display:flex; gap:8px; align-items:center;">
<select id="node-input-customAudioID" style="flex:1;"></select>
<input type="button" id="testFile" class="ui-button ui-corner-all ui-widget" style="background-color:#AEE1FF;width:100px" value="Play">
</div>
</div>
<div class="form-row">
<label for="node-input-volume"><i class="fa fa-tasks"></i> Volume</label>
<select id="node-input-volume"></select>
</div>
</script>
<script type="text/markdown" data-help-name="hikvisionUltimateSpeaker">
This node lets you play through the Speaker, the audio files that are loaded in the Hikvision Speaker.
The audio files must be already be uploaded to the speaker.<br/>
**General**
|Property|Description|
|--|--|
| Server | Select the Speaker to be used. |
| Name | The node name. |
| Topic | The msg.topic.|
| Volume | The speaker's volume from 1% to 100%. CAUTION, THE SPEAKER IS VERY LOUD. CHECK FOR PEOPLE AROUND AND PROTECT YOUR EARS! |
| File | This is the speaker's audio file list. If you see nothing, upload the audio files into your speaker, via the speaker web interface, via IVMS, etc...|
| Play button | Broadcasts the audio file you selected, to your speaker with volume set to 2%. Caution needed, protect your ear in any case! |
### Outputs
1. Standard output PIN 1
: payload (boolean) : the standard output of the command. It contains the status of the message being sent, as true/false.
2. Error output PIN 2
: msg (json) : the connection status. An error will be published in case of connection error
### Inputs
1. Standard input
: payload (boolean) : *true* for broadcasting the audio file on the speaker, *false* to stop playing.
### Details
CAUTION, THE SPEAKER IS VERY LOUD. CHECK FOR PEOPLE AROUND AND PROTECT YOUR EARS!
<br/>
[DONATE HERE, THANK YOU!](https://www.paypal.me/techtoday)
<br/>
</script>