Hi Folks,
The guys at MySensors were kind to convert this to 1.6 lib.
So being back in Europe for the holidays I decided to create a post with some explanations/tutorial about the code.
This example MockMySensors from the MySensors examples actually combines 30 sensors in a single node.
It may have a poor architecture but it will give you an idea of how to combine sensors and with some feedback we can always improve on the architecture.
It has been designed for you to customize it for the sensor you want to test by uncomment the initial lines.
This line defines your NODE ID, you can always change it to AUTO or to your specification
#define MY_NODE_ID 254
This part of the code defines the sensors you want to work with and their ids
#define ID_S_ARMED 0 // dummy to controll armed stated for several sensors
#define ID_S_DOOR 1
//#define ID_S_MOTION 2
//#define ID_S_SMOKE 3
//#define ID_S_LIGHT 4
//#define ID_S_DIMMER 5
//#define ID_S_COVER 6
//#define ID_S_TEMP 7
//#define ID_S_HUM 8
//#define ID_S_BARO 9
... code lines snipped ...
//#define ID_S_MOISTURE 33
//
//#define ID_S_CUSTOM 99
This part of the code defines the messages you want to instantiate to work with your sensors
#ifdef ID_S_DOOR // V_TRIPPED, V_ARMED
MyMessage msg_S_DOOR_T(ID_S_DOOR,V_TRIPPED);
MyMessage msg_S_DOOR_A(ID_S_DOOR,V_ARMED);
#endif
#ifdef ID_S_MOTION // V_TRIPPED, V_ARMED
MyMessage msg_S_MOTION_A(ID_S_MOTION,V_ARMED);
MyMessage msg_S_MOTION_T(ID_S_MOTION,V_TRIPPED);
#endif
#ifdef ID_S_SMOKE // V_TRIPPED, V_ARMED
MyMessage msg_S_SMOKE_T(ID_S_SMOKE,V_TRIPPED);
MyMessage msg_S_SMOKE_A(ID_S_SMOKE,V_ARMED);
#endif
#ifdef ID_S_LIGHT
MyMessage msg_S_LIGHT(ID_S_LIGHT,V_LIGHT);
bool isLightOn=0;
#endif
... code lines snipped ...
#ifdef ID_S_MOISTURE
// To be implemented
#endif
On the presentation section, you have all the sensors being presented, along with some debugging
void presentation() {
#ifdef ID_S_DOOR
Serial.println(" S_DOOR");
present(ID_S_DOOR,S_DOOR,"Outside Door");
wait(SHORT_WAIT);
#endif
#ifdef ID_S_MOTION
Serial.println(" S_MOTION");
present(ID_S_MOTION,S_MOTION,"Outside Motion");
wait(SHORT_WAIT);
#endif
#ifdef ID_S_SMOKE
Serial.println(" S_SMOKE");
present(ID_S_SMOKE,S_SMOKE,"Kitchen Smoke");
wait(SHORT_WAIT);
#endif
... code lines snipped ...
#ifdef ID_S_CUSTOM
Serial.println(" S_CUSTOM");
present(ID_S_CUSTOM,S_CUSTOM,"Other Stuff");
wait(SHORT_WAIT);
#endif
On the loop section you have methods which will trigger each sensor to report. This will happen periodically on the SLEEP_TIME, 15 minutes by default
void loop()[
//Read Sensors
#ifdef ID_S_DOOR
door();
#endif
#ifdef ID_S_MOTION
motion();
#endif
#ifdef ID_S_SMOKE
smoke();
#endif
... code lines snipped ...
#ifdef ID_S_CUSTOM
custom();
#endif
Lets take a look at one of them, the dimmer. As you can see its just reporting the dimmerVal which was declared as a global variable.
Sometimes these values are saved in the EPROM, for this example I wanted to avoid that.
#ifdef ID_S_DIMMER
void dimmer(){
Serial.print("Dimmer is set to: " );
Serial.println(dimmerVal);
send(msg_S_DIMMER.set(dimmerVal));
}
#endif
Finally the incoming message section.
void receive(const MyMessage &message) {
... code lines snipped ...
#ifdef ID_S_DIMMER
case V_DIMMER:
if ((message.getInt()<0)||(message.getInt()>100)) {
Serial.println( "V_DIMMER data invalid (should be 0..100)" );
break;
}
dimmerVal= message.getInt();
Serial.print("Incoming change for ID_S_DIMMER:");
Serial.print(message.sensor);
Serial.print(", New status: ");
Serial.println(message.getInt());
dimmer();// temp ack
break;
#endif
... code lines snipped ...
The temp ack mean I'm just forcing the sensor to report back the new value to the controller.
And this is basically what it takes to combine sensors in the MySensors library.
One node can have many sensors and each sensor can receive any number or combinations of messages.
So for the dimmer example
#define ID_S_DIMMER 5
... code lines snipped ...
#ifdef ID_S_DIMMER
MyMessage msg_S_DIMMER(ID_S_DIMMER,V_DIMMER);
int dimmerVal=100;
#endif
... code lines snipped ...
void presentation() {
... code lines snipped ...
#ifdef ID_S_DIMMER
Serial.println(" S_DIMMER");
present(ID_S_DIMMER,S_DIMMER,"Living room dimmer");
wait(SHORT_WAIT);
#endif
... code lines snipped ...
There is nothing stoping me to add another message type to the dimmer. So for example if the dimmer does have an on/off button I could add
MyMessage msg_S_DIMMER_BUTTON(ID_S_DIMMER,V_STATUS)
Note that your controller might not be expecting all this freedom of combinations of messages.
So although I could report a temperature on a dimmer sensor using
MyMessage msg_S_DIMMER_BUTTON(ID_S_DIMMER,V_TEMP)
Your controller might not like it.
As always feddback is welcome
Cheers