I'm trying to do something that is probably very over complicating according some of you, but its currently the way i want to work.
I want domoticz to sent dimmer values too a mysensors node. I will not use the values for a real dimmer. On the domoticz side i will create a viritual selector switch. This will communicate to a mysensors node build as a V_DIMMER. The selector switch will sent command like 10% to the mysensors node. Code in the mysensors node will convert this to a variable time period.
So basicly:
1) Viritual device in domoticz with button "2 minutes" is pressed
2) a dimmer value of 20% is sent trough JSON, this is sent to through the USB gateway
3) The 20% value is received by the mysensors node, and converted to a integer value of 1 representing 1 minute.
Step 1 and 2 work fine in the current sketch, but i cant do part 3 because the values i sent in domoticz are not the same as received by the mysensors node. For example. 20% in domotics is 23% (or something similar) in mysensors.
I suspect this may be caused by the limitation of the 16 dim values that Domoticz seems to work with. If there a workaround for this, so i can sent a value of 10 from domotics, and this is received as 10 too?
If your interested, the code (still in progress) is below:
Code: Select all
// -------- USED LIBARIES -----------
#include <SPI.h>
#include <MySensor.h>
#include <Countimer.h>
// -----------DEFINE----------------
// Names and identification. This will appear in controller
#define SKETCH_NAME "Irrigation Computer" // Displayed name
#define SKETCH_VER "0.4.2" // Sketch version
#define NODE_ID 100 // Used for the node ID
#define CHILD_ID1 101 // Used for valve 1
#define CHILD_ID2 103 // Used for valve 2
// Defines which IO pins are used
#define SWITCH1 4
#define SWITCH2 5
#define MOTOR1 6
#define MOTOR2 7
// Debug variables
#define SERIALPRINT 1 // change to 1 for serial print debug. Turn to 0 when no debug is needed
unsigned long previousMillis = 0; //timecode for last run of serial print debug
const long interval = 2000; // Serial print debug interval in ms
// Variables for switching the valves
boolean S_VALVE1 = false; // desired status valve 1
boolean S_VALVE2 = false; // desired status valve 2
// Timer variables
int TVALVE1_ONTIME = 0; // desired on time for valve 2 (sent by controler)
int TVALVE1_VAR0 = 0; // On time for valve 1, off state
int TVALVE1_VAR1 = 1; // On time for valve 1, timer 1 (in minutes)
int TVALVE1_VAR2 = 2; // On time for valve 1, timer 2 (in minutes)
int TVALVE1_VAR3 = 5; // On time for valve 1, timer 3 (in minutes)
int TVALVE1_VAR4 = 10; // On time for valve 1, timer 4 (in minutes)
int TVALVE1_VAR5 = 20; // On time for valve 1, timer 5 (in minutes)
int TVALVE2_ONTIME = 0; // desired on time for valve 2 (sent by controler)
int TVALVE2_VAR0 = 0; // On time for valve 2, off state
int TVALVE2_VAR1 = 1; // On time for valve 2, timer 1 (in minutes)
int TVALVE2_VAR2 = 2; // On time for valve 2, timer 2 (in minutes)
int TVALVE2_VAR3 = 5; // On time for valve 2, timer 3 (in minutes)
int TVALVE2_VAR4 = 10; // On time for valve 2, timer 4 (in minutes)
int TVALVE2_VAR5 = 20; // On time for valve 2, timer 5 (in minutes)
// Define other function names
MySensor gw;
MyMessage MSG_V1(CHILD_ID1, V_LIGHT);
int MESSAGE_V1 = 0;
MyMessage MSG_V2(CHILD_ID2, V_DIMMER);
int MESSAGE_V2 = 0;
Countimer tDown1; // Name of timer1
Countimer tDown2; // Name of timer2
// ------------SETUP---------------
// *** Identification ***
void setup(){
gw.begin(incomingMessage, NODE_ID, false); //mysensors initialization. Incomming message function, used node ID, reapeater mode decativated.
gw.sendSketchInfo(SKETCH_NAME, SKETCH_VER); //sent sketch info an version to controler
gw.present(CHILD_ID1, S_LIGHT); //child ID and type of device 1 as seen in controler
gw.present(CHILD_ID2, S_DIMMER); //child ID and type of device 2 as seen in controler
// *** IO SETUP ***
pinMode(SWITCH1,INPUT_PULLUP); //set switch 1 as a input (pin number defined in DEFINE)
pinMode(SWITCH2,INPUT_PULLUP); //set switch 2 as a output (pin number defined in DEFINE)
pinMode(MOTOR1,OUTPUT); //set motor 1 as a output (pin number defined in DEFINE)
digitalWrite(MOTOR1,LOW); //Activate internal pull-down for motor 1
pinMode(MOTOR2,OUTPUT); //set motor 2 as a output (pin number defined in DEFINE)
digitalWrite(MOTOR2,LOW); //Activate internal pull-down for motor 2
// *** MySensors functions ***
gw.send(MSG_V1.set(S_VALVE1 ? 1 : 0)); // Sends status of valve back to controler
gw.send(MSG_V2.set(S_VALVE2 ? 1 : 0)); // Sends status of valve back to controler
// *** timer function ***
//tDown1.setCounter(0, TVALVE1_ONTIME, 0, tDown1.COUNT_DOWN, tDown1Complete); // Setup timer 1
tDown1.setInterval(print_time1, 1000); // Cant remove function for some reason
tDown2.setCounter(0, TVALVE2_ONTIME, 0, tDown2.COUNT_DOWN, tDown2Complete); // Setup timer 2
tDown2.setInterval(print_time2, 1000); // Cant remove function for some reason
if (SERIALPRINT == 1){ //check is debug mode is activated,
Serial.begin(115200); //Set serial print speed
Serial.println("!!!!!!JUST REBOOTED!!!!!!!"); //Reboot warning
Serial.println("!!!!!!JUST REBOOTED!!!!!!!"); //Reboot warning
Serial.println("!!!!!!JUST REBOOTED!!!!!!!");} //Reboot warning
}
// ------------LOOP---------------
void loop()
{
gw.process();
tDown1.run();
//tDown1.start();
tDown2.run();
tDown2.start();
// ------------ I/O logic of valve 1 -------------------
// This code controles the valves based on the status of boolean S_VALVE1. 0 = valve should be closes, 1 = valve should be open
// If valve 1 should be on, but switch 1 says valve 1 is still off, turn on motor 1 to open te valve
if (S_VALVE1 == true && digitalRead(SWITCH1) == HIGH)
{digitalWrite(MOTOR1, HIGH);}
// If valve 1 should be on, and switch 1 says valve 1 is currely on, the valve is in the right position, and the motor should stop turning
if (S_VALVE1 == true && digitalRead(SWITCH1) == LOW)
{digitalWrite(MOTOR1, LOW);}
//If valve 1 should be off, but switch 1 says valve 1 is still on, turn on motor to close the valve
if (S_VALVE1 == false && digitalRead(SWITCH1) == LOW)
{digitalWrite(MOTOR1, HIGH);}
// If valve 1 should be off, and switch 1 says valve 1 is currently off, the valve is in the right position, and the motor should stop turning
if (S_VALVE1 == false && digitalRead(SWITCH1) == HIGH)
{digitalWrite(MOTOR1, LOW);}
// -----------End of I/O logic of valve 1------------------
// Below is the logic of valve 2. The code works the same a valve 1.
if (S_VALVE2 == true && digitalRead(SWITCH2) == HIGH)
{digitalWrite(MOTOR2, HIGH);}
if (S_VALVE2 == true && digitalRead(SWITCH2) == LOW)
{digitalWrite(MOTOR2, LOW);}
if (S_VALVE2 == false && digitalRead(SWITCH2) == LOW)
{digitalWrite(MOTOR2, HIGH);}
if (S_VALVE2 == false && digitalRead(SWITCH2) == HIGH)
{digitalWrite(MOTOR2, LOW);}
// -----------End of I/O logic of valve 2------------------
// ------- Serial printing printing for debug--------------
unsigned long currentMillis = millis(); // set new timestamp for current time
if (currentMillis - previousMillis >= interval && SERIALPRINT == 1) //compare new to old timestamp, if more than the selected interval has elapsed and debug is turned on, print
{previousMillis = currentMillis; // update the "old" timestamp to new value
debugSerialPrint();} //Run debug serial print function
// ------End of serial printing printing for debug---------
}
void incomingMessage(const MyMessage &message) {
if (message.type == V_LIGHT && message.sensor == CHILD_ID1)
{
S_VALVE1 = message.getBool();
gw.send(MSG_V1.set(S_VALVE1 ? 1 : 0)); //sent status of valve 1 (S_VALVE1)
TVALVE1_ONTIME = TVALVE1_VAR1; // set the desired on time to the custom value in TVALVE1_VAR1
tDown1.setCounter(0, TVALVE1_ONTIME, 0, tDown1.COUNT_DOWN, tDown1Complete); // Set up timer 1 (tDown1) as a countdown time counting down from a variable amount of minutes (TVALVE1_ONTIME)
tDown1.start(); // Start timer
TVALVE1_ONTIME = TVALVE1_VAR0; // Reset desired countdown time back to 0 (TVALVE1_VAR0)
}
// ---------------- Mysensor comminucation for valve 2
if (message.type == V_LIGHT || message.type == V_DIMMER) // If the message from the controler is V_LIGHT or V_DIMMER, do the following:
{
MESSAGE_V2 = atoi( message.data ); // Retrieve the power or dim level from the incoming request message, convert it to a integer, and save it to variable
MESSAGE_V2 *= ( message.type == V_LIGHT ? 100 : 1 ); // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
SetLevelToTime2( MESSAGE_V2 ); // Call setLevelToTime function. This will convert the gateway message to a selected time
}
// Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
// gw.send(lightMsg.set(currentLevel > 0 ? 1 : 0));
// hek comment: Is this really nessesary?
//gw.send( dimmerMsg.set(currentLevel) );
}
// if (message.type == V_LIGHT && message.sensor == CHILD_ID2)
// {
// S_VALVE2 = message.getBool();
// gw.send(MSG_V2.set(S_VALVE2 ? 1 : 0));
// }
void SetLevelToTime2(int MESSAGE_V2){
if (MESSAGE_V2 == 0){
TVALVE2_ONTIME = TVALVE2_VAR0;}
else if (MESSAGE_V2 == 10){
TVALVE2_ONTIME = TVALVE2_VAR1;}
else if (MESSAGE_V2 == 20){
TVALVE2_ONTIME = TVALVE2_VAR2;}
else if (MESSAGE_V2 == 30){
TVALVE2_ONTIME = TVALVE2_VAR3;}
else if (MESSAGE_V2 == 40){
TVALVE2_ONTIME = TVALVE2_VAR4;}
else if (MESSAGE_V2 == 50){
TVALVE2_ONTIME = TVALVE2_VAR5;}
else {
TVALVE2_ONTIME = TVALVE2_VAR0;}
}
void print_time1() {} // Cant remove function for some reason
void print_time2() {} // Cant remove function for some reason
void tDown1Complete()
{
S_VALVE1 = 0;
gw.send(MSG_V1.set(S_VALVE1 ? 1 : 0));
}
void tDown2Complete()
{
}
void debugSerialPrint(){
Serial.println("");
Serial.println("");
Serial.println("");
Serial.println("");
Serial.println("--------------------------------------------");
Serial.println("| Debugging mode on! Main variables are: |" );
Serial.println("--------------------------------------------");
Serial.println(" ***************** VALVE 1 : ***************");
Serial.print("Desired running time in min. = ");
Serial.print(TVALVE1_ONTIME);
Serial.println(" (TVALVE1_ONTIME)");
Serial.print("Timer 1 countdown = ");
Serial.print(tDown1.getCurrentTime());
Serial.println(" (tDown1.getCurrentTime())");
Serial.print("Desired status of valve = ");
Serial.print(S_VALVE1);
Serial.println(" (S_VALVE1)");
Serial.print("Phisical switch = ");
Serial.print(digitalRead(SWITCH1));
Serial.println(" (SWITCH1)");
Serial.print("Turn on motor = ");
Serial.print(digitalRead(MOTOR1));
Serial.println(" (MOTOR1)");
Serial.println("");
Serial.println(" ***************** VALVE 2 : ***************");
Serial.print("Controler message ");
Serial.print(MESSAGE_V2);
Serial.println(" (MESSAGE_V2)");
Serial.print("Desired running time in min. = ");
Serial.print(TVALVE2_ONTIME);
Serial.println(" (TVALVE2_ONTIME)");
Serial.print("Timer 2 countdown = ");
Serial.print(tDown2.getCurrentTime());
Serial.println(" (tDown2.getCurrentTime())");
Serial.print("Desired status of valve = ");
Serial.print(S_VALVE2);
Serial.println(" (S_VALVE2)");
Serial.print("Phisical switch = ");
Serial.print(digitalRead(SWITCH2));
Serial.println(" (SWITCH2)");
Serial.print("Turn on motor = ");
Serial.print(digitalRead(MOTOR2));
Serial.println(" (MOTOR2)");
}