Getting Sunset and sunrise data automatically

9 years 2 months ago #2263 by vickeyhort
Hi Friends

I want to get the sunset and sunrise time (Only Hour) from following api
sunrise-sunset.org/api

I will use this data to update "Sensor.LightLevel" values on a virtual node and mysensors node will get this value through another automation script I already have.

May someone help me to get this information? I have no experience with C#. I only want sunrise hour and sunset hour of my location as variable to update "Sensor.LightLevel" values of my virtual node. Thanks
The following user(s) said Thank You: osalval

Please Log in or Create an account to join the conversation.

9 years 2 months ago - 9 years 2 months ago #2264 by NightOne
Here is something for you to get started with:

Big thanks to medyk8ns on the forum for enabling the newtonsoft json call.
Code starts here:

private System.Reflection.MethodInfo _deserializeObjectMethodInfo;
public System.Reflection.MethodInfo DeserializeObjectMethodInfo
{
get
{
if (_deserializeObjectMethodInfo == null)
{
var assembly = System.Reflection.Assembly.LoadFrom("Newtonsoft.Json.dll");
var jobjectType = assembly.GetType("Newtonsoft.Json.JsonConvert");
_deserializeObjectMethodInfo = jobjectType.GetMethods().SingleOrDefault(m => m.Name == "DeserializeObject" && !m.IsGenericMethod && m.ReturnType==typeof(object) && m.GetParameters().Count()==1);
//can also use Parse method from JObject
//var jobjectType = assembly.GetType("Newtonsoft.Json.Linq.JObject");
//_deserializeObjectMethodInfo= jobjectType.GetMethod("Parse");
}
return _deserializeObjectMethodInfo;
}
}

public void Run()
{
{

using (System.Net.WebClient webClient = new System.Net.WebClient())
{
System.Net.WebClient n = new System.Net.WebClient();
var json = n.DownloadString(" api.sunrise-sunset.org/json?lat=36.72016...tted=0&date=tomorrow ");
dynamic valueOriginal = DeserializeObjectMethodInfo.Invoke(this, new object[] { json });
DateTime SunRise = valueOriginal.results.sunrise;
DateTime SunSet = valueOriginal.results.sunset;
string valueRise = SunRise.ToString("HH:mm");
string valueSet = SunSet.ToString("HH:mm");

Console.WriteLine("Sunrise is at: " + valueRise);
Console.WriteLine("Sunset is at: " + valueSet);

ModuleHelper.SetProperty(Domains.VIRTUAL, "N20S0", "Time.Sunrise", valueRise );
ModuleHelper.SetProperty(Domains.VIRTUAL, "N20S0", "Time.Sunset", valueSet );


}
}
}

On the EasyIOT side I created a little workaround and used custom properties to create values in a virtual sensor.
So you create a new sensor mine was N20S0 so you will need to change the code to reflect yours. In config on the sensor you can click on the sensor and make it an analog output... then click the configure gear on the side and add two new paramiters name the paramiters Time.Sunrise and Time.sunset. This will fill in the sensor values for the code..

This is in the run section of the code so it will need a cron job to run...as the values only change once a day I would run it only once....time is up to you...
The following user(s) said Thank You: osalval

Please Log in or Create an account to join the conversation.

9 years 2 months ago - 9 years 2 months ago #2265 by NightOne
A note on the above it returns the sunset and sunrise in TimeDate format, if you write it to EasyIOT server it will be converted to a string,.....remember yesterday mistake on my behalf. So if you want to read it again in automation you will need to convert it back into DateTime format to run calculations

Also you will need to change the api call to reflect your own Lat and Long and also remember that the time is in UTC so you would have to add or subtract depending on your timezone.

To retrive the values saved on the sensor you would use
ModuleHelper.GetProperty(Domains.VIRTUAL, "N20S0", "Time.Sunrise");
ModuleHelper.GetProperty(Domains.VIRTUAL, "N20S0", "Time.Sunset");

Remember you will declare a value like p... then when you want the value you will code p.Value to return the time
The following user(s) said Thank You: osalval

Please Log in or Create an account to join the conversation.

9 years 2 months ago - 9 years 2 months ago #2267 by vickeyhort
Thank you NightOne, you are helping me for the second time.

My EasyIOT server was getting slow last night when I ran it using standard method of running as service as described in iot-playground.com/2-uncategorised/4-run...ot-server-as-service . Method described did not work as it is and had to tweak a little bit to get it working. But performance gets so bad as slow behaviour of raspberry pi and easyiot server.

