After creating two Loxone pages full of building blocks, components and connection lines, I decided to go another way: building a simple program that filters the four signals before using them any further.
So, I added the script below to share. Feel free to use it and any comments or suggestions for improvement are welcome!
//
// Smart Sensor Filter
// Tested with Sensor Esylux PD-C360I/8 DC24VPLUS
// Tested with Loxone firmware v10
// By: Richard Verkaik
//
// Version 20180920
//
// Prologue
//
// Many sensors used in toilets and bathrooms, send short signals every 5 seconds
// when an entity is detected. These pulses are hard to use in Loxone, even with
// the Ventilation Programming Block. This filter captures these nasty pulses and
// provides clean, constant signals on the corresponding outputs.
//
// 1. The first 4 analogue ports are monitored for input values > 0 (rising edges)
// 2. First puls is ignored for STP
// 3. The filter applies 2 minutes continuity TIMEOUT
//
// (STP = Swinging Towel Protection)
//
#define BitPort0 8 // 2^3, bit 3 or AI1
#define BitPort1 16 // 2^4, bit 4 or AI2
#define BitPort2 32 // 2^5, bit 5 or AI3
#define BitPort3 64 // 2^6, bit 6 or AI4
#define ON 1
#define OFF 0
enum OutputPorts
{
OutputPort0, // AQ1
OutputPort1, // AQ2
OutputPort2, // AQ3
OutputPort3 // AQ4
};
// Modify these values to meet your own preferences
int nSTPseconds = 10;
int nTIMEOUTseconds = 120;
unsigned int InputStatus [4] = { 0, 0, 0, 0 };
int PortSwitch [4] = { OFF, OFF, OFF, OFF };
int nEvents;
unsigned int nCurrentTime;
void UpdateStatus( int InputNumber ) {
if (getinput(InputNumber) > 0) { // Only respond to Rising Edge
// printf("Event Trigger %d received at %d", InputNumber, nCurrentTime);
if (InputStatus[InputNumber] == 0) {
InputStatus[InputNumber] = 0 - nCurrentTime; // First Pulse
// printf(" InputStatus[%d] Time: %d", InputNumber, InputStatus[InputNumber]);
// printf(" STP time: %d", (-InputStatus[InputNumber]) + nSTPseconds);
} else {
InputStatus[InputNumber] = nCurrentTime; // Following Pulse within nSTPseconds
// printf(" InputStatus[%d] Time: %d", InputNumber, InputStatus[InputNumber]);
// printf(" TIMEOUT time: %d", InputStatus[InputNumber] + nTIMEOUTseconds);
}
if (InputStatus[InputNumber] > 0) {
PortSwitch[InputNumber] = ON;
}
// printf(" PortSwitch %d = %d", InputNumber, PortSwitch[InputNumber]);
}
}
void EvaluatePort( int PortNumber ) {
if (InputStatus[PortNumber] < 0) {
if (((-InputStatus[PortNumber]) + nSTPseconds) < nCurrentTime) {
InputStatus[PortNumber] = 0;
PortSwitch[PortNumber] = OFF;
// printf("Port %d reset due to STP", PortNumber);
}
} else if (InputStatus[PortNumber] > 0) {
if ((InputStatus[PortNumber] + nTIMEOUTseconds) < nCurrentTime) {
InputStatus[PortNumber] = 0;
PortSwitch[PortNumber] = OFF;
// printf("Port %d switched OFF after timeout", PortNumber);
}
}
}
while(TRUE)
{
nCurrentTime = getcurrenttime();
nEvents = getinputevent();
// Process input triggers...
if (nEvents) {
if (nEvents & BitPort0) UpdateStatus(0);
if (nEvents & BitPort1) UpdateStatus(1);
if (nEvents & BitPort2) UpdateStatus(2);
if (nEvents & BitPort3) UpdateStatus(3);
}
// Evaluate Ports...
if (InputStatus[0] != 0) EvaluatePort(0);
if (InputStatus[1] != 0) EvaluatePort(1);
if (InputStatus[2] != 0) EvaluatePort(2);
if (InputStatus[3] != 0) EvaluatePort(3);
// Update all Ports...
setoutput(OutputPort0, PortSwitch[0]);
setoutput(OutputPort1, PortSwitch[1]);
setoutput(OutputPort2, PortSwitch[2]);
setoutput(OutputPort3, PortSwitch[3]);
sleep(300);
}