request() - please clarify

Moderator: leecollings

Post Reply
hyla
Posts: 36
Joined: Tuesday 08 September 2015 16:44
Target OS: Raspberry Pi / ODroid
Domoticz version: current
Location: Germany
Contact:

request() - please clarify

Post by hyla »

Hi,

I'm not getting anywhere. For my EnergyMeter I really do need to retrieve last known values in case of
power loss. The MySensor API is providing a feature to send and request values like for example V_VAR1.

I've read suggestions to substitute request() and send() with setstate() and loadstate() but those two
require writing into an eeprom and that cannot be done continuously. The eeprom would stop working
after 100.000 or so write cycles.

So please, could anyone clarify that for me: Is request() supported by Domoticz or isn't it?

I need to know to get on :)

Thanks,
Christoph

EDIT: sending the value obviously does work: in the Domoticz database I can find the correct
value for V_VAR1. It's retrieving it that won't work...
User avatar
gizmocuz
Posts: 2706
Joined: Thursday 11 July 2013 18:59
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Top of the world
Contact:

Re: request() - please clarify

Post by gizmocuz »

See my sketch below, its for a watermeter, but it should get you some more understanding.
Yes, requestion V_VAR values works
Spoiler: show
/*
* Pulse Water Meter
*
* GizMoCuz 2015-08-24
*
*/

#include <MySensor.h>
#include <SPI.h>

#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your sensor. (Only 2 and 3 generates interrupt!)
#define SENSOR_INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)

#define PULSE_FACTOR 1000 // Nummber of blinks per m3 of your meter (One rotation/liter)

#define SLEEP_MODE false // flowvalue can only be reported when sleep mode is false.

#define MAX_FLOW 40 // Max flow (l/min) value to report. This filters outliers.

#define CHILD_ID 1 // Id of the sensor child

unsigned long SEND_FREQUENCY = 30000; // Minimum time between send (in milliseconds). We don't want to spam the gateway.

MySensor gw;
MyMessage flowMsg(CHILD_ID,V_FLOW);
MyMessage volumeMsg(CHILD_ID,V_VOLUME);
MyMessage lastCounterMsg(CHILD_ID,V_VAR1);

double ppl = ((double)PULSE_FACTOR)/1000; // Pulses per liter

volatile unsigned long pulseCount = 0;
volatile unsigned long lastBlink = 0;
volatile double flow = 0;
boolean pcReceived = false;
unsigned long oldPulseCount = 0;
unsigned long newBlink = 0;
double oldflow = 0;
double volume =0;
double oldvolume =0;
unsigned long lastSend =0;
unsigned long lastPulse =0;

void setup()
{
gw.begin(incomingMessage);

// initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion)
pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);

// Send the sketch version information to the gateway and Controller
gw.sendSketchInfo("Water Meter", "1.2");

// Register this device as Waterflow sensor
gw.present(CHILD_ID, S_WATER);

pulseCount = oldPulseCount = 0;

// Fetch last known pulse count value from gw
gw.request(CHILD_ID, V_VAR1);

lastSend = lastPulse = millis();

attachInterrupt(SENSOR_INTERRUPT, onPulse, FALLING);
}


void loop()
{
gw.process();
unsigned long currentTime = millis();

// Only send values at a maximum frequency or woken up from sleep
if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY))
{
lastSend=currentTime;

if (!pcReceived) {
//Last Pulsecount not yet received from controller, request it again
gw.request(CHILD_ID, V_VAR1);
return;
}

if (!SLEEP_MODE) {
oldflow = flow;

Serial.print("l/min:");
Serial.println(flow);

// Check that we dont get unresonable large flow value.
// could hapen when long wraps or false interrupt triggered
if (flow<((unsigned long)MAX_FLOW)) {
gw.send(flowMsg.set(flow, 2)); // Send flow value to gw
}
}

// No Pulse count received in 2min
if(currentTime - lastPulse > 120000){
flow = 0;
}

// Pulse count has changed
if ((pulseCount != oldPulseCount)||(!SLEEP_MODE)) {
oldPulseCount = pulseCount;

Serial.print("pulsecount:");
Serial.println(pulseCount);

gw.send(lastCounterMsg.set(pulseCount)); // Send pulsecount value to gw in VAR1

double volume = ((double)pulseCount/((double)PULSE_FACTOR));
if ((volume != oldvolume)||(!SLEEP_MODE)) {
oldvolume = volume;

Serial.print("volume:");
Serial.println(volume, 3);

gw.send(volumeMsg.set(volume, 3)); // Send volume value to gw
}
}
}
if (SLEEP_MODE) {
gw.sleep(SEND_FREQUENCY);
}
}

void incomingMessage(const MyMessage &message) {
if (message.type==V_VAR1) {
unsigned long gwPulseCount=message.getULong();
pulseCount += gwPulseCount;
flow=oldflow=0;
Serial.print("Received last pulse count from gw:");
Serial.println(pulseCount);
pcReceived = true;
}
}

