1.0.6 - Added thermostat status and auxiliary temp to web service API

This commit is contained in:
Ryan Wagoner 2016-11-20 21:31:27 -05:00
parent 828308717a
commit b4f4e5f795
8 changed files with 164 additions and 63 deletions

View file

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Data; using System.Data;
using System.Data.Odbc; using System.Data.Odbc;
using System.IO; using System.IO;
using System.Reflection;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -47,11 +48,12 @@ namespace HAILogger
Global.event_source = "HAI Logger"; Global.event_source = "HAI Logger";
if (string.IsNullOrEmpty(Global.dir_config)) if (string.IsNullOrEmpty(Global.dir_config))
Global.dir_config = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location); Global.dir_config = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
Settings.LoadSettings(); Settings.LoadSettings();
Event.WriteInfo("CoreServer", "Starting up server"); Event.WriteInfo("CoreServer", "Starting up server " +
Assembly.GetExecutingAssembly().GetName().Version.ToString());
tstat_timer.Elapsed += tstat_timer_Elapsed; tstat_timer.Elapsed += tstat_timer_Elapsed;
tstat_timer.AutoReset = false; tstat_timer.AutoReset = false;
@ -157,7 +159,7 @@ namespace HAILogger
Disconnect(); Disconnect();
HAC = null; HAC = null;
if(Global.mysql_logging) if (Global.mysql_logging)
DBClose(); DBClose();
terminate = true; terminate = true;
@ -270,7 +272,7 @@ namespace HAILogger
Event.WriteInfo("CoreServer", "CONNECTION STATUS: Disconnected"); Event.WriteInfo("CoreServer", "CONNECTION STATUS: Disconnected");
break; break;
case enuOmniLinkCommStatus.InterruptedFunctionCall: case enuOmniLinkCommStatus.InterruptedFunctionCall:
if(!quitting) if (!quitting)
Event.WriteError("CoreServer", "CONNECTION STATUS: Interrupted Function Call"); Event.WriteError("CoreServer", "CONNECTION STATUS: Interrupted Function Call");
break; break;
case enuOmniLinkCommStatus.PermissionDenied: case enuOmniLinkCommStatus.PermissionDenied:
@ -491,6 +493,10 @@ namespace HAILogger
break; break;
case enuObjectType.Zone: case enuObjectType.Zone:
HAC.Zones.CopyProperties(MSG); HAC.Zones.CopyProperties(MSG);
if (HAC.Zones[MSG.ObjectNumber].IsTemperatureZone())
HAC.Connection.Send(new clsOL2MsgRequestExtendedStatus(HAC.Connection, enuObjectType.Auxillary, MSG.ObjectNumber, MSG.ObjectNumber), HandleRequestAuxillaryStatus);
break; break;
case enuObjectType.Thermostat: case enuObjectType.Thermostat:
HAC.Thermostats.CopyProperties(MSG); HAC.Thermostats.CopyProperties(MSG);
@ -606,7 +612,7 @@ namespace HAILogger
break; break;
} }
if(Global.verbose_unhandled && !handled) if (Global.verbose_unhandled && !handled)
Event.WriteVerbose("CoreServer", "Unhandled notification: " + ((enuOmniLink2MessageType)B[2]).ToString()); Event.WriteVerbose("CoreServer", "Unhandled notification: " + ((enuOmniLink2MessageType)B[2]).ToString());
} }
@ -753,6 +759,19 @@ namespace HAILogger
MSG.ObjectNumber(i), HAC.Areas[MSG.ObjectNumber(i)]))); MSG.ObjectNumber(i), HAC.Areas[MSG.ObjectNumber(i)])));
} }
break; break;
case enuObjectType.Auxillary:
for (byte i = 0; i < MSG.AuxStatusCount(); i++)
{
HAC.Zones[MSG.ObjectNumber(i)].CopyAuxExtendedStatus(MSG, i);
LogZoneStatus(MSG.ObjectNumber(i));
if (HAC.Zones[MSG.ObjectNumber(i)].IsTemperatureZone())
{
WebNotification.Send("temp", Helper.Serialize<ZoneContract>(Helper.ConvertZone(
MSG.ObjectNumber(i), HAC.Zones[MSG.ObjectNumber(i)])));
}
}
break;
case enuObjectType.Zone: case enuObjectType.Zone:
for (byte i = 0; i < MSG.ZoneStatusCount(); i++) for (byte i = 0; i < MSG.ZoneStatusCount(); i++)
{ {
@ -837,6 +856,19 @@ namespace HAILogger
} }
#endregion #endregion
private void HandleRequestAuxillaryStatus(clsOmniLinkMessageQueueItem M, byte[] B, bool Timeout)
{
if (Timeout)
return;
clsOL2MsgExtendedStatus MSG = new clsOL2MsgExtendedStatus(HAC.Connection, B);
for (byte i = 0; i < MSG.AuxStatusCount(); i++)
{
HAC.Zones[MSG.ObjectNumber(i)].CopyAuxExtendedStatus(MSG, i);
}
}
#region Thermostats #region Thermostats
static double ThermostatTimerInterval() static double ThermostatTimerInterval()
{ {
@ -860,7 +892,7 @@ namespace HAILogger
{ {
HAC.Connection.Send(new clsOL2MsgRequestExtendedStatus(HAC.Connection, enuObjectType.Thermostat, tstat.Key, tstat.Key), HandleRequestThermostatStatus); HAC.Connection.Send(new clsOL2MsgRequestExtendedStatus(HAC.Connection, enuObjectType.Thermostat, tstat.Key, tstat.Key), HandleRequestThermostatStatus);
if(Global.verbose_thermostat_timer) if (Global.verbose_thermostat_timer)
Event.WriteVerbose("ThermostatTimer", "Polling status for " + HAC.Thermostats[tstat.Key].Name); Event.WriteVerbose("ThermostatTimer", "Polling status for " + HAC.Thermostats[tstat.Key].Name);
} }
@ -1001,10 +1033,10 @@ namespace HAILogger
Event.WriteAlarm("AreaStatus", "FIRE " + unit.Name + " " + unit.AreaFireAlarmText); Event.WriteAlarm("AreaStatus", "FIRE " + unit.Name + " " + unit.AreaFireAlarmText);
Prowl.Notify("ALARM", "FIRE " + unit.Name + " " + unit.AreaFireAlarmText, ProwlPriority.Emergency); Prowl.Notify("ALARM", "FIRE " + unit.Name + " " + unit.AreaFireAlarmText, ProwlPriority.Emergency);
if(!alarms.Contains("FIRE" + id)) if (!alarms.Contains("FIRE" + id))
alarms.Add("FIRE" + id); alarms.Add("FIRE" + id);
} }
else if(alarms.Contains("FIRE" + id)) else if (alarms.Contains("FIRE" + id))
{ {
Event.WriteAlarm("AreaStatus", "CLEARED - FIRE " + unit.Name + " " + unit.AreaFireAlarmText); Event.WriteAlarm("AreaStatus", "CLEARED - FIRE " + unit.Name + " " + unit.AreaFireAlarmText);
Prowl.Notify("ALARM CLEARED", "FIRE " + unit.Name + " " + unit.AreaFireAlarmText, ProwlPriority.High); Prowl.Notify("ALARM CLEARED", "FIRE " + unit.Name + " " + unit.AreaFireAlarmText, ProwlPriority.High);
@ -1076,10 +1108,10 @@ namespace HAILogger
unit.AreaFireAlarmText + "','" + unit.AreaBurglaryAlarmText + "','" + unit.AreaAuxAlarmText + "','" + unit.AreaFireAlarmText + "','" + unit.AreaBurglaryAlarmText + "','" + unit.AreaAuxAlarmText + "','" +
unit.AreaDuressAlarmText + "','" + status + "')"); unit.AreaDuressAlarmText + "','" + status + "')");
if(Global.verbose_area) if (Global.verbose_area)
Event.WriteVerbose("AreaStatus", id + " " + unit.Name + ", Status: " + status); Event.WriteVerbose("AreaStatus", id + " " + unit.Name + ", Status: " + status);
if(unit.LastMode != unit.AreaMode) if (unit.LastMode != unit.AreaMode)
Prowl.Notify("Security", unit.Name + " " + unit.ModeText()); Prowl.Notify("Security", unit.Name + " " + unit.ModeText());
} }
@ -1091,8 +1123,13 @@ namespace HAILogger
INSERT INTO log_zones (timestamp, id, name, status) INSERT INTO log_zones (timestamp, id, name, status)
VALUES ('" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + id.ToString() + "','" + unit.Name + "','" + unit.StatusText() + "')"); VALUES ('" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + id.ToString() + "','" + unit.Name + "','" + unit.StatusText() + "')");
if(Global.verbose_zone) if (Global.verbose_zone)
Event.WriteVerbose("ZoneStatus", id + " " + unit.Name + ", Status: " + unit.StatusText()); {
if (unit.IsTemperatureZone())
Event.WriteVerbose("ZoneStatus", id + " " + unit.Name + ", Temp: " + unit.TempText());
else
Event.WriteVerbose("ZoneStatus", id + " " + unit.Name + ", Status: " + unit.StatusText());
}
} }
private void LogThermostatStatus(ushort id) private void LogThermostatStatus(ushort id)
@ -1118,7 +1155,7 @@ namespace HAILogger
humidity + "','" + humidify + "','" + dehumidify + "','" + humidity + "','" + humidify + "','" + dehumidify + "','" +
unit.ModeText() + "','" + unit.FanModeText() + "','" + unit.HoldStatusText() + "')"); unit.ModeText() + "','" + unit.FanModeText() + "','" + unit.HoldStatusText() + "')");
if(Global.verbose_thermostat) if (Global.verbose_thermostat)
Event.WriteVerbose("ThermostatStatus", id + " " + unit.Name + Event.WriteVerbose("ThermostatStatus", id + " " + unit.Name +
", Status: " + unit.TempText() + " " + unit.HorC_StatusText() + ", Status: " + unit.TempText() + " " + unit.HorC_StatusText() +
", Heat: " + unit.HeatSetpointText() + ", Heat: " + unit.HeatSetpointText() +
@ -1145,8 +1182,8 @@ namespace HAILogger
VALUES ('" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + id.ToString() + "','" + unit.Name + "','" + VALUES ('" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + id.ToString() + "','" + unit.Name + "','" +
status + "','" + unit.Status + "','" + unit.StatusTime + "')"); status + "','" + unit.Status + "','" + unit.StatusTime + "')");
if(Global.verbose_unit) if (Global.verbose_unit)
Event.WriteVerbose("UnitStatus", id + " " + unit.Name + ", Status: " + status); Event.WriteVerbose("UnitStatus", id + " " + unit.Name + ", Status: " + status);
} }
private void LogMessageStatus(ushort id) private void LogMessageStatus(ushort id)
@ -1157,10 +1194,10 @@ namespace HAILogger
INSERT INTO log_messages (timestamp, id, name, status) INSERT INTO log_messages (timestamp, id, name, status)
VALUES ('" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + id.ToString() + "','" + unit.Name + "','" + unit.StatusText() + "')"); VALUES ('" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + id.ToString() + "','" + unit.Name + "','" + unit.StatusText() + "')");
if(Global.verbose_message) if (Global.verbose_message)
Event.WriteVerbose("MessageStatus", unit.Name + ", " + unit.StatusText()); Event.WriteVerbose("MessageStatus", unit.Name + ", " + unit.StatusText());
if(Global.prowl_messages) if (Global.prowl_messages)
Prowl.Notify("Message", id + " " + unit.Name + ", " + unit.StatusText()); Prowl.Notify("Message", id + " " + unit.Name + ", " + unit.StatusText());
} }
@ -1188,7 +1225,7 @@ namespace HAILogger
public void DBClose() public void DBClose()
{ {
if(mysql_conn.State != ConnectionState.Closed) if (mysql_conn.State != ConnectionState.Closed)
mysql_conn.Close(); mysql_conn.Close();
} }
@ -1197,7 +1234,7 @@ namespace HAILogger
if (!Global.mysql_logging) if (!Global.mysql_logging)
return; return;
lock(mysql_lock) lock (mysql_lock)
mysql_queue.Enqueue(query); mysql_queue.Enqueue(query);
} }

