I should say motivated readers, because this post is long. So thank you for reading!
I reused a PIR flood projector electronic and attached Z-Uno on 3 internal points: PIR detection (before inhibit logic by day light), Lamp Relay command and Day Light detector.
On a ZWave standpoint, my needs are:
- PIR detection should be seen as a Binary Sensor A.
- Day Light detection should be seen as a Binary Sensor B.
- Lamp Relay should be seen as a Binary Switch.
- PIR detection should be able to pilot other ZWave devices trhough Group Associations.
- Lamp should be actionable by other ZWave devices trhough Group Associations.
However, I have some questions on the Z-Uno Channel management.
After some unsuccessful attempts, I started again from scratch progressively to better understand (full code is at the end).
Bellow are all the steps. Unfortunately, I could not put each image just below the text at the right place, because this forum allows only 3 attachments. So I grouped all pictures into a single file and reference them by number.
Step one: just added one Binary Switch for the lamp
Code: Select all
ZUNO_SETUP_CHANNELS(ZUNO_SWITCH_BINARY(getterLamp, setterLamp));
Fig 1
And getterLamp() is called 3 times (see full code at the end)..
If I click on the device 1D01, both lamps on Domoticz are on:
Fig 2
And if I use the device 1D02, only lamp 2 on Domoticz is on
Fig 3
So far so good, just have to know that lamp is device 2.
Questions:
- Why two devices?
- Why this copy of Switch one => Switch two?
- Is that related to the explanations on the "mapp to root device" that we can find from place to place in this forum?
Channel setup becomes:
Code: Select all
ZUNO_SETUP_CHANNELS(
ZUNO_SWITCH_BINARY(getterLamp, setterLamp),
ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_GENERAL_PURPOSE, getterPir)
);
Fig 4
And getterPir () is called 2 times.
On PIR detection (it triggers a zunoSendReport(2)), lamp corresponding to Switch 2 on Domoticz is on.
Fig 5
Not good! Switch 2 is the Relay!
With the experience I got from former trials, I decided to add another sensor. Channel setup becomes:
Code: Select all
ZUNO_SETUP_CHANNELS(
ZUNO_SWITCH_BINARY(getterLamp, setterLamp),
ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_GENERAL_PURPOSE, getterPir),
ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_GENERAL_PURPOSE, getterPir2)
);
PIR detection now triggers a zunoSendReport(3).
Fig 6
And now PIR is not interfering with Relay, I have Relay working as device 02 and PIR working as device 03:
Fig 7
Questions:
- Is this need to add a "dummy" sensor related to the same "mapp to root device" consideration?
- What are those "Sensor", "Alarm Type", "Alarm Level", "Burglar" & "Sensor"? Is it a bad interaction between Z-Uno and DomoticZ?
Channel setup becomes:
Code: Select all
ZUNO_SETUP_CHANNELS(
ZUNO_SWITCH_BINARY(getterLamp, setterLamp),
ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_GENERAL_PURPOSE, getterPir),
ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_GENERAL_PURPOSE, getterPir2),
ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_GENERAL_PURPOSE, getterLum)
);
Fig 8
And it works well with the dashboard:
Fig 9
Groups management
Now, playing with group was really simpler.
Just had to add
Code: Select all
ZUNO_SETUP_ASSOCIATIONS(ZUNO_ASSOCIATION_GROUP_SET_VALUE);
and zunoSendToGroupSetValueCommand(CTRL_GROUP_1, ....
And Driving the Relay was given "out of the box" with standard Group Associations.
Just a question:
The Z-Uno Is showing "1.1" (figure 10) as its ID in the Domoticz Group Association management screen. This is the first time I see such a "doted" notation. Looks weird. Can somebody provide an explanation?
The conclusion
Even if a little bit tricky to understand well, this Z-Uno is really a good device. I think there is a tremendous job done to make it "Arduino like" (including hiding ZWave stack and the 8051 tool chain integration). Congrats for designers!
Thanks again for your reading and (I hope) answers.
Gerard
The whole code is here:
Code: Select all
#define DEBUG
#define REL_PIN 10
#define LED_PIN 13
#define PIR_PIN 6
#define LUM_PIN 22
// Globals holding current states
byte lampState;
byte lastPIRState;
byte pirState;
byte lastLumState;
byte lumState;
ZUNO_SETUP_CHANNELS(
ZUNO_SWITCH_BINARY(getterLamp, setterLamp),
ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_GENERAL_PURPOSE, getterPir),
ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_GENERAL_PURPOSE, getterPir2),
ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_GENERAL_PURPOSE, getterLum)
);
// Groups declaration
// !! Real association groups number are shifted by one. Means CTRL_GROUP_1 is in reality number 2. This is because number 1 is Life Line group.
ZUNO_SETUP_ASSOCIATIONS(ZUNO_ASSOCIATION_GROUP_SET_VALUE);
void setup() {
// Set I/O Directions
pinMode(LED_PIN, OUTPUT);
pinMode(REL_PIN, OUTPUT);
pinMode(PIR_PIN, INPUT);
pinMode(LUM_PIN, INPUT_PULLUP);
// Global variables initialisation
lampState = 0;
pirState = lastPIRState = LOW; // Not reading actual value from pin for this test
lumState = lastLumState = digitalRead(LUM_PIN);
Serial.begin();
}
void loop() {
// Get motion state from PIR
// pirState = digitalRead(PIR_PIN); ==> nor working, using temporarilly analogRead
int val = analogRead(A3);
if (val > 500)
pirState = HIGH;
else
pirState = LOW;
if (pirState != lastPIRState) { // Transition detected on PIR
lastPIRState = pirState; // save new state
if (pirState == HIGH) { // Motion detected
digitalWrite(LED_PIN, HIGH); // LED on
#ifdef DEBUG
Serial.println("Motion detected");
#endif
} else {
digitalWrite(LED_PIN, LOW); // LED off
#ifdef DEBUG
Serial.println("No more motion");
#endif
}
zunoSendReport(3); // Report motion over ZWave
zunoSendToGroupSetValueCommand(CTRL_GROUP_1, (lastPIRState == 0) ? 0 : 0xff); // Trigger Group cmd in case of an association made
}
lumState = digitalRead(LUM_PIN);
if (lumState != lastLumState) { // Change detected on Lum
lastLumState = lumState; // save new state
if (lumState == HIGH) {
#ifdef DEBUG
Serial.println("LUM is HIGH");
#endif
} else {
#ifdef DEBUG
Serial.println("LUM is LOW");
#endif
}
zunoSendReport(4); // Report Lum over ZWave
}
}
// Callback for Lamp Set Value. The Relay on REL pin drives the lamp
void setterLamp(byte value) {
#ifdef DEBUG
Serial.print("setterLamp called with "); Serial.println(value, DEC);
#endif
if (value > 0) {
digitalWrite (REL_PIN, HIGH);
} else {
digitalWrite(REL_PIN, LOW);
}
// we'll save our value for the situation, when the controller will ask us about it
lampState = value;
}
// Callback for Lamp Get Value
byte getterLamp() {
#ifdef DEBUG
Serial.print("getterLamp called, returned "); Serial.println(lampState, DEC);
#endif
return lampState;
}
// Callback for PIR Get Value
byte getterPir() {
#ifdef DEBUG
Serial.print("getterPir called, returned ");Serial.println((lastPIRState == 0) ? 0 : 0xff, HEX);
#endif
return ((lastPIRState == 0) ? 0 : 0xff);
}
// Callback for PIR 2 Get Value
byte getterPir2() {
#ifdef DEBUG
Serial.print("getterPir2 called, returned ");Serial.println((lastPIRState == 0) ? 0 : 0xff, HEX);
#endif
return ((lastPIRState == 0) ? 0 : 0xff);
}
// Callback for Lum Get Value
byte getterLum() {
#ifdef DEBUG
Serial.print("getterLum called, returned ");Serial.println((lumState == 0) ? 0 : 0xff, HEX);
#endif
return ((lumState == 0) ? 0 : 0xff);
}