Skip to content

Commit

Permalink
feat(result-filter): filter from browser and crawler
Browse files Browse the repository at this point in the history
fix: issue #70 could be undefined on just value option
  • Loading branch information
biancode committed Nov 11, 2018
1 parent 8b8d317 commit f7662cc
Show file tree
Hide file tree
Showing 8 changed files with 905 additions and 39 deletions.
715 changes: 715 additions & 0 deletions examples/client/result-filter.json

Large diffs are not rendered by default.

28 changes: 27 additions & 1 deletion src/core/opcua-iiot-core-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ de.biancoroyal.opcua.iiot.core.response.analyzeBrowserResults = function (node,
this.handlePayloadStatusCode(node, msg)
}

de.biancoroyal.opcua.iiot.core.response.analyzeCrawlerResults = function (node, msg) {
this.handlePayloadStatusCode(node, msg)
}

de.biancoroyal.opcua.iiot.core.response.analyzeReadResults = function (node, msg) {
this.handlePayloadStatusCode(node, msg)
if (msg.readtype === 'HistoryValue' && msg.payload && msg.payload.length) {
Expand Down Expand Up @@ -96,7 +100,7 @@ de.biancoroyal.opcua.iiot.core.response.analyzeEventResultStatus = function (nod
de.biancoroyal.opcua.iiot.core.response.handlePayloadStatusCode = function (node, msg) {
let entryStatus = [0, 0, 0]

if (msg.payload.length || msg.payload.results || msg.payload.statusCodes) {
if (msg.payload.length || msg.payload.results || msg.payload.browserResults || msg.payload.crawlerResults || msg.payload.statusCodes) {
entryStatus = this.handlePayloadArrayOfObjects(msg)
} else {
entryStatus = this.handlePayloadObject(msg)
Expand All @@ -117,6 +121,10 @@ de.biancoroyal.opcua.iiot.core.response.handlePayloadArrayOfObjects = function (

if (msg.payload.results) {
results = msg.payload.results
} else if (msg.payload.browserResults) {
results = msg.payload.browserResults
} else if (msg.payload.crawlerResults) {
results = msg.payload.crawlerResults
} else if (msg.payload.statusCodes) {
results = msg.payload.statusCodes
} else {
Expand Down Expand Up @@ -273,6 +281,24 @@ de.biancoroyal.opcua.iiot.core.response.compressBrowseMessageStructure = functio
}
}

de.biancoroyal.opcua.iiot.core.response.compressCrawlerMessageStructure = function (msg) {
if (msg.payload.hasOwnProperty('crawlerResults') && msg.payload.crawlerResults.length) {
let itemList = []
msg.payload.crawlerResults.forEach((item) => {
itemList.push({
nodeId: item.nodeId.toString(),
browseName: (item.browseName.namespaceIndex) ? item.browseName.namespaceIndex + ':' + item.browseName.name : item.browseName,
displayName: item.displayName.text
})
})
msg.payload = itemList
this.trimMessageExtensions(msg)
this.trimMessagePayloadExtensions(msg)
} else {
this.defaultCompress(msg)
}
}

de.biancoroyal.opcua.iiot.core.response.compressVariableValueMessage = function (msg) {
let itemList = []
let results = msg.payload
Expand Down
6 changes: 4 additions & 2 deletions src/locales/de-DE/opcua-iiot-inject.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
"success": "Erfolgreich injected: __label__",
"errors": {
"failed": "inject failed, see log for details"
}
},
"startDelay": "Delay beim Start",
"startDelayAddon": "Sek. und dann"
}
}
}
5 changes: 3 additions & 2 deletions src/locales/en-US/opcua-iiot-inject.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,14 @@
"Sunday"
],
"on": "on",
"onstart": "Inject once at start",
"onstart": "inject once and then",
"tip": "<b>Note:</b> \"interval between times\" and \"at a specific time\" will use cron.<br/>See info box for details.",
"success": "Successfully injected: __label__",
"errors": {
"failed": "inject failed, see log for details"
},
"startDelay": "Delay sec. at start",
"startDelay": "Delay at start",
"startDelayAddon": "sec. then",
"addButton": "Add",
"tabs-label": {
"addressSpaceItems": "OPC UA Nodes",
Expand Down
28 changes: 16 additions & 12 deletions src/opcua-iiot-inject.html
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,8 @@
})

$('#node-input-once').change(function () {
if ($(this).is(':checked')) {

if ($(this).is(':checked') || $('#opcuaiiotinject-time-type-select').val() !== 'none') {
$('#node-delay').show()
} else {
$('#node-delay').hide()
Expand Down Expand Up @@ -655,7 +656,8 @@
suffix = ' ¹'
}

if (this.repeat || this.crontab) {
let hasRepeat = ( this.repeat && this.repeat !== 'none' )
if (hasRepeat || this.crontab) {
suffix = suffix + ' ↻'
}

Expand Down Expand Up @@ -725,6 +727,17 @@
<input type="text" id="node-input-topic">
</div>

<div class="form-row" id="node-delay">
<label for="node-input-startDelay"><i class="fa fa-clock-o"></i> <span data-i18n="opcuaiiotinject.startDelay"></span></label>
<input type="text" id="node-input-startDelay" placeholder="10" style="width:60px"> <span data-i18n="opcuaiiotinject.startDelayAddon"></span>
</div>

<div class="form-row" id="node-once">
<label for="node-input-once" style="width:160px">
<i class="fa fa-power-off"></i> <span data-i18n="opcuaiiotinject.onstart"></span></label>
<input type="checkbox" id="node-input-once" style="width:40px">
</div>

<div class="form-row">
<label for=""><i class="fa fa-repeat"></i> <span data-i18n="opcuaiiotinject.label.repeat"></span></label>
<select id="opcuaiiotinject-time-type-select">
Expand Down Expand Up @@ -807,16 +820,6 @@
</div>
</div>

<div class="form-row" id="node-once">
<label for="node-input-once" style="width:140px">
<i class="fa fa-power-off"></i> <span data-i18n="opcuaiiotinject.onstart"></span></label>
<input type="checkbox" id="node-input-once" style="width:40px">
</div>
<div class="form-row" id="node-delay">
<label for="node-input-startDelay"><i class="fa fa-clock-o"></i> <span data-i18n="opcuaiiotinject.startDelay"></span></label>
<input type="text" id="node-input-startDelay" placeholder="10" style="width:80px">
</div>

<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
Expand Down Expand Up @@ -896,6 +899,7 @@ <h5>msg.payload.options<h5>

<strong>Repeat</strong>
<p>With the repeat settings you can set a cron configuration.</p>
<p>The interval settings needs a short delay on start. This is equal to the once option but without any inject at to start working.</p>

<strong>Inject once at start</strong>
<p>The 'Delay sec. at start' has to be set to a minimum for starting injects toward the OPC UA server.</p>
Expand Down
22 changes: 14 additions & 8 deletions src/opcua-iiot-inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,19 +134,25 @@ module.exports = function (RED) {
}
})

if (node.once) {
if (node.bianco.iiot.onceTimeout) {
clearTimeout(node.bianco.iiot.onceTimeout)
node.bianco.iiot.onceTimeout = null
}
if (node.bianco.iiot.onceTimeout) {
clearTimeout(node.bianco.iiot.onceTimeout)
node.bianco.iiot.onceTimeout = null
}
let timeout = parseInt(node.bianco.iiot.INPUT_TIMEOUT_MILLISECONDS * node.startDelay)

let timeout = parseInt(node.bianco.iiot.INPUT_TIMEOUT_MILLISECONDS * node.startDelay)
coreInject.internalDebugLog('injecting once at start delay timeout ' + timeout + ' msec.')
if (node.once) {
coreInject.detailDebugLog('injecting once at start delay timeout ' + timeout + ' msec.')
node.bianco.iiot.onceTimeout = setTimeout(function () {
coreInject.internalDebugLog('injecting once at start')
coreInject.detailDebugLog('injecting once at start')
node.emit('input', {})
node.bianco.iiot.repeaterSetup()
}, timeout)
} else if (node.repeat || node.crontab) {
coreInject.detailDebugLog('start with delay timeout ' + timeout + ' msec.')
node.bianco.iiot.onceTimeout = setTimeout(function () {
coreInject.detailDebugLog('had a start delay of ' + timeout + ' msec. to setup inject interval')
node.bianco.iiot.repeaterSetup()
}, timeout)
} else {
node.bianco.iiot.repeaterSetup()
}
Expand Down
82 changes: 79 additions & 3 deletions src/opcua-iiot-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ module.exports = function (RED) {
return msg
}

node.bianco.iiot.handleCrawlerMsg = function (msg) {
coreResponse.analyzeCrawlerResults(node, msg)
if (node.compressStructure) {
coreResponse.compressCrawlerMessageStructure(msg)
}
return msg
}

node.bianco.iiot.handleReadMsg = function (msg) {
coreResponse.analyzeReadResults(node, msg)
if (node.compressStructure) {
Expand Down Expand Up @@ -90,6 +98,9 @@ module.exports = function (RED) {
case 'browse':
message = node.bianco.iiot.handleBrowserMsg(message)
break
case 'crawl':
message = node.bianco.iiot.handleCrawlerMsg(message)
break
case 'read':
message = node.bianco.iiot.handleReadMsg(message)
break
Expand All @@ -109,18 +120,83 @@ module.exports = function (RED) {
return message
}

node.bianco.iiot.extractEntries = function (msg) {
node.bianco.iiot.extractBrowserEntriesFromFilter = function (message) {
let filteredEntries = []
message.payload.browserResults.forEach((item) => {
if (node.bianco.iiot.itemIsNotToFilter(item)) {
filteredEntries.push(item)
}
})
return filteredEntries
}

node.bianco.iiot.extractCrawlerEntriesFromFilter = function (message) {
let filteredEntries = []
message.payload.crawlerResults.forEach((item) => {
if (node.bianco.iiot.itemIsNotToFilter(item)) {
filteredEntries.push(item)
}
})
return filteredEntries
}

node.bianco.iiot.extractPayloadEntriesFromFilter = function (message) {
let filteredEntries = []
msg.payload.forEach((item) => {
message.payload.forEach((item) => {
if (node.bianco.iiot.itemIsNotToFilter(item)) {
filteredEntries.push(item)
}
})
return filteredEntries
}

node.bianco.iiot.extractMethodEntriesFromFilter = function (message) {
let filteredEntries = []
let filteredValues = []
message.addressSpaceItems.forEach((item, index) => {
if (node.bianco.iiot.itemIsNotToFilter(item)) {
filteredEntries.push(item)
filteredValues.push(index)
}
})

let outputArguments = null
if (message.payload.results) {
outputArguments = message.payload.results.outputArguments
} else {
outputArguments = message.payload.outputArguments
}

if (outputArguments) {
outputArguments.forEach((item, index) => {
if (node.bianco.iiot.itemIsNotToFilter(item)) {
if (filteredValues.includes(index)) {
filteredEntries[index].dataType = item.dataType
filteredEntries[index].arrayType = item.arrayType
filteredEntries[index].value = item.value
}
}
})
}

return filteredEntries
}

node.bianco.iiot.extractEntries = function (message) {
switch (message.nodetype) {
case 'browse':
return node.bianco.iiot.extractBrowserEntriesFromFilter(message)
case 'crawl':
return node.bianco.iiot.extractCrawlerEntriesFromFilter(message)
case 'method':
return node.bianco.iiot.extractMethodEntriesFromFilter(message)
default:
return node.bianco.iiot.extractPayloadEntriesFromFilter(message)
}
}

node.bianco.iiot.filterMsg = function (msg) {
if (msg.payload.length) {
if (msg.payload.length || msg.nodetype === 'browse' || msg.nodetype === 'crawl' || msg.nodetype === 'method') {
let filteredEntries = node.bianco.iiot.extractEntries(msg)
if (filteredEntries.length) {
msg.payload = filteredEntries
Expand Down
58 changes: 47 additions & 11 deletions src/opcua-iiot-result-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,13 @@ module.exports = function (RED) {
message.justValue = node.justValue
message.filter = true
message.filtertype = 'filter'
message.payload = node.bianco.iiot.filterByType(msg) || msg.payload
message.payload = node.bianco.iiot.filterByType(message) || message.payload

if (node.justValue) {
message.payload = node.bianco.iiot.filterResult(message)
}

coreFilter.core.assert(message.payload)
node.send(message)
})

Expand Down Expand Up @@ -199,11 +200,11 @@ module.exports = function (RED) {
return result
}

node.bianco.iiot.filterResult = function (msg, result) {
node.bianco.iiot.filterResult = function (msg) {
if (msg.nodetype === 'read' || msg.nodetype === 'listen') {
result = node.bianco.iiot.convertResultValue(msg) || msg.payload
return node.bianco.iiot.convertResultValue(msg) || msg.payload
}
return result
return msg.payload
}

node.bianco.iiot.extractValueFromOPCUAArrayStructure = function (msg, entryIndex) {
Expand Down Expand Up @@ -279,12 +280,12 @@ module.exports = function (RED) {
return result
}

node.bianco.iiot.filterByBrowserType = function (msg) {
node.bianco.iiot.filterListEntryByNodeId = function (list) {
let result = []

if (msg.nodetype === 'browse' && msg.payload.browserResults && msg.payload.browserResults.length) {
msg.payload.browserResults.forEach((item) => {
if (item.nodeId === node.nodeId) {
if (list && list.length) {
list.forEach((item) => {
if (item === node.nodeId) {
result.push(item)
}
})
Expand All @@ -293,11 +294,11 @@ module.exports = function (RED) {
return result
}

node.bianco.iiot.filterByCrawlerType = function (msg) {
node.bianco.iiot.filterListByNodeId = function (list) {
let result = []

if (msg.nodetype === 'crawl' && msg.payload.crawlerResults && msg.payload.crawlerResults.length) {
msg.payload.crawlerResults.forEach((item) => {
if (list && list.length) {
list.forEach((item) => {
if (item.nodeId === node.nodeId) {
result.push(item)
}
Expand All @@ -307,6 +308,41 @@ module.exports = function (RED) {
return result
}

node.bianco.iiot.filterByBrowserType = function (msg) {
let result = node.bianco.iiot.filterListByNodeId(msg.payload.browserResults)

if (msg.addressSpaceItems && msg.addressSpaceItems.length) {
msg.addressSpaceItems = node.bianco.iiot.filterListByNodeId(msg.addressSpaceItems)
}

if (msg.nodesToRead && msg.nodesToRead.length) {
msg.nodesToRead = node.bianco.iiot.filterListEntryByNodeId(msg.nodesToRead)
msg.nodesToReadCount = msg.nodesToRead.length
}

if (msg.addressItemsToRead && msg.addressItemsToRead.length) {
msg.addressItemsToRead = node.bianco.iiot.filterListByNodeId(msg.addressItemsToRead)
msg.addressItemsToReadCount = msg.addressItemsToRead.length
}

if (msg.addressItemsToBrowse && msg.addressItemsToBrowse.length) {
msg.addressItemsToBrowse = node.bianco.iiot.filterListByNodeId(msg.addressItemsToBrowse)
msg.addressItemsToBrowseCount = msg.addressItemsToBrowse.length
}

return result
}

node.bianco.iiot.filterByCrawlerType = function (msg) {
let result = node.bianco.iiot.filterListByNodeId(msg.payload.crawlerResults)

if (msg.addressSpaceItems && msg.addressSpaceItems.length) {
msg.addressItems = node.bianco.iiot.filterListByNodeId(msg.addressSpaceItems)
}

return result
}

node.bianco.iiot.convertDataType = function (result) {
coreFilter.internalDebugLog('data type convert for ' + node.nodeId)
return coreFilter.core.convertDataValueByDataType({value: result}, node.datatype)
Expand Down

0 comments on commit f7662cc

Please sign in to comment.