SemlerPDX icon

AVCS SENS OWM MAIN-v5 Inline Function in C# for VoiceAttack & Open Weather API

SemlerPDX | PRO | 06/15/22 02:31:15 AM UTC | 0 ⭐ | 1592 👁️ | Never ⏰ | []
C# |

39.88 KB

|

None

|

0 👍

/

0 👎

//AVCS SENS - Open Weather Maps Monitor Main Timer
// by SemlerPDX Mar2022 (see credits in menu)
// VETERANS-GAMING.COM
 
 
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Net;
 
 
public class VAInline
{
    string timerInterval = "";
    int GetWeatherTimerDelay = 5000;  // default timer delay 5 seconds
    int GetWeatherInterval = 180;  // default multiple of delay (180xDelay=15 minutes)
    bool debugging = false;
    bool debuggingFC = false;
    
    public void ClearWeatherVariables()
    {
        //Clear Weather TTS Variables
        VA.SetText("AVCS_SENS_TempOWMu", null);
        VA.SetText("AVCS_SENS_TempOWMwiu", null);
        VA.SetText("AVCS_SENS_TempOWMwid", null);
        VA.SetText("AVCS_SENS_TempOWMloc", null);
        VA.SetText("AVCS_SENS_TempOWMmain", null);
        VA.SetText("AVCS_SENS_TempOWMfull", null);
        VA.SetDecimal("AVCS_SENS_TempOWMc", null);
        VA.SetDecimal("AVCS_SENS_TempOWMf", null);
        VA.SetDecimal("AVCS_SENS_TempOWMhic", null);
        VA.SetDecimal("AVCS_SENS_TempOWMhif", null);
        VA.SetDecimal("AVCS_SENS_TempOWMh", null);
        VA.SetDecimal("AVCS_SENS_TempOWMwim", null);
        VA.SetDecimal("AVCS_SENS_TempOWMwik", null);
    }
    
    private void GetWeatherTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        int intervalOWM = 0;
        if (VA.GetInt("AVCS_SENS_OWM_INTERVAL") != null)
        {
            intervalOWM = Convert.ToInt32(VA.GetInt("AVCS_SENS_OWM_INTERVAL"));
            intervalOWM += 1;
            if (intervalOWM >= GetWeatherInterval)
                intervalOWM = 0;
            VA.SetInt("AVCS_SENS_OWM_INTERVAL", intervalOWM);
        }
        else
        {
            VA.SetInt("AVCS_SENS_OWM_INTERVAL", 0);
        }
        
        if (VA.GetBoolean("AVCS_OWM_Debugging") != true)
        {
            debugging = false;
        }
        else
        {
            debugging = true;
            if (canShowInterval(intervalOWM))
                VA.WriteToLog(showNextInterval(intervalOWM, GetWeatherInterval, GetWeatherTimerDelay), "blank");
        }
        
        if (intervalOWM == 0)
        {
            if (debugging)
                VA.WriteToLog("AVCS OWM Monitor is getting New Weather Data now...", "green");
            
            try
            {
                
                if (canGetWeatherData())
                {
                    VA.SetBoolean("AVCS_OWM_SET", null);
                    GetWeatherData(VA);
                }
                if (VA.GetBoolean("AVCS_OWM_SET") != true)
                {
                    VA.SetBoolean("AVCS_OWM_Monitoring", false);
                }
                else
                {
                    if (canGetDailyForecast())
                    {
                        GetWeatherDailyForecastData(VA);
                    }
                }
            }
            catch
            {
                //for any expected unexpected faults
                VA.SetBoolean("AVCS_OWM_Monitoring", false);
            }
        }
        
        if (VA.GetBoolean("AVCS_OWM_Monitoring") != true)
        {
            ClearWeatherVariables();
            VA.WriteToLog("AVCS Open Weather Map Timer has been terminated...", "black");
            if ((VA.GetBoolean("AVCS_SENS_UnloadClose") != true) && (VA.GetBoolean("AVCS_OWM_Checking") != true))
            {
                VA.SetText("AVCS_SENS_TTS_WILDCARD", "Weather Data [Monitoring;;] Systems have been [terminated;disabled;ended]");
                VA.Command.Execute("F_SAY_TTS", true);
            }
            VA.SetBoolean("AVCS_OWM_Checking", null);
            (sender as System.Timers.Timer).Stop();
        }
        
