So a bit like competitors ...
So a bit like competitors ...
I've been playing with your code
@cymplecy: Aha, busted. My code is protected by international laws all over the world, and you changed it anyway ...
P.S. was reading last night this article, and it seems that Google's Blockly team even went to kids at schools to test their UI. Just what we need
I'll think you'll find my mental age is appropriate to the task
I like to think that I CAN think like a kid but many say I DO think like one
Uh oh ... I'm in trouble again!
Prepare yourself for even more hacking.....
So, as I've said before - I am a simple person
So, here are my suggestions for some simple blocks that are similar to the standard change node but allow us to program in Blocky rather than having to use JSONata
Then the existing Json objects category can be used for more advanced programmers
What do you think?
Not much time, so some quick remarks:
- The label '(node) context' seems ok to me, since it uses the naming convention of Node-RED and explains that is about node memory.
- The 'msg' in the dropdown is indeed similar to the Change node, where there is only an input message. However in our blockly node you can build a NEW output message from scratch, or clone existing output messages... And users might wonder why those messages are not in the dropdown. Other ideas from other people?
- The '.' notation is indeed another way to go. But not sure, because it could be that novice users don't understand the dots. But they would surely understand 'Get property X of object Y'.
Moreover I assume that users will also want to get nested properties, for example msg.payload.data. There are 4 different ways to solve that: see article. Anybody suggestions about that??'
I'm just altering the text in your files
I haven't written any JS code at all
I was trying to get it as short as possible (so it could be horizontal) and the object.property nomenclature is the standard NR way but I think your right in that a bit of txt might be better (I just don't like having to use the word "object" as I think its frightening to non-expert Node-REDers)
I'll try out some variations
I didn't worry about msg.payload.data as I think that could still be handled in the Json objects category
My view is that the vast majority of people using Blockly would just want to manipulate the msg.payload object (and the context variables) so give them something easy to use at the top of 1st category e.g get/set/send
Fancy stuff like msg.payload.data etc could be handled by advanced blocks in the Json objects category using one of the nested properties approaches in that article
Back from holiday, so time to share a new version of the Blockly node on Github. I think that almost all feedback has been implemented, except from the timers (which will be postponed to version 0.0.2).
@cymplecy: I have restored the version back to 0.0.1. And be aware that all your local 'hacks' will be lost when you upgrade to the latest version!
All constructive feedback is welcome! Shoot ...
The Node-RED category is now in capitals:
Since nobody was enthousiastic about a model like in OpenHab, I just added a new "on node closed" block to the Node-RED category. This allows users to execute some coding when the node is being stopped (e.g. at a deploy):
P.S. At least one message should arrive at the blockly node, otherwise the close-handler will not be registered (and not called) …
I added (in the 'Logic' category) a new "switch" block, based on an example I found in the Blockly forum (which I had to tweek a bit). In Simon's RGB colour example above, the hexdigit value check had to be repeated six time in the if-else-elseif statement. It seems to me that a switch block is a nice alternative to simplify this. An example:
A new "return and send" block has been added (in the Node-RED category), with 'msg' as default input block:
Since there is no statement after a return, the block has no next statement gap (at the bottom)...
Blockly doesn't offer such a block, since it is integrated in their 'function' block:
Since we are already inside a function (i.e. the on-input-msg-event-handler of our blockly node), we need to offer such a block ourselves ...
A default msg input block has been added (as shadow blocks) for the next 3 blocks:
The 'node' memory label has been changed to '(node)context':
P.S. I haven't added the 'msg' option yet here (see Simon's approval above), since that seems to be someway not completely correct to me at the moment. I would love to have some extra feedback from others about this!
A new category "Buffer" has been added to the toolbox:
I implemented a small part of the NodeJs Buffer API, so users can at least handle buffer data (like images) in their blockly node. The following example shows (see new orange nodes) how it works:
In the above example 3 buffer (variables) are created, data is being copied and the results are stored in the output message:
Some questions already about those Buffer blocks:
- The 'copy from buffer' block will generate a 'copy' statement, so I named it like that. Or should I call it 'clone from buffer' similar like the 'clone msg' block?
- Some blocks don't implement the full API. For example the 'buffer fill' block doesn't has a startIndex and endIndex input. Currently I fill the entire buffer for simplicity. Is that good enough?
Hope you had a nice holiday and are all refreshed
I think we are missing a block to directly set the value of a buffer byte
For my Node-RED/Scratch interface I need to set the 4th byte to the length of the message and i used this approach in my original JS code
var msglength = msg.payload.length; ... var outbuff = new Buffer(4 + msglength); ... outbuff = msglength; ... return msg;
Thanks for this
I'm thinking that this block should just say
return and send
Posted a new version on Github with following changes:
- Added two blocks for getting and setting the value at a specified buffer index:
The problem is that the API is rather large, so I cannot add a block for every available function. Otherwise I end up building Blockly blocks for the remaining of my miserable life, which is not my intension. But you get those two for free, as a payment for your test services
TODO: I have to add a type check, so you can only have an input value of 1 number or character. Don't know at the moment how to achieve that.
- The return block has been updated:
So converted my Node-RED -> Scratch 1.4 message format function node to Blockly
Suggestion, as always , either default byte index to 0 or use Blockly 1-based and get your code to convert the 1 to a 0 for the JS
Obviously pros and cons of using 0 or 1 based indexing.
If I was voting, I'd use standard 1-based indexing in Blockly (as everything else in Blockly is 1-based and I'm a Scratcher and everything is 1-based in that as well) and do the conversion to JS 0-based in your code
Think we can call you 'mister Blockly' from now on, because I wasn't even aware that Blockly is 1-based instead of 0-based...
Found this discussion on the Blockly forum:
Traditionally Blockly uses one-based indexing for strings and lists. This is generally a good choice for beginner programmers, since most people start counting at one. However, there have been periodic calls for Blockly to use zero-based indexing to support more advanced programmers.
Monica has just checked in a significant update to the standard text and lists blocks that allows developers to choose the indexing type. If you want to switch to zero-based indexing set these two properties in your code:
Blockly.Blocks.ONE_BASED_INDEXING = true;
I could take those properties into account in my two Buffer blocks. But that is only useful if the user can set those properties to true/false. Does anybody think it might be useful to add such behaviour to the node's config screen:
Well it definitely needs a note in the Info panel on the right to say that Blockly by default indexes from 1....
I think having a checkbox that lets users switch is a very good way around the problem
I'd change the text to (default) instead of (recommended) so as to stop any wars breaking out
And if users leave it checked, then your Blockly buffer code would need to work behind the scenes to convert
get byte at index 1 of myBuffer to
myBuffer (and same for set byte)
I'd be wary of having checkboxes for options that your target user won't understand the meaning of. It may be one checkbox now, but the temptation is then there to add other options.
I would suggest stick with 1-based indexing, with a note in the info at first. Only add a checkbox if it proves to be a real problem.
Standard Node-RED way of setting the msg payload is to use
So I think Blockly should provide simple blocks looking like this
(I've got rid of dropdown from previous suggestion so that 1st parameter can now be any object and changed the
I think its important to stick with the standard NodeRED order of object followed by property
(Luckily, that is the order the JS code uses so I think that's 2 votes in favour )
msg['payload']; flow.set('limit', 999);
Ok will try to summarize your proposal here, so others can join the discussion without having to dig through the entire history. You want to combine both get-blocks (i.e. get from Object and get from Node-Red memory) into a single get-block, and combine the two set-blocks into a single set-block. To get that done, you introduce new 'global', 'flow' and '(node)context' blocks:
I agree that it looks a bit more similar to the standard Node-Red nodes, and perhaps less confusing if a user has a single get and set block. Some remarks:
The 'property' and 'value' fields have become inline fields (similar to my first version), which means it will be fixed: e.g. when you set it to 'payload', you cannot change that value afterwards. I assume you have done that because you like to have it as a horizontal block of a single line. I would like to keep those fields external, so you can change these values dynamically.
That would make no sense at all. Therefore I'm going to introduce a new Blockly type 'Memory' (similar to my new 'Buffer' type), beside the existing Blockly types like 'String', 'Number', 'Object'... Then I allow both 'Object' OR 'Memory' types in my set/get blocks. But I will have to check that users cannot use these 3 blocks in any other blocks from Google (that have NO type checking to allow every kind of input) !!
Is this more self explaining?
So I think it is possible what you ask, but what do others think about your proposal?
I haven't noticed any difference in how fields can be used between inline modes and external mode. I prefer the look of inline mode but that's all
I realise that trying to allow msg/flow/global/context blocks to be used interchangeably could lead to wrong block in wrong slot but thought that the benefit out-weighed the possible errors.
Maybe a compromise is to just check in the Node-RED category blocks as most possible errors would happen there?
Or maybe revert back to the earlier dropdown msg/flow/global/context to avoid a lot of work? There would still be the Json category blocks to deal with get/setting other objects apart from msg
That could be the start of yet another discussion...
The same input can be inline or external. For example:
Google's design guideline: Use inline inputs when a block is likely to have small inputs such as numbers.
So in our case the input is a property name (i.e. "payload"), so it is indeed making sense to use an internal input:
But when you want to compose the property name dynamically (e.g. to loop over message properties), it doesn't look nice anymore since the block becomes very large. For example:
So we have a number of options to vote for:
- we use inline inputs since most of the time the values will have a short fixed value.
- we use external inputs for cases where the value needs to be generated by N other blocks
- There is also a third option: seems you have a context menu available (at right click) where you can expand all blocks. This way the inline inputs automatically become external. But I have posted an issue on the Blockly forum, since that doesn't seem to work correctly.
That still bothers me, because we need to respect the type checking!
For example the get/set blocks don't do type checking on the value input, since users should be able to store ALL values on the Node-Red memory. But that means that they can even do this:
Storing flow on flow memory makes no sense. So I don't think it is a good idea to have your 3 new blocks (flow/node/global) available in the toolbox....