Skip to content

Commit

Permalink
[blockly] Add more thing blocks (#2562)
Browse files Browse the repository at this point in the history
Fixes #2552.

Add missing blocks to work with a thing or a group of things:

- oh_getthing (one particular)
- oh_getthing_state (the state of the string - to be consistent with
items)
- oh_getthings (get all things - can be used to iterate over all things)
- oh_getthing_attribute (retrieve any attribute of a thing)

---------

Also-by: Florian Hotze <[email protected]>
Signed-off-by: Stefan Höhn <[email protected]>
  • Loading branch information
stefan-hoehn authored May 7, 2024
1 parent 8ed66cc commit 5282f44
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import Blockly from 'blockly'
import { javascriptGenerator } from 'blockly/javascript.js'
import { FieldThingPicker } from './fields/thing-field.js'
import { blockGetCheckedInputType } from './utils.js'

const unavailMsg = 'Advanced Thing blocks aren\'t supported in "application/javascript;version=ECMAScript-5.1"'

export default function defineOHBlocks (f7, isGraalJs) {
Blockly.Blocks['oh_thing'] = {
Expand All @@ -27,6 +30,28 @@ export default function defineOHBlocks (f7, isGraalJs) {
return [code, 0]
}

Blockly.Blocks['oh_getthing'] = {
init: function () {
this.appendValueInput('thingUid')
.appendField('get thing')
.setCheck(['String', 'oh_thing'])
this.setInputsInline(false)
this.setOutput(true, 'oh_thingtype')
this.setColour(0)
this.setTooltip('Get a thing from the thing registry')
this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-items-things.html#get-thing')
}
}

javascriptGenerator.forBlock['oh_getthing'] = function (block) {
const thingUid = javascriptGenerator.valueToCode(block, 'thingUid', javascriptGenerator.ORDER_ATOMIC)
if (isGraalJs) {
return [`things.getThing(${thingUid})`, 0]
} else {
throw new Error(unavailMsg)
}
}

Blockly.Blocks['oh_getthing_state'] = {
init: function () {
this.appendValueInput('thingUid')
Expand All @@ -51,4 +76,130 @@ export default function defineOHBlocks (f7, isGraalJs) {
return [`things.getThingStatusInfo(${thingUid}).getStatus()`, 0]
}
}

Blockly.Blocks['oh_getthings'] = {
init: function () {
this.appendDummyInput()
.appendField('get things')
this.setInputsInline(false)
this.setOutput(true, 'Array')
this.setColour(0)
this.setTooltip('Retrieve all things')
this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-items-things.html#get-things')
this.setOutput(true, null) // Array of Thing objects
}
}

javascriptGenerator.forBlock['oh_getthings'] = function (block) {
if (isGraalJs) {
return ['things.getThings()', 0]
} else {
throw new Error(unavailMsg)
}
}

Blockly.Blocks['oh_getthing'] = {
init: function () {
this.appendValueInput('thingUid')
.appendField('get thing')
.setCheck(['String', 'oh_thing'])
this.setInputsInline(false)
this.setOutput(true, 'oh_thingtype')
this.setColour(0)
this.setTooltip('Get a thing from the thing registry')
this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-items-things.html#get-thing')
}
}

javascriptGenerator.forBlock['oh_getthing'] = function (block) {
const thingUid = javascriptGenerator.valueToCode(block, 'thingUid', javascriptGenerator.ORDER_ATOMIC)
if (isGraalJs) {
return [`things.getThing(${thingUid})`, 0]
} else {
throw new Error(unavailMsg)
}
}

Blockly.Blocks['oh_getthing_attribute'] = {
init: function () {
const block = this
const dropdown = new Blockly.FieldDropdown(
[['UID', 'uid'], ['label', 'label'], ['status', 'status'], ['status info', 'statusInfo'], ['location', 'location'], ['is enabled', 'enabled'], ['thing type UID', 'thingTypeUID'], ['bridge UID', 'bridgeUID']],
function (newMode) {
block._updateType(newMode)
})
this.appendValueInput('thing')
.setCheck(['oh_thingtype', 'oh_thing'])
.appendField('get ')
.appendField(dropdown, 'attributeName')
.appendField('of thing')
this.setInputsInline(false)

this.setOutput(true, 'String')
this.setColour(0)
this.setTooltip('Retrieve a specific attribute from the thing. Note that groups and tags return a list and should be used with the loops-block \'for each item ... in list\'. ')
this.setTooltip(function () {
const attributeName = block.getFieldValue('attributeName')
let TIP = {
'uid': 'unique id of the Thing (string)',
'label': 'label of the Thing (string)',
'status': 'status of the Thing (string)',
'statusInfo': 'detailed status of the Thing (string)',
'location': 'location of the Thing (string)',
'enabled': 'is the thing enabled (boolean)',
'thingTypeUID': 'unique id of the Thing\'s type (string)',
'bridgeUID': 'unique id of the Thing\'s bridge (string)'
}
return TIP[attributeName] + ' \n Note: make sure to use "get thing xxx"-Block for the connected block when working with Variables, not "thing xxx"-Block'
})
this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-items-things.html#get-particular-attributes-of-a-thing')
},
/**
* Modify this block to have the correct output type based on the attribute.
*/
_updateType: function (newAttributeName) {
if (['uid', 'status', 'statusInfo', 'location', 'thingTypeUID', 'bridgeUID'].includes(newAttributeName)) {
this.outputConnection.setCheck('String')
} else if (newAttributeName === 'enabled') {
this.outputConnection.setCheck('Boolean')
} else {
this.outputConnection.setCheck('String')
}
},
/**
* Create XML to represent the input and output types.
* @return {!Element} XML storage element.
* @this {Blockly.Block}
*/
mutationToDom: function () {
let container = Blockly.utils.xml.createElement('mutation')
container.setAttribute('attributeName', this.getFieldValue('attributeName'))
return container
},
/**
* Parse XML to restore the input and output types.
* @param {!Element} xmlElement XML storage element.
* @this {Blockly.Block}
*/
domToMutation: function (xmlElement) {
this._updateType(xmlElement.getAttribute('attributeName'))
}
}

/*
* Provides all attributes from a Thing
* Code part
*/
javascriptGenerator.forBlock['oh_getthing_attribute'] = function (block) {
const thing = javascriptGenerator.valueToCode(block, 'thing', javascriptGenerator.ORDER_ATOMIC)
const inputType = blockGetCheckedInputType(block, 'thing')
const attributeName = block.getFieldValue('attributeName')

if (isGraalJs) {
let code = (inputType === 'oh_thing') ? `things.getThing(${thing}).${attributeName}` : `${thing}.${attributeName}`
return [code, 0]
} else {
throw new Error(unavailMsg)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,21 @@
<shadow type="oh_thing" />
</value>
</block>
<block type="oh_getthing_attribute">
<value name="thing">
<shadow type="oh_getthing">
<value name="thingUid">
<shadow type="oh_thing" />
</value>
</shadow>
</value>
</block>
<block type="oh_getthing">
<value name="thingUid">
<shadow type="oh_thing" />
</value>
</block>
<block type="oh_getthings" />
<block type="oh_thing" />
</category>

Expand Down

0 comments on commit 5282f44

Please sign in to comment.