So let’s add the push button on/off functionality to our class file  – since each MCP23S17 chip has 16 GPIO’s we can handle 16 push-button actions per chip, and in reality the code is a simplified cut-down version of the rotary encoder without the switch-a/b code and which is implemented on the following premise –

If a push-button event is captured, then the logic of whether the light is on or off is irrelevant, i.e. from whatever state the light that the enumerated switch relates to, the action is to perform the inverse – e.g. if the light is ‘on’, turn it off, and if it is ‘off’, turn it on.

Here is the code –

Copy to Clipboard

So on the Listener end we’ll see a message with subject ‘switch’ and the switch number…

As with the RotaryEncoder class we can instantiate instances of the switch as follows –

Copy to Clipboard

To handle this on the Listener side we need to add some code to differentiate between messages with the topic ‘light’ and topic ‘switch’, and by reading our .ini file containing our pre-defined ‘min’, ‘max’, and default ‘on’ values we can on a per light fixture basis configure appropriate values for each.

An added ‘feature’ is to enable for each light the ability to set the default ‘on’ value – there are 2 possible strategies to implement this –

  1. Implement some sort of double press algorithm whereby a quick (sub second?) press indicates ‘set this light’s default ‘on value’ to the current light level
  2. Implement a long press algorithm to initiate a similar routine as use case 1

I chose option 1 since it seemed to me to be the most intuitive, but will admit this is a personal preference and others may differ!

Within the code to implement this feature, there is a routine included to persist (save) the user settings back into the .ini file so that these values are persisted  across system restarts/reboots – I myself live in a rural area and momentary power interruptions are not that uncommon….!!

It’s my assumption that updates to these user settings will be rare, and thus the simplest implementation of code to effect these changes actually re-writes the entire .ini file back out to file, and thus while for a Raspberry Pi that file exists on an SD that has a limited ‘write’ life, that in reality the overhead of these additional writes is irrelevant!

Below is the code adding this functionality to the listener code, it assumes there is capability to manage 32 switches, hence 2 PCA9685 devices at addresses ‘0’ & ‘1’ –

Copy to Clipboard