Added DeviceUsage logic. Requires testing on NYC program with real hardware. Ready for Merge.

This commit is contained in:
Neil Dorin
2017-08-21 18:04:47 -06:00
parent 710bfa3e8f
commit ce3de2baeb
11 changed files with 115 additions and 56 deletions

View File

@@ -31,6 +31,8 @@ namespace PepperDash.Essentials.Core
public UsageTracking() public UsageTracking()
{ {
InUseTracker = new InUseTracking();
InUseTracker.InUseFeedback.OutputChange +=new EventHandler<EventArgs>(InUseFeedback_OutputChange); InUseTracker.InUseFeedback.OutputChange +=new EventHandler<EventArgs>(InUseFeedback_OutputChange);
} }

View File

@@ -148,5 +148,11 @@ namespace PepperDash.Essentials
return o1; return o1;
} }
public static string GetGroupForDeviceKey(string key)
{
var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
return dev == null ? null : dev.Group;
}
} }
} }

View File

@@ -29,8 +29,8 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public override void InitializeSystem() public override void InitializeSystem()
{ {
//CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Reloads configuration file", CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Reloads configuration file",
// ConsoleAccessLevelEnum.AccessOperator); ConsoleAccessLevelEnum.AccessOperator);
//CrestronConsole.AddNewConsoleCommand(s => TearDown(), "ungo", "Reloads configuration file", //CrestronConsole.AddNewConsoleCommand(s => TearDown(), "ungo", "Reloads configuration file",
// ConsoleAccessLevelEnum.AccessOperator); // ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.AddNewConsoleCommand(s =>
@@ -40,7 +40,7 @@ namespace PepperDash.Essentials
}, },
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator); "listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
GoWithLoad(); //GoWithLoad();
} }
/// <summary> /// <summary>

View File

