Good morning everybody I have following Problem:
My controller (pimatic) opens via Gateway my Relay which activates a magnetic valve to fill my pond. depending on the water level, measured by my distance sensor.
By rule pimatic closes the relay if the distance is less or equal to 14cm. NOW: one out of ten my communication fails and pimatic changes the state of the switch in the frontend, therefor the controller thinks the relay is off (valve closed) But in the GW debug I see the the message to turn of was NOACK. Meaning the water keeps running and my pond overflows.
After reading everything I found Pimatic does not resend when NOACK or refuses Statechange when noack. IS IT POSSIBLE to report the state of the relay to the controller periodically like every time a distance Message gets send? Like correcting the "Wrong" state in the controler?
Here is my node Sketch:
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
*
* DESCRIPTION
* Example sketch for a "light switch" where you can control light or something
* else from both HA controller and a local physical button
* (connected between digital pin 3 and GND).
* This node also works as a repeader for other nodes
* http://www.mysensors.org/build/relay
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
#define MY_RF24_PA_LEVEL RF24_PA_MAX
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
// Enabled repeater feature for this node
#define MY_REPEATER_FEATURE
#include <SPI.h>
#include <MySensors.h>
#include <Bounce2.h>
#include <NewPing.h>
#define RELAY_PIN 4 // Arduino Digital I/O pin number for relay
#define BUTTON_PIN 3 // Arduino Digital I/O pin number for button
#define CHILD_ID_RELAY 1 // Id of the sensor child
#define RELAY_ON 1
#define RELAY_OFF 0
#define CHILD_ID_DIST 10
#define TRIGGER_PIN 6 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 5 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 300 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
MyMessage msgDist(CHILD_ID_DIST, V_DISTANCE);
int lastDist;
bool metric = true;
Bounce debouncer = Bounce();
int oldValue=0;
bool state;
MyMessage msgRelay(CHILD_ID_RELAY,V_LIGHT);
long previousMillis = 0; // will store last time Distance was measured
long interval = 10000; // interval at which to measure (milliseconds)
void setup()
{
// Setup the button
pinMode(BUTTON_PIN,INPUT);
// Activate internal pull-up
digitalWrite(BUTTON_PIN,HIGH);
// After setting up the button, setup debouncer
debouncer.attach(BUTTON_PIN);
debouncer.interval(1);
// Make sure relays are off when starting up
digitalWrite(RELAY_PIN, RELAY_OFF);
// Then set relay pins in output mode
pinMode(RELAY_PIN, OUTPUT);
// Set relay to last known state (using eeprom storage)
state = loadState(CHILD_ID_RELAY);
digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
metric = getControllerConfig().isMetric;
}
void presentation() {
// Send the sketch version information to the gateway and Controller
sendSketchInfo("Relay & Button Distance", "1.0");
// Register all sensors to gw (they will be created as child devices)
present(CHILD_ID_RELAY, S_LIGHT);
present(CHILD_ID_DIST, S_DISTANCE);
}
/*
* Example on how to asynchronously check for new messages from gw
*/
void loop()
{
debouncer.update();
// Get the update value
int value = debouncer.read();
if (value != oldValue && value==0) {
send(msgRelay.set(state?false:true), true); // Send new state and request ack back
}
oldValue = value;
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
int dist = metric?sonar.ping_cm():sonar.ping_in();
Serial.print("Ping: ");
Serial.print(dist); // Convert ping time to distance in cm and print result (0 = outside set distance range)
Serial.println(metric?" cm":" in");
if (dist != lastDist) {
send(msgDist.set(dist));
lastDist = dist;
}
}
// sleep(SLEEP_TIME);
}
void receive(const MyMessage &message) {
// We only expect one type of message from controller. But we better check anyway.
if (message.isAck()) {
Serial.println("This is an ack from gateway");
}
if (message.type == V_LIGHT) {
// Change relay state
state = message.getBool();
digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
// Store state in eeprom
saveState(CHILD_ID_RELAY, state);
// Write some debug info
Serial.print("Incoming change for sensor:");
Serial.print(message.sensor);
Serial.print(", New status: ");
Serial.println(message.getBool());
}
}