I had this slow behaviour problem in past when I adopted running as service. So I reinstalled raspbian and again installed easyiot etc. stuff. Speed is good now. I use the following command in "/etc/rc.local" to run the server during boot.

sudo mono /home/easyiot/EasyIoT.exe

But I am having an error now while updating code in automation.

Errors:

Error CS0006 in line -11 column 0, Metadata file `EasyIoT.exe' could not be found
Error CS0006 in line -11 column 0, Metadata file `GenericDriver.dll' could not be found
Program disabled, fix errors first.


Previously when I had this error, I shutdown the server and run manually through raspberry pi terminal and this error gone, after every restart, I have to do this thing manually otherwise I have above error in automation script.

Please Log in or Create an account to join the conversation.

9 years 2 months ago #2270 by vickeyhort
There is an update;

As i mentioned in my last post that I used to run EasyIOT server through terminal and It never gives me any error like below in automation script;

Errors:

Error CS0006 in line -11 column 0, Metadata file `EasyIoT.exe' could not be found
Error CS0006 in line -11 column 0, Metadata file `GenericDriver.dll' could not be found
Program disabled, fix errors first.


I want to share how did it work, when I type commands in series as following, I don't get any error in automation script

1) Shutdown the server and Open terminal
2) cd /home/easyiot
3) sudo mono EasyIoT.exe

Starting server as stated above resolves the above problem during updating automation script

Please Log in or Create an account to join the conversation.

9 years 2 months ago - 9 years 2 months ago #2271 by vickeyhort
As far as "Getting Sunset and sunrise data automatically" concerns, I have adopted the code and It is working like a charm. Here is my code

private System.Reflection.MethodInfo _deserializeObjectMethodInfo;
public System.Reflection.MethodInfo DeserializeObjectMethodInfo
{
get
{
if (_deserializeObjectMethodInfo == null)
{
var assembly = System.Reflection.Assembly.LoadFrom("Newtonsoft.Json.dll");
var jobjectType = assembly.GetType("Newtonsoft.Json.JsonConvert");
_deserializeObjectMethodInfo = jobjectType.GetMethods().SingleOrDefault(m => m.Name == "DeserializeObject" && !m.IsGenericMethod && m.ReturnType==typeof(object) && m.GetParameters().Count()==1);
//can also use Parse method from JObject
//var jobjectType = assembly.GetType("Newtonsoft.Json.Linq.JObject");
//_deserializeObjectMethodInfo= jobjectType.GetMethod("Parse");
}
return _deserializeObjectMethodInfo;
}
}

public void Run()
{
{

using (System.Net.WebClient webClient = new System.Net.WebClient())
{
System.Net.WebClient n = new System.Net.WebClient();
var json = n.DownloadString(" api.sunrise-sunset.org/json?lat=29.59047...tted=0&date=tomorrow ");
dynamic valueOriginal = DeserializeObjectMethodInfo.Invoke(this, new object[] { json });
DateTime SunRise = valueOriginal.results.sunrise;
DateTime SunSet = valueOriginal.results.sunset;
string valueRise = SunRise.ToString("HH:mm");
string valueSet = SunSet.ToString("HH:mm");

Console.WriteLine("Sunrise is at: " + valueRise);
Console.WriteLine("Sunset is at: " + valueSet);

ModuleHelper.SetProperty(Domains.VIRTUAL, "N1S0", "Time.Sunrise", valueRise );
ModuleHelper.SetProperty(Domains.VIRTUAL, "N1S0", "Time.Sunset", valueSet );


}
}
}



The code above is showing api address in ".." form.

(" api.sunrise-sunset.org/json?lat=29.59047...tted=0&date=tomorrow ")

If someone want to use this code, it should change latitude of its location after "lat=" and longitude after "lng=" in above line to make the script work. As NightOne mentioned in
iot-playground.com/forum/automation/413-...cally/edit/2271#2265
to add or subtract the received time according to timezone, When I tried this code, it updated the time in virtual node correctly according to my timezone set on my raspberry pi.

Now I want to add one more function that is ping. I want the script to ping www.google.com at first, if ping succeeds, it should try to fetch the sunrise and sunset data and if ping fails, it should try every 10 minutes to ping www.google.com unless ping succeeds and it fetch required data.

May someone help me to make this possible?

Please Log in or Create an account to join the conversation.

Time to create page: 0.252 seconds

Forum latest

  • No posts to display.