HomeGenie Forum

General Category => General Discussion => Topic started by: xefil on December 29, 2014, 10:01:44 AM

Title: Help Parse Web JSON data
Post by: xefil on December 29, 2014, 10:01:44 AM

The next step will be use the same technique to send data to the same arduino to trigger some actions.

Thanks a lot for the help!

Simon
Title: Re: Help Parse Web JSON data
Post by: mvdarend on December 29, 2014, 10:42:08 AM
Parsing JSON data is very easy in HomeGenie, take a look at the Weather Underground or OpenWeatherData APPs.

Another simple example is my Youless Energy monitor (http://www.homegenie.it/forum/index.php?topic=427.0) APP.
Title: Re: Help Parse Web JSON data
Post by: xefil on December 29, 2014, 03:59:04 PM
Parsing JSON data is very easy in HomeGenie, take a look at the Weather Underground or OpenWeatherData APPs.

Another simple example is my Youless Energy monitor ([url]http://www.homegenie.it/forum/index.php?topic=427.0[/url]) APP.


Thank you for the answer!
I'm starting to create a new program starting from the OpenWeatherData as example. I've written the following hgx file. It will be imported correctly, but trying to check the values I should supply (input), the tab is empty.
I expect to be able to add these values after enabling the program: url, LeafNodeId01, LeafNodeId01Enabled, LeafNodeId02, LeafNodeId02Enabled...
But the "OPTIONS" tab is empty, seems broken, OPTIONS totally missing.
What's wrong?

The Widget (Program.AddControlWidget("xefil/xefilhomearduino/xefilhomearduino");) actually doesn't exist but should in any case show me the popup to enter the data, or not?

HEre my code:

Code: [Select]
<?xml version="1.0" encoding="utf-16"?>
<ProgramBlock xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ConditionType>OnTrue</ConditionType>
  <Conditions />
  <Commands />
  <ScriptCondition>Program.Setup( () =&gt; {
  // list the program as custom weather widget
  Program.AddControlWidget("xefil/xefilhomearduino/xefilhomearduino");

  // set input fields parameters
  Program.AddInputField("URL", "http://192.168.1.1/test.xml", "Arduino 00 Leaf Station URL");
  Program.AddInputField("LeafNodeId01", "0", "Arduino 1st Leaf");
  Program.AddInputField("LeafNodeId01Enabled", "TRUE", "Arduino 1st Leaf Enabled? Set TRUE for YES, FALSE for NO");
  Program.AddInputField("LeafNodeId02", "2", "Arduino 2nd Leaf");
  Program.AddInputField("LeafNodeId02Enabled", "TRUE", "Arduino 2nd Leaf Enabled? Set TRUE for YES, FALSE for NO");
 

  // setup program parameters
  // Leaf 01
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Node").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Cmd").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.HasDHT11").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.DHT11_H").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.DHT11_T").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.HasRelay").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Relay01").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Relay02").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Relay03").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Relay04").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.HasDHT22").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.DHT22_H").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.DHT22_T").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.HasOneWire").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Dallas01").Value = "";
 
  // Leaf 02
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Node").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Cmd").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.HasDHT11").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT11_H").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT11_T").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.HasRelay").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Relay01").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Relay02").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Relay03").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Relay04").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.HasDHT22").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT22_H").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT22_T").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.HasOneWire").Value = "";
  Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Dallas01").Value = "";
         
  Program.Parameter("xefil.XefilHomeArduino.LastUpdated").Value = "";
});

return true;
</ScriptCondition>
  <ScriptSource>