View file

@ -119,35 +119,57 @@ namespace HAILogger
return names; return names;
} }
public List<NameContract> ListZonesTemp()
{
Event.WriteVerbose("WebService", "ListZonesTemp");
List<NameContract> names = new List<NameContract>();
for (ushort i = 1; i < WebService.HAC.Zones.Count; i++)
{
clsZone zone = WebService.HAC.Zones[i];
if (zone.IsTemperatureZone() && zone.DefaultProperties == false)
names.Add(new NameContract() { id = i, name = zone.Name });
}
return names;
}
public ZoneContract GetZone(ushort id) public ZoneContract GetZone(ushort id)
{ {
Event.WriteVerbose("WebService", "GetZone: " + id); Event.WriteVerbose("WebService", "GetZone: " + id);
WebOperationContext ctx = WebOperationContext.Current; WebOperationContext ctx = WebOperationContext.Current;
switch (WebService.HAC.Zones[id].ZoneType) if (WebService.HAC.Zones[id].IsTemperatureZone())
{ {
case enuZoneType.EntryExit: ctx.OutgoingResponse.Headers.Add("type", "temp");
case enuZoneType.X2EntryDelay: }
case enuZoneType.X4EntryDelay: else
case enuZoneType.Perimeter: {
ctx.OutgoingResponse.Headers.Add("type", "contact"); switch (WebService.HAC.Zones[id].ZoneType)
break; {
case enuZoneType.AwayInt: case enuZoneType.EntryExit:
ctx.OutgoingResponse.Headers.Add("type", "motion"); case enuZoneType.X2EntryDelay:
break; case enuZoneType.X4EntryDelay:
case enuZoneType.Water: case enuZoneType.Perimeter:
ctx.OutgoingResponse.Headers.Add("type", "water"); ctx.OutgoingResponse.Headers.Add("type", "contact");
break; break;
case enuZoneType.Fire: case enuZoneType.AwayInt:
ctx.OutgoingResponse.Headers.Add("type", "smoke"); ctx.OutgoingResponse.Headers.Add("type", "motion");
break; break;
case enuZoneType.Gas: case enuZoneType.Water:
ctx.OutgoingResponse.Headers.Add("type", "co"); ctx.OutgoingResponse.Headers.Add("type", "water");
break; break;
default: case enuZoneType.Fire:
ctx.OutgoingResponse.Headers.Add("type", "unknown"); ctx.OutgoingResponse.Headers.Add("type", "smoke");
break; break;
case enuZoneType.Gas:
ctx.OutgoingResponse.Headers.Add("type", "co");
break;
default:
ctx.OutgoingResponse.Headers.Add("type", "unknown");
break;
}
} }
clsZone unit = WebService.HAC.Zones[id]; clsZone unit = WebService.HAC.Zones[id];
@ -251,6 +273,12 @@ namespace HAILogger
WebService.HAC.SendCommand(enuUnitCommand.Fan, BitConverter.GetBytes(unit.value)[0], unit.id); WebService.HAC.SendCommand(enuUnitCommand.Fan, BitConverter.GetBytes(unit.value)[0], unit.id);
} }
public void SetThermostatHold(CommandContract unit)
{
Event.WriteVerbose("WebService", "SetThermostatHold: " + unit.id + " to " + unit.value);
WebService.HAC.SendCommand(enuUnitCommand.Hold, BitConverter.GetBytes(unit.value)[0], unit.id);
}
public List<NameContract> ListButtons() public List<NameContract> ListButtons()
{ {
Event.WriteVerbose("WebService", "ListButtons"); Event.WriteVerbose("WebService", "ListButtons");

View file

@ -21,9 +21,7 @@ namespace HAILogger
string mode = area.ModeText(); string mode = area.ModeText();
if (mode.Contains("OFF")) if (mode.Contains("DAY"))
ret.mode = "OFF";
else if (mode.Contains("DAY"))
ret.mode = "DAY"; ret.mode = "DAY";
else if (mode.Contains("NIGHT")) else if (mode.Contains("NIGHT"))
ret.mode = "NIGHT"; ret.mode = "NIGHT";
@ -31,6 +29,8 @@ namespace HAILogger
ret.mode = "AWAY"; ret.mode = "AWAY";
else if (mode.Contains("VACATION")) else if (mode.Contains("VACATION"))
ret.mode = "VACATION"; ret.mode = "VACATION";
else
ret.mode = "OFF";
return ret; return ret;
} }
@ -40,8 +40,10 @@ namespace HAILogger
ZoneContract ret = new ZoneContract(); ZoneContract ret = new ZoneContract();
ret.id = id; ret.id = id;
ret.zonetype = zone.ZoneType;
ret.name = zone.Name; ret.name = zone.Name;
ret.status = zone.StatusText(); ret.status = zone.StatusText();
ret.temp = zone.TempText();
return ret; return ret;
} }
@ -83,6 +85,16 @@ namespace HAILogger
ret.coolsetpoint = cool; ret.coolsetpoint = cool;
ret.mode = unit.Mode; ret.mode = unit.Mode;
ret.fanmode = unit.FanMode; ret.fanmode = unit.FanMode;
ret.hold = unit.HoldStatus;
string status = unit.HorC_StatusText();
if (status.Contains("COOLING"))
ret.status = "COOLING";
else if (status.Contains("HEATING"))
ret.status = "HEATING";
else
ret.status = "OFF";
return ret; return ret;
} }

