LOGIN  |  REGISTER
Smart Living Made Brilliant!
CASTLEOS FORUM

HomeScripting

A forum for information about scripting with CastleOS. Get samples, suggestions, and other help here

help with my morning wake up weather script Messages in this topic - RSS

Eric Hillen
Eric Hillen
Posts: 14


7/18/2015
Eric Hillen
Eric Hillen
Posts: 14
Bump for the previous post. Haven't found any other mentions of this problem in for forum.
0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366


7/18/2015
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366
Hey Eric!

Sorry for the delay. The missing piece is a CastleOS update, which is now available!

https://drive.google.com/open?id=0B4ZX9h5IVCtnQnBfdHgxdmViVms

Download the latest installer there, and you'll be able to run the scripts as you expect. Be sure to check out the new DemoScript.cs file, as it includes detailed instructions, especially about how to pick the speaker to make the announcement from.

Thanks, and please let us know how it works for you!

-Chris
0 link
Eric Hillen
Eric Hillen
Posts: 14


8/31/2015
Eric Hillen
Eric Hillen
Posts: 14
So I thought I had it... added the new coreservices to my script and tried to let it go, no success. I'm at a loss for this damn thing and I'm about over this Sh*T. heres the script if anyone wants to figure it out, as I am spent.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Web;
using CastleOSKinectService;
using CastleOSCoreService;
using System.Speech.Recognition;


namespace WeatherAlarm


