@isaac-platform/isaac-node-red
Version:
Set of Node-RED nodes to communicate with an ISAAC system
372 lines (335 loc) • 14.3 kB
HTML
<script type="text/javascript">
// isaac prefix ensures that node appears when filtering by "isaac"
RED.nodes.registerType('isaac variable', {
category: 'ISAAC',
color: '#C0C0C0',
icon: 'isaac.svg',
inputs: 1,
outputs: 1,
paletteLabel: 'variable',
label: function () {
if (this.name) {
return this.name;
}
return this.paletteLabel;
},
defaults: {
isaacConnection: { type: 'isaac-connection', required: true },
name: { value: '' },
action: { value: 'getAll' },
externalRef: { value: '' },
displayName: { value: '' },
description: { value: '' },
value: { value: null },
tags: { value: '' },
log: { value: false },
storeHistory: { value: false },
healthEnabled: { value: false },
healthGracePeriod: { value: 0 },
healthRules: { value: [] },
healthRulesString: { value: '[]' },
composite: { value: false },
compositeDefinition: { value: [] },
compositeDefinitionString: { value: '[]' },
},
oneditprepare: function () {
const updateLinks = () => {
const configNodeId = $('#node-input-isaacConnection').val();
if (!configNodeId) {
return;
}
const configNode = RED.nodes.node(configNodeId);
if (!configNode || !configNode.ipAddress) {
const links = document.querySelectorAll('.isaac-workspace-link, .isaac-doc-link');
links.forEach((link) => {
link.style.display = 'none';
});
return;
}
const getDisplay = (linkEl) => {
return linkEl.classList.contains('isaac-full-width') ? 'block' : 'inline';
};
const docLink = document.querySelector('.isaac-doc-link');
if (docLink) {
docLink.style.display = getDisplay(docLink);
docLink.href = `${configNode.ipAddress}/docs/v1/?urls.primaryName=Variables`;
}
const workspaceLinks = document.querySelectorAll('.isaac-workspace-link');
workspaceLinks.forEach((link) => {
link.style.display = getDisplay(link);
link.href = `${configNode.ipAddress}/logging/variables`;
});
};
updateLinks();
$('#node-input-isaacConnection').change(updateLinks);
document.querySelector('#node-config-input-composite').checked = !!this.composite;
document.querySelector('#node-config-input-healthEnabled').checked = !!this.healthEnabled;
document.querySelector('#node-config-input-log').checked = !!this.log;
document.querySelector('#node-config-input-storeHistory').checked = !!this.storeHistory;
$('#node-input-action').change((e) => {
$('.action-related').hide();
const value = e.target.value;
if (value === 'upsert') {
$('#row-externalRef').show();
$('#row-displayName').show();
$('#row-description').show();
$('#row-value').show();
$('#row-tags').show();
$('#row-log').show();
$('#row-storeHistory').show();
$('#row-healthEnabled').show();
$('#row-composite').show();
if (this.healthEnabled) {
$('#row-healthGracePeriod').show();
$('#row-healthRules').show();
}
if (this.composite) {
$('#row-compositeDefinition').show();
}
} else if (value === 'updateValue') {
$('#row-externalRef').show();
$('#row-value').show();
} else if (value === 'getOne' || value === 'delete') {
$('#row-externalRef').show();
}
});
$('#node-config-input-healthEnabled').change((e) => {
const className = '.heathEnabled-dependent';
if (e.target.checked) {
$(className).show();
} else {
$(className).hide();
}
});
$('#node-config-input-composite').change((e) => {
const className = '.composite-dependent';
if (e.target.checked) {
$(className).show();
} else {
$(className).hide();
}
});
// healthRules
try {
const inputElement = $('#node-input-healthRulesString');
inputElement.typedInput({ type: 'json', types: ['json'] });
if (this.healthRules) {
inputElement.value = JSON.stringify(this.healthRules);
}
} catch (e) {
console.error(e);
}
// compositeDefinition
try {
const inputElement = $('#node-input-compositeDefinitionString');
inputElement.typedInput({ type: 'json', types: ['json'] });
if (this.compositeDefinition) {
inputElement.value = JSON.stringify(this.compositeDefinition);
}
} catch (e) {
console.error(e);
}
},
oneditsave: function () {
this.composite = document.querySelector('#node-config-input-composite').checked;
this.healthEnabled = document.querySelector('#node-config-input-healthEnabled').checked;
this.log = document.querySelector('#node-config-input-log').checked;
this.storeHistory = document.querySelector('#node-config-input-storeHistory').checked;
// healthRules
try {
const inputElement = document.querySelector('#node-input-healthRulesString');
this.healthRules = JSON.parse(inputElement.value);
} catch (e) {
console.error(e);
}
// compositeDefinition
try {
const inputElement = document.querySelector('#node-input-compositeDefinitionString');
this.compositeDefinition = JSON.parse(inputElement.value);
} catch (e) {
console.error(e);
}
},
});
</script>
<script type="text/html" data-template-name="isaac variable">
<div class="form-row">
<label for="node-input-isaacConnection"><i class="fa fa-server"></i> Connection</label>
<input type="text" id="node-input-isaacConnection" />
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Node Name</label>
<input type="text" id="node-input-name" />
</div>
<div class="form-row">
<label for="node-input-action" title="Can be overwritten by msg.action">
<i class="fa fa-bolt"></i> Action <strong>*</strong>
</label>
<select id="node-input-action">
<option value="getOne">Get one</option>
<option value="getAll">Get all</option>
<option value="upsert">Add/replace one</option>
<option value="updateValue">Update value</option>
<option value="delete">Delete one</option>
</select>
</div>
<div class="form-row action-related" id="row-externalRef">
<label for="node-input-action" title="Can be overwritten by msg.config.externalRef">
External Ref <strong>*</strong>
</label>
<input type="text" id="node-input-externalRef" />
</div>
<div class="form-row action-related" id="row-displayName">
<label for="node-input-displayName" title="Can be overwritten by msg.config.displayName">Display Name</label>
<input type="text" id="node-input-displayName" />
</div>
<div class="form-row action-related" id="row-description">
<label for="node-input-description" title="Can be overwritten by msg.config.description">Description</label>
<input type="text" id="node-input-description" />
</div>
<div class="form-row action-related" id="row-value">
<label for="node-input-value" title="Can be overwritten by msg.payload">Value <strong>*</strong></label>
<input type="text" id="node-input-value" />
</div>
<div class="form-row action-related" id="row-tags">
<label for="node-input-tags" title="Can be overwritten by msg.config.tags"><i class="fa fa-tags"></i> Tags</label>
<input type="text" id="node-input-tags" placeholder="Comma separated" />
</div>
<div class="form-row action-related" id="row-log">
<label for="node-config-input-log" title="Can be overwritten by msg.config.log">Log</label>
<input class="switch__input" type="checkbox" id="node-config-input-log" style="width: auto;" />
</div>
<div class="form-row action-related" id="row-storeHistory">
<label for="node-config-input-storeHistory" title="Can be overwritten by msg.config.storeHistory">
Store History
</label>
<input class="switch__input" type="checkbox" id="node-config-input-storeHistory" style="width: auto;" />
</div>
<div class="form-row action-related" id="row-healthEnabled">
<label for="node-config-input-healthEnabled" title="Can be overwritten by msg.config.healthEnabled">
Health Enabled
</label>
<input class="switch__input" type="checkbox" id="node-config-input-healthEnabled" style="width: auto;" />
</div>
<div class="form-row action-related heathEnabled-dependent" id="row-healthGracePeriod">
<label for="node-input-healthGracePeriod" title="Can be overwritten by msg.config.healthGracePeriod">
Health Grace Period (s)
</label>
<input type="number" id="node-input-healthGracePeriod" />
</div>
<div class="form-row action-related heathEnabled-dependent" id="row-healthRules">
<label for="node-input-healthRulesString" title="Can be overwritten by msg.config.healthRules">Health Rules</label>
<input type="text" id="node-input-healthRulesString" />
</div>
<div class="form-row action-related" id="row-composite">
<label for="node-config-input-composite" title="Can be overwritten by msg.config.composite">Composite</label>
<input class="switch__input" type="checkbox" id="node-config-input-composite" style="width: auto;" />
</div>
<div class="form-row action-related composite-dependent" id="row-compositeDefinition">
<label for="node-input-compositeDefinitionString" title="Can be overwritten by msg.config.compositeDefinition">
Composite Definition
</label>
<input type="text" id="node-input-compositeDefinitionString" />
</div>
<div
style="color:#A3A3A3; display:flex; gap:16px; align-items:center; padding:8px 16px; border: 1px solid #a3a3a3; border-radius:12px; margin-top:12px"
>
<i class="fa fa-info" style="width:16px; text-align:center;"></i>
<p style="margin: 0; padding: 0;">
All properties can be overwritten by incoming messages.<br />
Hover a property label to see how it can be overwritten.<br />
Required properties (*) can be provided either in the UI or in messages.
</p>
</div>
<div style="margin-top:12px">
<a href="" target="_blank" class="isaac-workspace-link isaac-full-width" style="text-decoration:underline">
<i class="fa fa-external-link" style="margin-right:8px"></i>Workspace: Variables
</a>
<a
href=""
target="_blank"
class="isaac-doc-link isaac-full-width"
style="margin-top:12px; text-decoration:underline"
>
<i class="fa fa-book" style="margin-right:8px"></i>API Documentation: Variables
</a>
</div>
</script>
<script type="text/html" data-help-name="isaac variable">
<p>
Fetches, creates, updates and deletes ISAAC variables. Values passed in <code>msg.config</code> will override values
enterred in the UI editor dialog. Values not defined in <code>msg.config</code> nor the UI editor dialog will
fallback to the default values of the editor dialog, so make sure to define all values when updating an existing
item.
</p>
<h3>Inputs</h3>
<h4>Common</h4>
<dl class="message-properties">
<dt>action <span class="property-type">string</span></dt>
<dd>
Can be <code>getOne</code>, <code>getAll</code>, <code>upsert</code>, <code>updateValue</code> or
<code>delete</code>.
</dd>
</dl>
<h4>Action getOne</h4>
<dl class="message-properties">
<dt>config.externalRef <span class="property-type">string</span></dt>
<dd>The externalRef of the variable to fetch.</dd>
</dl>
<h4>Action upsert</h4>
<dl class="message-properties">
<dt>payload <span class="property-type">object</span></dt>
<dd>
The value of the variable. An empty string is ignored if the variable already exists. When this node is used with
ISAAC 2.5.0 and up, <code>null</code> clears the value of an existing variable.
</dd>
<dt>config.externalRef <span class="property-type">string</span></dt>
<dd><code>externalRef</code> of the variable to create or update.</dd>
<dt class="optional">config.displayName <span class="property-type">string</span></dt>
<dd>Optional. Display name of the new or updated variable.</dd>
<dt class="optional">config.description <span class="property-type">string</span></dt>
<dd>Optional. Description of the new or updated variable.</dd>
<dt class="optional">config.tags <span class="property-type">string | array of strings</span></dt>
<dd>Optional. Can be a string of coma separated tags or an array of strings</dd>
<dt class="optional">config.log <span class="property-type">boolean</span></dt>
<dd>Optional. Have changes of the variable update the log.</dd>
<dt class="optional">config.storeHistory <span class="property-type">boolean</span></dt>
<dd>Optional. If true, store lasValue history.</dd>
<dt class="optional">config.healthEnabled <span class="property-type">boolean</span></dt>
<dd>Optional. Whether the healthState is enabled.</dd>
<dt class="optional">config.healthGracePeriod <span class="property-type">number</span></dt>
<dd>Optional. Amount of seconds to wait before triggering a healthState change.</dd>
<dt class="optional">config.healthRules <span class="property-type">array of 3 arrays of strings</span></dt>
<dd>
Optional. Array of 3 sub-arrays: the first for healthy, the second warning and the third for error. Each sub-array
contains strings, one for each line of code. The variable can be referenced with: <code>[`self`]</code>
</dd>
<dt class="optional">config.composite <span class="property-type">boolean</span></dt>
<dd>Optional. Whether the variable is a composite one. This is only supported by the ISAAC module.</dd>
<dt class="optional">config.compositeDefinition <span class="property-type">array of strings</span></dt>
<dd>Optional. Array of strings, one for each line of code.</dd>
</dl>
<h4>Action updateValue</h4>
<dl class="message-properties">
<dd>Use this action if you only want to update the variable's value.</dd>
<dt>payload <span class="property-type">string</span></dt>
<dd>
The value to set. When this node is used with ISAAC 2.5.0 and up, <code>null</code> and <code>""</code> (empty
string) clear the value.
</dd>
<dt>config.externalRef <span class="property-type">string</span></dt>
<dd><code>externalRef</code> of the variable to update.</dd>
</dl>
<h4>Action delete</h4>
<dl class="message-properties">
<dt>config.externalRef <span class="property-type">string</span></dt>
<dd>The externalRef of the variable to delete.</dd>
</dl>
<h3>Outputs</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">object</span></dt>
<dd>The variable(s).</dd>
<dt>statusCode <span class="property-type">number</span></dt>
<dd>The status code of the response.</dd>
</dl>
</script>