View file

@ -39,6 +39,10 @@ namespace HAILogger
[WebGet(ResponseFormat = WebMessageFormat.Json)] [WebGet(ResponseFormat = WebMessageFormat.Json)]
List<NameContract> ListZonesCO(); List<NameContract> ListZonesCO();
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
List<NameContract> ListZonesTemp();
[OperationContract] [OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)] [WebGet(ResponseFormat = WebMessageFormat.Json)]
ZoneContract GetZone(ushort id); ZoneContract GetZone(ushort id);
@ -83,6 +87,10 @@ namespace HAILogger
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
void SetThermostatFanMode(CommandContract unit); void SetThermostatFanMode(CommandContract unit);
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
void SetThermostatHold(CommandContract unit);
[OperationContract] [OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)] [WebGet(ResponseFormat = WebMessageFormat.Json)]
List<NameContract> ListButtons(); List<NameContract> ListButtons();

View file

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.5.0")] [assembly: AssemblyVersion("1.0.6.0")]
[assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyFileVersion("1.0.6.0")]

View file

@ -29,5 +29,11 @@ namespace HAILogger
[DataMember] [DataMember]
public enuThermostatFanMode fanmode { get; set; } public enuThermostatFanMode fanmode { get; set; }
[DataMember]
public enuThermostatHoldMode hold { get; set; }
[DataMember]
public string status { get; set; }
} }
} }