{
public partial class Form1 : Form
{

public class MyScript
{
public void Main(string[] args)
{






string Temperature;
string Condition;
string Humidity;
string WindSpeed;
string Town;
string TFCond;
string TFHigh;
string TFLow;


public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{

}

void _recognizer_SpeechRecognizer(object sender, EventArgs e)
{
string speech = e.Result.Text;
switch (speech)
{
case " ":
GetWeather();


ScriptingAPI.Speak("The weather in " + Town + " is " + Condition + " at " + Temperature + " degrees ");

}



}
private void GetWeather()
{

string query = String.Format("http://weather.yahooapis.com/forecastrss?w=23424583");
XmlDocument wData = new XmlDocument();
wData.Load(query);

XmlNamespaceManager manager = new XmlNamespaceManager (wData.NameTable);
manager.AddNamespace("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0");

XmlNode channel = wData.SelectSingleNode("rss").SelectSingleNode("channel");
XmlNodeList node = wData.SelectNodes("/rss/channel/item/yweather:forecastr", manager);

Temperature = channel.SelectSingleNode("item").SelectSingleNode("yweather:condition", manager).Attributes["temp"].Value;

Condition = channel.SelectSingleNode("item").SelectSingleNode("yweather:condition", manager).Attributes["text"].Value;

Humidity = channel.SelectSingleNode("yweather:atmosphere", manager).Attributes[Humidity].Value;

WindSpeed = channel.SelectSingleNode("yweather:wing", manager).Attributes["speed"].Value;

Town = channel.SelectSingleNode("yweather:location", manager).Attributes["city"].Value;

TFCond = channel.SelectSingleNode("item").SelectSingleNode("yweather:forecast", manager).Attributes["text"].Value;

TFHigh = channel.SelectSingleNode("item").SelectSingleNode("yweather:forecast", manager).Attributes["high"].Value;

TFLow = channel.SelectSingleNode("item").SelectSingleNode("yweather:forecast", manager).Attributes["low"].Value;





}



}
0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366


9/3/2015
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366
Hey Eric! Don't give up just yet, you're learning a lot and almost there! Here's some things I noticed:

You need to pick one of these:


using CastleOSKinectService;
using CastleOSCoreService;


Using both will result in an error as it tries to load the one that's not there, in this case the Kinect Service.

You also reference using System.Speech.Recognition, but I'm not sure why?

You have code from a Windows form in there:


public partial class Form1 : Form
{

}

This isn't a Windows Form app, so that code will also try to load something that isn't there. Pulling out that code should solve that issue.

Likewise, this code needs to be pulled:


public Form1()
{
InitializeComponent();
}



private void Form1_Load(object sender, EventArgs e)
{

}


In addition, you have extraneous code in the _recognizer_SpeechRecognizer method, which itself is improperly nested in the Main method. So we pull that too smile

Finally, the variables are inside the Main method, when they should instead be one level higher in the MyScript class. By putting them at the class level instead of method level, it allows multiple methods to access the same variables.

I've made these changes and will post them in the next post after this one. Also, I highly recommend you try testing all of this in a console app (create a new Console Project in Visual Studio). By doing so it allows you to create fully testable code that can be copied and pasted into a CastleOS script with usually no modifications.

New code:
0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366


9/3/2015
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Web;
using CastleOSCoreService;

namespace WeatherAlarm
{
public class MyScript
{
string Temperature = "";
string Condition = "";
string Humidity = "";
string WindSpeed = "";
string Town = "";
string TFCond = "";
string TFHigh = "";
string TFLow = "";

public void Main(string[] args)
{
GetWeather();

ScriptingAPI.Speak("The weather in " + Town + " is " + Condition + " at " + Temperature + " degrees ");
}

private void GetWeather()
{
string query = String.Format("http://weather.yahooapis.com/forecastrss?w=23424583");
XmlDocument wData = new XmlDocument();
wData.Load(query);

XmlNamespaceManager manager = new XmlNamespaceManager (wData.NameTable);
manager.AddNamespace("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0");

XmlNode channel = wData.SelectSingleNode("rss").SelectSingleNode("channel");
XmlNodeList node = wData.SelectNodes("/rss/channel/item/yweather:forecastr", manager);

Temperature = channel.SelectSingleNode("item").SelectSingleNode("yweather:condition", manager).Attributes["temp"].Value;

Condition = channel.SelectSingleNode("item").SelectSingleNode("yweather:condition", manager).Attributes["text"].Value;

Humidity = channel.SelectSingleNode("yweather:atmosphere", manager).Attributes[Humidity].Value;

WindSpeed = channel.SelectSingleNode("yweather:wing", manager).Attributes["speed"].Value;

Town = channel.SelectSingleNode("yweather:location", manager).Attributes["city"].Value;

TFCond = channel.SelectSingleNode("item").SelectSingleNode("yweather:forecast", manager).Attributes["text"].Value;

TFHigh = channel.SelectSingleNode("item").SelectSingleNode("yweather:forecast", manager).Attributes["high"].Value;

TFLow = channel.SelectSingleNode("item").SelectSingleNode("yweather:forecast", manager).Attributes["low"].Value;
}
}
}
0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366


9/3/2015
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366
Note I did not test the GetWeather code. That's where the console app would be helpful, you'd just output text to the console in testing, and then convert that to speech calls in the script once you know the code works.
0 link
Phil Hawthorne
Phil Hawthorne
Posts: 400


1/23/2016
Phil Hawthorne
Phil Hawthorne
Posts: 400
So I've tried to get this bit of code working. I'm just using Sublime.

I got my own test script to run and respond with a random response. I discovered that if there is an error with a Kinect script, CastleOS raises the same error in the error log, and the Kinect service dies. This makes it really really hard to debug whats going wrong.

After commenting lines and lines of code, I was able to get my script working. So I decided to tackle this weather script. I can't get it to work, and I can't see why. I've isolated my problem down to the following line

XmlDocument wData = new XmlDocument();

if I comment out that line, the script speaks via my Sonos. However, as soon as I include that line an error is thrown and the Kinect service stops.

For reference, I'll attach my code below. Everything is commented out except the debug speech and the offending line above.


using System;
using CastleOSCoreService;
// using System.Text;
// using System.Collections.Generic;
// using System.ComponentModel;
// using System.Data;
// using System.Drawing;
// using System.Linq;
using System.IO;
using System.Xml;
// using System.Web;
// using System.Diagnostics;
// using System.Net;
// using System.Threading.Tasks;
// using System.Windows.Forms;
// using System.Xml.Linq;


// namespace WeatherAlarm
// {
public class MyScript
{
// string Temperature = "";
// string Condition = "";
// string Humidity = "";
// string WindSpeed = "";
// string Town = "";
// string TFCond = "";
// string TFHigh = "";
// string TFLow = "";

public void Main(string[] args)
{
try{
ScriptingAPI.Speak("Getting Weather");
} catch {
return;
}
try{
GetWeather();
} catch {
ScriptingAPI.Speak("There was a problem getting the wearther");
return;
}

try{
ScriptingAPI.Speak("I have the weather");
// ScriptingAPI.Speak("The weather in " + Town + " is " + Condition + " at " + Temperature + " degrees ");
} catch {
return;
}

}

private void GetWeather()
{
// string query = ;
try{
XmlDocument wData = new XmlDocument();
} catch {

}

// wData.Load(string "http://weather.yahooapis.com/forecastrss?w=23424583");

// XmlNamespaceManager manager = new XmlNamespaceManager (wData.NameTable);
// manager.AddNamespace("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0");

// XmlNode channel = wData.SelectSingleNode("rss").SelectSingleNode("channel");
// XmlNodeList node = wData.SelectNodes("/rss/channel/item/yweather:forecastr", manager);

// Temperature = channel.SelectSingleNode("item").SelectSingleNode("yweather:condition", manager).Attributes["temp"].Value;

// Condition = channel.SelectSingleNode("item").SelectSingleNode("yweather:condition", manager).Attributes["text"].Value;

// Humidity = channel.SelectSingleNode("yweather:atmosphere", manager).Attributes[Humidity].Value;

// WindSpeed = channel.SelectSingleNode("yweather:wing", manager).Attributes["speed"].Value;

// Town = channel.SelectSingleNode("yweather:location", manager).Attributes["city"].Value;

// TFCond = channel.SelectSingleNode("item").SelectSingleNode("yweather:forecast", manager).Attributes["text"].Value;

// TFHigh = channel.SelectSingleNode("item").SelectSingleNode("yweather:forecast", manager).Attributes["high"].Value;

// TFLow = channel.SelectSingleNode("item").SelectSingleNode("yweather:forecast", manager).Attributes["low"].Value;
}
}
// }
0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366


1/23/2016
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366
Hey Phil, as we always say in this case, your code should be working and tested independently of CastleOS, before trying to use it with CastleOS scripting. This helps ensure nothing with the code is a factor.

Also, keep in mind with .NET you can always compile your script into a EXE., and then call that EXE with the script that runs in CastleOS with just a few lines of code.
0 link
Phil Hawthorne
Phil Hawthorne
Posts: 400


1/23/2016
Phil Hawthorne
Phil Hawthorne
Posts: 400
Hey Chris,

How does one go about testing their scripts outside of CastleOS? When it comes time to run my script, I need to use the ":using CastleOSKInectService" etc, which I can't debug outside of CastleOS?
0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366


1/23/2016
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366
That line, "using CastleOSKinectService", is only needed when running in CastleOS. The rest of the code should be able to run in a standard C# console project. Once you have it running independently, then you can port it. That way you can quickly diagnose issues, as CastleOS has no built in debugging for scripts. It's expected that is done in an IDE.
0 link
Phil Hawthorne
Phil Hawthorne
Posts: 400


1/24/2016
Phil Hawthorne
Phil Hawthorne
Posts: 400
OK Chris,

I've made progress on this script, but have once again faced a hurdle with CastleOS.

First up, the weather script you posted, with fixed code from Eric will never work in CastleOS. As I suspected above, CastleOS scripts don't support the XML library.

So, I created an EXE file which takes a city ID parameter, and Celsius/Fahrenheit flag. This works great in Command Prompt.

I'm now looking at implementing this:
Chris Cicchitelli wrote:
Also, keep in mind with .NET you can always compile your script into a EXE., and then call that EXE with the script that runs in CastleOS with just a few lines of code.


As this C# uses the XML lib, I can't just run it inside a single file. CastleOS will crash with a vague error, as above. So I've got it in a nice EXE ready for me to handle the output. But, how does one pass paramters to an exe, and grab the output as a string?

I googled this question, and everyone (including the MSDN articles) are saying I need to use Process process = new Process().

That's fine, except now I'm running into the same error as the XML. When I call Process = new Process(), CastleOS crashes and burns. I'll attach a script I was hoping would work, but doesn't. Can you help me call an EXE file from CastleOS and then return the string to a variable?
edited by philhawthorne on 1/24/2016


Attachments:
weather.cs
0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366


1/24/2016
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366
That's not a CastleOS thing, it's a C#/Windows security thing. See here for how to do it: http://castleos.com/forum/topic385-remote-application-launcher.aspx
0 link
Phil Hawthorne
Phil Hawthorne
Posts: 400


1/26/2016
Phil Hawthorne
Phil Hawthorne
Posts: 400
Thanks Chris, but that doesn't work either.

I've got the server running on the CastleHUB (I had to disable the ethernet port on the hub to do it - Hub connected to Wifi), yet the Kinect service still dies when I run the following command.

Process.Start(@".\RemoteAppLaunchClient.exe", "192.168.1.21 iexplore.exe www.google.com");

Some notes
  • 192.168.1.21 is the IP address of the CastleHUB. The client and server are both running on the Hub
  • Running the command "iexplore.exe www.google.com" via Windows -> Run on the Hub opens internet Explorer as expected
  • The server is running, and waiting for commands with no errors in the console
  • The client file is in the Kinect scripts folder, next to the same c# script called, as the thread instructs.
  • Running the following from Windows -> Run on the CastleHUB launches Internet Explorer as expected: c:\ProgramData\CastleOS\CastleOS Kinect Service\Scripts\RemoteAppLaunchClient.exe 192.168.1.21 iexplore.exe www.google.com
  • Commenting out the Process.start() command above does not kill the Kinect service, and outputs debug speech via TTS


So far, to get this script working I have
  • Isolated the code into its own EXE file, which can be called via command prompt to return data from the Yahoo weather API as you suggested
  • Attempted to execute the code from a C# script using Process, as recommended by MSDN
  • Installed the Client/Server exe file from nikku posted to the forums, as you suggested.
In all cases, the Kinect service from CastleOS dies, and the common denominator is Process.start().
0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366


1/27/2016
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366
Have you tried using 127.0.0.1 instead of 192.168.1.21?
0 link
Phil Hawthorne
Phil Hawthorne
Posts: 400


1/27/2016
Phil Hawthorne
Phil Hawthorne
Posts: 400
Chris Cicchitelli wrote:
Have you tried using 127.0.0.1 instead of 192.168.1.21?


Yup. It gets refused. I just tried to run it via Windows -> Run, and got the following error

SocketException : System.Net.Sockets.SocketException (0x80004005): No connection could be made because the target machine actively refused it 127.0.0.1:11000
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at RemoteAppLaunchClient.Program.StartClient(String ip, String program, String args)


But, running it with the LAN IP address works.
0 link
Phil Hawthorne
Phil Hawthorne
Posts: 400


1/27/2016
Phil Hawthorne
Phil Hawthorne
Posts: 400
Which isn't the fault of CastleOS or the Kinect service. Its just the program Nick wrote only accepts commands on the LAN IP address.

The main issue I'm facing, is I can't get CastleOS to execute Nicks exe, or any exe without crashing
0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366


1/27/2016
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366
Can you upload your current script?
0 link
Phil Hawthorne
Phil Hawthorne
Posts: 400


1/27/2016
Phil Hawthorne
Phil Hawthorne
Posts: 400
Chris Cicchitelli wrote:
Can you upload your current script?

Yep, this is the one that fails.

Commenting out Process.Start, the TTS is fired off to the Sonos. If not, Kinect service crashes. Running the command in Windows -> Run opens IE as expected.


Attachments:
weather[1].cs
0 link
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366


1/27/2016
Chris Cicchitelli
Chris Cicchitelli
Administrator
Posts: 3366
Try running this, and see if it tells you the error...


Attachments:
weather[1].cs
0 link
Phil Hawthorne
Phil Hawthorne
Posts: 400


1/27/2016
Phil Hawthorne
Phil Hawthorne
Posts: 400
In my initial tests I did try catch the exception with try{} catch{} blocks, but they never went into the catch block.

I'll try that when I get home. Hopefully it speaks something back to me
0 link