UNPKG

node-red-contrib-hikvision-ultimate

Version:

A native set of nodes for Hikvision (and compatible) Cameras, Alarms, Radars, NVR, Doorbells, etc.

332 lines (312 loc) 13.3 kB
<script type="text/javascript"> RED.nodes.registerType('hikvisionUltimatePicture', { category: 'Hikvision Ultimate', color: '#C0C0C0', defaults: { name: { value: "" }, topic: { value: "" }, server: { type: "Hikvision-config", required: true }, channelID: { value: "1" }, rotateimage: { value: "0" }, heightimage: { value: "" }, widthimage: { value: "" }, qualityimage: { value: "100" }, cropimage: { value: "" }, textoverlay: { value: "" }, textoverlayXY: { value: "0,0" }, textoverlayWH: { value: "0,0" }, textoverlayFont: { value: "FONT_SANS_32_WHITE" }, urlImageCurrentIndex: { value: 0 } }, inputs: 1, outputs: 2, outputLabels: function (i) { var ret = ""; switch (i) { case 0: return "Picture"; break; case 1: return "Error"; break; default: break; } }, icon: "camera-icon.svg", label: function () { var label = "Picture" if (this.name !== undefined && this.name.length > 0) { label = this.name; } return label; }, paletteLabel: function () { return "Picture"; }, oneditprepare: function () { var oNodeServer = RED.nodes.node($("#node-input-server").val()); // Store the config-node // Timer var tImage = null; var bAlreadyIn = false; this.timerRetryAnotherURL = null; // 19/02/2020 Used to alert the user if the CSV file has not been loaded and to get the server sooner als deploy // ########################### $("#node-input-server").change(function () { try { oNodeServer = RED.nodes.node($(this).val()); $("#picture").html("<span>Click the <b>Refresh Image</b> button to get the picture from the camera</span>"); //if (oNodeServer !== null && oNodeServer !== undefined) readPictureFromCamera(oNodeServer, true); } catch (error) { } }); // ########################### function readPictureFromCamera(_oNodeServer, _beginRightURLSearchFromStart) { if (bAlreadyIn) return; bAlreadyIn = true; $("#picture").html("<img src=\"https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/loading.gif\">"); // Prepare the manipulation string var sManipulate = $("#node-input-channelID").val(); sManipulate += "-SEP-" + $("#node-input-qualityimage").val(); sManipulate += "-SEP-" + $("#node-input-rotateimage").val(); sManipulate += "-SEP-" + $("#node-input-widthimage").val(); sManipulate += "-SEP-" + $("#node-input-heightimage").val(); sManipulate += "-SEP-" + $("#node-input-cropimage").val().toString().trim().replace(/\s/g, '').replace(/,/g, "-"); sManipulate += "-SEP-" + $("#node-input-textoverlay").val(); sManipulate += "-SEP-" + $("#node-input-textoverlayXY").val().toString().trim().replace(/\s/g, '').replace(/,/g, "-"); sManipulate += "-SEP-" + $("#node-input-textoverlayWH").val().toString().trim().replace(/\s/g, '').replace(/,/g, "-"); sManipulate += "-SEP-" + $("#node-input-textoverlayFont").val(); sManipulate += "-SEP-" + (_beginRightURLSearchFromStart ? "YES" : "NO"); // Begin cycling right picture URL from the beginning? $.getJSON('hikvisionUltimateGetPicture?serverID=' + _oNodeServer.id + "&manipulate=" + sManipulate, (data) => { $("#picture").html("<img src=\"" + data.picture + "\" style=\"width:320px;height:200px;\" \">"); $("#picturedimensions").html("Width:" + data.width + "px" + " Height:" + data.height + "px"); bAlreadyIn = false; // Check the return string to understand wether i must retry with another image URL or not if (data.width.toString().toLowerCase().includes("retry")) { // Retry RED.notify("Problem getting image. Trying another URL...", { modal: false, fixed: false, type: 'info' }) setTimeout(() => { if (this.timerRetryAnotherURL !== null) clearTimeout(this.timerRetryAnotherURL); readPictureFromCamera(oNodeServer, false); }, 1000); } else if (data.width.toString().toLowerCase().includes("error")) { // I've cycled to all URLS, so the .js returns "Error" RED.notify("Unable to get the image.", { modal: false, fixed: false, type: 'error' }) } else if (data.hasOwnProperty("urlImageCurrentIndex")) { // The image returned is OK and the .js tells me the index of the URL's Array. $("#node-input-urlImageCurrentIndex").val(data.urlImageCurrentIndex); } }).error(function (jqXHR, textStatus, errorThrown) { bAlreadyIn = false; $("#picture").html("<span>THIS NODE IS NEW. PLEASE SAVE AND DEPLOY FIRST! <br/> THEN CLICK AGAIN THE BUTTON.</span>"); // SAVE FIRST! RED.notify("THIS NODE IS NEW. PLEASE SAVE AND DEPLOY FIRST! THEN CLICK AGAIN THE BUTTON.", { modal: false, fixed: false, type: 'error' }); }); } $("#getinfocam").click(function () { if ($("#node-input-widthimage").val() !== "" && Number($("#node-input-widthimage").val()) > 9999) { RED.notify("Max value for width is 9999", { modal: false, fixed: false, type: 'warning' }) return; } if ($("#node-input-heightimage").val() !== "" && Number($("#node-input-heightimage").val()) > 9999) { RED.notify("Max value fot height is 9999", { modal: false, fixed: false, type: 'warning' }) return; } if ($("#node-input-cropimage").val().split(",").length !== 4) { if ($("#node-input-cropimage").val() !== undefined && $("#node-input-cropimage").val() !== "") { RED.notify("Check the CROP string. Must be: x,y,width,height", { modal: false, fixed: false, type: 'warning' }) return; } } readPictureFromCamera(oNodeServer, true); }); }, oneditsave: function () { if (this.timerRetryAnotherURL !== null) clearTimeout(this.timerRetryAnotherURL); } }); </script> <script type="text/x-red" data-template-name="hikvisionUltimatePicture"> <div class="form-row"> <b>Picture node</b>&nbsp&nbsp&nbsp&nbsp<span style="color:red"><i class="fa fa-question-circle"></i>&nbsp<a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-hikvision-ultimate"><u>Help online</u></a></span> <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-channelID"><i class="fa fa-tasks"></i> Camera</label> <select id="node-input-channelID"> <option value="1">1 (DEFAULT)</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> <option value="6">6</option> <option value="7">7</option> <option value="8">8</option> <option value="9">9</option> <option value="10">10</option> <option value="11">11</option> <option value="12">12</option> <option value="13">13</option> <option value="14">14</option> <option value="15">15</option> <option value="16">16</option> <option value="17">17</option> <option value="18">18</option> <option value="19">19</option> <option value="20">20</option> <option value="21">21</option> <option value="22">22</option> <option value="23">23</option> <option value="24">24</option> <option value="25">25</option> <option value="26">26</option> <option value="27">27</option> <option value="28">28</option> <option value="29">29</option> <option value="30">30</option> <option value="31">31</option> <option value="32">32</option> </select> <div class="form-tips" style="margin-top:11px"> Above option: Leave 1 if your camera has only one channel (most of the time) </div> </div> <div class="form-row"> <p align="center" id="picture"><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-hikvision-ultimate/master/img/loading.gif"></p> <p align="center" id="picturedimensions"></p> </div> <div class="form-row"> <label> <i class="fa fa-sign-in"></i> Image</label> <input type="button" id="getinfocam" class="ui-button ui-corner-all ui-widget" style="background-color:#AEE1FF;width:150px" value="Refresh Image"> </div> <div class="form-row"> <label for="node-input-qualityimage"><i class="fa fa-tasks"></i> Jpeg Quality</label> <select id="node-input-qualityimage"> <option value="100">100 (Unchanged)</option> <option value="90">90</option> <option value="80">80</option> <option value="70">70</option> <option value="60">60</option> <option value="50">50</option> <option value="40">40</option> <option value="30">30</option> <option value="20">20</option> <option value="10">10</option> </select> </div> <div class="form-row"> <label for="node-input-rotateimage"><i class="fa fa-tasks"></i> Rotate</label> <select id="node-input-rotateimage"> <option value="0">No</option> <option value="45">45°</option> <option value="90">90°</option> <option value="135">135°</option> <option value="180">180°</option> <option value="225">225°</option> </select> </div> <div class="form-row"> <label for="node-input-widthimage"><i class="fa fa-tasks"></i> Max Width</label> <input type="text" id="node-input-widthimage" placeholder="Leave as is"> </div> <div class="form-row"> <label for="node-input-heightimage"><i class="fa fa-tasks"></i> Max Height</label> <input type="text" id="node-input-heightimage" placeholder="Leave as is"> <div class="form-tips" style="margin-top:11px"> Above options: Resizes the image. Set the MAX width and height in pixels. Leave empty not to resize. If you specify one max dimension, you MUST specify BOTH! Otherwise, leave all blank. </div> </div> <div class="form-row"> <label for="node-input-cropimage"><i class="fa fa-tasks"></i> Crop</label> <input type="text" id="node-input-cropimage" placeholder="Leave as is"> <div class="form-tips" style="margin-top:11px"> Above options: Crop the image (get only a portion of image, for example, to zoom on a door). Accepted string is "x, y, width, height" for example "20,30,200,200". Leave blank not to crop. </div> </div> <div class="form-row"> <label for="node-input-textoverlay"><i class="fa fa-tasks"></i> Text Overlay</label> <input type="text" id="node-input-textoverlay" placeholder="No text"> </div> <div class="form-row"> <label for="node-input-textoverlayXY"><i class="fa fa-tasks"></i> Position (X,Y)</label> <input type="text" id="node-input-textoverlayXY" placeholder="Example 10,10"> </div> <div class="form-row"> <label for="node-input-textoverlayWH"><i class="fa fa-tasks"></i> Max boundary (Width,Height)</label> <input type="text" id="node-input-textoverlayWH" placeholder="Example 200,100"> </div> <div class="form-row"> <label for="node-input-textoverlayFont"><i class="fa fa-tasks"></i> Font</label> <select id="node-input-textoverlayFont"> <option value="FONT_SANS_8_BLACK">FONT_SANS_8_BLACK</option> <option value="FONT_SANS_10_BLACK">FONT_SANS_10_BLACK</option> <option value="FONT_SANS_12_BLACK">FONT_SANS_12_BLACK</option> <option value="FONT_SANS_14_BLACK">FONT_SANS_14_BLACK</option> <option value="FONT_SANS_16_BLACK">FONT_SANS_16_BLACK</option> <option value="FONT_SANS_32_BLACK">FONT_SANS_32_BLACK</option> <option value="FONT_SANS_64_BLACK">FONT_SANS_64_BLACK</option> <option value="FONT_SANS_128_BLACK">FONT_SANS_128_BLACK</option> <option value="FONT_SANS_8_WHITE">FONT_SANS_8_WHITE</option> <option value="FONT_SANS_16_WHITE">FONT_SANS_16_WHITE</option> <option value="FONT_SANS_32_WHITE">FONT_SANS_32_WHITE</option> <option value="FONT_SANS_64_WHITE">FONT_SANS_64_WHITE</option> <option value="FONT_SANS_128_WHITE">FONT_SANS_128_WHITE</option> </select> <div class="form-tips" style="margin-top:11px"> Above options: overlay a text over the image. You can set the X position from TOP and the Y position from LEFT, as well as the fonts. You can only choose between the list of avaiable fonts. You cannot currently add more than a row. You can override the overlayed text, by msg.textoverlay </div> </div> <div class="form-row"> <input type="hidden" id="node-input-urlImageCurrentIndex" > </div> </script> <script type="text/x-red" data-help-name="hikvisionUltimatePicture"> <p> <a href="https://www.paypal.me/techtoday" target="_blank"><img src='https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square' width='30%'></a> </p> <p> The node outputs the picture on PIN 1 and a connection ERROR on PIN 2 (true if the node is DISCONNECTED to the server, otherwise false IF IT'S RECONNECTED). </p> </script>