Hi all,
I am modifying a set of nodes to manage a family of i2c port expander chips. Each chip is configured in a hidden config node, where among other things the i2c bus and i2c address are entered. The i2c bus number can be either directly entered or the user can search for available buses and select one from a drop down list (analogous to searching for a serial port in the serial port node). The range of i2c addresses depends on the chip type selected, which in turn dynamically creates a drop down list of valid addresses, usually in the range 0X20 - 0X27. This all works.
A node can be either an input or output node and is connected to a pin of a configured chip (the port expander chips have either 8 or 16 pins, each of which can be either an input or output). Needless to say no 2 nodes can be connected to the same pin. The pin number is selected from a dropdown list, that keeps track of which pins are already in use and limits selection to unused pins only. This too all works.
What I would like to do is likewise limit the selection of an i2c address to available, unused addresses on a bus only (yes I know there could be a completely unrelated chip connected to an i2c address within the range available, but at a certain point it becomes a trade-off between ease of use and user understanding of their own system). So as I do with the input/output nodes, I would like to keep track of which addresses have been used by existing chip configurations when a new hidden chip node is configured. In the input/output nodes' oneditprepare function I can get the list of users of a hidden config through the
RED.nodes.node($('#node-input-chip').val())
object ('#node-input-chip'
refers to the html id that holds the dropdown list of config nodes as they are created). By running through the .users
property of this object I can check how many users there are and for each user disable the selection of that user's pin number. The function in oneditprepare is
function blockUsedPins() {
if (RED.nodes.node($('#node-input-chip').val()) != undefined) {
var chipStuff = RED.nodes.node($('#node-input-chip').val());
for (var i=0; i<chipStuff.users.length;i++) {
if (chipStuff.users[i].id == node.id) {
$('#node-input-bitNum option[value='+chipStuff.users[i].bitNum+']').removeAttr('disabled');
} else {
$('#node-input-bitNum option[value='+chipStuff.users[i].bitNum+']').attr("disabled","disabled").css("background","#a6bbdf");
}
}
$('#node-input-bitNum').find("option:not(:disabled):eq(0)").attr('selected',true); //< set pin number to next available
}
}
(if an input or output node is edited to change its pin number, then its previously selected and therefore disabled pin number needs to be enabled for selection, hence the check of .users[i].id==node.id
).
I would like to do something similar for the i2c address of a config node, but I don't know how to get a config node's id when in the property dialog of a config node (i.e. I am creating a new chip configuration or editing a previously created configuration), nor how to run through all the previously created config nodes and get their i2c bus and address, which I could then use to disable/enable from selection, just like I do for the pin numbers of the input/output nodes.
I tried running through all the hidden configuration nodes from an input/output node, using the dropdown list of hidden configuration nodes. Each config node object contains the properties busNum (=i2c bus) and addr (=i2c address), so the information is available for a selected configuration node. To get all buses and addresses used, I would need to run through all selection options available in this dropdown list. So I tried using
$('#node-input-chip').length
but this was always equal to 1, no matter how long the actual list is??
I have a strong preference to do this client side, so that any errors can be avoided/caught before deploying.