View file

@ -1,4 +1,5 @@
using System.Runtime.Serialization; using HAI_Shared;
using System.Runtime.Serialization;
namespace HAILogger namespace HAILogger
{ {
@ -8,10 +9,16 @@ namespace HAILogger
[DataMember] [DataMember]
public ushort id { get; set; } public ushort id { get; set; }
[DataMember]
public enuZoneType zonetype { get; set; }
[DataMember] [DataMember]
public string name { get; set; } public string name { get; set; }
[DataMember] [DataMember]
public string status { get; set; } public string status { get; set; }
[DataMember]
public string temp { get; set; }
} }
} }

View file

@ -2,7 +2,7 @@
Provides logging and web service API for HAI/Leviton OmniPro II controllers Provides logging and web service API for HAI/Leviton OmniPro II controllers
##Download ##Download
You can download the [binary here](http://www.excalibur-partners.com/downloads/HAILogger_1_0_5.zip) You can download the [binary here](http://www.excalibur-partners.com/downloads/HAILogger_1_0_6.zip)
##Requirements ##Requirements
- .NET Framework 4.0 - .NET Framework 4.0
@ -58,6 +58,9 @@ To test the API you can use your browser to view a page or PowerShell (see below
- Invoke-WebRequest -Uri "http://localhost:8000/SetUnit" -Method POST -ContentType "application/json" -Body (convertto-json -InputObject @{"id"=1;"value"=100}) -UseBasicParsing - Invoke-WebRequest -Uri "http://localhost:8000/SetUnit" -Method POST -ContentType "application/json" -Body (convertto-json -InputObject @{"id"=1;"value"=100}) -UseBasicParsing
##Change Log ##Change Log
Version 1.0.6 - 2016-11-20
- Added thermostat status and auxiliary temp to web service API
Version 1.0.5 - 2016-11-15 Version 1.0.5 - 2016-11-15
- Added web service API for Samsung SmartThings integration - Added web service API for Samsung SmartThings integration