@@ -16,36 +16,36 @@ namespace PepperDash.Essentials.Fusion
public string RoomName { get; set; } public string RoomName { get; set; }
public uint IpId { get; set; } public uint IpId { get; set; }
public string RoomGuid { get; set; } public string RoomGuid { get; set; }
public List<StaticAsset> StaticAssets { get; set; } public List<FusionAsset> StaticAssets { get; set; }
public FusionRoomGuids() public FusionRoomGuids()
{ {
StaticAssets = new List<StaticAsset>(); StaticAssets = new List<FusionAsset>();
} }
public FusionRoomGuids(string roomName, uint ipId, string roomGuid, List<StaticAsset> staticAssets) public FusionRoomGuids(string roomName, uint ipId, string roomGuid, List<FusionAsset> staticAssets)
{ {
RoomName = roomName; RoomName = roomName;
IpId = ipId; IpId = ipId;
RoomGuid = roomGuid; RoomGuid = roomGuid;
StaticAssets = new List<StaticAsset>(staticAssets); StaticAssets = new List<FusionAsset>(staticAssets);
} }
} }
public class StaticAsset public class FusionAsset
{ {
public uint Number { get; set; } public uint Number { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string Type { get; set; } public string Type { get; set; }
public string InstanceID { get; set; } public string InstanceID { get; set; }
public StaticAsset() public FusionAsset()
{ {
} }
public StaticAsset(uint slotNum, string assetName, string type, string instanceID) public FusionAsset(uint slotNum, string assetName, string type, string instanceID)
{ {
Number = slotNum; Number = slotNum;
Name = assetName; Name = assetName;

View File

@@ -34,6 +34,10 @@ namespace PepperDash.Essentials.Fusion
Dictionary<Device, BoolInputSig> SourceToFeedbackSigs = Dictionary<Device, BoolInputSig> SourceToFeedbackSigs =
new Dictionary<Device, BoolInputSig>(); new Dictionary<Device, BoolInputSig>();
FusionOccupancySensor OccSensor;
BooleanSigData OccupancyStatusSig;
StatusMonitorCollection ErrorMessageRollUp; StatusMonitorCollection ErrorMessageRollUp;
StringSigData SourceNameSig; StringSigData SourceNameSig;
@@ -85,7 +89,7 @@ namespace PepperDash.Essentials.Fusion
public long PushNotificationTimeout = 5000; public long PushNotificationTimeout = 5000;
List<StaticAsset> StaticAssets; List<FusionAsset> FusionAssets;
//ScheduleResponseEvent NextMeeting; //ScheduleResponseEvent NextMeeting;
@@ -97,7 +101,7 @@ namespace PepperDash.Essentials.Fusion
IpId = ipId; IpId = ipId;
StaticAssets = new List<StaticAsset>(); FusionAssets = new List<FusionAsset>();
GUIDs = new FusionRoomGuids(); GUIDs = new FusionRoomGuids();
@@ -127,33 +131,34 @@ namespace PepperDash.Essentials.Fusion
SetUpCommunitcationMonitors(); SetUpCommunitcationMonitors();
SetUpDisplay(); SetUpDisplay();
SetUpError(); SetUpError();
SetUpOccupancy();
// test assets --- THESE ARE BOTH WIRED TO AssetUsage somewhere internally. // test assets --- THESE ARE BOTH WIRED TO AssetUsage somewhere internally.
var tempAsset1 = new StaticAsset(); //var tempAsset1 = new StaticAsset();
var tempAsset2 = new StaticAsset(); //var tempAsset2 = new StaticAsset();
//Check for existing GUID ////Check for existing GUID
if (GuidFileExists) //if (GuidFileExists)
{ //{
tempAsset1 = StaticAssets.FirstOrDefault(a => a.Number.Equals(1)); // tempAsset1 = StaticAssets.FirstOrDefault(a => a.Number.Equals(1));
tempAsset2 = StaticAssets.FirstOrDefault(a => a.Number.Equals(2)); // tempAsset2 = StaticAssets.FirstOrDefault(a => a.Number.Equals(2));
} //}
else //else
{ //{
tempAsset1 = new StaticAsset(1, "Test Asset 1", "Test Asset 1", ""); // tempAsset1 = new StaticAsset(1, "Test Asset 1", "Test Asset 1", "");
StaticAssets.Add(tempAsset1); // StaticAssets.Add(tempAsset1);
tempAsset2 = new StaticAsset(2, "Test Asset 2", "Test Asset 2", ""); // tempAsset2 = new StaticAsset(2, "Test Asset 2", "Test Asset 2", "");
StaticAssets.Add(tempAsset2); // StaticAssets.Add(tempAsset2);
} //}
var ta1 = FusionRoom.CreateStaticAsset(tempAsset1.Number, tempAsset1.Name, tempAsset1.Type, tempAsset1.InstanceID); //var ta1 = FusionRoom.CreateStaticAsset(tempAsset1.Number, tempAsset1.Name, tempAsset1.Type, tempAsset1.InstanceID);
ta1.AssetError.InputSig.StringValue = "This should be error"; //ta1.AssetError.InputSig.StringValue = "This should be error";
var ta2 = FusionRoom.CreateStaticAsset(tempAsset2.Number, tempAsset2.Name, tempAsset2.Type, tempAsset2.InstanceID); //var ta2 = FusionRoom.CreateStaticAsset(tempAsset2.Number, tempAsset2.Name, tempAsset2.Type, tempAsset2.InstanceID);
ta2.AssetUsage.InputSig.StringValue = "This should be usage"; //ta2.AssetUsage.InputSig.StringValue = "This should be usage";
// Make it so! // Make it so!
FusionRVI.GenerateFileForAllFusionDevices(); FusionRVI.GenerateFileForAllFusionDevices();
@@ -184,7 +189,7 @@ namespace PepperDash.Essentials.Fusion
Debug.Console(1, this, "Writing GUIDs to file"); Debug.Console(1, this, "Writing GUIDs to file");
GUIDs = new FusionRoomGuids(Room.Name, IpId, RoomGuid, StaticAssets); GUIDs = new FusionRoomGuids(Room.Name, IpId, RoomGuid, FusionAssets);
var JSON = JsonConvert.SerializeObject(GUIDs, Newtonsoft.Json.Formatting.Indented); var JSON = JsonConvert.SerializeObject(GUIDs, Newtonsoft.Json.Formatting.Indented);
@@ -237,7 +242,7 @@ namespace PepperDash.Essentials.Fusion
IpId = GUIDs.IpId; IpId = GUIDs.IpId;
StaticAssets = GUIDs.StaticAssets; FusionAssets = GUIDs.StaticAssets;
} }
@@ -245,7 +250,7 @@ namespace PepperDash.Essentials.Fusion
Debug.Console(1, this, "\nRoom Name: {0}\nIPID: {1:x}\n RoomGuid: {2}", Room.Name, IpId, RoomGuid); Debug.Console(1, this, "\nRoom Name: {0}\nIPID: {1:x}\n RoomGuid: {2}", Room.Name, IpId, RoomGuid);
foreach (StaticAsset asset in StaticAssets) foreach (FusionAsset asset in FusionAssets)
{ {
Debug.Console(1, this, "\nAsset Name: {0}\nAsset No: {1}\n Guid: {2}", asset.Name, asset.Number, asset.InstanceID); Debug.Console(1, this, "\nAsset Name: {0}\nAsset No: {1}\n Guid: {2}", asset.Name, asset.Number, asset.InstanceID);
} }
@@ -823,8 +828,8 @@ namespace PepperDash.Essentials.Fusion
if (usageDevice != null) if (usageDevice != null)
{ {
usageDevice.UsageTracker = new UsageTracking(); usageDevice.UsageTracker = new UsageTracking();
usageDevice.UsageTracker.UsageIsTracked = true;
usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_SourceUsageEnded); usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
} }
} }
@@ -842,25 +847,29 @@ namespace PepperDash.Essentials.Fusion
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
void UsageTracker_SourceUsageEnded(object sender, DeviceUsageEventArgs e) void UsageTracker_DeviceUsageEnded(object sender, DeviceUsageEventArgs e)
{ {
var device = sender as Device; var device = sender as Device;
var configDevice = ConfigReader.ConfigObject.Devices.Where(d => d.Key.Equals(device.Key)); var configDevice = ConfigReader.ConfigObject.Devices.Where(d => d.Key.Equals(device.Key));
string group = ""; string group = ConfigReader.GetGroupForDeviceKey(device.Key);
#warning Figure out how to get the group value from the device config string currentMeetingId = "";
if (CurrentMeeting != null)
currentMeetingId = CurrentMeeting.MeetingID;
//Double check my time and date formatting in the ToString() methods //String Format: "USAGE||[Date YYYY-MM-DD]||[Time HH-mm-ss]||TIME||[Asset_Type]||[Asset_Name]||[Minutes_used]||[Asset_ID]||[Meeting_ID]"
// [Asset_ID] property does not appear to be used in Crestron SSI examples. They are sending "-" instead so that's what is replicated here
string deviceUsage = string.Format("USAGE||{0}||{1}||TIME||{2}||{3}||{4}||{5}||{6})", e.UsageEndTime.ToString("YYYY-MM-DD"), e.UsageEndTime.ToString("HH-mm-ss"), string deviceUsage = string.Format("USAGE||{0}||{1}||TIME||{2}||{3}||{4}||{5}||{6})", e.UsageEndTime.ToString("YYYY-MM-DD"), e.UsageEndTime.ToString("HH-mm-ss"),
group, device.Name, e.MinutesUsed, "asset_id", CurrentMeeting.MeetingID); group, device.Name, e.MinutesUsed, "-", currentMeetingId);
FusionRoom.DeviceUsage.InputSig.StringValue = deviceUsage; FusionRoom.DeviceUsage.InputSig.StringValue = deviceUsage;
} }
void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc) void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc)
{ {
Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}",
@@ -963,44 +972,59 @@ namespace PepperDash.Essentials.Fusion
{ {
//Setup Display Usage Monitoring //Setup Display Usage Monitoring
#warning Somehow get list of room's displays and activate Usage tracking and subscribe to event var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
var display = Room.DefaultDisplay as DisplayBase; #warning should work for now in single room systems but will grab all devices regardless of room assignment. In multi-room systems, this will need to be handled differently.
if (display == null)
foreach (DisplayBase display in displays)
{
display.UsageTracker = new UsageTracking();
display.UsageTracker.UsageIsTracked = true;
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
}
var defaultDisplay = Room.DefaultDisplay as DisplayBase;
if (defaultDisplay == null)
{ {
Debug.Console(1, this, "Cannot link null display to Fusion"); Debug.Console(1, this, "Cannot link null display to Fusion");
return; return;
} }
var dispPowerOnAction = new Action<bool>(b => { if (!b) display.PowerOn(); }); var dispPowerOnAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOn(); });
var dispPowerOffAction = new Action<bool>(b => { if (!b) display.PowerOff(); }); var dispPowerOffAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOff(); });
// Display to fusion room sigs // Display to fusion room sigs
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction; FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
display.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig); defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
if (display is IDisplayUsage) if (defaultDisplay is IDisplayUsage)
(display as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); (defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
// static assets --------------- testing // static assets --------------- testing
// Make a display asset // Make a display asset
string dispAssetInstanceId; string dispAssetInstanceId;
//Check for existing GUID //Check for existing GUID
var tempAsset = StaticAssets.FirstOrDefault(a => a.Number.Equals(3)); var tempAsset = FusionAssets.FirstOrDefault(a => a.Name.Equals("Display"));
if(tempAsset != null) if(tempAsset != null)
dispAssetInstanceId = tempAsset.InstanceID; dispAssetInstanceId = tempAsset.InstanceID;
else else
dispAssetInstanceId = ""; {
var nextSlotNum = FusionAssets.Count + 1;
var dispAsset = FusionRoom.CreateStaticAsset(3, display.Name, "Display", dispAssetInstanceId); tempAsset = new FusionAsset((uint)nextSlotNum, defaultDisplay.Name, "Display", "");
FusionAssets.Add(tempAsset);
dispAssetInstanceId = tempAsset.InstanceID;
}
var dispAsset = FusionRoom.CreateStaticAsset(3, defaultDisplay.Name, "Display", dispAssetInstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
display.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig); defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig); // NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
// Use extension methods // Use extension methods
dispAsset.TrySetMakeModel(display); dispAsset.TrySetMakeModel(defaultDisplay);
dispAsset.TryLinkAssetErrorToCommunication(display); dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
} }
void SetUpError() void SetUpError()
@@ -1025,6 +1049,33 @@ namespace PepperDash.Essentials.Fusion
} }
void SetUpOccupancy()
{
#warning Add actual object logic check here
//if (Room.OccupancyObj != null)
//{
string occAssetId;
var tempAsset = FusionAssets.FirstOrDefault(a => a.Type.Equals("Occupancy Sensor"));
if(tempAsset != null)
occAssetId = tempAsset.InstanceID;
else
{
var nextAssetNum = FusionAssets.Count + 1;
tempAsset = new FusionAsset((uint)nextAssetNum, "Occupancy Sensor", "Occupancy Sensor", "");
FusionAssets.Add(tempAsset);
occAssetId = tempAsset.InstanceID;
}
FusionRoom.AddAsset(eAssetType.OccupancySensor, tempAsset.Number, tempAsset.Name, tempAsset.Type, tempAsset.InstanceID);
((FusionOccupancySensor)FusionRoom.UserConfigurableAssetDetails[tempAsset.Number].Asset).RoomOccupied.InputSig = OccupancyStatusSig;
//}
}
/// <summary> /// <summary>
/// Helper to get the number from the end of a device's key string /// Helper to get the number from the end of a device's key string
/// </summary> /// </summary>