more G-Labs products

Author Topic: Test result of .execute() ?  (Read 5158 times)

December 16, 2014, 11:27:28 PM
Read 5158 times

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Hi,

I am starting a script that could launch a z-wave command and check the response (for this : http://www.homegenie.it/forum/index.php?topic=230.msg1207#msg1207).
I try something like :
Code: [Select]
Modules.WithName("xxxxx").Command("Basic.Get").Execute();And use it with a try/catch :
Code: [Select]
 
try {
    Modules.WithName("xxxxx").Command("Basic.Get").Execute();
} catch(Exception ex) {
            ///// Send alert //////
}
But if there is no module or no response, it's not be catch by the try/catch ..
So is there a way to have a status of "Execute" command ?

Bye

December 16, 2014, 11:36:21 PM
Reply #1

Gene

  • *****
  • Information
  • Administrator
  • Posts: 1472
  • Tangible is the future!
    • Yet Another Programmer
You don't have a result from a module command. This is because the module itself is supposed to store all up to date values in its parameters.
So when you execute a Z-Wave basic get, you're just asking to update the value of "Status.Level" in the selected module(s).

g.

December 17, 2014, 10:57:19 AM
Reply #2

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Hi Gene,

Ok that's clear.

So is there another way like ?
  • Request a node and see last time this node has a status update
  • Request a node and verify with "ModuleParameterChanged" that this node is really updated
  • Other way ...
My aim is to test my z-wave network is working well (no jamming by a thief).

Bye

December 17, 2014, 01:36:34 PM
Reply #3

Gene

  • *****
  • Information
  • Administrator
  • Posts: 1472
  • Tangible is the future!
    • Yet Another Programmer
It could be added some method to test the freshness of a parameter or wait it to get updated:

Code: [Select]
var module = Module.InDomain("Whatever.Domain").WithAddress("1234").Get();
var parameter = module.Parameter("Status.Level");
var idleTime = parameter.IdleTime; // the parameter is not being update since "idleTime" milliseconds
// ....
module.Command("Basic.Get").Execute();
if (parameter.Wait(5000))
{
    // ok value was updated in the meantime
    var freshValue = parameter.Value;
}
else
{
   // parameter was not updated in the last 5 seconds
   Program.Notify("Warning", "No updates from Status.Level within latest 5 seconds");
}

if you like this, please file a issue on github.

Cheers,
g.

January 04, 2015, 03:35:25 PM
Reply #4

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Hi Gene,

I update in r453 and see the add "parameter.wait" was added. So i try this code (by replacing 5000 to 5, because it seem to be in second instead milliseconds), but it use the "else" part (therefore i see the pop-up in HG UI of the device level updated).

Perhaps "parameter.wait" is launch after the system have receive the result of "module.Command("Basic.Get").Execute();" ?
Any idea ?

I don't use :
Code: [Select]
var idleTime = parameter.IdleTime; // the parameter is not being update since "idleTime" milliseconds
Bye

January 04, 2015, 04:18:54 PM
Reply #5

Gene

  • *****
  • Information
  • Administrator
  • Posts: 1472
  • Tangible is the future!
    • Yet Another Programmer
I was expecting an issue like this.
I think it might be correct to have the .Wait method consider a parameter is updated whenever its timestamp is within a range of 1 second before the .Wait is invoked.
Cloud this be a good solution?
Eventually file a issue to github, also regarding IdleTime property that I totally forget to implement.

Cheers,
g.

January 04, 2015, 07:54:12 PM
Reply #6

Gene

  • *****
  • Information
  • Administrator
  • Posts: 1472
  • Tangible is the future!
    • Yet Another Programmer
Hi nolio,

I think I will change things like this:

Code: [Select]
parameter.RequestUpdate(); // this will store current parameter timestamp
module.Command("Basic.Get").Execute();
if (parameter.WaitUpdate(5)) // will check against previously stored timestamp
{
    // ok value was updated in the meantime
    var freshValue = parameter.Value;
}
else
{
   // parameter was not updated in the last 5 seconds
   Program.Notify("Warning", "No updates from Status.Level within latest 5 seconds");
}

I did reopen the issue.
https://github.com/genielabs/HomeGenie/issues/72

Cheers,
g.
« Last Edit: January 04, 2015, 07:56:11 PM by Gene »

January 04, 2015, 08:56:11 PM
Reply #7

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Gene,

By this change, i am not sure that you can avoid so quick response of basic command. But it probably depend on how you imagine to work for .WaitUpdate.

 .IdleTime, do you mean something that return that the return value is the last time the device has been reuqested ? Or something else ?

Bye

January 04, 2015, 09:18:55 PM
Reply #8

Gene

  • *****
  • Information
  • Administrator
  • Posts: 1472
  • Tangible is the future!
    • Yet Another Programmer
By calling parameter.RequestUpdate(); before sending the command, it will be stored the current timestamp (before the command is sent so...).
Then the parameter.WaitUpdate(); will use that timestamp to find out if the parameter has really been updated.
It will work ;)

