mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 12:44:58 +00:00
Added DeviceUsage logic. Requires testing on NYC program with real hardware. Ready for Merge.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user