Define iCbox with different types of buttons shown.
The layout of an IEC ID is: ID,<button_select_mask>,<reset_time>,<reset_mask>
At minimu, ID must be given.
Below are different flavours of the button definition given for an IEC of type IX.
Toggle button
This is the default behaviour.
When you click the button with the left mouse button (further referred to as LMB), the button goes to the "on" state.
Clicking again the LMB button brings the button back to the "off" state.
To achieve this, just define IX.
Example:
IX0
Button follows LMB
For this to happen, the <reset_time> parameter has to be set to -1.
As long as you press the LMB the button is put in the "on" state. Only when you release the LMB the button goes to the "off" state again.
Example: IX0,,-1
Note: since the first parameter <button_select_mask> is not given you have to use the ,, syntax before defining the second parameter <reset_time>.
Note: this cannot be applied to individual buttons. It's all buttons or none.
Limit number of buttons shown
By default all 8 buttons are shown for IX.
If you only want to show a limited amount of buttons, the first parameter <button_selection_mask> of the IX definition has to be used.
Example:
IX0,0b00001111
Only IX0.0 until IX0.3 will be shown in iCbox
Mix of buttons
Playing around with a mix of visble buttons, pushbuttons, timed buttons, mouse-following buttons,... can be found below.
Example:
IX0,0b00001111,100
Only IX0.0 until IX0.3 will be shown in iCbox and those buttons will behave as pushbuttons with an "on" time of 100ms, regardless of how long the LMB is held.
Example:
IX0,0b00001111,300
As before, but now the buttons act as pushbuttons with a fixed "on" duration of 300ms, regardless of how long the left mouse button is held.
This simulates a normal push button press done by a user (kind of...)
Example
IX0,0b10101010,500
Only IX0.1, IX0.3, IX0.5 and IX0.7 will be shown in iCbox and those buttons will behave as pushbuttons with an "on" limited to 500ms, regardless of how long the LMB is held.
Example:
IX0,0b10101010,-1
Same as above, only here the button will be "on" for as long as you press the leLMB. Only when you release the LMB, the button will go back to its "off" state.
Example:
IX0,0b00111111,-1,0b00001111
Only show the first 6 buttons (IX0.0 - IX0.5) of which button IX0.4 and IX0.5 behave as "normal" buttons (see Toggle button) and buttons IX0.0 until IX0.3 are following the LMB action (see Buttons follows LMB above).
Example:
IX0,0b00111111,400,0b00001111
Same as above, only the buttons IX0.0 until IX0.3 are automatically reset to the "off" state after 400ms, regardless of the state of the LMB (pressed or not).
iCbox with different flavours of button representation
The intention is that we can communicate between two Raspberry Pi's using immediateC. To achieve this, one Raspberry Pi has to be the master and another Raspberry Pi has to be the slave.
Should you introduce a third Raspberry Pi, then also that one has to be a slave.
For the master Raspberry Pi nothing changes. The setup as we know, remains as-is. That is:
Ports are defined as 0 for GPIO_A and 1 for GPIO_B
iCserver must be started in the startup script
No special namings have to be taken into account: the master is free to use whatever name he wants to define header names for, e.g., iCbox (using -n as name parameter) or iCmqtt (using -N as name parameter)
Use whatever -I and -Q parameter you want when generating the MQTT files for openHAB.
Use the same -I and -Q parameters in the setup file where you define the iCmqtt setup.
Currently, I've used -I20 and -Q20 on the master Raspberry Pi to generate the MQTT files.
If the master uses "internal" IX-properties (e.g. to control a switch also from an iCbox panel), he's free to use whatever number he wants.
Example:
In the setup file, we can have
-R iCbox -n Test \
IX0,,100 \
IX1,,100 \
IX2,0b10001111,100 \
In the .ic file we can have
imm bit Sw01 = IX0.0;
imm bit Sw02 = IX0.1;
imm bit Sw03 = IX0.2;
imm bit Sw04 = IX0.3;
imm bit Sw05 = IX0.4;
imm bit Sw06 = IX0.5;
imm bit Sw07 = IX0.6;
imm bit Sw08 = IX0.7;
Something similar for IX1 and IX2.
For the slave Raspberry Pi(s), the situation is different, much different! That is:
Ports for the first slave are defined as 2 for GPIO_A and 3 for GPIO_B
Ports for the second slave are defined as 4 for GPIO_A and 5 for GPIO_B
And so on...
We can go to a max. of 8 for GPIO_A and 9 for GPIO_B
iCserver must NOT be started on the slave(s): only one instance of iCserver shall run and that is on the master Raspberry Pi!
When launching a setup on the slave Raspberry Pi and the master is not running yet, the slave will sense and try to connect to the server until iCserver on the master is up and running (or until eternity minus one day...)
The option -o 2 shall be passed as one of the parameters to iCpiI2C to indicate all MCP ports are now mapped on 2 and 3 (see above)
In case yet another slave would be part of the game, then -o 4 shall be passed and so on.
The option -s <ip_address_master_raspberry_pi> shall be passed so that the slave can connect to the iCserver running on the master.
Example currently used:
iCpiI2C -s 192.168.1.40 -o 2 -f -d330 \
All names that are used (file names, header names for iCbox, iCmqtt) must be unique: I deploy the _o2 postfix to make them unique (in case the same filename would initially be used on the different Raspberry Pi's).
Example:
Name of the header of the iCbox on the master: MCP_IO
Name of the header of the iCbox on the slave: MCP_IO_o2
Name of the setup file on the master: setup
Name of the setup file on the slave: setup_o2
Name fo the .ic file on the master: piI2c.ic
Name of the .ic file on the slave: piI2C_o2.ic
And so on... (you get the picture, right?)
When generating MQTT variables you MUST use other -I and -Q numbers during the generation phase: it's not allowed to have the same ones!
A hint: when you generate the MQTT files on the master Raspberry Pi you will get some helpful feedback telling you which -I and -Q values could be used for the generation on the slave Raspberry Pi.
Currently, I've used -I50 and -Q50 for the slave Raspberry Pi to be sure they're not conflicing with the ones used on the master Raspberry Pi (-I20 and -Q20)
I have situations where I want to control a (pulse)relay from pusbuttons located on both floors of our house. This is also possible with immediateC running with a master and a slave Raspberry Pi.
Suppose the following use case:
One pusbutton controlled by the master Raspberry Pi - btn_01 - activates two relays - Rel1 and Rel21 - also controlled by the master Raspberry Pi. The corresponding LED for the pushbutton is led_01.
I want a pushbutton controlled by the slave Raspberry Pi - btn_47 - to also activate the two relays controlled by the master Raspberry Pi. The corresponding LED for the pushbutton is led_47.
To achieve this, a few things must be known:
What's the IEC value of the LED led_01 controlled by the master Raspberry Pi?
What's the IEC value of pushbutton btn_47 controlled by the slave Raspberry Pi?
What's the IEC value of the LED led_47 controlled by the slave Raspberry Pi?
When the above is known, one can start building the connections.
What has to be done on the slave Raspberry Pi?
Well, since LED led_47 controlled by the slave Raspberry Pi has to follow LED led_01 controlled by the master Raspberry Pi, one has to know the IEC value of LED led_01.
In my test setup, the IEC address of LED led_01 controlled by the master Raspberry Pi is QX101.3.
To be able to use the value of QX101.3 on the slave Raspberry Pi this IEC address has to be tagged as extern in the .ic file, like so:
extern QX101.3;
This informs the iCserver that QX101.3 is "received" by the slave Raspberry Pi.
Once this is done, you can connect the LED of the corresponding push button to the value of QX101.3, like so:
imm bit led_47 = QX101.3;
And then, led_47 itself is controlling an I/O pin of one of the MCP23017 I/O expanders controlled by the slave Raspberry Pi. In my case, the following connection is made:
QX153.5 = led_47;
From now on, whenever LED led_01 controlled by the master Raspberry Pi changes level, led_47 will follow. Since led_47 is following led_01, in the end the IEC output QX153.5 will also follow that same level change.
This will then control the hardware pin of the I/O expander and thus the physical LED connected to QX153.1.
So, you could see the immediate variable led_47 as a "glue" between QX101.3 and QX153.2. Amazing, right?
What has to be done on the master Raspberry Pi?
Since we want Rel1 and Rel21 to be controlled not only by btn_01 controlled by the master Raspberry Pi but also by btn_47 controlled by the slave Raspberry Pi, we have to introduce the IEC address of btn_47 at the level of the master Raspberry Pi.
Since the addres of btn_47 is an IX address, there's nothing special that has to be done. Here, there's no need for extern since IX addresses can be received by any application.
The only thing we have to do is to creat an imm bit variable and assign it the debounced and filtered value of the IX IEC address of btn_47.
The IEC value of btn_47 is in my case IX152.1 and is defined in the .ic file as follows:
imm bit btn_47 = RISE(deBounce(IX152.1, t10ms, 50));
This means:
that the button is debounced with a debounce time of 500 ms (10ms x 50)
that btn_01 is only active for a very short time: at the moment the level of the physical button rises. That means, the RISE function is "waiting" until the level of button btn_47 goes high.
This is needed to be able to have a clean and valid pushbutton value for the logic defined in the .ic file.
To be able to use the value of btn_47 on the level of the master Raspberry Pi, we also have to introduce the same code in the .ic file running on the master Raspberry Pi like so:
imm bit gf_btn_47 = RISE(deBounce(IX152.1, t10ms, 50));
I've given the variable a name that refers to the origin of the button. That's a personal choice, but is not necessary. We could have used btn_47 too.
Once gf_btn_47 is defined, there's not much to be done anymore to allow btn_47 of the slave Raspberry Pi to also control Rel1 and Rel21 through that gf_btn_47 immediateC variable: wherever btn_01 of the master Raspberry Pi is used we have to "OR" it with the value of gf_btn_47:
This is how Rel1 is controlled:
imm bit Rel1 = fb_relay
(
btn_01 | gf_btn_47,
RelayGroup_Relay_01_ON | RISE(Sw01),
RelayGroup_Relay_01_OFF | RISE(Sw01)
);
And this is how Rel21 is contolled:
imm bit Rel21 = fb_relay
(
btn_01 | gf_btn_47,
RelayGroup_Relay_01_ON,
RelayGroup_Relay_01_OFF
);
Watch the "OR" construction for both btn_01 and gf_btn_47
And that's it! From now onwards, Rel1 and Rel21 can be controlled not only from 2 different places, but also from 2 different floors!
Yes, immediateC is really powerful. But unfortunately heavily underestimated.