Func&lt;bool&gt; _checkWeather = new Func&lt;bool&gt;(()=&gt;{
  Program.RunAsyncTask(()=&gt;
{
  string webserviceurl = Program.InputField("URL").Value;
     
      TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
      int UTCTimeNow = (int)t.TotalSeconds;
      string UCTTimeNowString = UTCTimeNow.ToString();
     
      Program.Parameter("xefil.XefilHomeArduino.LastUpdated").Value = UCTTimeNowString; //last_updated;
     
      try
      {
 
        // get data
        var data = Net.WebService(webserviceurl).GetData();   
     
        //check for update in data     
        //if(data.dt.ToString() != Program.Parameter("jkUtils.OpenWeatherMap.Dt").Value ) {
        if(0 != 1 ) {

Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Node").Value = data.nodes.node ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Cmd").Value = data.nodes.cmd ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.HasDHT11").Value = data.nodes.has_dht11 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.DHT11_H").Value = data.nodes.DHT11_H ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.DHT11_T").Value = data.nodes.DHT11_T ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.HasRelay").Value = data.nodes.has_relay ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Relay01").Value = data.nodes.relay01 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Relay02").Value = data.nodes.relay02 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Relay03").Value = data.nodes.relay03 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Relay04").Value = data.nodes.relay04 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.HasDHT22").Value = data.nodes.has_dht22 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.DHT22_H").Value = data.nodes.DHT22_H ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.DHT22_T").Value = data.nodes.DHT22_T ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.HasOneWire").Value = data.nodes.has_onewire ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId01.Dallas01").Value = data.nodes.dallas01 ?? "";

Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Node").Value = data.nodes.node ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Cmd").Value = data.nodes.cmd ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.HasDHT11").Value = data.nodes.has_dht11 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT11_H").Value = data.nodes.DHT11_H ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT11_T").Value = data.nodes.DHT11_T ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.HasRelay").Value = data.nodes.has_relay ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Relay01").Value = data.nodes.relay01 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Relay02").Value = data.nodes.relay02 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Relay03").Value = data.nodes.relay03 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Relay04").Value = data.nodes.relay04 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.HasDHT22").Value = data.nodes.has_dht22 ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT22_H").Value = data.nodes.DHT22_H ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT22_T").Value = data.nodes.DHT22_T ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.HasOneWire").Value = data.nodes.has_onewire ?? "";
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.Dallas01").Value = data.nodes.dallas01 ?? "";
   
         
        }
       
        Program.Notify("xefil: XefilHomeArduino","Data has been updated.");
       
      }
      catch (Exception e)
      {               
        Program.Notify("xefil: XefilHomeArduino", "Update of data failed.");
        DEBUG: Program.Notify("XefilHomeArduino ERROR!", e.Message);
        Console.WriteLine( e.Message );
        //Pause(10);       
      }
 
     
     
    });
 
  return true;
});     

//
// web service calls handling
//
When.WebServiceCallReceived("HomeAutomation.HomeGenie.Automation", (args) =&gt; //"HomeGenie.SecuritySystem", ( args ) =&gt;
{
    string[] reqs = ((string)args).Split('/');
    var res = "";
   
    try
    {
      string command = reqs[2];
      string pid = reqs[1];
      if (pid == Program.Module.Address)
      {

        switch(command)
        {
          case "Control.On":

          break;
          case "Control.Off":

            break;
          case "Control.Refresh":
            //Program.Notify("jkutils: OpenWeatherMap","Update triggered.");
          _checkWeather();
            break;
        }

      }
    }
    catch (Exception ex)
    {
      res = "{ 'ResponseValue' : 'ERROR: "   ex.Message   " "   ex.StackTrace   "' }";
    }
    // unable to process request
    return res;

});

while (Program.IsEnabled)
{
  _checkWeather();
  Pause(Program.InputField("UpdateInterval").DecimalValue * 60); // pause before next check
  //Pause(10);
}

</ScriptSource>
  <ScriptErrors />
  <IsRunning>true</IsRunning>
  <Features />
  <LastConditionEvaluationResult>true</LastConditionEvaluationResult>
  <Domain>HomeAutomation.HomeGenie.Automation</Domain>
  <Address>1979</Address>
  <Name>xefil - XefilHomeArduino</Name>
  <Description>Gathers data from XefilHomeArduino</Description>
  <Group>Contrib</Group>
  <ActivationTime>2014-12-29T15:00:00.000000Z</ActivationTime>
  <TriggerTime>2014-12-29T15:00:00.000000Z</TriggerTime>
  <Type>CSharp</Type>
  <IsEnabled>true</IsEnabled>
</ProgramBlock>

Thanks for the help!

Simon
Title: Re: Help Parse Web JSON data
Post by: Gene on December 29, 2014, 06:03:47 PM
Hi xefil,

I tried the code you posted and it's working as expected.
Did you compile the program?

Cheers,
g.
Title: Re: Help Parse Web JSON data
Post by: xefil on December 29, 2014, 07:31:06 PM
Hi xefil,

I tried the code you posted and it's working as expected.
Did you compile the program?

Cheers,
g.

oh sorry, how should i compile it?

Title: Re: Help Parse Web JSON data
Post by: Gene on December 29, 2014, 08:08:21 PM
Like by clicking the "Compile" button?!?!? =)

Cheers,
g.
Title: Re: Help Parse Web JSON data
Post by: xefil on December 30, 2014, 10:07:28 AM
Like by clicking the "Compile" button?!?!? =)

Cheers,
g.

