diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dateoffsets.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dateoffsets.js
index 5f9b6331ac..57a729ca4c 100644
--- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dateoffsets.js
+++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dateoffsets.js
@@ -212,6 +212,8 @@ export default function (f7) {
this.setOutput(true, 'ZonedDateTime')
this.setColour(70)
let tooltip = 'Parses a text into a ZonedDateTime supporting the following formats detected:\n' +
+ 'HH:mm\n' +
+ 'HH:mm:ss\n' +
'yyyy-MM-dd\n' +
'yyyy-MM-ddTHH:mm\n' +
'yyyy-MM-ddTHH:mm:ss\n' +
diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-items.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-items.js
index 67c203b671..f01bc98df9 100644
--- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-items.js
+++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-items.js
@@ -27,7 +27,7 @@ export default function (f7) {
return [code, 0]
}
- /* get item structures */
+ /* retrieve members of a group */
Blockly.Blocks['oh_groupmembers'] = {
init: function () {
this.appendValueInput('groupName')
@@ -48,6 +48,35 @@ export default function (f7) {
return [code, 0]
}
+ /* retrieve items via their tags */
+ Blockly.Blocks['oh_taggeditems'] = {
+ init: function () {
+ this.appendValueInput('tagName')
+ .appendField('get items with tag')
+ .setCheck('String')
+ this.setInputsInline(false)
+ this.setOutput(true, 'Array')
+ this.setColour(0)
+ this.setTooltip('Retrieve the items that have all the given tags')
+ this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-items-things.html#get-tagged-items')
+ this.setOutput(true, null)
+ }
+ }
+
+ Blockly.JavaScript['oh_taggeditems'] = function (block) {
+ let tagNames = Blockly.JavaScript.valueToCode(block, 'tagName', Blockly.JavaScript.ORDER_ATOMIC)
+ tagNames = tagNames.split(',')
+ let tags = ''
+ for (let i = 0; i < tagNames.length; i++) {
+ if (i > 0) {
+ tags += '\',\''
+ }
+ tags += tagNames[i]
+ }
+ let code = `Java.from(itemRegistry.getItemsByTag(${tags}))`
+ return [code, 0]
+ }
+
Blockly.Blocks['oh_getitem'] = {
init: function () {
this.appendValueInput('itemName')
diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-list.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-list.js
new file mode 100644
index 0000000000..15733020b8
--- /dev/null
+++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-list.js
@@ -0,0 +1,33 @@
+/*
+* Adds new blocks to the list section
+*/
+import Blockly from 'blockly'
+export default function (f7) {
+ /*
+ * allows the concatenate a list into a new list
+ * Block
+ */
+ Blockly.Blocks['oh_list_concatenate'] = {
+ init: function () {
+ this.appendValueInput('list1')
+ .appendField('concatenate')
+ .setCheck('Array')
+ this.appendValueInput('list2')
+ .appendField('to')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .setCheck('Array')
+ this.setInputsInline(true)
+ this.setOutput(true, 'Array')
+ this.setColour('%{BKY_LISTS_HUE}')
+ this.setTooltip('concatenate two arrays returning a new array')
+ this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-standard-ext.html#concatenate-list')
+ }
+ }
+
+ Blockly.JavaScript['oh_list_concatenate'] = function (block) {
+ const list1 = Blockly.JavaScript.valueToCode(block, 'list1', Blockly.JavaScript.ORDER_ATOMIC)
+ const list2 = Blockly.JavaScript.valueToCode(block, 'list2', Blockly.JavaScript.ORDER_ATOMIC)
+ const code = list1 + '.concat(' + list2 + ');\n'
+ return [code, 0]
+ }
+}
diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-persistence.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-persistence.js
index 684d03b413..d4fb784461 100644
--- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-persistence.js
+++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-persistence.js
@@ -16,21 +16,21 @@ export default function defineOHBlocks_Persistence (f7) {
.appendField(new Blockly.FieldDropdown([
['average', 'averageSince'], ['delta', 'deltaSince'],
['deviation', 'deviationSince'], ['variance', 'varianceSince'], ['evolution rate', 'evolutionRate'],
- ['minimum', 'minimumSince'], ['maximum', 'maximumSince'], ['sum', 'sumSince']
- ]
+ ['minimum', 'minimumSince'], ['maximum', 'maximumSince'], ['sum', 'sumSince'],
+ ['previous state value', 'previousState'], ['previous state value time', 'previousStateTime']
+ ], this.handleTypeSelection.bind(this)
), 'methodName')
+ this.methodName = this.getFieldValue('methodName')
this.appendValueInput('itemName')
- .appendField('of the state of item')
+ .appendField('of the state of item named ')
.setAlign(Blockly.ALIGN_RIGHT)
- .setCheck('oh_itemtype')
- this.appendValueInput('dayInfo')
- .appendField('since')
- .setAlign(Blockly.ALIGN_RIGHT)
- .setCheck(['ZonedDateTime'])
+ .setCheck('String', 'oh_item')
+ this.updateShape()
this.setInputsInline(false)
this.setOutput(true, null)
this.setColour(0)
let thisBlock = this
+
this.setTooltip(function () {
let methodName = thisBlock.getFieldValue('methodName')
let TIP = {
@@ -41,11 +41,42 @@ export default function defineOHBlocks_Persistence (f7) {
'evolutionRate': 'Gets the evolution rate of the state of a given Item since a certain point in time',
'minimumSince': 'Gets the minimum value of the State of a persisted Item since a certain point in time',
'maximumSince': 'Gets the maximum value of the State of a persisted Item since a certain point in time',
- 'sumSince': 'Gets the sum of the previous States of a persisted Item since a certain point in time'
+ 'sumSince': 'Gets the sum of the previous States of a persisted Item since a certain point in time',
+ 'previousState': 'Gets the previous state with option to skip to different value as current',
+ 'previousStateTime': 'Gets the time when previous state last occurred with option to skip to different value as current'
}
return TIP[methodName]
})
this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-persistence.html#get-statistical-value-of-an-item')
+ },
+ handleTypeSelection: function (methodName) {
+ if (this.methodName !== methodName) {
+ this.methodName = methodName
+ this.updateShape()
+ }
+ },
+ updateShape: function () {
+ if (this.methodName === 'previousState' || this.methodName === 'previousStateTime') {
+ if (this.getInput('dayInfo')) {
+ this.removeInput('dayInfo')
+ }
+ if (!this.getInput('skipPrevious')) {
+ this.appendValueInput('skipPrevious')
+ .appendField('skip same ')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .setCheck(['Boolean'])
+ }
+ } else {
+ if (this.getInput('skipPrevious')) {
+ this.removeInput('skipPrevious')
+ }
+ if (!this.getInput('dayInfo')) {
+ this.appendValueInput('dayInfo')
+ .appendField('since')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .setCheck(['ZonedDateTime'])
+ }
+ }
}
}
@@ -59,12 +90,32 @@ export default function defineOHBlocks_Persistence (f7) {
const itemName = Blockly.JavaScript.valueToCode(block, 'itemName', Blockly.JavaScript.ORDER_ATOMIC)
const methodName = block.getFieldValue('methodName')
- const dayInfo = Blockly.JavaScript.valueToCode(block, 'dayInfo', Blockly.JavaScript.ORDER_NONE)
+
let code = ''
- if (methodName === 'maximumSince' || methodName === 'minimumSince') {
- code = `${persistence}.${methodName}(itemRegistry.getItem(${itemName}), ${dayInfo}).getState()`
- } else {
- code = `${persistence}.${methodName}(itemRegistry.getItem(${itemName}), ${dayInfo})`
+ let dayInfo = ''
+
+ switch (methodName) {
+ case 'maximumSince':
+ case 'minimumSince':
+ dayInfo = Blockly.JavaScript.valueToCode(block, 'dayInfo', Blockly.JavaScript.ORDER_NONE)
+ code = `${persistence}.${methodName}(itemRegistry.getItem(${itemName}), ${dayInfo}).getState()`
+ break
+
+ case 'previousState':
+ case 'previousStateTime':
+ let skipPrevious = Blockly.JavaScript.valueToCode(block, 'skipPrevious', Blockly.JavaScript.ORDER_NONE)
+ skipPrevious = ((skipPrevious === 'undefined') ? false : skipPrevious)
+ if (methodName === 'previousState') {
+ code = `((${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious})) ? ${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious}).getState(): 'undefined')`
+ } else if (methodName === 'previousStateTime') {
+ code = `((${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious})) ? ${persistence}.previousState(itemRegistry.getItem(${itemName}),${skipPrevious}).getTimestamp() : 'undefined')`
+ }
+ break
+
+ default:
+ dayInfo = Blockly.JavaScript.valueToCode(block, 'dayInfo', Blockly.JavaScript.ORDER_NONE)
+ code = `${persistence}.${methodName}(itemRegistry.getItem(${itemName}), ${dayInfo})`
+ break
}
return [code, Blockly.JavaScript.ORDER_NONE]
diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-scripts.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-scripts.js
index 818e043804..1792a08e7d 100644
--- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-scripts.js
+++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-scripts.js
@@ -105,7 +105,6 @@ export default function defineOHBlocks_Scripts (f7, scripts) {
this.appendValueInput('function')
.appendField('apply')
.appendField(new Blockly.FieldTextInput('MAP'), 'type')
- // .appendField(new Blockly.FieldDropdown([['MAP', 'MAP'], ['REGEX', 'REGEX'], ['JSONPATH', 'JSONPATH']]), 'type')
.appendField('with')
this.setInputsInline(false)
@@ -128,7 +127,7 @@ export default function defineOHBlocks_Scripts (f7, scripts) {
})
this.setHelpUrl(function () {
const type = thisBlock.getFieldValue('type')
- return 'https://www.openhab.org/addons/transformations/' + type.toLowerCase() + '/'
+ return 'https://www.openhab.org/docs/configuration/blockly/rules-blockly-run-and-process.html#transform-values-via-map-regex-or-jsonpath-and-others' + type.toLowerCase() + '/'
})
}
}
diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-text.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-text.js
index eb2beffb47..2aeb2b2faf 100644
--- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-text.js
+++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-text.js
@@ -15,7 +15,7 @@ export default function (f7) {
this.appendDummyInput()
.appendField('CRLF')
this.setOutput(true, 'String')
- this.setColour(160)
+ this.setColour('%{BKY_TEXTS_HUE}')
this.setTooltip('Returns a carriage return line feed (\\r\\n).')
this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/')
}
@@ -25,4 +25,37 @@ export default function (f7) {
let code = '\'\\r\\n\''
return [code, Blockly.JavaScript.ORDER_NONE]
}
+
+ /*
+ * allows to replace a string
+ * Block
+ */
+ Blockly.Blocks['oh_text_replace'] = {
+ init: function () {
+ this.appendValueInput('pattern')
+ .appendField('replace')
+ .setCheck('String')
+ this.appendValueInput('replacement')
+ .appendField('with')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .setCheck('String')
+ this.appendValueInput('origin')
+ .appendField('in')
+ .setAlign(Blockly.ALIGN_RIGHT)
+ .setCheck('String')
+ this.setInputsInline(true)
+ this.setOutput(true, 'String')
+ this.setColour('%{BKY_TEXTS_HUE}')
+ this.setTooltip('returns a new string with one, some, or all matches of a pattern replaced by a replacement. The pattern can be a string or a RegEx. If it is a string, all occurences are replaced.')
+ this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-standard-ext.html#concatenate-list')
+ }
+ }
+
+ Blockly.JavaScript['oh_text_replace'] = function (block) {
+ const pattern = Blockly.JavaScript.valueToCode(block, 'pattern', Blockly.JavaScript.ORDER_ATOMIC)
+ const replacement = Blockly.JavaScript.valueToCode(block, 'replacement', Blockly.JavaScript.ORDER_ATOMIC)
+ const originText = Blockly.JavaScript.valueToCode(block, 'origin', Blockly.JavaScript.ORDER_ATOMIC)
+ const code = originText + '.replaceAll(' + pattern + ',' + replacement + ')'
+ return [code, 0]
+ }
}
diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/index.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/index.js
index 62e504c497..9d0b68dea5 100644
--- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/index.js
+++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/index.js
@@ -13,6 +13,7 @@ import defineScriptsBlocks from './blocks-scripts'
import definePersistenceBlocks from './blocks-persistence'
import defineColorBlocks from './blocks-color'
import defineTextBlocks from './blocks-text'
+import defineListBlocks from './blocks-list'
import { defineLibraries } from './libraries'
@@ -34,5 +35,6 @@ export default function (f7, libraryDefinitions, data) {
definePersistenceBlocks(f7)
defineColorBlocks(f7)
defineTextBlocks(f7)
+ defineListBlocks(f7)
defineLibraries(libraryDefinitions)
}
diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/utils.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/utils.js
index ffc8e87b72..92f6ef282a 100644
--- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/utils.js
+++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/utils.js
@@ -46,6 +46,8 @@ export function addDateSupport () {
'getZonedDateTime', [
'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '(datetime) {',
' datetime = String(datetime).replace(\'T\', \' \')',
+ ' var regex_time_min = /^\\d{2}:\\d{2}$/;',
+ ' var regex_time_sec = /^\\d{2}:\\d{2}:\\d{2}$/;',
' var regex_date = /^\\d{4}-\\d{2}-\\d{2}$/;',
' var regex_date_time_min = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$/;',
' var regex_date_time_sec = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/;',
@@ -55,7 +57,16 @@ export function addDateSupport () {
' var regex_date_time_ms_tz = /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3}[+-]\\d{2}:\\d{2}$/;',
' var regex_date_time_us_tz = /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{6}[+-]\\d{2}:\\d{2}$/;',
' var regex_oh = /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3}[+-]\\d{4}$/;',
+ ' var now = zdt.now();',
+ ' var now_year = now.getYear();',
+ ' var now_month = now.getMonthValue();',
+ ' var now_day = now.getDayOfMonth();',
+ ' var today = \'\' + now_year;',
+ ' today += \'-\' + (\'0\' + now_month).slice(-2);',
+ ' today += \'-\' + (\'0\' + now_day).slice(-2)+\' \';',
' switch (true) {',
+ ` case regex_time_min.test(datetime): return ${zdt}.parse(today + datetime + ':00+00:00', dtf.ofPattern('yyyy-MM-dd HH:mm:ssz'));`,
+ ` case regex_time_sec.test(datetime): return ${zdt}.parse(today + datetime + '+00:00', dtf.ofPattern('yyyy-MM-dd HH:mm:ssz'));`,
` case regex_date.test(datetime): return ${zdt}.parse(datetime + ' 00:00:00+00:00', dtf.ofPattern('yyyy-MM-dd HH:mm:ssz'));`,
` case regex_date_time_min.test(datetime): return ${zdt}.parse(datetime + ':00+00:00', dtf.ofPattern('yyyy-MM-dd HH:mm:ssz'));`,
` case regex_date_time_sec.test(datetime): return ${zdt}.parse(datetime + '+00:00', dtf.ofPattern('yyyy-MM-dd HH:mm:ssz'));`,
diff --git a/bundles/org.openhab.ui/web/src/pages/settings/rules/script/blockly-editor.vue b/bundles/org.openhab.ui/web/src/pages/settings/rules/script/blockly-editor.vue
index d485081edd..36f266d532 100644
--- a/bundles/org.openhab.ui/web/src/pages/settings/rules/script/blockly-editor.vue
+++ b/bundles/org.openhab.ui/web/src/pages/settings/rules/script/blockly-editor.vue
@@ -209,6 +209,23 @@
+
+
+
+ pattern
+
+
+
+
+ replacement
+
+
+
+
+ origin
+
+
+
@@ -221,6 +238,7 @@
+
@@ -357,6 +375,11 @@
+
+
+
+
+