g.

January 04, 2015, 09:22:48 PM
Reply #9

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544

January 28, 2015, 12:26:57 AM
Reply #10

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Hi Gene,
I try this in r466 but it's weird because i have a lot of lost. I didn't count the ok and ko response. But i have too much lost.
My code :
Code: [Select]
var capteur = Program.InputField("Test.Capteur").Value;
var module = Modules.WithName(capteur).Get();
var parameter = module.Parameter("Status.Level");
var idleTime = parameter.IdleTime; // the parameter is not being update since "idleTime" milliseconds
while (Program.IsEnabled)
{
  parameter.RequestUpdate(); // this will store current parameter timestamp
  module.Command("Basic.Get").Execute();
  if (parameter.WaitUpdate(5)) // will check against previously stored timestamp
  {
      // ok value was updated in the meantime
      var freshValue = parameter.Value;
      Program.Notify("Ok", "Updates from Status.Level within latest 5 seconds");
  }
  else
  {
     // parameter was not updated in the last 5 seconds
Program.Notify("Warning", "No updates from Status.Level within latest 5 seconds");
  }
}
Can i optimize it ?
Bye

February 09, 2015, 10:35:21 PM
Reply #11

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Hi,
I found a work-around by :
* Delete the following line :
Code: [Select]
module.Command("Basic.Get").Execute();* Add a polling on the device (use of the native HG function "Level Poll"
* Replace 5 seconds by 60 seconds
=> No error again.

So the command :
Code: [Select]
module.Command("Basic.Get").Execute();must be run asynchronously or by another program ... Perhaps problem with
Code: [Select]
parameter.RequestUpdate(); command ?

Bye

February 10, 2015, 09:02:57 PM
Reply #12

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
My script run 24hours without any errors. Tonight, i shutdown my testing device and i got error.
So it works fine ! I have my anti-jamming system !!

I can now optimize my script ... :)
Thanks

February 18, 2015, 09:07:20 PM
Reply #13

nolio

  • *****
  • Information
  • Global Moderator
  • Posts: 544
Hi,
Each time my script is running, my mono process is almost at 100%.
I have no idea how can i reduce the cpu use ...
Usually in script i use the :
Code: [Select]
Program.Setup( () => {
Program.AddInputField("Test.Capteur", "", "Nom du capteur à tester");
});
return true;
---
Code: [Select]
When.ModuleParameterChanged( (module, parameter) =>But in that case, i want to do that all the time. More over, if the zwave signal is jamming i will probably have no "ModuleParameterChanged" so it's useless ..
Someone as an idea ?
My script :
Code: [Select]
while (Program.IsEnabled)
{
  Program.RunAsyncTask(()=>
  {
  parameter.RequestUpdate(); // this will store current parameter timestamp
  if (parameter.WaitUpdate(60)) // will check against previously stored timestamp
  {
      var freshValue = parameter.Value;
      Program.Notify("Ok", "Updates from Status.Level within latest 60 seconds");
  }
  else
  {
      Program.Notify("Ko", "Update failed from Status.Level within latest 60 seconds");
  }
  });
}
Bye

February 18, 2015, 11:42:05 PM
Reply #14

Gene

  • *****
  • Information
  • Administrator
  • Posts: 1472
  • Tangible is the future!
    • Yet Another Programmer
you program do a restless loop because you're using runasynctask that launches a new thread inside a while loop.
this means that your program will spawn infinite threads one after the other.
I think you don't need runasynctask or either put a reasonable pause inside the loop.
is there any reason you're using runasynctask?

g.