        if (VA.Stopped)
        {
            // Catch Here if anything could be interrupted by VA Stop (long running TTS?)
            if (debugging)
                VA.WriteToLog("AVCS OWM Monitor Timer saw and ignored Stop Commands", "yellow");
        }
    }
    
    
    private void GetWeatherTimer(string timerInterval)
    {
        System.Timers.Timer t = new System.Timers.Timer(GetWeatherTimerDelay);
        t.Elapsed += GetWeatherTimerElapsed;
        VA.WriteToLog("AVCS Open Weather Map Timer is now running...", "black");
        VA.WriteToLog("Current Weather Update Interval: " + timerInterval, "black");
        t.Start();
    }
    
    
    public class AVCSexception : Exception
    {
        public void GetWeatherURLException(dynamic VA)
        {
            VA.SetBoolean("AVCS_OWM_SET", null);
            VA.WriteToLog("AVCS OWM Get Weather Data has failed!", "red");
            VA.WriteToLog("Please check settings. See user guide for more information.", "blank");
        }
        public void GetWeatherFailException(dynamic VA)
        {
            VA.WriteToLog("AVCS OWM Get Weather Data has failed!", "red");
            VA.WriteToLog("Please check settings. See user guide for more information.", "blank");
            VA.SetText("AVCS_SENS_TTS_WILDCARD", "Weather data unavailable. Please check settings.");
            VA.Command.Execute("F_SAY_TTS", false);
            VA.SetBoolean("AVCS_OWM_Monitoring", false);
        }
    }
    
    private void GetWeatherData(dynamic VA)
    {
        string cityName;
        string stateName;
        string newLat = "";
        string newLon = "";
        string locationData = "New York, NY, US";
        string apiKey = "";
        string baseURL = "https://api.openweathermap.org/data/2.5/weather?lat=AVCS_SENS_OWMLAT&lon=AVCS_SENS_OWMLON&units=metric&exclude=minutely,hourly&appid=AVCS_SENS_OWMKEY";
        string weatherURL = "";
        bool hasGPS = false;
        bool faultDetected = false;
        
        
        if (VA.GetText("AVCS_SENS_OWMKEY") != null)
        {
            apiKey = VA.GetText("AVCS_SENS_OWMKEY");
        }
        else
        {
            apiKey = VA.GetText("AVCS_SENS_OWM_DefaultKey");
        }
        if (VA.GetText("AVCS_SENS_OWMCITY") != null)
            locationData = VA.GetText("AVCS_SENS_OWMCITY");
        if (VA.GetText("AVCS_SENS_OWMLAT") != null && VA.GetText("AVCS_SENS_OWMLON") != null)
            weatherURL = baseURL.Replace("AVCS_SENS_OWMLAT",VA.GetText("AVCS_SENS_OWMLAT")).Replace("AVCS_SENS_OWMLON",VA.GetText("AVCS_SENS_OWMLON")).Replace("AVCS_SENS_OWMKEY",apiKey).Trim();
        if (weatherURL == "")
        {
            if (locationData.Contains(","))
            {
                string[] locationDataSet = locationData.Split(
                    new string[] { "," },
                    StringSplitOptions.RemoveEmptyEntries
                );
                if (1 < locationDataSet.Length)
                {
                    decimal checkLat;
                    decimal checkLon;
                    bool checkLatIsValid = decimal.TryParse(locationDataSet[0], out checkLat) && Math.Abs(checkLat) < 90;
                    bool checkLonIsValid = decimal.TryParse(locationDataSet[1], out checkLon) && Math.Abs(checkLon) < 180;
                    if ((checkLatIsValid && checkLonIsValid) && (Math.Abs(checkLat) > 4.4m && Math.Abs(checkLon) > 4.4m))
                    {
                        hasGPS = true;
                        newLat = locationDataSet[0].Trim();
                        newLon = locationDataSet[1].Trim();
                        VA.SetText("AVCS_SENS_OWMLAT", newLat);
                        VA.SetText("AVCS_SENS_OWMLON", newLon);
                        weatherURL = baseURL.Replace("AVCS_SENS_OWMLAT",newLat).Replace("AVCS_SENS_OWMLON",newLon).Replace("AVCS_SENS_OWMKEY",apiKey).Trim();
                    }
                }
            }
            if (hasGPS != true)
            {
                try
                {
                    string apiReturn = "";
                    VA.SetText("~avcs_owm_return", null);
                    weatherURL = "http://api.openweathermap.org/geo/1.0/direct?q="+locationData+"&limit=1&appid="+apiKey;
                    
                    GetWeatherApiReturn(weatherURL, VA);
                    
                    if (VA.GetText("~avcs_owm_return") != null)
                        apiReturn = VA.GetText("~avcs_owm_return").Replace("\"","").Replace("{","").Replace("}","");
                    
                    if (apiReturn.Contains(","))
                    {
                        string[] lines = apiReturn.Split(
                            new string[] { "," },
                            StringSplitOptions.RemoveEmptyEntries
                        );
                        
                        foreach (string line in lines)
                        {
                            if (line.Contains("lat"))
                            {
                                if (line.Contains(":"))
                                {
                                    string[] checkLine = line.Split(
                                        new string[] { ":" },
                                        StringSplitOptions.RemoveEmptyEntries
                                    );
                                    if(1 < checkLine.Length)
                                        newLat = checkLine[1];
                                }
                            }
                            if (line.Contains("lon"))
                            {
                                if (line.Contains(":"))
                                {
                                    string[] checkLine = line.Split(
                                        new string[] { ":" },
                                        StringSplitOptions.RemoveEmptyEntries
                                    );
                                    if(1 < checkLine.Length)
                                        newLon = checkLine[1];
                                }
                            }
                        }
                        decimal tryNewDecimal;
                        if ((newLat != "" && Decimal.TryParse(newLat, out tryNewDecimal)) && (newLon != "" && Decimal.TryParse(newLat, out tryNewDecimal)))
                        {
                            VA.SetText("AVCS_SENS_OWMLAT", newLat);
                            VA.SetText("AVCS_SENS_OWMLON", newLon);
                            weatherURL = baseURL.Replace("AVCS_SENS_OWMLAT",newLat).Replace("AVCS_SENS_OWMLON",newLon).Replace("AVCS_SENS_OWMKEY",apiKey);
                        }
                        else
                        {
                            throw new AVCSexception();
                        }
                    }
                    else
                    {
                        throw new AVCSexception();
                    }
                }
                catch (AVCSexception e)
                {
                    //for any expected unexpected faults
                    faultDetected = true;
                    e.GetWeatherURLException(VA);
                }
            }
        }
        if (faultDetected != true)
        {
            string apiLoc = "";
            string apiMain = "";
            string apiTempC = "";
            string apiTempF = "";
            string apiHeatIndexC = "";
            string apiHeatIndexF = "";
            string apiWindSpeedK = "";
            string apiWindSpeedM = "";
            string apiHumidity = "";
            string apiWindDir = "";
            string apiTempUnits = "°C";
            string apiWindUnits = "kph";
            string apiWindFrom = "North";
            string ttsTemp = "";
            string ttsIndex = "";
            string ttsWind = "";
            
            try
            {
                string apiReturn = "";
                VA.SetText("~avcs_owm_return", null);
                GetWeatherApiReturn(weatherURL, VA);
                if (VA.GetText("~avcs_owm_return") != null)
                    apiReturn = VA.GetText("~avcs_owm_return").Replace("\"","").Replace("{","").Replace("}","");
                
                if (apiReturn.Contains(","))
                {
                    string[] lines = apiReturn.Split(
                        new string[] { "," },
                        StringSplitOptions.RemoveEmptyEntries
                    );
                    foreach (string line in lines)
                    {
                        if (line.Contains("name") && apiLoc == "")
                        {
                            if (line.Contains(":"))
                            {
                                string[] checkLine = line.Split(
                                    new string[] { ":" },
                                    StringSplitOptions.RemoveEmptyEntries
                                );
                                if(1 < line.Length)
                                    apiLoc = checkLine[1];
                            }
                        }
                        if (line.Contains("description") && apiMain == "")
                        {
                            if (line.Contains(":"))
                            {
                                string[] checkLine = line.Split(
                                    new string[] { ":" },
                                    StringSplitOptions.RemoveEmptyEntries
                                );
                                if (1 < line.Length)
                                {
                                    apiMain = checkLine[1].Trim().ToLower();
                                }
                                
                                if (apiMain.StartsWith("few"))
                                {
                                    apiMain = apiMain.Replace("few","a few");
                                }
                                else if (apiMain == "clouds" )
                                {
                                    apiMain = apiMain.Replace("clouds","cloudy");
                                }
                                else if (apiMain == "sun" )
                                {
                                    apiMain = apiMain.Replace("sun","sunny");
                                }
                                else if ((apiMain == "rain" ) || (apiMain == "mist" ))
                                {
                                    apiMain = apiMain + "y";
                                }
                                apiMain = apiMain.Replace("sky","skies");
                            }
                        }
                        if (line.Contains("temp") && apiTempC == "")
                        {
                            if (line.Contains(":"))
                            {
                                string[] checkLine = line.Split(
                                    new string[] { ":" },
                                    StringSplitOptions.RemoveEmptyEntries
                                );
                                if(1 < line.Length)
                                {
                                    decimal convertTemp = 1;
                                    decimal convertedTemp = 1;
                                    apiTempC = checkLine[2];
                                    if (Decimal.TryParse(apiTempC, out convertTemp))
                                    {
                                        convertedTemp = ((convertTemp * 9) / 5) + 32;
                                        convertedTemp = Math.Round(convertedTemp, 0);
                                        VA.SetDecimal("AVCS_SENS_TempOWMf", convertedTemp);
                                        apiTempF = convertedTemp.ToString();
                                    }
                                    if (Decimal.TryParse(apiTempC, out convertTemp))
                                    {
                                        convertedTemp = Math.Round(convertedTemp, 0);
                                        VA.SetDecimal("AVCS_SENS_TempOWMc", convertedTemp);
                                        apiTempC = convertedTemp.ToString();
                                    }
                                    if (VA.GetBoolean("AVCS_SENS_OWM_UnitMetric") != true)
                                    {
                                        ttsTemp = apiTempF;
                                        apiTempUnits = "°F";
                                    }
                                    else
                                    {
                                        ttsTemp = apiTempC;
                                        apiTempUnits = "°C";
                                    }
                                }
                            }
                        }
                        if (line.Contains("feels_like") && apiHeatIndexC == "")
                        {
                            if (line.Contains(":"))
                            {
                                string[] checkLine = line.Split(
                                    new string[] { ":" },
                                    StringSplitOptions.RemoveEmptyEntries
                                );
                                if(1 < line.Length)
                                {
                                    decimal convertIndex = 1;
                                    decimal convertedIndex = 1;
                                    apiHeatIndexC = checkLine[1];
                                    
                                    if (Decimal.TryParse(apiHeatIndexC, out convertIndex))
                                    {
                                        convertedIndex = ((convertIndex * 9) / 5) + 32;
                                        convertedIndex = Math.Round(convertedIndex, 0);
                                        VA.SetDecimal("AVCS_SENS_TempOWMhif", convertedIndex);
                                        apiHeatIndexF = convertedIndex.ToString();
                                        ttsIndex = apiHeatIndexF;
                                    }
                                    if (Decimal.TryParse(apiHeatIndexC, out convertIndex))
                                    {
                                        convertedIndex = Math.Round(convertedIndex, 0);
                                        VA.SetDecimal("AVCS_SENS_TempOWMhic", convertedIndex);
                                        apiHeatIndexC = convertedIndex.ToString();
                                        ttsIndex = apiHeatIndexC;
                                    }
                                }
                            }
                        }
                        if (line.Contains("humidity") && apiHumidity == "")
                        {
                            if (line.Contains(":"))
                            {
                                string[] checkLine = line.Split(
                                    new string[] { ":" },
                                    StringSplitOptions.RemoveEmptyEntries
                                );
                                if(1 < line.Length)
                                {
                                    decimal convertedRH;
                                    apiHumidity = checkLine[1];
                                    if (Decimal.TryParse(apiHumidity, out convertedRH))
                                    {
                                        convertedRH = Math.Round(convertedRH, 0);
                                        VA.SetDecimal("AVCS_SENS_TempOWMh", convertedRH);
                                        apiHumidity = convertedRH.ToString();
                                    }
                                }
                            }
                        }
                        if (line.Contains("speed") && apiWindSpeedK == "")
                        {
                            if (line.Contains(":"))
                            {
                                string[] checkLine = line.Split(
                                    new string[] { ":" },
                                    StringSplitOptions.RemoveEmptyEntries
                                );
                                if(1 < line.Length)
                                {
                                    decimal convertedSpeed;
                                    apiWindSpeedK = checkLine[2];
                                    if (VA.GetBoolean("AVCS_SENS_OWM_WindMetric") != true)
                                    {
                                        if (Decimal.TryParse(apiWindSpeedK, out convertedSpeed))
                                        {
                                            convertedSpeed *= 0.6214m;
                                            convertedSpeed = Math.Round(convertedSpeed, 0);
                                            VA.SetDecimal("AVCS_SENS_TempOWMwim", convertedSpeed);
                                            apiWindSpeedM = convertedSpeed.ToString();
                                            ttsWind = apiWindSpeedM;
                                            apiWindUnits = "mph";
                                        }
                                    }
                                    else
                                    {
                                        if (Decimal.TryParse(apiWindSpeedK, out convertedSpeed))
                                        {
                                            convertedSpeed = Math.Round(convertedSpeed, 0);
                                            VA.SetDecimal("AVCS_SENS_TempOWMwik", convertedSpeed);
                                            apiWindSpeedK = convertedSpeed.ToString();
                                            ttsWind = apiWindSpeedK;
                                            apiWindUnits = "kph";
                                        }
                                    }
                                }
                            }
                        }
                        if (line.Contains("deg") && apiWindDir == "")
                        {
                            if (line.Contains(":"))
                            {
                                string[] checkLine = line.Split(
                                    new string[] { ":" },
                                    StringSplitOptions.RemoveEmptyEntries
                                );
                                if(1 < line.Length)
                                {
                                    apiWindDir = checkLine[1];
                                    decimal convertedDir = 1;
                                    
                                    if (Decimal.TryParse(apiWindDir, out convertedDir))
                                    {
                                        if ((convertedDir > 337.5m && convertedDir <= 359m) || (convertedDir >= 0m && convertedDir < 22.5m))
                                        {
                                            apiWindFrom = "North";
                                        }
                                        else if (convertedDir >= 22.5m && convertedDir < 67.5m)
                                        {
                                            apiWindFrom = "Northeast";
                                        }
                                        else if (convertedDir >= 67.5m && convertedDir <= 112.5m)
                                        {
                                            apiWindFrom = "East";
                                        }
                                        else if (convertedDir > 112.5m && convertedDir <= 157.5m)
                                        {
                                            apiWindFrom = "Southeast";
                                        }
                                        else if (convertedDir > 157.5m && convertedDir <= 202.5m)
                                        {
                                            apiWindFrom = "South";
                                        }
                                        else if (convertedDir > 202.5m && convertedDir <= 247.5m)
                                        {
                                            apiWindFrom = "Southwest";
                                        }
                                        else if (convertedDir > 247.5m && convertedDir <= 292.5m)
                                        {
                                            apiWindFrom = "West";
                                        }
                                        else if (convertedDir > 292.5m && convertedDir <= 337.5m)
                                        {
                                            apiWindFrom = "Northwest";
                                        }
                                    }
                                }
                            }
                        }
                    }
                    
                    //Store New Temperature Units Text for TTS Requests
                    VA.SetText("AVCS_SENS_TempOWMu", apiTempUnits);
                    
                    //Store New Wind Units Text for TTS Requests
                    VA.SetText("AVCS_SENS_TempOWMwiu", apiWindUnits);
                    VA.SetText("AVCS_SENS_TempOWMwid", apiWindFrom);
                    
                    //Store New Weather Conditions and City Name Values for TTS Requests
                    VA.SetText("AVCS_SENS_TempOWMloc", apiLoc);
                    VA.SetText("AVCS_SENS_TempOWMmain", apiMain);
                    
                    //Store New Main Conditions Value for TTS Requests
                    VA.SetText("AVCS_SENS_TempOWMfull", "Conditions are " + apiMain + " right now at around " + ttsTemp + apiTempUnits + ", with a heat index of " + ttsIndex + apiTempUnits + " and humidity at " + apiHumidity + "%. Winds are out of the " + apiWindFrom + " at " + ttsWind + apiWindUnits);
                    
                    //Store current time plus seconds of interval for next check
                    string nextCheckUnixSecsString = "UNIX";
                    decimal setNextCheckUnixSecs = 0;
                    if (VA.GetInt("AVCS_SENS_OWM_WG_Calls") != null && (Decimal.TryParse(VA.ParseTokens("{INT:AVCS_SENS_OWM_WG_Calls:900}"), out setNextCheckUnixSecs)))
                    {
                        setNextCheckUnixSecs += DateTimeOffset.Now.ToUnixTimeSeconds();
                    }
                    else
                    {
                        VA.SetInt("AVCS_SENS_OWM_WG_Calls", 900);
                        setNextCheckUnixSecs = 900m + DateTimeOffset.Now.ToUnixTimeSeconds();
                    }
                    nextCheckUnixSecsString += setNextCheckUnixSecs.ToString();
                    VA.SetText("AVCS_SENS_OWM_NextWeatherGetCheck", nextCheckUnixSecsString);
                    
                    VA.SetBoolean("AVCS_OWM_SET", true);
                    if (debugging)
                        VA.WriteToLog(VA.GetText("AVCS_SENS_TempOWMfull"), "green");
                }
                else
                {
                    throw new AVCSexception();
                }
            }
            catch (AVCSexception e)
            {
                //for any expected unexpected faults
                e.GetWeatherURLException(VA);
            }
        }
    }
    
    private void GetWeatherDailyForecastData(dynamic VA)
    {
        string cityName;
        string stateName;
        string newLat = "";
        string newLon = "";
        string locationData = "New York, NY, US";
        string apiKey = "";
        string baseURL = "https://api.openweathermap.org/data/2.5/onecall?lat=AVCS_SENS_OWMLAT&lon=AVCS_SENS_OWMLON&exclude=current,minutely,hourly,alerts&appid=AVCS_SENS_OWMKEY&units=metric";
 
        string weatherURL = "";
        bool hasGPS = false;
        bool faultDetected = false;
        
        
        if (VA.GetText("AVCS_SENS_OWMKEY") != null)
        {
            apiKey = VA.GetText("AVCS_SENS_OWMKEY");
        }
        else
        {
            apiKey = VA.GetText("AVCS_SENS_OWM_DefaultKey");
        }
        if (VA.GetText("AVCS_SENS_OWMCITY") != null)
            locationData = VA.GetText("AVCS_SENS_OWMCITY");
        if (VA.GetText("AVCS_SENS_OWMLAT") != null && VA.GetText("AVCS_SENS_OWMLON") != null)
            weatherURL = baseURL.Replace("AVCS_SENS_OWMLAT",VA.GetText("AVCS_SENS_OWMLAT")).Replace("AVCS_SENS_OWMLON",VA.GetText("AVCS_SENS_OWMLON")).Replace("AVCS_SENS_OWMKEY",apiKey).Trim();
        if (weatherURL == "")
        {
            if (locationData.Contains(","))
            {
                string[] locationDataSet = locationData.Split(
                    new string[] { "," },
                    StringSplitOptions.RemoveEmptyEntries
                );
                if (1 < locationDataSet.Length)
                {
                    decimal checkLat;
                    decimal checkLon;
                    bool checkLatIsValid = decimal.TryParse(locationDataSet[0], out checkLat) && Math.Abs(checkLat) < 90;
                    bool checkLonIsValid = decimal.TryParse(locationDataSet[1], out checkLon) && Math.Abs(checkLon) < 180;
                    if ((checkLatIsValid && checkLonIsValid) && (Math.Abs(checkLat) > 4.4m && Math.Abs(checkLon) > 4.4m))
                    {
                        hasGPS = true;
                        newLat = locationDataSet[0].Trim();
                        newLon = locationDataSet[1].Trim();
                        VA.SetText("AVCS_SENS_OWMLAT", newLat);
                        VA.SetText("AVCS_SENS_OWMLON", newLon);
                        weatherURL = baseURL.Replace("AVCS_SENS_OWMLAT",newLat).Replace("AVCS_SENS_OWMLON",newLon).Replace("AVCS_SENS_OWMKEY",apiKey).Trim();
                    }
                }
            }
            if (hasGPS != true)
            {
                try
                {
                    string apiReturn = "";
                    VA.SetText("~avcs_owm_return", null);
                    weatherURL = "http://api.openweathermap.org/geo/1.0/direct?q="+locationData+"&limit=1&appid="+apiKey;
                    
                    GetWeatherApiReturn(weatherURL, VA);
                    
                    if (VA.GetText("~avcs_owm_return") != null)
                        apiReturn = VA.GetText("~avcs_owm_return").Replace("\"","").Replace("{","").Replace("}","");
                    
                    if (apiReturn.Contains(","))
                    {
                        string[] lines = apiReturn.Split(
                            new string[] { "," },
                            StringSplitOptions.RemoveEmptyEntries
                        );
                        
                        foreach (string line in lines)
                        {
                            if (line.Contains("lat"))
                            {
                                if (line.Contains(":"))
                                {
                                    string[] checkLine = line.Split(
                                        new string[] { ":" },
                                        StringSplitOptions.RemoveEmptyEntries
                                    );
                                    if(1 < checkLine.Length)
                                        newLat = checkLine[1];
                                }
                            }
                            if (line.Contains("lon"))
                            {
                                if (line.Contains(":"))
                                {
                                    string[] checkLine = line.Split(
                                        new string[] { ":" },
                                        StringSplitOptions.RemoveEmptyEntries
                                    );
                                    if(1 < checkLine.Length)
                                        newLon = checkLine[1];
                                }
                            }
                        }
                        decimal tryNewDecimal;
                        if ((newLat != "" && Decimal.TryParse(newLat, out tryNewDecimal)) && (newLon != "" && Decimal.TryParse(newLat, out tryNewDecimal)))
                        {
                            VA.SetText("AVCS_SENS_OWMLAT", newLat);
                            VA.SetText("AVCS_SENS_OWMLON", newLon);
                            weatherURL = baseURL.Replace("AVCS_SENS_OWMLAT",newLat).Replace("AVCS_SENS_OWMLON",newLon).Replace("AVCS_SENS_OWMKEY",apiKey);
                        }
                        else
                        {
                            throw new AVCSexception();
                        }
                    }
                    else
                    {
                        throw new AVCSexception();
                    }
                }
                catch (AVCSexception e)
                {
                    //for any expected unexpected faults
                    faultDetected = true;
                    e.GetWeatherURLException(VA);
                }
            }
        }
        if (faultDetected != true)
        {
            string apiLoc = "";
            string apiMain = "";
            string apiTempMinC = "";
            string apiTempMinF = "";
            string apiTempMaxC = "";
            string apiTempMaxF = "";
            string apiWindSpeedK = "";
            string apiWindSpeedM = "";
            string apiHumidity = "";
            string apiWindDir = "";
            string apiTempUnits = "°C";
            string apiWindUnits = "kph";
            string apiWindFrom = "North";
            string ttsTempMin = "";
            string ttsTempMax = "";
            string ttsWind = "";
            
            int dayCounter = -1;
            string dayCurrent = "";
            
            decimal convertTempMin = 1;
            decimal convertedTempMin = 1;
            decimal convertTempMax = 1;
            decimal convertedTempMax = 1;
            
            bool nextCheckSet = false;
            //===================== GET FORECAST===================
            
            
            try
            {
                string apiReturn = "";
                VA.SetText("~avcs_owm_return", null);
                GetWeatherApiReturn(weatherURL, VA);
                if (VA.GetText("~avcs_owm_return") != null)
                    apiReturn = VA.GetText("~avcs_owm_return").Replace("\"","").Replace("{","").Replace("}","").Replace("uvi",";,uvi");
                
                if (apiReturn.Contains(";"))
                {
                    string[] daysForecasted = apiReturn.Split(
                        new string[] { ";" },
                        StringSplitOptions.RemoveEmptyEntries
                    );
                    //Get Days of Week array
                    List<string> newDaysOfWeek = (new List<string> {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}).GetRange((int)DateTime.Now.DayOfWeek, 8);
                    dayCounter = -1;
                    dayCurrent = "";
                    VA.SetText("AVCS_SENS_OWM_FORECASTS", "");
                    foreach (string dayForcasted in daysForecasted)
                    {
                        apiLoc = "";
                        apiMain = "";
                        apiTempMinC = "";
                        apiTempMinF = "";
                        apiTempMaxC = "";
                        apiTempMaxF = "";
                        apiWindSpeedK = "";
                        apiWindSpeedM = "";
                        apiHumidity = "";
                        apiWindDir = "";
                        dayCounter++;
                        if (dayCounter >= 8)
                            break;
                        
                        dayCurrent = newDaysOfWeek[dayCounter];
                        if (dayCounter == 0)
                            dayCurrent = "Today";
                        
                        if (dayForcasted.Contains(","))
                        {
                            string[] lines = dayForcasted.Split(
                                new string[] { "," },
                                StringSplitOptions.RemoveEmptyEntries
                            );
                            foreach (string line in lines)
                            {
                                
                                // Check and save the second forecast day 'dt' Unix Time (seconds) as time of next daily forecast check
                                if (nextCheckSet != true && line.Contains("dt") && dayCounter == 1)
                                {
                                    if (line.Contains(":"))
                                    {
                                        string[] checkLine = line.Split(
                                            new string[] { ":" },
                                            StringSplitOptions.RemoveEmptyEntries
                                        );
                                        if(1 < line.Length)
                                        {
                                            string nextUnixSecsString = "UNIX";
                                            decimal setNextUnixSecs = 0;
                                            if (VA.GetInt("AVCS_SENS_OWM_FC_Calls") != null && (Decimal.TryParse(VA.ParseTokens("{INT:AVCS_SENS_OWM_FC_Calls:86400}"), out setNextUnixSecs)))
                                            {
                                                setNextUnixSecs += DateTimeOffset.Now.ToUnixTimeSeconds();
                                            }
                                            else
                                            {
                                                setNextUnixSecs = 86400m + DateTimeOffset.Now.ToUnixTimeSeconds();
                                            }
                                            nextUnixSecsString += setNextUnixSecs.ToString();
                                            VA.SetText("AVCS_SENS_OWM_NextDailyForecastCheck", nextUnixSecsString);
                                            VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_OWM_NextDailyForecastCheck=" + nextUnixSecsString + Environment.NewLine);
                                            nextCheckSet = true;
                                        }
                                    }
                                }
                                
                                
                                if (line.Contains("description") && apiMain == "")
                                {
                                    if (line.Contains(":"))
                                    {
                                        string[] checkLine = line.Split(
                                            new string[] { ":" },
                                            StringSplitOptions.RemoveEmptyEntries
                                        );
                                        if (1 < line.Length)
                                        {
                                            apiMain = checkLine[1].Trim().ToLower();
                                        }
                                        
                                        if (apiMain.StartsWith("few"))
                                        {
                                            apiMain = apiMain.Replace("few", "a few");
                                        }
                                        else if (apiMain == "clouds" )
                                        {
                                            apiMain = apiMain.Replace("clouds", "cloudy");
                                        }
                                        else if (apiMain == "sun" )
                                        {
                                            apiMain+="ny";
                                        }
                                        else if ((apiMain == "rain" ) || (apiMain == "mist" ))
                                        {
                                            apiMain+="y";
                                        }
                                        apiMain = apiMain.Replace("sky", "skies");
                                        VA.SetText("AVCS_SENS_TempOWMmain_" + dayCurrent, apiMain);
                                        VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_TempOWMmain_" + dayCurrent + "=" + apiMain + Environment.NewLine);
                                    }
                                }
                                
                                //Min Temp for this day (in C and F)
                                if (line.Contains("min") && apiTempMinC == "")
                                {
                                    if (line.Contains(":"))
                                    {
                                        string[] checkLine = line.Split(
                                            new string[] { ":" },
                                            StringSplitOptions.RemoveEmptyEntries
                                        );
                                        if(1 < line.Length)
                                        {
                                            convertTempMin = 1;
                                            convertedTempMin = 1;
                                            apiTempMinC = checkLine[1];
                                            if (Decimal.TryParse(apiTempMinC, out convertTempMin))
                                            {
                                                convertedTempMin = ((convertTempMin * 9) / 5) + 32;
                                                convertedTempMin = Math.Round(convertedTempMin, 0);
                                                VA.SetInt("AVCS_SENS_TempOWMf_Min_" + dayCurrent, Convert.ToInt32(convertedTempMin));
                                                apiTempMinF = convertedTempMin.ToString();
                                                VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_TempOWMf_Min_" + dayCurrent + "=" + apiTempMinF + Environment.NewLine);
                                            }
                                            if (Decimal.TryParse(apiTempMinC, out convertTempMin))
                                            {
                                                convertedTempMin = Math.Round(convertedTempMin, 0);
                                                VA.SetInt("AVCS_SENS_TempOWMc_Min_" + dayCurrent, Convert.ToInt32(convertedTempMin));
                                                apiTempMinC = convertedTempMin.ToString();
                                                VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_TempOWMf_Min_" + dayCurrent + "=" + apiTempMinC + Environment.NewLine);
                                            }
                                            if (VA.GetBoolean("AVCS_SENS_OWM_UnitMetric") != true)
                                            {
                                                ttsTempMin = apiTempMinF;
                                            }
                                            else
                                            {
                                                ttsTempMin = apiTempMinC;
                                            }
                                        }
                                    }
                                }
                                
                                //Max Temp for this day (in C and F)
                                if (line.Contains("max") && apiTempMaxC == "")
                                {
                                    if (line.Contains(":"))
                                    {
                                        string[] checkLine = line.Split(
                                            new string[] { ":" },
                                            StringSplitOptions.RemoveEmptyEntries
                                        );
                                        if(1 < line.Length)
                                        {
                                            convertTempMax = 1;
                                            convertedTempMax = 1;
                                            apiTempMaxC = checkLine[1];
                                            if (Decimal.TryParse(apiTempMaxC, out convertTempMax))
                                            {
                                                convertedTempMax = ((convertTempMax * 9) / 5) + 32;
                                                convertedTempMax = Math.Round(convertedTempMax, 0);
                                                VA.SetInt("AVCS_SENS_TempOWMf_Max_" + dayCurrent, Convert.ToInt32(convertedTempMax));
                                                apiTempMaxF = convertedTempMax.ToString();
                                                VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_TempOWMf_Max_" + dayCurrent + "=" + apiTempMaxF + Environment.NewLine);
                                            }
                                            if (Decimal.TryParse(apiTempMaxC, out convertTempMax))
                                            {
                                                convertedTempMax = Math.Round(convertedTempMax, 0);
                                                VA.SetInt("AVCS_SENS_TempOWMc_Max_" + dayCurrent, Convert.ToInt32(convertedTempMax));
                                                apiTempMaxC = convertedTempMax.ToString();
                                                VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_TempOWMc_Max_" + dayCurrent + "=" + apiTempMaxC + Environment.NewLine);
                                            }
                                            if (VA.GetBoolean("AVCS_SENS_OWM_UnitMetric") != true)
                                            {
                                                ttsTempMax = apiTempMaxF;
                                            }
                                            else
                                            {
                                                ttsTempMax = apiTempMaxC;
                                            }
                                        }
                                    }
                                }
                                
                                
                                
                                // Humidity for this days forecast
                                if (line.Contains("humidity") && apiHumidity == "")
                                {
                                    if (line.Contains(":"))
                                    {
                                        string[] checkLine = line.Split(
                                            new string[] { ":" },
                                            StringSplitOptions.RemoveEmptyEntries
                                        );
                                        if(1 < line.Length)
                                        {
                                            decimal convertedRH;
                                            apiHumidity = checkLine[1];
                                            if (Decimal.TryParse(apiHumidity, out convertedRH))
                                            {
                                                convertedRH = Math.Round(convertedRH, 0);
                                                VA.SetInt("AVCS_SENS_TempOWMh_" + dayCurrent, Convert.ToInt32(convertedRH));
                                                apiHumidity = convertedRH.ToString();
                                                VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_TempOWMh_" + dayCurrent + "=" + apiHumidity + Environment.NewLine);
                                            }
                                        }
                                    }
                                }
                                
                                // Avg. Wind Speed for this days forecast
                                if (line.Contains("speed") && apiWindSpeedK == "")
                                {
                                    if (line.Contains(":"))
                                    {
                                        string[] checkLine = line.Split(
                                            new string[] { ":" },
                                            StringSplitOptions.RemoveEmptyEntries
                                        );
                                        if(1 < line.Length)
                                        {
                                            decimal convertedSpeed;
                                            apiWindSpeedK = checkLine[1];
                                            if (Decimal.TryParse(apiWindSpeedK, out convertedSpeed))
                                            {
                                                convertedSpeed *= 0.6214m;
                                                convertedSpeed = Math.Round(convertedSpeed, 0);
                                                VA.SetInt("AVCS_SENS_TempOWMwim_" + dayCurrent, Convert.ToInt32(convertedSpeed));
                                                apiWindSpeedM = convertedSpeed.ToString();
                                                VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_TempOWMwim_" + dayCurrent + "=" + apiWindSpeedM + Environment.NewLine);
                                            }
                                            if (Decimal.TryParse(apiWindSpeedK, out convertedSpeed))
                                            {
                                                convertedSpeed = Math.Round(convertedSpeed, 0);
                                                VA.SetInt("AVCS_SENS_TempOWMwik_" + dayCurrent, Convert.ToInt32(convertedSpeed));
                                                apiWindSpeedK = convertedSpeed.ToString();
                                                VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_TempOWMwik_" + dayCurrent + "=" + apiWindSpeedK + Environment.NewLine);
                                            }
                                            if (VA.GetBoolean("AVCS_SENS_OWM_WindMetric") != true)
                                            {
                                                ttsWind = apiWindSpeedM;
                                            }
                                            else
                                            {
                                                ttsWind = apiWindSpeedK;
                                            }
                                        }
                                    }
                                }
                                
                                // Avg. expected Wind Direct for this days forecast
                                if (line.Contains("deg") && apiWindDir == "")
                                {
                                    if (line.Contains(":"))
                                    {
                                        string[] checkLine = line.Split(
                                            new string[] { ":" },
                                            StringSplitOptions.RemoveEmptyEntries
                                        );
                                        if(1 < line.Length)
                                        {
                                            apiWindDir = checkLine[1];
                                            decimal convertedDir = 1;
                                            
                                            if (Decimal.TryParse(apiWindDir, out convertedDir))
                                            {
                                                if ((convertedDir > 337.5m && convertedDir <= 359m) || (convertedDir >= 0m && convertedDir < 22.5m))
                                                {
                                                    apiWindFrom = "North";
                                                }
                                                else if (convertedDir >= 22.5m && convertedDir < 67.5m)
                                                {
                                                    apiWindFrom = "Northeast";
                                                }
                                                else if (convertedDir >= 67.5m && convertedDir <= 112.5m)
                                                {
                                                    apiWindFrom = "East";
                                                }
                                                else if (convertedDir > 112.5m && convertedDir <= 157.5m)
                                                {
                                                    apiWindFrom = "Southeast";
                                                }
                                                else if (convertedDir > 157.5m && convertedDir <= 202.5m)
                                                {
                                                    apiWindFrom = "South";
                                                }
                                                else if (convertedDir > 202.5m && convertedDir <= 247.5m)
                                                {
                                                    apiWindFrom = "Southwest";
                                                }
                                                else if (convertedDir > 247.5m && convertedDir <= 292.5m)
                                                {
                                                    apiWindFrom = "West";
                                                }
                                                else if (convertedDir > 292.5m && convertedDir <= 337.5m)
                                                {
                                                    apiWindFrom = "Northwest";
                                                }
                                                VA.SetText("AVCS_SENS_TempOWMwid_" + dayCurrent, apiWindFrom);
                                                VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_TempOWMwid_" + dayCurrent + "=" + apiWindFrom + Environment.NewLine);
                                            }
                                        }
                                    }
                                    
                                }
                                
                                
                            }
                            
                            if (VA.GetBoolean("AVCS_SENS_OWM_UnitMetric") != true)
                                apiTempUnits = "°F";
                            if (VA.GetBoolean("AVCS_SENS_OWM_WindMetric") != true)
                                apiWindUnits = "mph";
                            
                            //Store New Main Conditions Value for TTS Requests
                            VA.SetText("AVCS_SENS_TempOWMfull_" + dayCurrent, dayCurrent + " will be " + apiMain + " with [lows;low temperatures] around " + ttsTempMin + apiTempUnits + " and highs [of;around;of around] " + ttsTempMax + ". [Expect;There will be] " + apiHumidity + "% humidity, and winds out of the " + apiWindFrom + " at " + ttsWind + apiWindUnits + ".");
                            VA.SetText("AVCS_SENS_OWM_FORECASTS", VA.GetText("AVCS_SENS_OWM_FORECASTS") + "AVCS_SENS_TempOWMfull_" + dayCurrent + "=" + VA.GetText("AVCS_SENS_TempOWMfull_" + dayCurrent) + Environment.NewLine);
                            if (debuggingFC)
                                VA.WriteToLog(VA.GetText("AVCS_SENS_TempOWMfull_" + dayCurrent), "black");
                        }
                        else
                        {
                            throw new AVCSexception();
                        }
                        
                        //end of days loop
                    }
                    VA.SetBoolean("AVCS_OWM_FCSET", true);
                    if (VA.Command.Active("F_SFS_SAVE_FORECAST") != true)
                        VA.Command.Execute("F_SFS_SAVE_FORECAST", false);
                }
                else
                {
                    throw new AVCSexception();
                }
            }
            catch (AVCSexception e)
            {
                //for any expected unexpected faults
                e.GetWeatherURLException(VA);
            }
        }
    }
    
    private void GetWeatherApiReturn(string apiURL, dynamic VA)
    {
        VA.SetText("~avcs_owm_return", null);
        try
        {
            string apiReturn;
            using (WebClient wc = new WebClient())
            {
                wc.Headers.Add("Accept-Language", " en-US");
                wc.Headers.Add("Accept", " text/html, application/xhtml+xml, */*");
                apiReturn = wc.DownloadString(apiURL);
                VA.SetText("~avcs_owm_return", apiReturn);
            }
            
        }
        catch (WebException ex)
        {
            if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
            {
                var resp = (HttpWebResponse)ex.Response;
                if (resp.StatusCode == HttpStatusCode.NotFound)// handle HTTP 404 errors
                {
                    VA.WriteToLog("AVCS ERROR - HTTP 404 - Unable to find page at URL:", "red");
                    VA.WriteToLog(apiURL, "blank");
                }
            }
        }
    }
    
    static bool canShowInterval(int n)
    {
        if (n > 0)
        {
            while (n > 0)
                n = n - 3;
            
            if (n == 0)
                return true;
        }
        return false;
    }
    
    private bool canGetDailyForecast()
    {
        decimal nextUnixSecs;
        if (Decimal.TryParse(VA.ParseTokens("{TXTNUM:AVCS_SENS_OWM_NextDailyForecastCheck}"), out nextUnixSecs))
            if (nextUnixSecs >= DateTimeOffset.Now.ToUnixTimeSeconds())
                return false;
        return true;
    }
    
    private bool canGetWeatherData()
    {
        decimal nextUnixSecs;
        if (Decimal.TryParse(VA.ParseTokens("{TXTNUM:AVCS_SENS_OWM_NextWeatherGetCheck}"), out nextUnixSecs))
            if (nextUnixSecs >= DateTimeOffset.Now.ToUnixTimeSeconds())
                return false;
        return true;
    }
    
    private static string showNextInterval(int intervalOWM, int GetWeatherInterval, int GetWeatherTimerDelay)
    {
        string timeRemaining;
        try
        {
            double minutesRemaining = TimeSpan.FromMilliseconds(((GetWeatherInterval - intervalOWM) * GetWeatherTimerDelay)).TotalMinutes;
            timeRemaining = "AVCS OWM Monitor will get new data in " + minutesRemaining.ToString().Substring(0,4) + " minutes";
        }
        catch
        {
            timeRemaining = "";
        }
        
        return timeRemaining;
    }
    
    public void main()
    {
        if (VA.GetBoolean("AVCS_OWM_Monitoring") != true)
        {
            VA.SetBoolean("AVCS_OWM_Monitoring", true);
            VA.SetBoolean("AVCS_OWM_SET", null);
            if (VA.GetBoolean("AVCS_OWM_Monitor_Startup") != true)
                VA.SetBoolean("AVCS_OWM_Monitor_Startup", true);
            
            try
            {
                GetWeatherData(VA);
                if (VA.GetBoolean("AVCS_OWM_SET") != true)
                {
                    VA.SetBoolean("AVCS_OWM_Monitoring", false);
                }
            }
            catch
            {
                //for any expected unexpected faults
                VA.SetBoolean("AVCS_OWM_Monitoring", false);
            }
            
            if (VA.GetBoolean("AVCS_OWM_Monitoring") == true)
            {
                if (VA.GetInt("AVCS_SENS_OWM_API_Calls") != null)
                {
                    GetWeatherInterval = Convert.ToInt32(VA.GetInt("AVCS_SENS_OWM_API_Calls"));
                    if (GetWeatherInterval == 180)
                    {
                        timerInterval = "15 minutes";
                    }
                    else if (GetWeatherInterval == 360)
                    {
                        timerInterval = "30 minutes";
                    }
                    else if (GetWeatherInterval == 720)
                    {
                        timerInterval = "60 minutes";
                    }
                    else
                    {
                        int getNextWeatherInterval = (GetWeatherInterval * 5) / 60;
                        timerInterval = getNextWeatherInterval.ToString() + " minute(s)";
                    }
                }
                else
                {
                    GetWeatherInterval = 180;
                    timerInterval = "15 minutes";
                }
                
                int getNextCheckInterval = (GetWeatherTimerDelay/1000) * GetWeatherInterval;
                VA.SetInt("AVCS_SENS_OWM_WG_Calls", getNextCheckInterval);
                
                GetWeatherTimer(timerInterval);
                
                if (VA.ParseTokens("{CMDACTION}") == "Plugin")
                {
                    VA.SetText("AVCS_SENS_TTS_WILDCARD", "Weather Data [Monitoring;;] Systems are now [active;online;ready;engaged]");
                    VA.Command.Execute("F_SAY_TTS", true);
                }
            }
            else
            {
                if (VA.ParseTokens("{CMDACTION}") == "Plugin")
                {
                    VA.SetText("AVCS_SENS_TTS_WILDCARD", "Weather data unavailable. Please check settings.");
                    VA.Command.Execute("F_SAY_TTS", true);
                }
            }
            VA.SetBoolean("AVCS_OWM_Monitor_Startup", null);
        }
    }
}

Comments