MySensors Library & Examples  2.3.2
DimmableLight.ino
1 /*
2  * The MySensors Arduino library handles the wireless radio link and protocol
3  * between your home built sensors/actuators and HA controller of choice.
4  * The sensors forms a self healing radio network with optional repeaters. Each
5  * repeater and gateway builds a routing tables in EEPROM which keeps track of the
6  * network topology allowing messages to be routed to nodes.
7  *
8  * Created by Henrik Ekblad <[email protected]>
9  * Copyright (C) 2013-2019 Sensnology AB
10  * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
11  *
12  * Documentation: http://www.mysensors.org
13  * Support Forum: http://forum.mysensors.org
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * version 2 as published by the Free Software Foundation.
18  *
19  *******************************
20  *
21  * REVISION HISTORY
22  * Version 1.0 - January 30, 2015 - Developed by GizMoCuz (Domoticz)
23  *
24  * DESCRIPTION
25  * This sketch provides an example how to implement a Dimmable Light
26  * It is pure virtual and it logs messages to the serial output
27  * It can be used as a base sketch for actual hardware.
28  * Stores the last light state and level in eeprom.
29  *
30  */
31 
32 // Enable debug prints
33 #define MY_DEBUG
34 
35 // Enable and select radio type attached
36 #define MY_RADIO_RF24
37 //#define MY_RADIO_NRF5_ESB
38 //#define MY_RADIO_RFM69
39 //#define MY_RADIO_RFM95
40 
41 #include <MySensors.h>
42 
43 #define CHILD_ID_LIGHT 1
44 
45 #define EPROM_LIGHT_STATE 1
46 #define EPROM_DIMMER_LEVEL 2
47 
48 #define LIGHT_OFF 0
49 #define LIGHT_ON 1
50 
51 #define SN "Dimmable Light"
52 #define SV "1.0"
53 
54 int16_t LastLightState=LIGHT_OFF;
55 int16_t LastDimValue=100;
56 
57 MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
58 MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
59 
60 void setup()
61 {
62  //Retreive our last light state from the eprom
63  int LightState=loadState(EPROM_LIGHT_STATE);
64  if (LightState<=1) {
65  LastLightState=LightState;
66  int DimValue=loadState(EPROM_DIMMER_LEVEL);
67  if ((DimValue>0)&&(DimValue<=100)) {
68  //There should be no Dim value of 0, this would mean LIGHT_OFF
69  LastDimValue=DimValue;
70  }
71  }
72 
73  //Here you actually switch on/off the light with the last known dim level
74  SetCurrentState2Hardware();
75 
76  Serial.println( "Node ready to receive messages..." );
77 }
78 
80 {
81  // Send the Sketch Version Information to the Gateway
82  sendSketchInfo(SN, SV);
83 
84  present(CHILD_ID_LIGHT, S_DIMMER );
85 }
86 
87 void loop()
88 {
89 }
90 
91 void receive(const MyMessage &message)
92 {
93  if (message.getType() == V_LIGHT) {
94  Serial.println( "V_LIGHT command received..." );
95 
96  int lstate= atoi( message.data );
97  if ((lstate<0)||(lstate>1)) {
98  Serial.println( "V_LIGHT data invalid (should be 0/1)" );
99  return;
100  }
101  LastLightState=lstate;
102  saveState(EPROM_LIGHT_STATE, LastLightState);
103 
104  if ((LastLightState==LIGHT_ON)&&(LastDimValue==0)) {
105  //In the case that the Light State = On, but the dimmer value is zero,
106  //then something (probably the controller) did something wrong,
107  //for the Dim value to 100%
108  LastDimValue=100;
109  saveState(EPROM_DIMMER_LEVEL, LastDimValue);
110  }
111 
112  //When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
113  //This means if you previously set the lights dimmer value to 50%, and turn the light ON
114  //it will do so at 50%
115  } else if (message.getType() == V_DIMMER) {
116  Serial.println( "V_DIMMER command received..." );
117  int dimvalue= atoi( message.data );
118  if ((dimvalue<0)||(dimvalue>100)) {
119  Serial.println( "V_DIMMER data invalid (should be 0..100)" );
120  return;
121  }
122  if (dimvalue==0) {
123  LastLightState=LIGHT_OFF;
124  } else {
125  LastLightState=LIGHT_ON;
126  LastDimValue=dimvalue;
127  saveState(EPROM_DIMMER_LEVEL, LastDimValue);
128  }
129  } else {
130  Serial.println( "Invalid command received..." );
131  return;
132  }
133 
134  //Here you set the actual light state/level
135  SetCurrentState2Hardware();
136 }
137 
138 void SetCurrentState2Hardware()
139 {
140  if (LastLightState==LIGHT_OFF) {
141  Serial.println( "Light state: OFF" );
142  } else {
143  Serial.print( "Light state: ON, Level: " );
144  Serial.println( LastDimValue );
145  }
146 
147  //Send current state to the controller
148  SendCurrentState2Controller();
149 }
150 
151 void SendCurrentState2Controller()
152 {
153  if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
154  send(dimmerMsg.set((int16_t)0));
155  } else {
156  send(dimmerMsg.set(LastDimValue));
157  }
158 }
MyMessage is used to create, manipulate, send and read MySensors messages.
Definition: MyMessage.h:289
bool sendSketchInfo(const char *name, const char *version, const bool requestEcho=false)
API declaration for MySensors.
bool send(MyMessage &msg, const bool requestEcho=false)
bool present(const uint8_t sensorId, const mysensors_sensor_t sensorType, const char *description="", const bool requestEcho=false)
void setup()
Called after node initialises but before main loop.
void receive(const MyMessage &message)
Callback for incoming messages.
void presentation()
Node presentation.
uint8_t getType(void) const
Get message type.
uint8_t loadState(const uint8_t pos)
char data[MAX_PAYLOAD_SIZE+1]
Buffer for raw payload data.
Definition: MyMessage.h:660
MyMessage & set(const void *payload, const size_t length)
Set entire payload.
void loop()
Main loop.
void saveState(const uint8_t pos, const uint8_t value)