Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[blockly] Add new list, item, persistence, text blocks #1549

Merged
merged 9 commits into from Dec 10, 2022
Expand Up @@ -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' +
Expand Down
Expand Up @@ -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')
Expand All @@ -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')
Expand Down
@@ -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]
}
}
Expand Up @@ -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 = {
Expand All @@ -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'])
}
}
}
}

Expand All @@ -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]
Expand Down
Expand Up @@ -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)
Expand All @@ -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() + '/'
})
}
}
Expand Down
Expand Up @@ -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/')
}
Expand All @@ -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]
}
}
Expand Up @@ -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'

Expand All @@ -34,5 +35,6 @@ export default function (f7, libraryDefinitions, data) {
definePersistenceBlocks(f7)
defineColorBlocks(f7)
defineTextBlocks(f7)
defineListBlocks(f7)
defineLibraries(libraryDefinitions)
}
Expand Up @@ -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}$/;',
Expand All @@ -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'));`,
Expand Down
Expand Up @@ -209,6 +209,23 @@
</shadow>
</value>
</block>
<block type="oh_text_replace">
<value name="pattern">
<shadow type="text">
<field name="TEXT">pattern</field>
</shadow>
</value>
<value name="replacement">
<shadow type="text">
<field name="TEXT">replacement</field>
</shadow>
</value>
<value name="origin">
<shadow type="text">
<field name="TEXT">origin</field>
</shadow>
</value>
</block>
<block type="oh_text_crlf" />
</category>

Expand All @@ -221,6 +238,7 @@
<mutation items="0" />
</block>
<block type="lists_create_with" />
<block type="oh_list_concatenate" />
<block type="lists_repeat">
<value name="NUM">
<shadow type="math_number">
Expand Down Expand Up @@ -357,6 +375,11 @@
<shadow type="oh_item" />
</value>
</block>
<block type="oh_taggeditems">
<value name="tagName">
<shadow type="text" />
</value>
</block>
<block type="oh_event">
<value name="value">
<shadow type="text">
Expand Down