Simulation

Hi,

I am planning to buy an heat pump this year so I’ve installed emoncms locally. Now I would like to simulate data feeding to it, just like they were provided by a real device.
How can I do that? (if possible) Should I send data to a port/device/file descriptor or what?
Regards

PS I am running debian testing

Hello @Raffaele_Morelli, there is an input API described here: Emoncms - site api also available on emoncms running locally from the inputs page, see link “Input api helper”.

For example, posting using a basic csv format:

emoncms/input/post?node=mynode&csv=100,200,300&apikey=APIKEY

@TrystanLea great, thank you.
So I should just send data regularly, with cron for example… so easy :grinning:
Regards

1 Like

Yes that will work. You will aslo need the write apikey for authentication, it is shown on the api helper page or alternatively the user account page.

1 Like

Keep in mind that cron can’t run a script (or other app) at intervals smaller than one minute.
So if you want to simulate sending data at say, 10 second invervals, you’ll need to get creative with cron.

Here’s an example of a simple Python script that can run at the interval you choose.
As written, it prints the text foo and the time, every 5 seconds.

import time, traceback

def every(delay, task):
  next_time = time.time() + delay
  while True:
    time.sleep(max(0, next_time - time.time()))
    try:
      task()
    except Exception:
      traceback.print_exc()
      # in production code you might want to have this instead of course:
      # logger.exception("Problem while executing repetitive task.")
    # skip tasks if we are behind schedule:
    next_time += (time.time() - next_time) // delay * delay + delay

def foo():
  print("foo", time.time())

every(5, foo)

More info from the script author:

  • Exception handling: As far as possible on this level, exceptions are handled properly, i.e. get logged for debugging purposes without aborting the program.
  • No chaining: The common chain-like implementation (for scheduling the next event) you find in many answers is brittle in the sense that if anything goes wrong within the scheduling mechanism,
    (threading.Timer, etc), it terminates the chain. No further execution will happen even if the cause of the problem is fixed. A simple loop and waiting with a simple sleep() is much more robust in comparison.
  • No drift: This solution keeps track of the time it’s supposed to run at. There is no drift depending on the called code’s execution time (as in many other solutions).
  • Skipping: This solution will skip tasks if an execution took too long (e. g. do X every five seconds, but X took 6 seconds). This is the standard cron behavior (and for a good reason). Many other solutions then simply execute the task several times in a row without any delay. For most cases (e. g. cleanup tasks) this is not desired. If it is desired, simply use next_time += delay instead.

Ref:

There are other examples on the page at the link above.

To be fair, you can use cron to run a job at intervals smaller than one minute. Here’s how it can be done:
It’s something of a hack, though…

1 Like

Thank you, I’ll give the script a try.
Anyway I must say 1 minute interval it’s enough to work with for having fun with emoncms, really straightforward, well done IMHO.

YVW,S!

Or use Node-red and the emoncms node or an MQTT input.

Forgot to say, I am using php script (for random values) so I could use sleep inside the script itself.

That should work.

I am currently fine with that simple/rude script and cron :wink:

function gauss() {
	$x=random_0_1();
	$y=random_0_1();

	$u=sqrt(-2*log($x))*cos(2*pi()*$y);
	$v=sqrt(-2*log($x))*sin(2*pi()*$y);

	return $u;
}

function gauss_ms($m=0.0,$s=1.0) {
	return gauss()*$s+$m;
}

function random_0_1() {
	return (float)rand()/(float)getrandmax();
}

function postdata() {
    $temp = gauss_ms(10, 2);
    $hum = gauss_ms(20, 2);
    $man = gauss_ms(49, 1);
    $rit = gauss_ms(39, 2);

    $cms = "curl --data \"node=MyNode&data={mandata:$man,ritorno:$rit,temperature:$temp,humidity:$hum}&apikey=xxxxxxxxxxxxxxxx\" \"http://localhost/emoncms/input/post\"";
    exec($cms);
}

for ($i = 1; $i <= 11; $i++) {
    postdata();
    sleep(5);
}

thumbsup