void onPulse()
{
if (!SLEEP_MODE)
{
unsigned long newBlink = micros();
unsigned long interval = newBlink-lastBlink;

if (interval!=0)
{
lastPulse = millis();
if (interval<500000L) {
// Sometimes we get interrupt on RISING, 500000 = 0.5sek debounce ( max 120 l/min)
return;
}
flow = (60000000.0 /interval) / ppl;
}
lastBlink = newBlink;
}
pulseCount++;
}
Quality outlives Quantity!
hyla
Posts: 36
Joined: Tuesday 08 September 2015 16:44
Target OS: Raspberry Pi / ODroid
Domoticz version: current
Location: Germany
Contact:

Re: request() - please clarify

Post by hyla »

I've not delved into this yet but looking over it casually I did not find any obvious differences to my own code
(which all in all is not very different to the demo code on the mySensors page, as Yours).
Before I get going: what is Your setup when You are trying this?
Are You using a repeater node in between?
My controller is on my desk in first floor while my water meter is in the cellar (with two repeaters in between)
and my power meter in on ground floor, with one repeater. Maybe it has got something to do with the
repeaters ...


Thanx,
Christoph
User avatar
gizmocuz
Posts: 2706
Joined: Thursday 11 July 2013 18:59
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Top of the world
Contact:

Re: request() - please clarify

Post by gizmocuz »

Could you post your sketch ?

My Gateway is on the first floor, the water meter in the cellar, no repeater, as the gateway is almost on top of it ;)
I never tried to build a repeater... i could try this, but i dont think it changes anything, it should just pass all messages through

Make sure you are on the latest domoticz version
Quality outlives Quantity!
sundberg84
Posts: 52
Joined: Sunday 17 May 2015 11:20
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Sweden
Contact:

Re: request() - please clarify

Post by sundberg84 »

Hi!

I have the same issue with a repeater and trying to request time or counter from controller. I dont know if this is Domoticz or MySensors problem. It almost feel like the repons with the time/counter from the controller does not go through the repeater...
Controller: Domoticz (Raspberry PI)
Gateways: MySensors (Ethernet W5100), RFLink
hyla
Posts: 36
Joined: Tuesday 08 September 2015 16:44
Target OS: Raspberry Pi / ODroid
Domoticz version: current
Location: Germany
Contact:

Re: request() - please clarify

Post by hyla »

gizmocuz wrote:Could you post your sketch ?
I've used Your very source code example above and the "incoming" routine is never ever called. So, no function.

Meanwhile I've had great problems connecting my sensors on the lower floors to my controller. I've tried a lot,
like reflashing the controller (wasn't sure it had the latest version of mySensors running). Wouldn't work.
So I had a look at some of the EEPROMS of my Arduinos, especially the first part where the Node ID and the
Parent ID was stored. As I wrote I have the controller and one repeater on 1st floor, the energy meter on
ground level and the water meter and another repeater in the cellar. In the EEPROMs I found stuff like
the meter on ground level connecting to the repeater in the cellar which in turn connects to the repeater in the
roof and then the controller. The connection resulting took ages (if it worked at all) and was at best sporadic.
So I reprogrammed the EEPROM of my meter manually, setting it to the appropriate route and this has been working
for the past two hours.

Concerning my original problem I have made up a work-around by writing the values into the Arduino's EEPROM in
case of a power failure and retrieve values afterwards when rebooting. SInce that works for me I'll leave it at that
for now. But since the problem of retrieving values from the controller will definitely come up again I'd like to
look into that further. I suggest to write some minimal code example, try that and using something like the nrf-sniffer
log the resulting traffic. Maybe someone can make something of it. I didn't understand this, really. ;)
My Gateway is on the first floor, the water meter in the cellar, no repeater, as the gateway is almost on top of it ;)
Lucky You :)
I never tried to build a repeater... i could try this, but i dont think it changes anything, it should just pass all messages through
Maybe You should try this. Eventually You might come up with a solution. Who else would? :)
Make sure you are on the latest domoticz version
Always, Gizmocuz. Always ;)

Thanks,
Christoph
alexsh1
Posts: 169
Joined: Wednesday 30 September 2015 11:50
Target OS: Raspberry Pi / ODroid
Domoticz version: v3.8975
Location: United Kingdom
Contact:

Re: request() - please clarify

Post by alexsh1 »

hyla wrote: Meanwhile I've had great problems connecting my sensors on the lower floors to my controller. I've tried a lot,
like reflashing the controller (wasn't sure it had the latest version of mySensors running). Wouldn't work.
Just a suggestion. I noticed that sometimes making nrf24l01+ work is a bit more like shamanic dancing.
Did you try (1) nrf24l01+ with amp at the gateway (2) different nrf24l01+ modules?
There is a huge discussion on MySensors forum about fake modules and their range issues.
Just recently I ordered and received a dead (DOA) module. Luckily it was a completely dead module, not the one
working but with a short range etc.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest