public String SetStateActuatorPreset(String XS1_URL, String Username, String Password, String actorname, String preset, XS1Configuration XS1_Configuration) { String Output = ""; // get the XS1 Actuator List to find the ID and the Preset ID XS1ActuatorList actuatorlist = XS1_Configuration.getXS1ActuatorList(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password); //bool foundatleastoneactuator = false; Int32 foundActorID = 0; Int32 foundPresetID = 0; foreach (XS1Actuator _actuator in actuatorlist.actuator) { foundActorID++; if (_actuator.name.ToUpper() == actorname.ToUpper()) { //foundActorID = _actuator.id; bool foundpreset = false; foreach (actuator_function actorfunction in _actuator.function) { foundPresetID++; if (actorfunction.type.ToUpper() == preset.ToUpper()) { foundpreset = true; break; } } #region doing real stuff if (foundpreset) { if (foundActorID != 0) { // so we obviously got the actor and the preset id... now lets do the call set_state_actuator ssa = new set_state_actuator(); Output = ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, foundActorID, foundPresetID); //foundatleastoneactuator = true; break; } } #endregion } } return Output; }
public String SetStateActuatorPreset(String XS1_URL, String Username, String Password, String actorname, String preset, XS1Configuration XS1_Configuration) { String Output = ""; // get the XS1 Actuator List to find the ID and the Preset ID XS1ActuatorList actuatorlist = XS1_Configuration.getXS1ActuatorList(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password); //bool foundatleastoneactuator = false; Int32 foundActorID = 0; Int32 foundPresetID = 0; foreach (XS1Actuator _actuator in actuatorlist.actuator) { foundActorID++; if (_actuator.name.ToUpper() == actorname.ToUpper()) { //foundActorID = _actuator.id; bool foundpreset = false; foreach (actuator_function actorfunction in _actuator.function) { foundPresetID++; if (actorfunction.type.ToUpper() == preset.ToUpper()) { foundpreset = true; break; } } #region doing real stuff if (foundpreset) { if (foundActorID != 0) { // so we obviously got the actor and the preset id... now lets do the call set_state_actuator ssa = new set_state_actuator(); Output = ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, foundActorID, foundPresetID); //foundatleastoneactuator = true; break; } } #endregion } } return(Output); }
/// <summary> /// We need to make sure that the url that we are trying to treat as a file /// lies below the document root of the http server so that people can't grab /// random files off your computer while this is running. /// </summary> public void writeURL() { try { // set this to true when implementing and reaching a new method bool method_found = false; // first check if the request is actually authenticated IPEndPoint AC_endpoint = (IPEndPoint)s.RemoteEndPoint; ConsoleOutputLogger.WriteLine(AC_endpoint.Address.ToString() + " GET " + original_url); //if (!HTTPAuthProcessor.AllowedToAccessThisServer(AC_endpoint.Address)) //{ // // now give the user a 403 and break... // writeForbidden(); // ns.Flush(); // return; //} //querystring = ""; url = original_url; #region Authentification if (AC_endpoint.Address.ToString().StartsWith(AuthDisabledForAdressesThatStartWith)) AuthenticatedSuccessfully = true; if (AuthorizationEnabled) { if (!AuthenticatedSuccessfully) { writeNotAuthorized("hacs"); } } #endregion if (internal_proxy.isThisAProxyURL(url)) { ProxyResponse proxy_response = internal_proxy.Proxy(url); if (proxy_response == null) { writeError(500, "Proxy Activation URL not found"); return; } int left = new UTF8Encoding().GetByteCount(proxy_response.Content); writeSuccess(left, "text/html"); byte[] buffer = new UTF8Encoding().GetBytes(proxy_response.Content); ns.Write(buffer, 0, left); ns.Flush(); return; } #region NUMERICS JSON data implementation if (url.ToUpper().StartsWith("/NUMERICS/")) { #region data request // remove the /data/ stuff url = url.Remove(0, 10); #region Sensor Data if (url.ToUpper().StartsWith("SENSOR")) { method_found = true; url = url.Remove(0, 6); NameValueCollection nvcollection = HttpUtility.ParseQueryString(url); String ObjectTypeName = ""; String ObjectName = ""; String StartDate = ""; String EndDate = ""; Boolean JustLastEntry = false; DateTime start = DateTime.Now; DateTime end = DateTime.Now; //ConsoleOutputLogger.WriteLineToScreenOnly("..."); foreach (String Key in nvcollection.AllKeys) { if (Key.ToUpper() == "NAME") ObjectName = nvcollection[Key]; if (Key.ToUpper() == "TYPE") ObjectTypeName = nvcollection[Key]; if (Key.ToUpper() == "START") StartDate = nvcollection[Key]; if (Key.ToUpper() == "END") EndDate = nvcollection[Key]; if (Key.ToUpper() == "LASTENTRY") JustLastEntry = true; } //ConsoleOutputLogger.WriteLineToScreenOnly("..."); if (ObjectTypeName == "") { writeError(404, "No Method found"); return; } if (ObjectName == "") { writeError(404, "No Method found"); return; } if (StartDate == "") // defaults { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = StartDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); start = new DateTime(year, month, day); } else { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } if (EndDate == "") { end = DateTime.Now; } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = EndDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); end = new DateTime(year, month, day); } else { end = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } //ConsoleOutputLogger.WriteLineToScreenOnly("..."); String Output; if (!JustLastEntry) Output = NumericsJSON_Data.GenerateDataNumericsJSONOutput(ObjectTypes.Sensor, ObjectTypeName, ObjectName, start, end); else Output = NumericsJSON_Data.GenerateDataNumericsJSONOutput_LastEntryOnly(ObjectTypes.Sensor, ObjectTypeName, ObjectName); int left = new UTF8Encoding().GetByteCount(Output); //writeSuccess(left, "application/json"); writeSuccess(left, "text/html"); byte[] buffer = new UTF8Encoding().GetBytes(Output); ns.Write(buffer, 0, left); ns.Flush(); return; } #endregion #region Power Sensor Data if (url.ToUpper().StartsWith("POWERSENSOR")) { method_found = true; url = url.Remove(0, 11); NameValueCollection nvcollection = HttpUtility.ParseQueryString(url); // TODO: ADD handling and calculation here String ObjectName = ""; String StartDate = ""; String EndDate = ""; String OutputType = ""; DateTime start = DateTime.Now; DateTime end = DateTime.Now; PowerSensorOutputs Outputs = PowerSensorOutputs.HourkWh; foreach (String Key in nvcollection.AllKeys) { if (Key.ToUpper() == "NAME") ObjectName = nvcollection[Key]; if (Key.ToUpper() == "TYPE") OutputType = nvcollection[Key]; if (Key.ToUpper() == "START") StartDate = nvcollection[Key]; if (Key.ToUpper() == "END") EndDate = nvcollection[Key]; } if (ObjectName == "") { writeError(404, "No Method found"); return; } if (StartDate == "") // defaults { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = StartDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); start = new DateTime(year, month, day); } else { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } if (EndDate == "") { end = DateTime.Now; } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = EndDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); end = new DateTime(year, month, day); } else { end = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } if (OutputType.ToUpper() == "HOUR") Outputs = PowerSensorOutputs.HourkWh; if (OutputType.ToUpper() == "HOURPEAK") Outputs = PowerSensorOutputs.HourPeakkWh; if (OutputType.ToUpper() == "CALCKWH") Outputs = PowerSensorOutputs.CalculatedkWhCounterTotal; if (OutputType.ToUpper() == "CALCWEEKLYKWH") Outputs = PowerSensorOutputs.CalculateWeeklykWh; if (OutputType.ToUpper() == "CALCDAILYKWH") Outputs = PowerSensorOutputs.CalculatedDailykWh; if (OutputType.ToUpper() == "CALCHOURLYKWH") Outputs = PowerSensorOutputs.CalculatedHourlykWh; String Output = NumericsJSON_Data.GeneratePowerSensorNumericsJSONOutput(Outputs, ObjectName, start, end); int left = new UTF8Encoding().GetByteCount(Output); writeSuccess(left, "text/html"); byte[] buffer = new UTF8Encoding().GetBytes(Output); ns.Write(buffer, 0, left); ns.Flush(); return; } #endregion #region Actor Data if (url.ToUpper().StartsWith("ACTOR")) { method_found = true; url = url.Remove(0, 5); NameValueCollection nvcollection = HttpUtility.ParseQueryString(url); String ObjectName = ""; String OutputType = ""; ActorsStatusOutputTypes ActorOutputType = ActorsStatusOutputTypes.Binary; foreach (String Key in nvcollection.AllKeys) { if (Key.ToUpper() == "NAME") ObjectName = nvcollection[Key]; if (Key.ToUpper() == "OUTPUTTYPE") OutputType = nvcollection[Key]; } if (ObjectName == "") { writeError(404, "No Method found"); return; } if (OutputType != "") { if (OutputType.ToUpper() == "BINARY") ActorOutputType = ActorsStatusOutputTypes.Binary; if (OutputType.ToUpper() == "TRUEFALSE") ActorOutputType = ActorsStatusOutputTypes.TrueFalse; if (OutputType.ToUpper() == "ONOFF") ActorOutputType = ActorsStatusOutputTypes.OnOff; } // now we should have a name we need to look up //bool foundactor = false; // get the XS1 Actuator List to find the ID and the Preset ID XS1ActuatorList actuatorlist = XS1_Configuration.getXS1ActuatorList(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password); foreach (XS1Actuator _actuator in actuatorlist.actuator) { if (_actuator.name.ToUpper() == ObjectName.ToUpper()) { // we found one! //foundactor = true; // TODO: we need to output a JSON dataset here // bool Status = false; // // if (_actuator.value == 0.0) // Status = false; // else // Status = true; String Output = NumericsJSON_Data.GenerateNumericsJSONDataActorStatus(ActorOutputType, _actuator.name); int left = new UTF8Encoding().GetByteCount(Output); writeSuccess(left, "text/html"); byte[] buffer = new UTF8Encoding().GetBytes(Output); ns.Write(buffer, 0, left); ns.Flush(); return; } } } #endregion if (!method_found) { // nothing to do... writeError(404, "No Method found"); } #endregion } #endregion #region JSON data implementation if (url.ToUpper().StartsWith("/DATA/")) { #region data request // remove the /data/ stuff url = url.Remove(0, 6); #region Swimlane - All Sensors // this is a swimlane diagram containing for now containing all switches in the given household // TODO: do something more useful here if (url.ToUpper().StartsWith("SWIMLANE")) { String ObjectTypeName = ""; String ObjectName = ""; String StartDate = ""; String EndDate = ""; DateTime start = DateTime.Now; DateTime end = DateTime.Now; method_found = true; #region Querystring Handling url = url.Remove(0,8); NameValueCollection nvcollection = HttpUtility.ParseQueryString(url); foreach (String Key in nvcollection.AllKeys) { if (Key.ToUpper() == "NAME") ObjectName = nvcollection[Key]; if (Key.ToUpper() == "TYPE") ObjectTypeName = nvcollection[Key]; if (Key.ToUpper() == "START") StartDate = nvcollection[Key]; if (Key.ToUpper() == "END") EndDate = nvcollection[Key]; } if (ObjectTypeName == "") { writeError(404, "No Method found"); return; } if (ObjectName == "") { writeError(404, "No Method found"); return; } if (StartDate == "") // defaults { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = StartDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); start = new DateTime(year, month, day); } else { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } if (EndDate == "") { end = DateTime.Now; } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = EndDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); end = new DateTime(year, month, day); } else { end = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } #endregion String Output = GenerateSwimlane.Generate(ELVMAX,SensorDataStore,ObjectName,ObjectTypeName,start,end); int left = new UTF8Encoding().GetByteCount(Output); //writeSuccess(left, "application/json"); writeSuccess(left, "text/html"); byte[] buffer = new UTF8Encoding().GetBytes(Output); ns.Write(buffer, 0, left); ns.Flush(); return; } #endregion #region Sensor Data if (url.ToUpper().StartsWith("SENSOR")) { method_found = true; url = url.Remove(0,6); NameValueCollection nvcollection = HttpUtility.ParseQueryString(url); String ObjectTypeName = ""; String ObjectName = ""; String StartDate = ""; String EndDate = ""; Boolean JustLastEntry = false; DateTime start = DateTime.Now; DateTime end = DateTime.Now; //ConsoleOutputLogger.WriteLineToScreenOnly("..."); foreach (String Key in nvcollection.AllKeys) { if (Key.ToUpper() == "NAME") ObjectName = nvcollection[Key]; if (Key.ToUpper() == "TYPE") ObjectTypeName = nvcollection[Key]; if (Key.ToUpper() == "START") StartDate = nvcollection[Key]; if (Key.ToUpper() == "END") EndDate = nvcollection[Key]; if (Key.ToUpper() == "LASTENTRY") JustLastEntry = true; } //ConsoleOutputLogger.WriteLineToScreenOnly("..."); if (ObjectTypeName == "") { writeError(404, "No Method found"); return; } if (ObjectName == "") { writeError(404, "No Method found"); return; } if (StartDate == "") // defaults { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = StartDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); start = new DateTime(year, month, day); } else { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } if (EndDate == "") { end = DateTime.Now; } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = EndDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); end = new DateTime(year, month, day); } else { end = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } //ConsoleOutputLogger.WriteLineToScreenOnly("..."); String Output; if (!JustLastEntry) Output = JSON_Data.GenerateDataJSONOutput(ObjectTypes.Sensor, ObjectTypeName, ObjectName,start,end); else Output = JSON_Data.GenerateDataJSONOutput_LastEntryOnly(ObjectTypes.Sensor, ObjectTypeName, ObjectName); int left = new UTF8Encoding().GetByteCount(Output); //writeSuccess(left, "application/json"); writeSuccess(left, "text/html"); byte[] buffer = new UTF8Encoding().GetBytes(Output); ns.Write(buffer, 0, left); ns.Flush(); return; } #endregion /* #region Google Latitude if (hacs.Properties.Settings.Default.GoogleLatitudeEnabled) { if (url.ToUpper().StartsWith("GEOLOCATION")) { method_found = true; url = url.Remove(0, 11); NameValueCollection nvcollection = HttpUtility.ParseQueryString(url); // TODO: ADD handling and calculation here String ObjectName = ""; String StartDate = ""; String EndDate = ""; //String OutputType = ""; DateTime start = DateTime.Now; DateTime end = DateTime.Now; Boolean JustLastEntry = false; #region Querystring handling foreach (String Key in nvcollection.AllKeys) { if (Key.ToUpper() == "NAME") ObjectName = nvcollection[Key]; if (Key.ToUpper() == "START") StartDate = nvcollection[Key]; if (Key.ToUpper() == "END") EndDate = nvcollection[Key]; if (Key.ToUpper() == "LASTENTRY") JustLastEntry = true; } if (ObjectName == "") { writeError(404, "No Method found"); return; } if (StartDate == "") // defaults { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = StartDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); start = new DateTime(year, month, day); } else { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } if (EndDate == "") { end = DateTime.Now; } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = EndDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); end = new DateTime(year, month, day); } else { end = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } #endregion String Output = ""; if (JustLastEntry) Output = LatitudeGeoLocation.GenerateJSON_LastEntry(ObjectName); int left = new UTF8Encoding().GetByteCount(Output); writeSuccess(left, "text/html"); byte[] buffer = new UTF8Encoding().GetBytes(Output); ns.Write(buffer, 0, left); ns.Flush(); return; } } #endregion */ #region Power Sensor Data if (url.ToUpper().StartsWith("POWERSENSOR")) { method_found = true; url = url.Remove(0, 11); NameValueCollection nvcollection = HttpUtility.ParseQueryString(url); // TODO: ADD handling and calculation here String ObjectName = ""; String StartDate = ""; String EndDate = ""; String OutputType = ""; DateTime start = DateTime.Now; DateTime end = DateTime.Now; PowerSensorOutputs Outputs = PowerSensorOutputs.HourkWh; foreach (String Key in nvcollection.AllKeys) { if (Key.ToUpper() == "NAME") ObjectName = nvcollection[Key]; if (Key.ToUpper() == "TYPE") OutputType = nvcollection[Key]; if (Key.ToUpper() == "START") StartDate = nvcollection[Key]; if (Key.ToUpper() == "END") EndDate = nvcollection[Key]; } if (ObjectName == "") { writeError(404, "No Method found"); return; } if (StartDate == "") // defaults { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = StartDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); start = new DateTime(year, month, day); } else { start = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } if (EndDate == "") { end = DateTime.Now; } else { // parse the date and set it... // since we are only interested in the day, month and year it's necessary to only parse that // we expect the following format: day-month-year // for example: 12-01-2012 will be 12th of January 2012 String[] Splitted = EndDate.Split(new char[1] { '-' }); if (Splitted.Length == 3) { Int32 year = Convert.ToInt32(Splitted[2]); Int32 month = Convert.ToInt32(Splitted[1]); Int32 day = Convert.ToInt32(Splitted[0]); end = new DateTime(year, month, day); } else { end = DateTime.Now - (new TimeSpan(hacs.Properties.Settings.Default.DefaultSensorOutputPeriod, 0, 0, 0)); } } if (OutputType.ToUpper() == "HOUR") Outputs = PowerSensorOutputs.HourkWh; if (OutputType.ToUpper() == "HOURPEAK") Outputs = PowerSensorOutputs.HourPeakkWh; if (OutputType.ToUpper() == "CALCKWH") Outputs = PowerSensorOutputs.CalculatedkWhCounterTotal; if (OutputType.ToUpper() == "CALCWEEKLYKWH") Outputs = PowerSensorOutputs.CalculateWeeklykWh; if (OutputType.ToUpper() == "CALCDAILYKWH") Outputs = PowerSensorOutputs.CalculatedDailykWh; if (OutputType.ToUpper() == "CALCHOURLYKWH") Outputs = PowerSensorOutputs.CalculatedHourlykWh; String Output = JSON_Data.GeneratePowerSensorJSONOutput(Outputs,ObjectName, start, end); int left = new UTF8Encoding().GetByteCount(Output); writeSuccess(left, "text/html"); byte[] buffer = new UTF8Encoding().GetBytes(Output); ns.Write(buffer, 0, left); ns.Flush(); return; } #endregion #region Actor Data if (url.ToUpper().StartsWith("ACTOR")) { method_found = true; url = url.Remove(0,5); NameValueCollection nvcollection = HttpUtility.ParseQueryString(url); String ObjectName = ""; String OutputType = ""; ActorsStatusOutputTypes ActorOutputType = ActorsStatusOutputTypes.Binary; foreach (String Key in nvcollection.AllKeys) { if (Key.ToUpper() == "NAME") ObjectName = nvcollection[Key]; if (Key.ToUpper() == "OUTPUTTYPE") OutputType = nvcollection[Key]; } if (ObjectName == "") { writeError(404, "No Method found"); return; } if (OutputType != "") { if (OutputType.ToUpper() == "BINARY") ActorOutputType = ActorsStatusOutputTypes.Binary; if (OutputType.ToUpper() == "TRUEFALSE") ActorOutputType = ActorsStatusOutputTypes.TrueFalse; if (OutputType.ToUpper() == "ONOFF") ActorOutputType = ActorsStatusOutputTypes.OnOff; } // now we should have a name we need to look up //bool foundactor = false; // get the XS1 Actuator List to find the ID and the Preset ID XS1ActuatorList actuatorlist = XS1_Configuration.getXS1ActuatorList(hacs.Properties.Settings.Default.XS1,hacs.Properties.Settings.Default.Username,hacs.Properties.Settings.Default.Password); foreach (XS1Actuator _actuator in actuatorlist.actuator) { if (_actuator.name.ToUpper() == ObjectName.ToUpper()) { // we found one! //foundactor = true; // TODO: we need to output a JSON dataset here // bool Status = false; // // if (_actuator.value == 0.0) // Status = false; // else // Status = true; String Output = JSON_Data.GenerateJSONDataActorStatus(ActorOutputType, _actuator.name); int left = new UTF8Encoding().GetByteCount(Output); writeSuccess(left, "text/html"); byte[] buffer = new UTF8Encoding().GetBytes(Output); ns.Write(buffer, 0, left); ns.Flush(); return; } } } #endregion if (!method_found) { // nothing to do... writeError(404, "No Method found"); } #endregion } #endregion #region ACTOR switching requests if (url.ToUpper().StartsWith("/ACTOR/")) { #region actor switching request // /actor/preset?name=[actor_name]&preset=[preset_function_name] // /actor/direct?name=[actor_name]&value=[new_actor_value] // remove the /actor/ stuff url = url.Remove(0, 7); #region Preset Mode if (url.ToUpper().StartsWith("PRESET")) { method_found = true; url = url.Remove(0, 6); NameValueCollection nvcollection = HttpUtility.ParseQueryString(url); String actorname = ""; String preset = ""; foreach (String Key in nvcollection.AllKeys) { if (Key.ToUpper() == "NAME") actorname = nvcollection[Key]; if (Key.ToUpper() == "PRESET") preset = nvcollection[Key]; } Int32 foundActorID = 0; Int32 foundPresetID = 0; #region error handling if (actorname == "") { writeError(404, "No Method found"); return; } if (preset == "") { writeError(404, "No Method found"); return; } #endregion // get the XS1 Actuator List to find the ID and the Preset ID XS1ActuatorList actuatorlist = XS1_Configuration.getXS1ActuatorList(hacs.Properties.Settings.Default.XS1,hacs.Properties.Settings.Default.Username,hacs.Properties.Settings.Default.Password); bool foundatleastoneactuator = false; // foreach (XS1Actuator _actuator in actuatorlist.actuator) { if (_actuator.name.ToUpper() == actorname.ToUpper()) { foundActorID = _actuator.id; bool foundpreset = false; foreach (actuator_function actorfunction in _actuator.function) { foundPresetID++; if (actorfunction.type.ToUpper() == preset.ToUpper()) { foundpreset = true; break; } } #region error handling if (foundpreset) { if (foundActorID != 0) { // so we obviously got the actor and the preset id... now lets do the call set_state_actuator ssa = new set_state_actuator(); ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, foundActorID, foundPresetID); foundatleastoneactuator = true; break; } } #endregion } } if (!foundatleastoneactuator) { writeError(404, "actor or function not found"); return; } } else if (url.ToUpper().StartsWith("DIRECT")) { } #endregion if (!method_found) { // nothing to do... writeError(404, "No Method found"); return; } #endregion } #endregion else { #region File request (everything else...) #region default page if (url == "/") { url = "/index.html"; } #endregion // check if we have some querystring parameters if (url.Contains("?")) { // yes, remove everything after the ? from the url but save it to querystring //querystring = url.Substring(url.IndexOf('?') + 1); url = url.Remove(url.IndexOf('?')); } // Replace the forward slashes with back-slashes to make a file name string filename = url.Replace('/', Path.DirectorySeparatorChar); //you have different path separators in unix and windows try { // Construct a filename from the doc root and the filename FileInfo file = new FileInfo(docRootFile + filename); // Make sure they aren't trying in funny business by checking that the // resulting canonical name of the file has the doc root as a subset. filename = file.FullName; if (!filename.StartsWith(docRootFile.FullName)) { writeForbidden(); } else { FileStream fs = null; BufferedStream bs = null; long bytesSent = 0; //bool resumed = false; try { if (filename.EndsWith(".log")) { // now give the user a 403 and break... writeForbidden(); ns.Flush(); } else if (filename.EndsWith(".html") | (filename.EndsWith(".htm"))) { // String Output = File.ReadAllText(filename); int left = new UTF8Encoding().GetByteCount(Output); writeSuccess(left, "text/html"); byte[] buffer = new UTF8Encoding().GetBytes(Output); ns.Write(buffer, 0, left); ns.Flush(); } else { // Open the file for binary transfer fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); long left = file.Length; //bool isThisARecordingRecording = false; #region different mime-type-handling switch (getFileExtension(filename)) { case ".css": writeSuccess(left, "text/css"); break; case ".gif": writeSuccess(left, "image/gif"); break; case ".png": writeSuccess(left, "image/png"); break; case ".jpg": writeSuccess(left, "image/jpeg"); break; case ".jpeg": writeSuccess(left, "image/jpeg"); break; case ".ico": writeSuccess(left, "image/ico"); break; default: // Write the content length and the success header to the stream; it's binary...so treat it as binary writeSuccess(left, "application/octet-stream"); break; } #endregion // Copy the contents of the file to the stream, ensure that we never write // more than the content length we specified. Just in case the file somehow // changes out from under us, although I don't know if that is possible. bs = new BufferedStream(fs); left = file.Length; // for performance reasons... int read; while (left > 0 && (read = bs.Read(bytes, 0, (int)Math.Min(left, bytes.Length))) != 0) { ns.Write(bytes, 0, read); bytesSent = bytesSent + read; left -= read; } ns.Flush(); bs.Close(); fs.Close(); } } catch (Exception e) { ConsoleOutputLogger.WriteLineToScreenOnly("[FEHLER@HTTP] " + e.Message); try { writeFailure(); } catch (Exception) { ConsoleOutputLogger.WriteLineToScreenOnly("[FEHLER@HTTP] connection lost to client"); } if (bs != null) bs.Close(); if (bs != null) fs.Close(); } } } catch (Exception e) { ConsoleOutputLogger.WriteLineToScreenOnly("[FEHLER@HTTP] " + e.Message); writeFailure(); } #endregion } } catch (Exception e) { ConsoleOutputLogger.WriteLineToScreenOnly("[FEHLER@HTTP] " + e.Message+" ## "+e.StackTrace); writeFailure(); } }
public void Run() { // initialize XS1 Configuration XS1_Configuration = new XS1Configuration(ConfigurationCacheMinutes); MAXMonitoringThread ELVMax = null; SolarLogMonitoringThread SolarLog = null; // Start Sensor-Check Thread SensorCheck Sensorcheck = new SensorCheck(ConsoleOutputLogger); Thread SensorCheckThread = new Thread(new ThreadStart(Sensorcheck.Run)); SensorCheckThread.Start(); // Start Actor Re-Switching Thread ActorReswitching ActorReSwitch_ = new ActorReswitching(XS1_Configuration, ConsoleOutputLogger, TemporaryBlacklist, OnWaitOffLIst); Thread ActorReswitchThread = new Thread(new ThreadStart(ActorReSwitch_.Run)); ActorReswitchThread.Start(); // Start the SolarLog Thread (if enabled) // TODO: make it switchable / configurable if (Properties.Settings.Default.SolarLogEnabled) { SolarLog = new SolarLogMonitoringThread(Properties.Settings.Default.SolarLogURLDomain, ConsoleOutputLogger, SolarLog_DataQueue, Properties.Settings.Default.SolarLogUpdateIntervalMsec); Thread SolarLogThread = new Thread(new ThreadStart(SolarLog.Run)); SolarLogThread.Start(); } // Start the ELVMax Thread if (Properties.Settings.Default.ELVMAXEnabled) { ELVMax = new MAXMonitoringThread(Properties.Settings.Default.ELVMAXIP, Properties.Settings.Default.ELVMAXPort, ConsoleOutputLogger, MAX_DataQueue, Properties.Settings.Default.ELVMAXUpdateIntervalMsec); Thread ELVMaxThread = new Thread(new ThreadStart(ELVMax.Run)); ELVMaxThread.Start(); } XS1MonitoringThread XS1 = new XS1MonitoringThread(ServerName, ConsoleOutputLogger, UserName, Password, XS1_DataQueue); Thread XS1Thread = new Thread(new ThreadStart(XS1.Run)); XS1Thread.Start(); // Start integrated HTTP Server HttpServer httpServer = new HttpServer(Properties.Settings.Default.HTTPPort, Properties.Settings.Default.HTTPIP, Properties.Settings.Default.HTTPDocumentRoot, sensor_data_store, miataru_data_store, XS1_Configuration, ConsoleOutputLogger, ELVMax, Properties.Settings.Default.HTTPAuthEnabled, Properties.Settings.Default.HTTPAuthUsername, Properties.Settings.Default.HTTPAuthPassword, Properties.Settings.Default.HTTPAuthDisabledAdressStartsWith); Thread http_server_thread = new Thread(new ThreadStart(httpServer.listen)); http_server_thread.Start(); // Start Service Monitorng thread if (Properties.Settings.Default.NetworkMonitorEnabled) { NetworkMonitoring monitor = new NetworkMonitoring(ConsoleOutputLogger, NetworkMonitor_Queue, Properties.Settings.Default.NetworkMonitorUpdateIntervalMsec); Thread monitorThread = new Thread(new ThreadStart(monitor.Run)); monitorThread.Start(); } // Start Alarming thread if (Properties.Settings.Default.AlarmingEnabled) { AlarmingThread alarmThread = new AlarmingThread(ConsoleOutputLogger, Alarming_Queue, sensor_data_store, actor_data_store, miataru_data_store); Thread alarming_thread = new Thread(new ThreadStart(alarmThread.Run)); alarming_thread.Start(); } // Start Miataru Thread if (Properties.Settings.Default.MiataruEnabled) { MiataruThread miataruThread = new MiataruThread(ConsoleOutputLogger, miataru_data_store, Properties.Settings.Default.MiataruUpdateTime); Thread miataru_Thread = new Thread(new ThreadStart(miataruThread.Run)); miataru_Thread.Start(); } // Start MQTT Thread if (Properties.Settings.Default.MQTTBindingEnabled) { MQTT_Binding = new MQTT_Handling(ConsoleOutputLogger); Thread mqtt_Thread = new Thread(new ThreadStart(MQTT_Binding.Run)); mqtt_Thread.Start(); } while (!Shutdown) { try { #region Handle XS1 events XS1_DataObject dataobject = null; if (XS1_DataQueue.TryDequeue(out dataobject)) { if (dataobject.Type == ObjectTypes.Actor) { // Write to Disk lock (actor_data_store) { actor_data_store.Write(dataobject.Serialize()); } lock (KnownActorStates.KnownActorStatuses) { bool usethisactor = true; // check if this actor is on temporary blacklist (like when it was handled) lock (TemporaryBlacklist) { if (TemporaryBlacklist.Contains(dataobject.Name)) { usethisactor = false; } TemporaryBlacklist.Remove(dataobject.Name); } if (usethisactor) { // if Alarming is enabled, queue this XS1 Event up for alarming... if (Properties.Settings.Default.AlarmingEnabled) { Alarming_Queue.Enqueue(dataobject); } // this actor action did not result in any action hacs made - so we try to make the best out of it #region Scripting Handling // check if this sensor is something we should act uppon foreach (ScriptingActorElement Element in ScriptingActorConfiguration.ScriptingActorActions) { if (dataobject.Name == Element.SensorToWatchName) { if (dataobject.Value == Element.SensorValue) { // obviously there is a ScriptingActorConfiguration entry // so we execute the actor preset set_state_actuator.set_state_actuator ssa = new set_state_actuator.set_state_actuator(); ConsoleOutputLogger.WriteLineToScreenOnly("detected actor scripting action on actor " + Element.SensorToWatchName + " - " + Element.ActorToSwitchName + " to " + Element.ActionToRunName); if (Element.isCurrentlyWithinStartEndHours()) { #region Scripting Actor Actions if (Element.ActionToRunName == actor_status.URL) { ConsoleOutputLogger.WriteLine("Scripting Actor URL"); // handle URLs -> the ActorToSwitch Name will be the URL to trigger try { WebClient client = new WebClient(); client.Encoding = System.Text.Encoding.UTF8; String JSONInput = client.DownloadString(Element.ActorToSwitchName); ConsoleOutputLogger.WriteLine("Doing HTTP GET on: " + Element.ActorToSwitchName); } catch (Exception e) { ConsoleOutputLogger.WriteLine("Exception on URL Actor Scripting: " + e.Message); } } // check what action is going to happen now... if (Element.ActionToRunName == actor_status.On) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } if (Element.ActionToRunName == actor_status.Off) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "OFF", XS1_Configuration); // remove from OnWaitOffList lock (OnWaitOffLIst) { if (OnWaitOffLIst.Contains(Element.ActorToSwitchName)) { OnWaitOffLIst.Remove(Element.ActorToSwitchName); } } } if (Element.ActionToRunName == actor_status.OnOff) { // look for the current status in the known actors table lock (KnownActorStates.KnownActorStatuses) { if (KnownActorStates.KnownActorStatuses.ContainsKey(Element.ActorToSwitchName)) { current_actor_status Status = KnownActorStates.KnownActorStatuses[Element.ActorToSwitchName]; if (Status.Status == actor_status.On) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "OFF", XS1_Configuration); } else if (Status.Status == actor_status.Off) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } } else { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } } } if (Element.ActionToRunName == actor_status.OnWaitOff) { lock (OnWaitOffLIst) { ConsoleOutputLogger.WriteLine("Adding " + Element.ActorToSwitchName + " to ActorReSwitching OnWaitOff List"); OnWaitOffLIst.Add(Element.ActorToSwitchName); } ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON_WAIT_OFF", XS1_Configuration); } #endregion } } } } #endregion #region MQTT Handling Actor if (Properties.Settings.Default.MQTTBindingEnabled) { MQTT_Binding.MQTT_Handle_Actor(dataobject); } #endregion if (KnownActorStates.KnownActorStatuses.ContainsKey(dataobject.Name)) { // is contained if (dataobject.Value == 100) { KnownActorStates.KnownActorStatuses[dataobject.Name] = new current_actor_status(dataobject.Name, actor_status.On); } else { KnownActorStates.KnownActorStatuses[dataobject.Name] = new current_actor_status(dataobject.Name, actor_status.Off); } } else { if (dataobject.Value == 100) { KnownActorStates.KnownActorStatuses.Add(dataobject.Name, new current_actor_status(dataobject.Name, actor_status.On)); } else { KnownActorStates.KnownActorStatuses.Add(dataobject.Name, new current_actor_status(dataobject.Name, actor_status.Off)); } } } else { ConsoleOutputLogger.WriteLine("Actor " + dataobject.Name + " is on the blacklist (ActorReSwitching) and therefore is ignored this time."); } } } else if (dataobject.Type == ObjectTypes.Sensor) { lock (sensor_data_store) { sensor_data_store.Write(dataobject.Serialize()); } // update the sensor in the sensor check Sensorcheck.UpdateSensor(dataobject.Name); // if Alarming is enabled, queue this XS1 Event up for alarming... if (Properties.Settings.Default.AlarmingEnabled) { if (!dataobject.IgnoreForAlarming) // this if for those events which get re-queued as xs1 events despite being for example elvmax events { Alarming_Queue.Enqueue(dataobject); } } #region Scripting // check if this sensor is something we should act uppon foreach (ScriptingActorElement Element in ScriptingActorConfiguration.ScriptingActorActions) { if (dataobject.Name == Element.SensorToWatchName) { if (dataobject.Value == Element.SensorValue) { // obviously there is a ScriptingActorConfiguration entry // so we execute the actor preset set_state_actuator.set_state_actuator ssa = new set_state_actuator.set_state_actuator(); ConsoleOutputLogger.WriteLineToScreenOnly("detected actor scripting action on sensor " + Element.SensorToWatchName + " - " + Element.ActorToSwitchName + " to " + Element.ActionToRunName); if (Element.isCurrentlyWithinStartEndHours()) { #region Scripting Actor actions if (Element.ActionToRunName == actor_status.URL) { ConsoleOutputLogger.WriteLine("Scripting Actor URL"); // handle URLs -> the ActorToSwitch Name will be the URL to trigger try { WebClient client = new WebClient(); client.Encoding = System.Text.Encoding.UTF8; String JSONInput = client.DownloadString(Element.ActorToSwitchName); ConsoleOutputLogger.WriteLine("Doing HTTP GET on: " + Element.ActorToSwitchName); } catch (Exception e) { ConsoleOutputLogger.WriteLine("Exception on URL Actor Scripting: " + e.Message); } } // check what action is going to happen now... if (Element.ActionToRunName == actor_status.On) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } if (Element.ActionToRunName == actor_status.Off) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "OFF", XS1_Configuration); // remove from OnWaitOffList lock (OnWaitOffLIst) { if (OnWaitOffLIst.Contains(Element.ActorToSwitchName)) { OnWaitOffLIst.Remove(Element.ActorToSwitchName); } } } if (Element.ActionToRunName == actor_status.OnOff) { // look for the current status in the known actors table lock (KnownActorStates.KnownActorStatuses) { if (KnownActorStates.KnownActorStatuses.ContainsKey(Element.ActorToSwitchName)) { current_actor_status Status = KnownActorStates.KnownActorStatuses[Element.ActorToSwitchName]; if (Status.Status == actor_status.On) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "OFF", XS1_Configuration); } else if (Status.Status == actor_status.Off) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } } else { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } } } if (Element.ActionToRunName == actor_status.OnWaitOff) { lock (OnWaitOffLIst) { ConsoleOutputLogger.WriteLine("Adding " + Element.ActorToSwitchName + " to ActorReSwitching OnWaitOff List"); OnWaitOffLIst.Add(Element.ActorToSwitchName); } ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON_WAIT_OFF", XS1_Configuration); } #endregion } else { ConsoleOutputLogger.WriteLine("Actorswitching Action not triggered since it's out of timespan. (" + Element.StartHour + "-" + Element.EndHour + ")"); } } } } #endregion #region MQTT Handling Sensor if (Properties.Settings.Default.MQTTBindingEnabled) { MQTT_Binding.MQTT_Handle_Sensor(dataobject); } #endregion } else if (dataobject.Type == ObjectTypes.Unknown) { unknown_data_store.Write(dataobject.Serialize()); } ConsoleOutputLogger.WriteLine(ServerName + " - " + dataobject.OriginalXS1Statement); } #endregion #region Handle MAX events // the strategy for MAX events is quite easy: emulate XS1 events and stuff the XS1 queue with those faked events // that takes care of the storage and the if (Properties.Settings.Default.ELVMAXEnabled) { IDeviceDiffSet max_dataobject = null; if (MAX_DataQueue.TryDequeue(out max_dataobject)) { // if Alarming is enabled, queue this ELV MAX up for alarming... if (Properties.Settings.Default.AlarmingEnabled) { Alarming_Queue.Enqueue(max_dataobject); } StringBuilder sb = new StringBuilder(); sb.Append("S\t" + max_dataobject.DeviceName + "\t" + max_dataobject.DeviceType); if (max_dataobject.DeviceType == DeviceTypes.HeatingThermostat) { HeatingThermostatDiff _heating = (HeatingThermostatDiff)max_dataobject; // this is what is different on the heating thermostats //ConsoleOutputLogger.WriteLine(_heating.ToString()); // first the temperature data XS1_DataObject maxdataobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP, _heating.RoomName + "-" + _heating.DeviceName, ObjectTypes.Sensor, "heating_thermostat", DateTime.Now, _heating.RoomID, _heating.Temperature, _heating.ToString(), true); SensorCheckIgnoreConfiguration.AddToIgnoreList(maxdataobject.Name); XS1_DataQueue.Enqueue(maxdataobject); // then the low battery if exists if (_heating.LowBattery == BatteryStatus.lowbattery) { XS1_DataObject lowbatteryobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP, _heating.RoomName + "-" + _heating.DeviceName, ObjectTypes.Sensor, "low_battery", DateTime.Now, _heating.RoomID, _heating.Temperature, _heating.ToString() + ", LowBattery", true); SensorCheckIgnoreConfiguration.AddToIgnoreList(lowbatteryobject.Name); XS1_DataQueue.Enqueue(lowbatteryobject); } if (_heating.Mode == ThermostatModes.boost) { XS1_DataObject boostmodeobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP, _heating.RoomName + "-" + _heating.DeviceName, ObjectTypes.Sensor, "boost", DateTime.Now, _heating.RoomID, _heating.Temperature, _heating.ToString() + ", Boost", true); SensorCheckIgnoreConfiguration.AddToIgnoreList(boostmodeobject.Name); XS1_DataQueue.Enqueue(boostmodeobject); } } if (max_dataobject.DeviceType == DeviceTypes.ShutterContact) { ShutterContactDiff _shutter = (ShutterContactDiff)max_dataobject; // this is what is different on the ShutterContacts //ConsoleOutputLogger.WriteLine(_shutter.ToString()); // first the open/close status if (_shutter.ShutterState == ShutterContactModes.open) { XS1_DataObject maxdataobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP, _shutter.RoomName + "-" + _shutter.DeviceName, ObjectTypes.Sensor, "shutter_contact", DateTime.Now, _shutter.RoomID, 1.0, _shutter.ToString(), true); SensorCheckIgnoreConfiguration.AddToIgnoreList(maxdataobject.Name); XS1_DataQueue.Enqueue(maxdataobject); } else { XS1_DataObject maxdataobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP, _shutter.RoomName + "-" + _shutter.DeviceName, ObjectTypes.Sensor, "shutter_contact", DateTime.Now, _shutter.RoomID, 0.0, _shutter.ToString(), true); SensorCheckIgnoreConfiguration.AddToIgnoreList(maxdataobject.Name); XS1_DataQueue.Enqueue(maxdataobject); } // then the low battery if exists if (_shutter.LowBattery == BatteryStatus.lowbattery) { if (_shutter.ShutterState == ShutterContactModes.open) { XS1_DataObject lowbatteryobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP, _shutter.RoomName + "-" + _shutter.DeviceName, ObjectTypes.Sensor, "low_battery", DateTime.Now, _shutter.RoomID, 1.0, _shutter.ToString() + ",LowBattery", true); SensorCheckIgnoreConfiguration.AddToIgnoreList(lowbatteryobject.Name); XS1_DataQueue.Enqueue(lowbatteryobject); } else { XS1_DataObject lowbatteryobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP, _shutter.RoomName + "-" + _shutter.DeviceName, ObjectTypes.Sensor, "low_battery", DateTime.Now, _shutter.RoomID, 0.0, _shutter.ToString() + ",LowBattery", true); SensorCheckIgnoreConfiguration.AddToIgnoreList(lowbatteryobject.Name); XS1_DataQueue.Enqueue(lowbatteryobject); } } } } } #endregion #region Handle SolarLog events if (Properties.Settings.Default.SolarLogEnabled) { SolarLogDataSet solarlog_dataobject = null; if (SolarLog_DataQueue.TryDequeue(out solarlog_dataobject)) { // Pac XS1_DataQueue.Enqueue(new XS1_DataObject(Properties.Settings.Default.SolarLogURLDomain, "Pac", ObjectTypes.Sensor, "Pac", solarlog_dataobject.DateAndTime, 1, solarlog_dataobject.Pac, "solarlog," + Properties.Settings.Default.SolarLogURLDomain + ",Pac," + solarlog_dataobject.Pac + "," + solarlog_dataobject.DateAndTime.Ticks, true)); // aPdc XS1_DataQueue.Enqueue(new XS1_DataObject(Properties.Settings.Default.SolarLogURLDomain, "aPdc", ObjectTypes.Sensor, "aPdc", solarlog_dataobject.DateAndTime, 1, solarlog_dataobject.aPdc, "solarlog," + Properties.Settings.Default.SolarLogURLDomain + ",aPdc," + solarlog_dataobject.aPdc + "," + solarlog_dataobject.DateAndTime.Ticks, true)); // if Alarming is enabled, queue this SolarLog Event up for alarming... if (Properties.Settings.Default.AlarmingEnabled) { Alarming_Queue.Enqueue(solarlog_dataobject); } } } #endregion #region Handle Network Monitor events if (Properties.Settings.Default.NetworkMonitorEnabled) { NetworkMonitoringDataSet networkmonitor_dataobject = null; if (NetworkMonitor_Queue.TryDequeue(out networkmonitor_dataobject)) { if (networkmonitor_dataobject.Status == Org.Mentalis.Network.ICMP_Status.Success) { XS1_DataQueue.Enqueue(new XS1_DataObject(networkmonitor_dataobject.Descriptor, networkmonitor_dataobject.HostnameIP, ObjectTypes.Sensor, "Ping", networkmonitor_dataobject.TimeOfMeasurement, 2, 1, "OnlineCheck," + networkmonitor_dataobject.HostnameIP + "," + networkmonitor_dataobject.Descriptor + ",Online", true)); } else { XS1_DataQueue.Enqueue(new XS1_DataObject(networkmonitor_dataobject.Descriptor, networkmonitor_dataobject.HostnameIP, ObjectTypes.Sensor, "Ping", networkmonitor_dataobject.TimeOfMeasurement, 2, 0, "OnlineCheck," + networkmonitor_dataobject.HostnameIP + "," + networkmonitor_dataobject.Descriptor + ",Offline", true)); } // if Alarming is enabled, queue this Network Monitor Event up for alarming... if (Properties.Settings.Default.AlarmingEnabled) { Alarming_Queue.Enqueue(networkmonitor_dataobject); } } } #endregion } catch (Exception) { AcceptingCommands = false; //Thread.Sleep(1); } Thread.Sleep(1); } if (ELVMax != null) { ELVMax.running = false; } XS1.running = false; Thread.Sleep(200); // ... msecs period to wait for new input... }
public void Run() { // initialize XS1 Configuration XS1_Configuration = new XS1Configuration(ConfigurationCacheMinutes); MAXMonitoringThread ELVMax = null; SolarLogMonitoringThread SolarLog = null; // Start Sensor-Check Thread SensorCheck Sensorcheck = new SensorCheck(ConsoleOutputLogger); Thread SensorCheckThread = new Thread(new ThreadStart(Sensorcheck.Run)); SensorCheckThread.Start(); // Start Actor Re-Switching Thread ActorReswitching ActorReSwitch_ = new ActorReswitching(XS1_Configuration, ConsoleOutputLogger, TemporaryBlacklist,OnWaitOffLIst); Thread ActorReswitchThread = new Thread(new ThreadStart(ActorReSwitch_.Run)); ActorReswitchThread.Start(); // Start the SolarLog Thread (if enabled) // TODO: make it switchable / configurable if (Properties.Settings.Default.SolarLogEnabled) { SolarLog = new SolarLogMonitoringThread(Properties.Settings.Default.SolarLogURLDomain,ConsoleOutputLogger,SolarLog_DataQueue,Properties.Settings.Default.SolarLogUpdateIntervalMsec); Thread SolarLogThread = new Thread(new ThreadStart(SolarLog.Run)); SolarLogThread.Start(); } // Start the ELVMax Thread if (Properties.Settings.Default.ELVMAXEnabled) { ELVMax = new MAXMonitoringThread(Properties.Settings.Default.ELVMAXIP,Properties.Settings.Default.ELVMAXPort,ConsoleOutputLogger,MAX_DataQueue,Properties.Settings.Default.ELVMAXUpdateIntervalMsec); Thread ELVMaxThread = new Thread(new ThreadStart(ELVMax.Run)); ELVMaxThread.Start(); } XS1MonitoringThread XS1 = new XS1MonitoringThread(ServerName,ConsoleOutputLogger,UserName,Password,XS1_DataQueue); Thread XS1Thread = new Thread(new ThreadStart(XS1.Run)); XS1Thread.Start(); // Start integrated HTTP Server HttpServer httpServer = new HttpServer(Properties.Settings.Default.HTTPPort, Properties.Settings.Default.HTTPIP, Properties.Settings.Default.HTTPDocumentRoot, sensor_data_store, miataru_data_store, XS1_Configuration, ConsoleOutputLogger, ELVMax,Properties.Settings.Default.HTTPAuthEnabled,Properties.Settings.Default.HTTPAuthUsername,Properties.Settings.Default.HTTPAuthPassword,Properties.Settings.Default.HTTPAuthDisabledAdressStartsWith); Thread http_server_thread = new Thread(new ThreadStart(httpServer.listen)); http_server_thread.Start(); // Start Service Monitorng thread if (Properties.Settings.Default.NetworkMonitorEnabled) { NetworkMonitoring monitor = new NetworkMonitoring(ConsoleOutputLogger,NetworkMonitor_Queue,Properties.Settings.Default.NetworkMonitorUpdateIntervalMsec); Thread monitorThread = new Thread(new ThreadStart(monitor.Run)); monitorThread.Start(); } // Start Alarming thread if (Properties.Settings.Default.AlarmingEnabled) { AlarmingThread alarmThread = new AlarmingThread(ConsoleOutputLogger,Alarming_Queue,sensor_data_store,actor_data_store,miataru_data_store); Thread alarming_thread = new Thread(new ThreadStart(alarmThread.Run)); alarming_thread.Start(); } // Start Miataru Thread if (Properties.Settings.Default.MiataruEnabled) { MiataruThread miataruThread = new MiataruThread (ConsoleOutputLogger, miataru_data_store, Properties.Settings.Default.MiataruUpdateTime); Thread miataru_Thread = new Thread(new ThreadStart(miataruThread.Run)); miataru_Thread.Start(); } while (!Shutdown) { try { #region Handle XS1 events XS1_DataObject dataobject = null; if (XS1_DataQueue.TryDequeue(out dataobject)) { if (dataobject.Type == ObjectTypes.Actor) { lock(actor_data_store) { actor_data_store.Write(dataobject.Serialize()); } lock(KnownActorStates.KnownActorStatuses) { bool usethisactor = true; // check if this actor is on temporary blacklist (like when it was handled) lock (TemporaryBlacklist) { if (TemporaryBlacklist.Contains(dataobject.Name)) usethisactor = false; TemporaryBlacklist.Remove(dataobject.Name); } if (usethisactor) { // if Alarming is enabled, queue this XS1 Event up for alarming... if (Properties.Settings.Default.AlarmingEnabled) { Alarming_Queue.Enqueue(dataobject); } // this actor action did not result in any action hacs made - so we try to make the best out of it #region Scripting Handling // check if this sensor is something we should act uppon foreach (ScriptingActorElement Element in ScriptingActorConfiguration.ScriptingActorActions) { if (dataobject.Name == Element.SensorToWatchName) { if (dataobject.Value == Element.SensorValue) { // obviously there is a ScriptingActorConfiguration entry // so we execute the actor preset set_state_actuator.set_state_actuator ssa = new set_state_actuator.set_state_actuator(); ConsoleOutputLogger.WriteLineToScreenOnly("detected actor scripting action on actor "+Element.SensorToWatchName+" - "+Element.ActorToSwitchName+" to "+Element.ActionToRunName); if (Element.ActionToRunName == actor_status.URL) { ConsoleOutputLogger.WriteLine("Scripting Actor URL"); // handle URLs -> the ActorToSwitch Name will be the URL to trigger try { WebClient client = new WebClient(); client.Encoding = System.Text.Encoding.UTF8; String JSONInput = client.DownloadString(Element.ActorToSwitchName); ConsoleOutputLogger.WriteLine("Doing HTTP GET on: "+Element.ActorToSwitchName); } catch(Exception e) { ConsoleOutputLogger.WriteLine("Exception on URL Actor Scripting: " + e.Message); } } // check what action is going to happen now... if (Element.ActionToRunName == actor_status.On) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } if (Element.ActionToRunName == actor_status.Off) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "OFF", XS1_Configuration); // remove from OnWaitOffList lock (OnWaitOffLIst) { if (OnWaitOffLIst.Contains(Element.ActorToSwitchName)) OnWaitOffLIst.Remove(Element.ActorToSwitchName); } } if (Element.ActionToRunName == actor_status.OnOff) { // look for the current status in the known actors table lock(KnownActorStates.KnownActorStatuses) { if (KnownActorStates.KnownActorStatuses.ContainsKey(Element.ActorToSwitchName)) { current_actor_status Status = KnownActorStates.KnownActorStatuses[Element.ActorToSwitchName]; if (Status.Status == actor_status.On) ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "OFF", XS1_Configuration); else if (Status.Status == actor_status.Off) ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } else ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } } if (Element.ActionToRunName == actor_status.OnWaitOff) { lock (OnWaitOffLIst) { ConsoleOutputLogger.WriteLine("Adding " + Element.ActorToSwitchName + " to ActorReSwitching OnWaitOff List"); OnWaitOffLIst.Add(Element.ActorToSwitchName); } ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON_WAIT_OFF", XS1_Configuration); } } } } #endregion if (KnownActorStates.KnownActorStatuses.ContainsKey(dataobject.Name)) { // is contained if (dataobject.Value == 100) KnownActorStates.KnownActorStatuses[dataobject.Name] = new current_actor_status(dataobject.Name, actor_status.On); else KnownActorStates.KnownActorStatuses[dataobject.Name] = new current_actor_status(dataobject.Name, actor_status.Off); } else { if (dataobject.Value == 100) KnownActorStates.KnownActorStatuses.Add(dataobject.Name, new current_actor_status(dataobject.Name, actor_status.On)); else KnownActorStates.KnownActorStatuses.Add(dataobject.Name, new current_actor_status(dataobject.Name, actor_status.Off)); } } else ConsoleOutputLogger.WriteLine("Actor "+dataobject.Name+" is on the blacklist (ActorReSwitching) and therefore is ignored this time."); } } else if (dataobject.Type == ObjectTypes.Sensor) { lock(sensor_data_store) { sensor_data_store.Write(dataobject.Serialize()); } // update the sensor in the sensor check Sensorcheck.UpdateSensor(dataobject.Name); // if Alarming is enabled, queue this XS1 Event up for alarming... if (Properties.Settings.Default.AlarmingEnabled) { if (!dataobject.IgnoreForAlarming) // this if for those events which get re-queued as xs1 events despite being for example elvmax events Alarming_Queue.Enqueue(dataobject); } // check if this sensor is something we should act uppon foreach (ScriptingActorElement Element in ScriptingActorConfiguration.ScriptingActorActions) { if (dataobject.Name == Element.SensorToWatchName) { if (dataobject.Value == Element.SensorValue) { // obviously there is a ScriptingActorConfiguration entry // so we execute the actor preset set_state_actuator.set_state_actuator ssa = new set_state_actuator.set_state_actuator(); ConsoleOutputLogger.WriteLineToScreenOnly("detected actor scripting action on sensor "+Element.SensorToWatchName+" - "+Element.ActorToSwitchName+" to "+Element.ActionToRunName); if (Element.ActionToRunName == actor_status.URL) { ConsoleOutputLogger.WriteLine("Scripting Actor URL"); // handle URLs -> the ActorToSwitch Name will be the URL to trigger try { WebClient client = new WebClient(); client.Encoding = System.Text.Encoding.UTF8; String JSONInput = client.DownloadString(Element.ActorToSwitchName); ConsoleOutputLogger.WriteLine("Doing HTTP GET on: " + Element.ActorToSwitchName); } catch (Exception e) { ConsoleOutputLogger.WriteLine("Exception on URL Actor Scripting: " + e.Message); } } // check what action is going to happen now... if (Element.ActionToRunName == actor_status.On) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } if (Element.ActionToRunName == actor_status.Off) { ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "OFF", XS1_Configuration); // remove from OnWaitOffList lock (OnWaitOffLIst) { if (OnWaitOffLIst.Contains(Element.ActorToSwitchName)) OnWaitOffLIst.Remove(Element.ActorToSwitchName); } } if (Element.ActionToRunName == actor_status.OnOff) { // look for the current status in the known actors table lock(KnownActorStates.KnownActorStatuses) { if (KnownActorStates.KnownActorStatuses.ContainsKey(Element.ActorToSwitchName)) { current_actor_status Status = KnownActorStates.KnownActorStatuses[Element.ActorToSwitchName]; if (Status.Status == actor_status.On) ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "OFF", XS1_Configuration); else if (Status.Status == actor_status.Off) ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } else ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON", XS1_Configuration); } } if (Element.ActionToRunName == actor_status.OnWaitOff) { lock (OnWaitOffLIst) { ConsoleOutputLogger.WriteLine("Adding " + Element.ActorToSwitchName + " to ActorReSwitching OnWaitOff List"); OnWaitOffLIst.Add(Element.ActorToSwitchName); } ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, Element.ActorToSwitchName, "ON_WAIT_OFF", XS1_Configuration); } } } } } else if (dataobject.Type == ObjectTypes.Unknown) { unknown_data_store.Write(dataobject.Serialize()); } ConsoleOutputLogger.WriteLine(ServerName+" - "+dataobject.OriginalXS1Statement); } #endregion #region Handle MAX events // the strategy for MAX events is quite easy: emulate XS1 events and stuff the XS1 queue with those faked events // that takes care of the storage and the if (Properties.Settings.Default.ELVMAXEnabled) { IDeviceDiffSet max_dataobject = null; if(MAX_DataQueue.TryDequeue(out max_dataobject)) { // if Alarming is enabled, queue this ELV MAX up for alarming... if (Properties.Settings.Default.AlarmingEnabled) { Alarming_Queue.Enqueue(max_dataobject); } StringBuilder sb = new StringBuilder(); sb.Append("S\t"+max_dataobject.DeviceName+"\t"+max_dataobject.DeviceType); if (max_dataobject.DeviceType == DeviceTypes.HeatingThermostat) { HeatingThermostatDiff _heating = (HeatingThermostatDiff)max_dataobject; // this is what is different on the heating thermostats //ConsoleOutputLogger.WriteLine(_heating.ToString()); // first the temperature data XS1_DataObject maxdataobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP,_heating.RoomName+"-"+_heating.DeviceName,ObjectTypes.Sensor,"heating_thermostat",DateTime.Now,_heating.RoomID,_heating.Temperature,_heating.ToString(),true); SensorCheckIgnoreConfiguration.AddToIgnoreList(maxdataobject.Name); XS1_DataQueue.Enqueue(maxdataobject); // then the low battery if exists if (_heating.LowBattery == BatteryStatus.lowbattery) { XS1_DataObject lowbatteryobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP,_heating.RoomName+"-"+_heating.DeviceName,ObjectTypes.Sensor,"low_battery",DateTime.Now,_heating.RoomID,_heating.Temperature,_heating.ToString()+", LowBattery",true); SensorCheckIgnoreConfiguration.AddToIgnoreList(lowbatteryobject.Name); XS1_DataQueue.Enqueue(lowbatteryobject); } if (_heating.Mode == ThermostatModes.boost) { XS1_DataObject boostmodeobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP,_heating.RoomName+"-"+_heating.DeviceName,ObjectTypes.Sensor,"boost",DateTime.Now,_heating.RoomID,_heating.Temperature, _heating.ToString()+", Boost",true); SensorCheckIgnoreConfiguration.AddToIgnoreList(boostmodeobject.Name); XS1_DataQueue.Enqueue(boostmodeobject); } } if (max_dataobject.DeviceType == DeviceTypes.ShutterContact) { ShutterContactDiff _shutter = (ShutterContactDiff)max_dataobject; // this is what is different on the ShutterContacts //ConsoleOutputLogger.WriteLine(_shutter.ToString()); // first the open/close status if (_shutter.ShutterState == ShutterContactModes.open) { XS1_DataObject maxdataobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP,_shutter.RoomName+"-"+_shutter.DeviceName,ObjectTypes.Sensor,"shutter_contact",DateTime.Now,_shutter.RoomID,1.0,_shutter.ToString(),true); SensorCheckIgnoreConfiguration.AddToIgnoreList(maxdataobject.Name); XS1_DataQueue.Enqueue(maxdataobject); } else { XS1_DataObject maxdataobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP,_shutter.RoomName+"-"+_shutter.DeviceName,ObjectTypes.Sensor,"shutter_contact",DateTime.Now,_shutter.RoomID,0.0,_shutter.ToString(),true); SensorCheckIgnoreConfiguration.AddToIgnoreList(maxdataobject.Name); XS1_DataQueue.Enqueue(maxdataobject); } // then the low battery if exists if (_shutter.LowBattery == BatteryStatus.lowbattery) { if (_shutter.ShutterState == ShutterContactModes.open) { XS1_DataObject lowbatteryobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP,_shutter.RoomName+"-"+_shutter.DeviceName,ObjectTypes.Sensor,"low_battery",DateTime.Now,_shutter.RoomID,1.0,_shutter.ToString()+",LowBattery",true); SensorCheckIgnoreConfiguration.AddToIgnoreList(lowbatteryobject.Name); XS1_DataQueue.Enqueue(lowbatteryobject); } else { XS1_DataObject lowbatteryobject = new XS1_DataObject(Properties.Settings.Default.ELVMAXIP,_shutter.RoomName+"-"+_shutter.DeviceName,ObjectTypes.Sensor,"low_battery",DateTime.Now,_shutter.RoomID,0.0,_shutter.ToString()+",LowBattery",true); SensorCheckIgnoreConfiguration.AddToIgnoreList(lowbatteryobject.Name); XS1_DataQueue.Enqueue(lowbatteryobject); } } } } } #endregion #region Handle SolarLog events if (Properties.Settings.Default.SolarLogEnabled) { SolarLogDataSet solarlog_dataobject = null; if(SolarLog_DataQueue.TryDequeue(out solarlog_dataobject)) { // Pac XS1_DataQueue.Enqueue(new XS1_DataObject(Properties.Settings.Default.SolarLogURLDomain, "Pac", ObjectTypes.Sensor, "Pac", solarlog_dataobject.DateAndTime, 1, solarlog_dataobject.Pac, "solarlog," + Properties.Settings.Default.SolarLogURLDomain + ",Pac," + solarlog_dataobject.Pac + "," + solarlog_dataobject.DateAndTime.Ticks,true)); // aPdc XS1_DataQueue.Enqueue(new XS1_DataObject(Properties.Settings.Default.SolarLogURLDomain, "aPdc", ObjectTypes.Sensor, "aPdc", solarlog_dataobject.DateAndTime, 1, solarlog_dataobject.aPdc, "solarlog," + Properties.Settings.Default.SolarLogURLDomain + ",aPdc," + solarlog_dataobject.aPdc+","+solarlog_dataobject.DateAndTime.Ticks,true)); // if Alarming is enabled, queue this SolarLog Event up for alarming... if (Properties.Settings.Default.AlarmingEnabled) { Alarming_Queue.Enqueue(solarlog_dataobject); } } } #endregion #region Handle Network Monitor events if (Properties.Settings.Default.NetworkMonitorEnabled) { NetworkMonitoringDataSet networkmonitor_dataobject = null; if(NetworkMonitor_Queue.TryDequeue(out networkmonitor_dataobject)) { if (networkmonitor_dataobject.Status == Org.Mentalis.Network.ICMP_Status.Success) XS1_DataQueue.Enqueue(new XS1_DataObject(networkmonitor_dataobject.Descriptor,networkmonitor_dataobject.HostnameIP,ObjectTypes.Sensor,"Ping",networkmonitor_dataobject.TimeOfMeasurement,2,1,"OnlineCheck,"+networkmonitor_dataobject.HostnameIP+","+networkmonitor_dataobject.Descriptor+",Online",true)); else XS1_DataQueue.Enqueue(new XS1_DataObject(networkmonitor_dataobject.Descriptor,networkmonitor_dataobject.HostnameIP,ObjectTypes.Sensor,"Ping",networkmonitor_dataobject.TimeOfMeasurement,2,0,"OnlineCheck,"+networkmonitor_dataobject.HostnameIP+","+networkmonitor_dataobject.Descriptor+",Offline",true)); // if Alarming is enabled, queue this Network Monitor Event up for alarming... if (Properties.Settings.Default.AlarmingEnabled) { Alarming_Queue.Enqueue(networkmonitor_dataobject); } } } #endregion } catch (Exception) { AcceptingCommands = false; //Thread.Sleep(1); } Thread.Sleep(1); } if (ELVMax != null) ELVMax.running = false; XS1.running = false; Thread.Sleep (200); // ... msecs period to wait for new input... }
/// <summary> /// Run this instance. /// </summary> public void Run() { ConsoleOutputLogger.WriteLine("Starting Actor Re-Switching."); DateTime LastCheckpoint = DateTime.Now; TimeSpan SinceLastCheckpoint = new TimeSpan(); while (!_Shutdown) { // we start by // checking how much time passed since we were here the last time SinceLastCheckpoint = DateTime.Now - LastCheckpoint; //Console.WriteLine(SinceLastCheckpoint.TotalMinutes); // now we can do something every minute or so if (SinceLastCheckpoint.TotalMinutes >= hacs.Properties.Settings.Default.SwitchAgainCheckpointMinutes) { //ConsoleOutputLogger.WriteLine("Sensor Checkpoint"); LastCheckpoint = DateTime.Now; #region Switch Actors again with same state // go through all the known actor status codes and try to send // them again to the actor one after another // TODO: this try is just here to handle enum exceptions just in case, introduce locking! try { foreach (current_actor_status status in KnownActorStates.KnownActorStatuses.Values) { // if this actor was switched within the last configured minutes we switch it again to the exact same // state, just to make sure that they were successfully switched (just ON/OFF states) if ((DateTime.Now - status.LastUpdate).TotalMinutes <= hacs.Properties.Settings.Default.SwitchAgainTimeWindowMinutes) { bool ignorethisone = false; lock (OnWaitOffList) { if (OnWaitOffList.Contains(status.ActorName)) { //Console.WriteLine(status.ActorName+" is on the ignorelist"); ignorethisone = true; } } if (!ignorethisone) { ConsoleOutputLogger.WriteLine("Switching again actor " + status.ActorName + "(" + (DateTime.Now - status.LastUpdate).TotalMinutes + ")"); // yes, within the last given number of minutes set_state_actuator.set_state_actuator ssa = new set_state_actuator.set_state_actuator(); #region ON state if (status.Status == actor_status.On) { // set on temporary blacklist lock (TemporaryBlacklist) { TemporaryBlacklist.Add(status.ActorName); } ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, status.ActorName, "ON", XS1_Configuration); } #endregion #region OFF state if (status.Status == actor_status.Off) { // set on temporary blacklist lock (TemporaryBlacklist) { TemporaryBlacklist.Add(status.ActorName); } ssa.SetStateActuatorPreset(hacs.Properties.Settings.Default.XS1, hacs.Properties.Settings.Default.Username, hacs.Properties.Settings.Default.Password, status.ActorName, "OFF", XS1_Configuration); } #endregion } } Thread.Sleep(2000); } } catch (Exception) { } #endregion } Thread.Sleep(10000); // just check every 10 seconds... } }