Uhm sorry Gene. I was on an old HG version (411) and the Compile button was missing. I've used the update ACTION on the program after reading your message. Then, updating the software, I've got the correct button.
I'm getting an error and noticing a strange behaviour:
Trying to update the program, I get "CR: Thread creation failed.", seems on line:

Code: [Select]
Func<bool> _checkXefilXML = new Func<bool>(()=>{
How debug?

The whole HGX file is attached.

And then the system seems hangs. I need to restart the software multiple times until the program appears disabled.

Thanks for help!

Simon
Title: Re: Help Parse Web JSON data
Post by: Gene on December 30, 2014, 03:37:19 PM
What system/configuration are you running homegenie on?
Also try avoiding the use of "Program.RunAsyncTask".

Cheers,
g.
Title: Re: Help Parse Web JSON data
Post by: xefil on December 30, 2014, 11:19:46 PM
What system/configuration are you running homegenie on?
Also try avoiding the use of "Program.RunAsyncTask".

Cheers,
g.

I'm using HG on a BananaPI board (armhf Bananian/Raspbian OK).
I would avoit using "Program.RunAsyncTask" but what use instead?
Really I'm using this program to parse a JSON file so I've tried the example from the 'OpenWeatherData' as suggested from mvdarend. Every alternative is OK for me.
The prupose is initially parse an JSON URL content from an Arduino shield. After that I would:
- send HTTP commands to the same Arduino
- graph some values.
But I would start to make one step at time, so first I need to be able to parse the file content. The output from the URL is something like this:

Code: [Select]
{
"nodes":[
{
"node":0,
"cmd":0,
"has_dht11":1,
"DHT11_H":3600,
"DHT11_T":2500,
"has_relay":0,
"relay01":0,
"relay02":0,
"relay03":0,
"relay04":0,
"has_dht22":0,
"DHT22_H":0,
"DHT22_T":0,
"has_onewire":0,
"dallas01":0
},
{
"node":2,
"cmd":0,
"has_dht11":1,
"DHT11_H":4400,
"DHT11_T":1600,
"has_relay":0,
"relay01":0,
"relay02":0,
"relay03":0,
"relay04":0,
"has_dht22":1,
"DHT22_H":2570,
"DHT22_T":140,
"has_onewire":1,
"dallas01":1706
}
]
}

I don't pretend to have the program written by you  ;) (even if a help is always appreciated)
I would try by myself so I'm started from this APP.

Thanks for the help!

Simon
Title: Re: Help Parse Web JSON data
Post by: mvdarend on December 31, 2014, 06:34:20 AM
Here's a post of mine which gives an example of data I'm trying to parse and how it works:

http://www.homegenie.it/forum/index.php?topic=429.0 (http://www.homegenie.it/forum/index.php?topic=429.0)

You're JSON is in an array, so you'll also need to take that into account.
Title: Re: Help Parse Web JSON data
Post by: xefil on January 02, 2015, 11:29:33 AM
Hello!

Could you share with me the code?
The issue seems related to "Func<bool> _checkXefilXML = new Func<bool>(()=>{" (copied from the other example).
In addition Gene suggest not to use RunAsyncTask. So, an example as you've it done could help me :)

Simon
Title: Re: Help Parse Web JSON data
Post by: mvdarend on January 02, 2015, 11:59:27 AM
You're probably better off using my YouLess Energy Monitor  (http://www.homegenie.it/forum/index.php?topic=427) code as it's a lot less complex than the weather examples, I've added an example of the JSON data to the thread so you can compare the code to the data being queried.

If you import the Youless APP and replace all the code in the try block with this it should work. (I haven't tested this though, and I've not queried a JSON array before, so you'll probably have to adapt it a little.)

Code: [Select]
       var myData = Net.WebService("http://192.168.0.100/myJSONPage/").GetData();
       
       // Query the first node, don't know if this is the correct syntax though...
       int DHT22_T = int.Parse(myData.nodes[0].DHT22_T.ToString());
       int DHT22_H = int.Parse(myData.nodes[0].DHT22_H.ToString());
       
       
       Program.Parameter("Sensor.Humidity").Value = DHT22_T; // Should value be divided by 100?
       Program.Parameter("Sensor.Temperature").Value = DHT22_H; // Should value be divided by 100?
Title: Re: Help Parse Web JSON data
Post by: xefil on January 02, 2015, 12:56:35 PM
You're probably better off using my YouLess Energy Monitor  ([url]http://www.homegenie.it/forum/index.php?topic=427[/url]) code as it's a lot less complex than the weather examples, I've added an example of the JSON data to the thread so you can compare the code to the data being queried.

If you import the Youless APP and replace all the code in the try block with this it should work. (I haven't tested this though, and I've not queried a JSON array before, so you'll probably have to adapt it a little.)

Code: [Select]
       var myData = Net.WebService("[url]http://192.168.0.100/myJSONPage/[/url]").GetData();
       
       // Query the first node, don't know if this is the correct syntax though...
       int DHT22_T = int.Parse(myData.nodes[0].DHT22_T.ToString());
       int DHT22_H = int.Parse(myData.nodes[0].DHT22_H.ToString());
       
       
       Program.Parameter("Sensor.Humidity").Value = DHT22_T; // Should value be divided by 100?
       Program.Parameter("Sensor.Temperature").Value = DHT22_H; // Should value be divided by 100?


Thanks for the suggestions!
Seems it starts to work!
I've a little issue here:

Code: [Select]
int DHT22_T = int.Parse(data.nodes[1].DHT22_T.ToString());
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT22_T").Value = (DHT22_T / 100).ToString();

The sensor reads: -120 (yess, it needs to be divided by 100).
After adding the value to the string, I only can read "-1" from the details.

Then, if I leave the "catch (Exception e) " to log in case of errors I get:

- Unexpected symbol `catch'
- Unexpected symbol `e'
- Unexpected symbol `)'

Code: [Select]
     catch (Exception e)
     {
        Program.Notify("xefil: XefilHomeArduino!", "Error retrieving XefilHomeArduino data!");
        //Program.Parameter("YouLess.Current").Value = "ERROR: " + e.Message;
        Console.WriteLine( e.Message );
        Pause(5);
     }

Title: Re: Help Parse Web JSON data
Post by: mvdarend on January 02, 2015, 01:07:15 PM
The first problem sounds like a rounding error, you could try something line this:

Code: [Select]
int DHT22_T = int.Parse(data.nodes[1].DHT22_T.ToString());
double temperature = DHT22_T / 100

Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT22_T").Value = temperature.ToString();

The catch needs to be part of the try.. catch block, like this

Code: [Select]
try
{
  // your code here
}
catch (Exception e)
{
  Program.Notify("xefil: XefilHomeArduino!", "Error retrieving XefilHomeArduino data!");
  //Program.Parameter("YouLess.Current").Value = "ERROR: " + e.Message;
  Console.WriteLine( e.Message );
  Pause(5);
}

* I haven't tested any of the above code, so it may not work out of the box, but it should help you further
Title: Re: Help Parse Web JSON data
Post by: xefil on January 02, 2015, 01:50:52 PM
The first problem sounds like a rounding error, you could try something line this:

Code: [Select]
int DHT22_T = int.Parse(data.nodes[1].DHT22_T.ToString());
double temperature = DHT22_T / 100

Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT22_T").Value = temperature.ToString();


This is not working but you've pointed me to the right direction. I've solved with:

Code: [Select]
float DHT22_T = (float.Parse(data.nodes[1].DHT22_T.ToString()) / 100);
Program.Parameter("xefil.XefilHomeArduino.LeafNodeId02.DHT22_T").Value = DHT22_T.ToString();


The catch needs to be part of the try.. catch block, like this

Code: [Select]
try
{
  // your code here
}
catch (Exception e)
{
  Program.Notify("xefil: XefilHomeArduino!", "Error retrieving XefilHomeArduino data!");
  //Program.Parameter("YouLess.Current").Value = "ERROR: " + e.Message;
  Console.WriteLine( e.Message );
  Pause(5);
}

* I haven't tested any of the above code, so it may not work out of the box, but it should help you further

Thank you for this, that worked well!

So, now I can complete to parse the whole array.
Meanwhile, I've another question (in real I've a lot of questions, but one step per time ;) )
If I would like to graph this values, should they saved in a different way? I've seen in your example it uses 'Meter.Total' and 'Meter.Watts'. Has it to do something with that?

I see they should selectable on "Analysis" page.

Thanks again!

Simon

PS: After that I'll try to create the WIDGET :D
Title: Re: Help Parse Web JSON data
Post by: mvdarend on January 02, 2015, 01:55:40 PM
Quote
This is not working but you've pointed me to the right direction
I see that I forgot the semicolon at the end of the line...  ::)

If you use the parameters Sensor.Humidity and Sensor.Temperature with a sgeneric sensor widget (like used in the YouLess example) the values will show on the Analysis page. (after about 5 minutes or so)

I'm not sure if it will also work on a custom widget, but I can't see why not.
Title: Re: Help Parse Web JSON data
Post by: xefil on January 02, 2015, 02:49:48 PM
Quote
This is not working but you've pointed me to the right direction
I see that I forgot the semicolon at the end of the line...  ::)

If you use the parameters Sensor.Humidity and Sensor.Temperature with a sgeneric sensor widget (like used in the YouLess example) the values will show on the Analysis page. (after about 5 minutes or so)

I'm not sure if it will also work on a custom widget, but I can't see why not.

Now it works! Looks very great!
I was able to get temperature and humidity and place them on the generic widget. The values are now graphed as well.
That's a great point! Now, I think I need to create my own widget because in my array there are different temperatures. I would like to add them all to the widget. I ask you some suggestions:
As you've seen the central arduino expose a json array. It could add more leafes (records) as soon I add new sensors.
Do you suggest to create a program+widget per sensor or put all together into a single widget?

Maybe a good approach would be to have the program with the whole parsing system and then add widgets that are taken from the program. one widget for temperature+humidity of record 1. one widget for relay status from record 1. one widget for temperature+humidity of record 2. .... Possible? Or other suggestions?

About the graphs:
These values should graphed as well. Is there a naming convention that enables the graphs or how it works? I've seen calling the variables Sensor.Humidity it has generated the graph, but don't know how.

Opinions? :)

Thanks!

Simon
Title: Re: Help Parse Web JSON data
Post by: Gene on January 02, 2015, 02:56:03 PM
You can keep using bultin sensor widget to show all values from your app.
The sensor widget will display any parameter that starts with "Sensor.*".
So you can use "Sensor.Temperature.1", "Sensor.Temperature.2" and so on.
If you still want to create your own widget, I suggest to try the online editor:

http://codepen.io/genielabs/public/ (http://codepen.io/genielabs/public/)

there are few examples and also a slightly different sensor widget.

Cheers,
g.
Title: Re: Help Parse Web JSON data
Post by: xefil on January 02, 2015, 03:16:19 PM
You can keep using bultin sensor widget to show all values from your app.
The sensor widget will display any parameter that starts with "Sensor.*".
So you can use "Sensor.Temperature.1", "Sensor.Temperature.2" and so on.
If you still want to create your own widget, I suggest to try the online editor:

[url]http://codepen.io/genielabs/public/[/url] ([url]http://codepen.io/genielabs/public/[/url])

there are few examples and also a slightly different sensor widget.

Cheers,
g.


Hello Gene!
It's ok to use the generic widgets, maybe easier for me. I've tested using the naming convention you've suggested and it works.
The problem is I cannot specify a description on where the sensor is. I can only edit the title, but all temperatures are in the same windget so it's difficult to identfy which is the one I'm reading.
What do you suggest? Do I need to create a new Widget (maybe starting from your example)?
Is possible then to create multiple Widgets pointing to the same program or there is a relationship 1:1? Looking at the code "Program.AddControlWidget("homegenie/generic/sensor");" seems more a 1:1 relationship. One program, one widget. In this case I would need to create a bigger windget with all informations.

Thanks!

Simon
Title: Re: Help Parse Web JSON data
Post by: Gene on January 02, 2015, 03:27:41 PM
You can make your program add multiple sensor modules by using the Program.AddVirtualModules helper function:

AddVirtualModules (http://www.homegenie.it/docs/doxy/de/d1f/class_home_genie_1_1_automation_1_1_scripting_1_1_program_helper.html#a6ce0c82ab9edb50be6689919cf29c1ca)

Code: [Select]
// create 4 virtual modules in the domain HomeAutomation.Arduino with address from 1 to 4
Program.AddVirtualModules("HomeAutomation.Arduino", "Sensor", "homegenie/generic/sensor", 1, 4);

then you program can use the function Program.RaiseEvent to update each sensor value:

Code: [Select]
// update temperature value of Sensor with address 1
var module1 = Modules.InDomain("HomeAutomation.Arduino").WithAddres("1").Get();
Program.RaiseEvent(module1, "Sensor.Temperature", value, "Sensor 1");

g.
Title: Re: Help Parse Web JSON data
Post by: mvdarend on January 02, 2015, 03:38:12 PM
That's exactly how I did it with my temperature sensors, I have 5 separate widgets. That way I can add a single widget per group (ie. Living room, Backyard etc.) and I also have one group, "temperature" with all of the temperature widgets.

Title: Re: Help Parse Web JSON data
Post by: xefil on January 02, 2015, 04:20:38 PM
You can make your program add multiple sensor modules by using the Program.AddVirtualModules helper function:

AddVirtualModules ([url]http://www.homegenie.it/docs/doxy/de/d1f/class_home_genie_1_1_automation_1_1_scripting_1_1_program_helper.html#a6ce0c82ab9edb50be6689919cf29c1ca[/url])

Code: [Select]
// create 4 virtual modules in the domain HomeAutomation.Arduino with address from 1 to 4
Program.AddVirtualModules("HomeAutomation.Arduino", "Sensor", "homegenie/generic/sensor", 1, 4);


Code: [Select]
// update temperature value of Sensor with address 1
var module1 = Modules.InDomain("HomeAutomation.Arduino").WithAddres("1").Get();
Program.RaiseEvent(module1, "Sensor.Temperature", value, "Sensor 1");

g.


Thanks Gene!
I've written a long post to ask for other errors I've then solved by myself :)
Ok, I'm starting to understand it a little bit thanks to both you Gene and mvdarend!

@mvdarend:
The group with all the temperatures is a Widget you've created from new?

@all
What do you suggest to display the status of a relay?
I could get the status via json like temperatures and then act on the relay with an http post.

Suggestions?

Simon
Title: Re: Help Parse Web JSON data
Post by: mvdarend on January 02, 2015, 05:44:30 PM
Quote
The group with all the temperatures is a Widget you've created from new?

No, the group is just a standard HomeGenie group that I filled with widgets:

Configure -> Groups and Modules -> Add Group and then add al of my temperature widgets.
Title: Re: Help Parse Web JSON data
Post by: Gene on January 02, 2015, 07:29:10 PM
for implementing a relay logic you can use the "switch" widget ("homegenie/generic/switch").

g.
Title: Re: Help Parse Web JSON data
Post by: xefil on January 02, 2015, 10:11:09 PM
for implementing a relay logic you can use the "switch" widget ("homegenie/generic/switch").

g.

In this case do I need to make a new program to get the data via web to read the relay status or could I call the same program I've made to get the temperatures? the array I parse is containing all values, from temperature to relay status.
Do you have a relay example I could follow?
I suppose I need to:
- update the status every 'x' time via http get (like done here for temperatures)
- change the status if pressed via http post

Thanks again for the help!
I really like this software every day more :)

Simon

PS: @mvdarend: thanks, I've done the same :)
Title: Re: Help Parse Web JSON data
Post by: xefil on January 05, 2015, 03:47:30 PM
Sorry if I top post again this thread.
Could someone help me with my doubts and needs?
Most of all, an example of a SWITCH logic and how to use it, would be great. Even an example that does nothing or simple write a loca file ON or OFF when the switch button is pressed would be enough to start trying some code.

Thanks a lot!

Simon
Title: Re: Help Parse Web JSON data
Post by: mvdarend on January 05, 2015, 03:57:09 PM
This should get you started, I use the attached code for a couple of virtual switches.

By changing the code here you can create extra virtual switches: (I have two at the moment)
Code: [Select]
Program.AddVirtualModules("HomeAutomation.SettingSwitch", "Switch", "homegenie/generic/switch", 1, 2);
Title: Re: Help Parse Web JSON data
Post by: xefil on January 05, 2015, 04:31:48 PM
This should get you started, I use the attached code for a couple of virtual switches.

By changing the code here you can create extra virtual switches: (I have two at the moment)
Code: [Select]
Program.AddVirtualModules("HomeAutomation.SettingSwitch", "Switch", "homegenie/generic/switch", 1, 2);

Thanks mvdarend!
What does exactly turn the switch ON or OFF?
Code: [Select]
case "Control.On"
This means here I should put the code that will be executed when the Relay is switched to on?

And what does this?
Code: [Select]
case "Control.Toggle"

Thanks a lot!

Simon
Title: Re: Help Parse Web JSON data
Post by: mvdarend on January 05, 2015, 04:44:48 PM
You can control the virtual switches as follows:
Code: [Select]
// Get the Switch by ID
var mySwitch = Modules.InDomain("HomeAutomation.SettingSwitch").WithAddres("1").Get();
// Alternatively get the switch by name (you'll need to add it as a module to a group for this)
var myOtherSwitch = Modules.WithName("MyOtherSwitch").Get();

// Turn Switch on
mySwitch.Command("Control.On").Set();
// or Off
mySwitch.Command("Control.Off").Set();
// or Toggle the switch
mySwitch.Command("Control.Toggle").Set();

Quote
This means here I should put the code that will be executed when the Relay is switched to on?

You could, but putting it in When.ModuleParameterChanged() (http://www.homegenie.it/docs/doxy/d4/dd7/class_home_genie_1_1_automation_1_1_scripting_1_1_events_helper.html#a7e82383574aeff32db8d09d4eb916718) is probably better. I'm not certain about that though, maybe someone else could correct me here.

Quote
And what does this?

This 'toggles' the switch value, so if it was on, it will switch off and vice versa.
Title: Re: Help Parse Web JSON data
Post by: xefil on January 05, 2015, 05:12:35 PM

I'll give a try, thank you!

Simon
Title: Re: Help Parse Web JSON data
Post by: xefil on January 07, 2015, 10:48:50 AM
Hello!

I'm still blocked, cannot understand very well how it works.
As seen, I can get vaules with the previous code I've implemented. Using program and virtual modules I was able to create them and collect informations. Googling on this forum as well as on the sourceforge forum I've found how to query the modules:

http://<MY_IP>/api/HomeAutomation.HomeGenie/Config/Modules.List/

This produces a long list. Let me take this block:

Code: [Select]
{
   "Name": "xefil - XefilHomeArduino",
   "Description": "",
   "DeviceType": "Program",
   "Domain": "HomeAutomation.HomeGenie.Automation",
   "Address": "1007",
   "Properties": [

(..snip...)

       {
           "Name": "xefil.XefilHomeArduino.LeafNodeId01.Relay01",
           "Description": "",
           "Value": "0",
           "UpdateTime": "2015-01-07 09:37:09Z",
           "ValueIncrement": "0",
           "LastValue": "0",
           "LastUpdateTime": "2015-01-07 09:35:12Z"
       },

(..snip...)

       {
           "Name": "xefil.XefilHomeArduino.LeafNodeId01.DHT11_H",
           "Description": "",
           "Value": "36",
           "UpdateTime": "2015-01-07 09:37:09Z",
           "ValueIncrement": "0",
           "LastValue": "36",
           "LastUpdateTime": "2015-01-07 09:35:12Z"
       },
       {
           "Name": "xefil.XefilHomeArduino.LeafNodeId01.DHT11_T",
           "Description": "",
           "Value": "25",
           "UpdateTime": "2015-01-07 09:37:09Z",
           "ValueIncrement": "0",
           "LastValue": "25",
           "LastUpdateTime": "2015-01-07 09:35:12Z"
       },

(..snip...)


To start understanding, how could I create a generic switch that simply write to the console the 'xefil.XefilHomeArduino.LeafNodeId01.DHT11_H' if the switch is ON and the 'xefil.XefilHomeArduino.LeafNodeId01.DHT11_T' if the switch is OFF?

I know, this doesn't make much sense, but it's only a start point to inderstand how to query already collected values. I'll use them later to query the relay status and do something with that later.


Where should I get the values? From here?

Code: [Select]
   "Name": "xefil - XefilHomeArduino",
   "Description": "",
   "DeviceType": "Program",
   "Domain": "HomeAutomation.HomeGenie.Automation",
   "Address": "1007"

Or from here?

Code: [Select]
   "Name": "Corridoio DHT11",
   "Description": "",
   "DeviceType": "Sensor",
   "Domain": "HomeAutomation.XefilHomeArduino",
   "Address": "1"

Also is better to get vaules from the program or from the sensor Widget? Or it's the same?

Thanks again, really!


Simon
Title: Re: Help Parse Web JSON data
Post by: djatie on August 03, 2015, 06:29:16 PM
Waiting for answer too. I need the value to to somthing with my automation. i hop somebody can answer. :)
Title: Re: Help Parse Web JSON data
Post by: djatie on August 08, 2015, 11:26:36 AM
UP UP
Title: Re: Help Parse Web JSON data
Post by: nolio on August 08, 2015, 02:37:56 PM
Hi,
Did you take a look here ?
http://www.homegenie.it/docs/api/overview.html (http://www.homegenie.it/docs/api/overview.html)

I remember last time i found the correct API, i used the "record macro" in action menu. In my case : /api/HomeAutomation.HomeGenie.Automation/90/Control.On/1393535869092.

Control.On/139353586909 isn't very easy to find ... ;)

About "HomeAutomation.XefilHomeArduino" versus "HomeAutomation.HomeGenie.Automation", i don't know but perhaps you can try or use the more easy ...

Not sure to help ...
Bye
Title: Re: Help Parse Web JSON data
Post by: Gene on August 09, 2015, 01:48:56 AM
Hey nolio,

you don't need that 139353586909 number at all. Those numbers in the end HG client API calls are just put to ensure that the web browser is not caching the request. It's old stuff anyway. Use the standard API syntax as explained here http://www.homegenie.it/docs/api/ (http://www.homegenie.it/docs/api/) .



g.
Title: Re: Help Parse Web JSON data
Post by: djatie on August 10, 2015, 06:26:24 PM
this my gpio case control to call from web api

                                  case "Control.Value":
                                 
                                  //var iplocation = Net.WebService("169.254.122.100:8080/api/HomeAutomation.HomeGenie/Config/Modules.Get/RaspberryPi.Gpio/GPIO23/").GetData();
                                 
                                 
                                    WebClient n = new WebClient();
                                    var json = n.DownloadString("http://169.254.122.100:8080/api/HomeAutomation.HomeGenie/Config/Modules.Get/RaspberryPi.Gpio/GPIO23");
                                    string valueOriginal = Convert.ToString(json);
                                 
                                    JObject rss = JObject.Parse(json);

                           //string rssDomain = (string)rss["Domain"];   //working
                                    string itemProperties = (string)rss["Properties"]["Name"][11]; //not working
                                    //JArray status = (JArray)rss["Name"]["Properties"][11]["Name"]; //not working
                                     //string result1 = string.Join("", status); //not working
                                     //IList<string> categoriesText = status.Select(c => (string)c).ToList(); //not working
                                                             
                                  res = itemProperties;
                                  break;
                                 
                                } 
                              //return "{ 'AResponseValue' : 'OK' }";   

i call it use web api
http://169.254.122.100:8080/api/RaspberryPi.Gpio/GPIO23/Control.Value (http://169.254.122.100:8080/api/RaspberryPi.Gpio/GPIO23/Control.Value)
its  show like this

Accessed JArray values with invalid key value: "Name". Array position index expected.   at Newtonsoft.Json.Linq.JArray.get_Item (System.Object key) [0x00000] in <filename unknown>:0
  at HomeGenie.Automation.Scripting.ScriptingInstance+<RunCode>c__AnonStorey0.<>m__2 (System.Object args) [0x00000] in <filename unknown>:0

can help to get data on Properties? for the example "update time:" on "Homegenie scheduled control On", thx for help  :)

{
   "Name": "",
   "Description": "",
   "DeviceType": "Switch",
   "Domain": "RaspberryPi.Gpio",
   "Address": "GPIO23",
   "Properties": [
       {
           "Name": "HomeGenie.ScheduleControl",
           "Description": "",
           "Value": "On",
           "UpdateTime": "2015-08-09 19:53:50Z"
       },
Title: Re: Help Parse Web JSON data
Post by: nolio on August 10, 2015, 09:39:22 PM
you don't need that 139353586909 number at all. Those numbers in the end HG client API calls are just put to ensure that the web browser is not caching the request. It's old stuff anyway. Use the standard API syntax as explained here [url]http://www.homegenie.it/docs/api/[/url] ([url]http://www.homegenie.it/docs/api/[/url]).

Ok i will try without and change my severals call to this API :).
Thanks.
Title: Re: Help Parse Web JSON data
Post by: Jens on December 13, 2016, 04:13:19 PM
Hi,

I'd like to get the value out of this json response

json({
   "version": 16,
   "type": "get_state_sensor",
   "sensor": {
      "number": 2,
      "name": "Temp",
      "type": "temperature",
      "value": 21.5,
      "state": [],
      "unit": "°C",
      "utime": 1481641629,
      "date": {
         "weekday": "tu",
         "day": 13,
         "month": 12,
         "year": 2016
      },
      "time": {
         "hour": 16,
         "min": 7,
         "sec": 9
      }
   }
})

I tried with

var SensorData = Net.WebService(webserviceurl).GetData();
string Temperature = int.Parse(SensorData.sensor.value.ToString());

Which is unfortunate not working.

Could the json(....) be the problem? I have no chance to get rid of it.

Anybody any idea?

Many thanks
Cheers
Jens


Title: Re: Help Parse Web JSON data
Post by: Bounz on January 28, 2017, 08:48:06 PM
Hi, Jens.

Yes, the json(....) is the problem, as it's not a valid JSON object. You need that your response contains only inner part, {...}.
Title: Re: Help Parse Web JSON data
Post by: Jens on January 31, 2017, 01:17:24 PM
Hi Bounz,

this is what I assumed, unfortunate there's no way in getting rid of this, as the firmware is not accessible in any way.

Thanks
Jens
Title: Re: Help Parse Web JSON data
Post by: raptorjr on January 31, 2017, 02:21:50 PM
You don't have access to any string manipulation functions where you receive this JSON? Shouldn't be that hard to remove everything before, and including, the first ( and the the same with the last ) if you have that.
Don't know anything about JSON, but looking at your example it doesn't look like ( and ) is part of a JSON reply. So there won't be a case where searcing for these and remove everything before and after would a problem in the future.

But I'm just throwing out ideas =)