mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-03 06:44:58 +00:00
Compare commits
27 Commits
1.4.33-rc-
...
1.4.33-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a324191d8 | ||
|
|
83298bb06a | ||
|
|
f6ef7017a2 | ||
|
|
1418e8f8c6 | ||
|
|
d097cfe51b | ||
|
|
88ea297f16 | ||
|
|
63feaac9bd | ||
|
|
c5f0bff133 | ||
|
|
bcfd90204b | ||
|
|
475be152a7 | ||
|
|
534110cfbf | ||
|
|
cbe96dbed9 | ||
|
|
e2fe8834c5 | ||
|
|
93e542befd | ||
|
|
3852617270 | ||
|
|
d7a04e202b | ||
|
|
abd6ab121e | ||
|
|
0c274015dd | ||
|
|
ffc0f8f58e | ||
|
|
c47f7ba7e3 | ||
|
|
733dbf9bd7 | ||
|
|
58c3c4fac7 | ||
|
|
82ddd40953 | ||
|
|
e6fb9cd1eb | ||
|
|
830b83f99f | ||
|
|
a2ebeab839 | ||
|
|
d81bcfba9a |
4
.github/scripts/ZipBuildOutput.ps1
vendored
4
.github/scripts/ZipBuildOutput.ps1
vendored
@@ -26,7 +26,7 @@ Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz
|
||||
} | Copy-Item -Destination ($destination) -Force
|
||||
Write-Host "Getting matching files..."
|
||||
# Get any files from the output folder that match the following extensions
|
||||
Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz"))} | ForEach-Object {
|
||||
Get-ChildItem -Path $destination | Where-Object { ($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz")) } | ForEach-Object {
|
||||
# Replace the extensions with dll and xml and create an array
|
||||
$filenames = @($($_ -replace "cpz|clz|cplz", "dll"), $($_ -replace "cpz|clz|cplz", "xml"))
|
||||
Write-Host "Filenames:"
|
||||
@@ -36,6 +36,8 @@ Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or (
|
||||
Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force
|
||||
}
|
||||
}
|
||||
|
||||
Get-ChildItem -Path $destination\*.cpz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" }
|
||||
Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force
|
||||
Write-Host "Output Contents post Zip"
|
||||
Get-ChildItem -Path $destination
|
||||
17
.github/workflows/docker.yml
vendored
17
.github/workflows/docker.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
env:
|
||||
# solution path doesn't need slashes unless there it is multiple folders deep
|
||||
# solution name does not include extension. .sln is assumed
|
||||
# solution name does not include extension. .sln is assumed
|
||||
SOLUTION_PATH: PepperDashEssentials
|
||||
SOLUTION_FILE: PepperDashEssentials
|
||||
# Do not edit this, we're just creating it here
|
||||
@@ -78,7 +78,8 @@ jobs:
|
||||
# Create the release on the source repo
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
# using contributor's version to allow for pointing at the right commit
|
||||
uses: fleskesvor/create-release@feature/support-target-commitish
|
||||
with:
|
||||
tag_name: ${{ env.VERSION }}
|
||||
release_name: ${{ env.VERSION }}
|
||||
@@ -143,6 +144,12 @@ jobs:
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||
Remove-Item -Path .\output -Recurse
|
||||
# Commits the build output to the branch and tags it with the version
|
||||
- name: Commit build output and tag the commit
|
||||
shell: powershell
|
||||
@@ -214,6 +221,12 @@ jobs:
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||
Remove-Item -Path .\output -Recurse
|
||||
# Commits the build output to the branch and tags it with the version
|
||||
- name: Commit build output and tag the commit
|
||||
shell: powershell
|
||||
|
||||
30
.github/workflows/master.yml
vendored
30
.github/workflows/master.yml
vendored
@@ -56,21 +56,11 @@ jobs:
|
||||
- name: Zip Build Output
|
||||
shell: powershell
|
||||
run: ./.github/scripts/ZipBuildOutput.ps1
|
||||
# Write the version to a file to be consumed by the push jobs
|
||||
- name: Write Version
|
||||
run: Write-Output "$($Env:VERSION)" | Out-File -FilePath "$($Env:GITHUB_HOME)\output\version.txt"
|
||||
# Upload the build output as an artifact
|
||||
- name: Upload Build Output
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: Build
|
||||
path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
|
||||
# Upload the Version file as an artifact
|
||||
- name: Upload version.txt
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: Version
|
||||
path: ${{env.GITHUB_HOME}}\output\version.txt
|
||||
# Upload the build package to the release
|
||||
- name: Upload Release Package
|
||||
id: upload_release
|
||||
@@ -82,6 +72,7 @@ jobs:
|
||||
asset_content_type: application/zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# This step always runs and pushes the build to the internal build rep
|
||||
Internal_Push_Output:
|
||||
needs: Build_Project
|
||||
runs-on: windows-latest
|
||||
@@ -111,8 +102,8 @@ jobs:
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout/Create the branch
|
||||
- name: Checkout Master branch
|
||||
run: git checkout master
|
||||
- name: Create new branch
|
||||
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
@@ -128,7 +119,7 @@ jobs:
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
@@ -148,7 +139,10 @@ jobs:
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: git push -u origin master --force
|
||||
run: |
|
||||
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
|
||||
Write-Host "Branch: $branch"
|
||||
git push -u origin $($branch) --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
@@ -158,6 +152,7 @@ jobs:
|
||||
Public_Push_Output:
|
||||
needs: Build_Project
|
||||
runs-on: windows-latest
|
||||
if: contains(github.ref, 'master') || contains(github.ref, 'release')
|
||||
steps:
|
||||
# Checkout the repo
|
||||
- name: Checkout Builds Repo
|
||||
@@ -185,7 +180,7 @@ jobs:
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout/Create the branch
|
||||
- name: Create new branch
|
||||
run: git checkout -b master
|
||||
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
@@ -221,7 +216,10 @@ jobs:
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: git push -u origin master --force
|
||||
run: |
|
||||
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
|
||||
Write-Host "Branch: $branch"
|
||||
git push -u origin $($branch) --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Monitoring;
|
||||
|
||||
@@ -23,11 +17,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
SysMon = sysMon;
|
||||
|
||||
SysMon.SystemMonitorPropertiesChanged += new EventHandler<EventArgs>(SysMon_SystemMonitorPropertiesChanged);
|
||||
SysMon.SystemMonitorPropertiesChanged += SysMon_SystemMonitorPropertiesChanged;
|
||||
|
||||
foreach (var p in SysMon.ProgramStatusFeedbackCollection)
|
||||
{
|
||||
p.Value.ProgramInfoChanged += new EventHandler<ProgramInfoEventArgs>(ProgramInfoChanged);
|
||||
p.Value.ProgramInfoChanged += ProgramInfoChanged;
|
||||
}
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s => SendFullStatusMessage(), "SendFullSysMonStatus", "Sends the full System Monitor Status", ConsoleAccessLevelEnum.AccessOperator);
|
||||
@@ -72,18 +66,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
Debug.Console(1, "Posting System Monitor Status Message.");
|
||||
|
||||
// This takes a while, launch a new thread
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
CrestronInvoke.BeginInvoke(o => PostStatusMessage(new
|
||||
{
|
||||
PostStatusMessage(new
|
||||
{
|
||||
timeZone = SysMon.TimeZoneFeedback.IntValue,
|
||||
timeZoneName = SysMon.TimeZoneTextFeedback.StringValue,
|
||||
ioControllerVersion = SysMon.IOControllerVersionFeedback.StringValue,
|
||||
snmpVersion = SysMon.SnmpVersionFeedback.StringValue,
|
||||
bacnetVersion = SysMon.BACnetAppVersionFeedback.StringValue,
|
||||
controllerVersion = SysMon.ControllerVersionFeedback.StringValue
|
||||
});
|
||||
});
|
||||
timeZone = SysMon.TimeZoneFeedback.IntValue,
|
||||
timeZoneName = SysMon.TimeZoneTextFeedback.StringValue,
|
||||
ioControllerVersion = SysMon.IoControllerVersionFeedback.StringValue,
|
||||
snmpVersion = SysMon.SnmpVersionFeedback.StringValue,
|
||||
bacnetVersion = SysMon.BaCnetAppVersionFeedback.StringValue,
|
||||
controllerVersion = SysMon.ControllerVersionFeedback.StringValue
|
||||
}));
|
||||
}
|
||||
|
||||
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Bridges
|
||||
{
|
||||
@@ -14,11 +9,21 @@ namespace PepperDash.Essentials.Bridges
|
||||
/// </summary>
|
||||
public uint ProgramStartJoin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Offset to indicate where the range of iterated Ethernet joins will start
|
||||
/// </summary>
|
||||
public uint EthernetStartJoin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Offset between each program join set
|
||||
/// </summary>
|
||||
public uint ProgramOffsetJoin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Offset between each Ethernet Interface join set
|
||||
/// </summary>
|
||||
public uint EthernetOffsetJoin { get; set; }
|
||||
|
||||
#region Digitals
|
||||
/// <summary>
|
||||
/// Range Sets and reports whether the corresponding program slot is started
|
||||
@@ -87,6 +92,68 @@ namespace PepperDash.Essentials.Bridges
|
||||
/// Serialized JSON output that aggregates the program info of the corresponding program
|
||||
/// </summary>
|
||||
public uint AggregatedProgramInfo { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the controller serial number
|
||||
/// </summary>
|
||||
public uint SerialNumber { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the controller model
|
||||
/// </summary>
|
||||
public uint Model { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the Host name set on the corresponding interface
|
||||
/// </summary>
|
||||
public uint HostName { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the Current IP address set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned address.
|
||||
/// </summary>
|
||||
public uint CurrentIpAddress { get; set; }
|
||||
/// <summary>
|
||||
/// Reporst the Current Default Gateway set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned gateway
|
||||
/// </summary>
|
||||
public uint CurrentDefaultGateway { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask
|
||||
/// </summary>
|
||||
public uint CurrentSubnetMask { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the Static IP address set on the corresponding interface. If DHCP is disabled, this will match the Current IP address
|
||||
/// </summary>
|
||||
public uint StaticIpAddress { get; set; }
|
||||
/// <summary>
|
||||
/// Reporst the Static Default Gateway set on the corresponding interface. If DHCP is disabled, this will match the Current gateway
|
||||
/// </summary>
|
||||
public uint StaticDefaultGateway { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask
|
||||
/// </summary>
|
||||
public uint StaticSubnetMask { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the current DomainFeedback on the corresponding interface
|
||||
/// </summary>
|
||||
public uint Domain { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the current DNS Servers on the corresponding interface
|
||||
/// </summary>
|
||||
public uint DnsServer { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the MAC Address of the corresponding interface
|
||||
/// </summary>
|
||||
public uint MacAddress { get; set; }
|
||||
/// <summary>
|
||||
/// Reports the DHCP Status of the corresponding interface
|
||||
/// </summary>
|
||||
public uint DhcpStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reports the current uptime. Updated in 5 minute intervals.
|
||||
/// </summary>
|
||||
public uint Uptime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reports the date of the last boot
|
||||
/// </summary>
|
||||
public uint LastBoot { get; set; }
|
||||
#endregion
|
||||
|
||||
public SystemMonitorJoinMap()
|
||||
@@ -98,6 +165,10 @@ namespace PepperDash.Essentials.Bridges
|
||||
SnmpAppVersion = 3;
|
||||
BACnetAppVersion = 4;
|
||||
ControllerVersion = 5;
|
||||
SerialNumber = 6;
|
||||
Model = 7;
|
||||
Uptime = 8;
|
||||
LastBoot = 9;
|
||||
|
||||
|
||||
ProgramStartJoin = 10;
|
||||
@@ -115,6 +186,23 @@ namespace PepperDash.Essentials.Bridges
|
||||
ProgramCrestronDatabaseVersion = 3;
|
||||
ProgramEnvironmentVersion = 4;
|
||||
AggregatedProgramInfo = 5;
|
||||
|
||||
EthernetStartJoin = 75;
|
||||
|
||||
EthernetOffsetJoin = 15;
|
||||
|
||||
// Offset in groups of 15
|
||||
HostName = 1;
|
||||
CurrentIpAddress = 2;
|
||||
CurrentSubnetMask = 3;
|
||||
CurrentDefaultGateway = 4;
|
||||
StaticIpAddress = 5;
|
||||
StaticSubnetMask = 6;
|
||||
StaticDefaultGateway = 7;
|
||||
Domain = 8;
|
||||
DnsServer = 9;
|
||||
MacAddress = 10;
|
||||
DhcpStatus = 11;
|
||||
}
|
||||
|
||||
public override void OffsetJoinNumbers(uint joinStart)
|
||||
@@ -131,6 +219,7 @@ namespace PepperDash.Essentials.Bridges
|
||||
|
||||
// Sets the initial join value where the iterated program joins will begin
|
||||
ProgramStartJoin = ProgramStartJoin + joinOffset;
|
||||
EthernetStartJoin = EthernetStartJoin + joinOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.Diagnostics;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
@@ -17,7 +12,7 @@ namespace PepperDash.Essentials.Bridges
|
||||
{
|
||||
public static void LinkToApi(this SystemMonitorController systemMonitorController, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||
{
|
||||
SystemMonitorJoinMap joinMap = new SystemMonitorJoinMap();
|
||||
var joinMap = new SystemMonitorJoinMap();
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey);
|
||||
|
||||
@@ -30,36 +25,71 @@ namespace PepperDash.Essentials.Bridges
|
||||
Debug.Console(2, systemMonitorController, "Linking API starting at join: {0}", joinStart);
|
||||
|
||||
systemMonitorController.TimeZoneFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeZone]);
|
||||
//trilist.SetUShortSigAction(joinMap.TimeZone, new Action<ushort>(u => systemMonitorController.SetTimeZone(u)));
|
||||
systemMonitorController.TimeZoneTextFeedback.LinkInputSig(trilist.StringInput[joinMap.TimeZoneName]);
|
||||
|
||||
systemMonitorController.IOControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.IOControllerVersion]);
|
||||
systemMonitorController.IoControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.IOControllerVersion]);
|
||||
systemMonitorController.SnmpVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.SnmpAppVersion]);
|
||||
systemMonitorController.BACnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]);
|
||||
systemMonitorController.BaCnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]);
|
||||
systemMonitorController.ControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.ControllerVersion]);
|
||||
systemMonitorController.SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumber]);
|
||||
systemMonitorController.ModelFeedback.LinkInputSig(trilist.StringInput[joinMap.Model]);
|
||||
systemMonitorController.UptimeFeedback.LinkInputSig(trilist.StringInput[joinMap.Uptime]);
|
||||
systemMonitorController.LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot]);
|
||||
|
||||
// iterate the program status feedback collection and map all the joins
|
||||
LinkProgramInfoJoins(systemMonitorController, trilist, joinMap);
|
||||
|
||||
LinkEthernetInfoJoins(systemMonitorController, trilist, joinMap);
|
||||
}
|
||||
|
||||
private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap)
|
||||
{
|
||||
var ethernetSlotJoinStart = joinMap.EthernetStartJoin;
|
||||
|
||||
foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection)
|
||||
{
|
||||
fb.Value.CurrentIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentIpAddress]);
|
||||
fb.Value.CurrentSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentSubnetMask]);
|
||||
fb.Value.CurrentDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentDefaultGateway]);
|
||||
fb.Value.StaticIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticIpAddress]);
|
||||
fb.Value.StaticSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticSubnetMask]);
|
||||
fb.Value.StaticDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticDefaultGateway]);
|
||||
fb.Value.HostNameFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.HostName]);
|
||||
fb.Value.MacAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.MacAddress]);
|
||||
fb.Value.DomainFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.Domain]);
|
||||
fb.Value.DnsServerFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DnsServer]);
|
||||
fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus]);
|
||||
|
||||
ethernetSlotJoinStart += joinMap.EthernetOffsetJoin;
|
||||
}
|
||||
}
|
||||
|
||||
private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist,
|
||||
SystemMonitorJoinMap joinMap)
|
||||
{
|
||||
var programSlotJoinStart = joinMap.ProgramStartJoin;
|
||||
|
||||
foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection)
|
||||
{
|
||||
var programNumber = p.Value.Program.Number;
|
||||
|
||||
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart, new Action<bool>
|
||||
(b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start));
|
||||
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart,
|
||||
b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start);
|
||||
p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart]);
|
||||
|
||||
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop, new Action<bool>
|
||||
(b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop));
|
||||
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop,
|
||||
b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop);
|
||||
p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop]);
|
||||
|
||||
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister, new Action<bool>
|
||||
(b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register));
|
||||
p.Value.ProgramRegisteredFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]);
|
||||
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister,
|
||||
b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register);
|
||||
p.Value.ProgramRegisteredFeedback.LinkInputSig(
|
||||
trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]);
|
||||
|
||||
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister, new Action<bool>
|
||||
(b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister));
|
||||
p.Value.ProgramUnregisteredFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]);
|
||||
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister,
|
||||
b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister);
|
||||
p.Value.ProgramUnregisteredFeedback.LinkInputSig(
|
||||
trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]);
|
||||
|
||||
p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName]);
|
||||
p.Value.ProgramCompileTimeFeedback.LinkInputSig(
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
HttpLogoServer LogoServer;
|
||||
|
||||
|
||||
public ControlSystem()
|
||||
: base()
|
||||
{
|
||||
@@ -46,6 +47,8 @@ namespace PepperDash.Essentials
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(PluginLoader.ReportAssemblyVersions, "reportversions", "Reports the versions of the loaded assemblies", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
// CrestronConsole.AddNewConsoleCommand(S => { ConfigWriter.WriteConfigFile(null); }, "writeconfig", "writes the current config to a file", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
@@ -78,10 +81,12 @@ namespace PepperDash.Essentials
|
||||
GoWithLoad();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the program is running on a processor (appliance) or server (VC-4).
|
||||
///
|
||||
/// Sets Global.FilePathPrefix based on platform
|
||||
/// Sets Global.FilePathPrefix and Global.ApplicationDirectoryPathPrefix based on platform
|
||||
/// </summary>
|
||||
public void DeterminePlatform()
|
||||
{
|
||||
@@ -108,7 +113,7 @@ namespace PepperDash.Essentials
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", Global.AssemblyVersion);
|
||||
|
||||
// Check if User/ProgramX exists
|
||||
if (Directory.Exists(directoryPrefix + dirSeparator + "User"
|
||||
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User"
|
||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
|
||||
{
|
||||
Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber);
|
||||
@@ -158,11 +163,13 @@ namespace PepperDash.Essentials
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration");
|
||||
|
||||
PluginLoader.AddProgramAssemblies();
|
||||
|
||||
var filesReady = SetupFilesystem();
|
||||
if (filesReady)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Checking for plugins");
|
||||
LoadPlugins();
|
||||
PluginLoader.LoadPlugins();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Folder structure verified. Loading config...");
|
||||
if (!ConfigReader.LoadConfig2())
|
||||
@@ -197,118 +204,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initial simple implementation. Reads user/programXX/plugins folder and
|
||||
/// use
|
||||
/// </summary>
|
||||
void LoadPlugins()
|
||||
{
|
||||
var dir = Global.FilePathPrefix + "plugins";
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
// TODO Clear out or create localPlugins folder (maybe in program slot folder)
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Plugins directory found, checking for factory plugins");
|
||||
var di = new DirectoryInfo(dir);
|
||||
var zFiles = di.GetFiles("*.cplz");
|
||||
foreach (var fi in zFiles)
|
||||
{
|
||||
Debug.Console(0, "Found cplz: {0}. Unzipping into plugins directory", fi.Name);
|
||||
var result = CrestronZIP.Unzip(fi.FullName, di.FullName);
|
||||
Debug.Console(0, "UnZip Result: {0}", result.ToString());
|
||||
fi.Delete();
|
||||
}
|
||||
var files = di.GetFiles("*.dll");
|
||||
Dictionary<string, Assembly> assyList = new Dictionary<string, Assembly>();
|
||||
foreach (FileInfo fi in files)
|
||||
{
|
||||
// TODO COPY plugin to loadedPlugins folder
|
||||
// TODO LOAD that loadedPlugins dll file
|
||||
try
|
||||
{
|
||||
var assy = Assembly.LoadFrom(fi.FullName);
|
||||
var ver = assy.GetName().Version;
|
||||
var verStr = string.Format("{0}.{1}.{2}.{3}", ver.Major, ver.Minor, ver.Build, ver.Revision);
|
||||
assyList.Add(fi.FullName, assy);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loaded plugin file '{0}', version {1}", fi.FullName, verStr);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(2, "Assembly {0} is not a custom assembly", fi.FullName);
|
||||
continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here
|
||||
}
|
||||
}
|
||||
foreach (var assy in assyList)
|
||||
{
|
||||
// iteratate this assembly's classes, looking for "LoadPlugin()" methods
|
||||
try
|
||||
{
|
||||
var types = assy.Value.GetTypes();
|
||||
foreach (var type in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
|
||||
var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin"));
|
||||
if (loadPlugin != null)
|
||||
{
|
||||
Debug.Console(2, "LoadPlugin method found in {0}", type.Name);
|
||||
|
||||
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||
|
||||
var minimumVersion = fields.FirstOrDefault(p => p.Name.Equals("MinimumEssentialsFrameworkVersion"));
|
||||
if (minimumVersion != null)
|
||||
{
|
||||
Debug.Console(2, "MinimumEssentialsFrameworkVersion found");
|
||||
|
||||
var minimumVersionString = minimumVersion.GetValue(null) as string;
|
||||
|
||||
if (!string.IsNullOrEmpty(minimumVersionString))
|
||||
{
|
||||
var passed = Global.IsRunningMinimumVersionOrHigher(minimumVersionString);
|
||||
|
||||
if (!passed)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", minimumVersionString);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", minimumVersionString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion found but not set. Loading plugin, but your mileage may vary.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion not found. Loading plugin, but your mileage may vary.");
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding plugin: {0}", assy.Key);
|
||||
loadPlugin.Invoke(null, null);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(2, "Load Plugin not found. {0} is not a plugin assembly", assy.Value.FullName);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(2, "Assembly {0} is not a custom assembly. Types cannot be loaded.", assy.Value.FullName);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// plugin dll will be loaded. Any classes in plugin should have a static constructor
|
||||
// that registers that class with the Core.DeviceFactory
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Verifies filesystem is set up. IR, SGD, and programX folders
|
||||
|
||||
@@ -1,266 +0,0 @@
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using Crestron.SimplSharp;
|
||||
//using Crestron.SimplSharp.CrestronIO;
|
||||
//using Crestron.SimplSharp.Net.Http;
|
||||
|
||||
//using Newtonsoft.Json;
|
||||
//using Newtonsoft.Json.Linq;
|
||||
|
||||
//using PepperDash.Essentials.Core;
|
||||
//using PepperDash.Essentials.Core.Http;
|
||||
//using PepperDash.Core;
|
||||
|
||||
//namespace PepperDash.Essentials
|
||||
//{
|
||||
// public class EssentialsHttpApiHandler
|
||||
// {
|
||||
// string ConfigPath;
|
||||
// string PresetsPathPrefix;
|
||||
// EssentialsHttpServer Server;
|
||||
|
||||
// /// <summary>
|
||||
// ///
|
||||
// /// </summary>
|
||||
// /// <param name="server">HTTP server to attach to</param>
|
||||
// /// <param name="configPath">The full path to configuration file</param>
|
||||
// /// <param name="presetsListPath">The folder prefix for the presets path, eq "\HTML\presets\"</param>
|
||||
// public EssentialsHttpApiHandler(EssentialsHttpServer server, string configPath, string presetsPathPrefix)
|
||||
// {
|
||||
// if (server == null) throw new ArgumentNullException("server");
|
||||
// Server = server;
|
||||
// ConfigPath = configPath;
|
||||
// PresetsPathPrefix = presetsPathPrefix;
|
||||
// server.ApiRequest += Server_ApiRequest;
|
||||
// }
|
||||
|
||||
|
||||
// void Server_ApiRequest(object sender, Crestron.SimplSharp.Net.Http.OnHttpRequestArgs args)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// var path = args.Request.Path.ToLower();
|
||||
|
||||
// if (path == "/api/config")
|
||||
// HandleApiConfig(args);
|
||||
// else if (path.StartsWith("/api/presetslist/"))
|
||||
// HandleApiPresetsList(args);
|
||||
// else if (path == "/api/presetslists")
|
||||
// HandleApiGetPresetsLists(args.Request, args.Response);
|
||||
// else
|
||||
// {
|
||||
// args.Response.Code = 404;
|
||||
// return;
|
||||
// }
|
||||
// args.Response.Header.SetHeaderValue("Access-Control-Allow-Origin", "*");
|
||||
// args.Response.Header.SetHeaderValue("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// Debug.Console(1, "Uncaught HTTP server error: \n{0}", e);
|
||||
// args.Response.Code = 500;
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// GET will return the running configuration. POST will attempt to take in a new config
|
||||
// /// and restart the program.
|
||||
// /// </summary>
|
||||
// void HandleApiConfig(OnHttpRequestArgs args)
|
||||
// {
|
||||
// var request = args.Request;
|
||||
// if (request.Header.RequestType == "GET")
|
||||
// {
|
||||
// if (File.Exists(ConfigPath))
|
||||
// {
|
||||
// Debug.Console(2, "Sending config:{0}", ConfigPath);
|
||||
// args.Response.Header.ContentType = EssentialsHttpServer.GetContentType(new FileInfo(ConfigPath).Extension);
|
||||
// args.Response.ContentStream = new FileStream(ConfigPath, FileMode.Open, FileAccess.Read);
|
||||
// }
|
||||
// }
|
||||
// else if (request.Header.RequestType == "POST")
|
||||
// {
|
||||
// Debug.Console(2, "Post type: '{0}'", request.Header.ContentType);
|
||||
|
||||
// // Make sure we're receiving at least good json
|
||||
// Debug.Console(1, "Receving new config");
|
||||
// if (GetContentStringJson(args) == null)
|
||||
// return;
|
||||
|
||||
// //---------------------------- try to move these into common method
|
||||
// // Move current file aside
|
||||
// var bakPath = ConfigPath + ".bak";
|
||||
// if (File.Exists(bakPath))
|
||||
// File.Delete(bakPath);
|
||||
// File.Move(ConfigPath, bakPath);
|
||||
|
||||
// // Write the file
|
||||
// using (FileStream fs = File.Open(ConfigPath, FileMode.OpenOrCreate))
|
||||
// using (StreamWriter sw = new StreamWriter(fs))
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// sw.Write(args.Request.ContentString);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// string err = string.Format("Error writing received config file:\r{0}", e);
|
||||
// CrestronConsole.PrintLine(err);
|
||||
// ErrorLog.Warn(err);
|
||||
// // Put file back
|
||||
// File.Move(ConfigPath + ".bak", ConfigPath);
|
||||
// args.Response.Code = 500;
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // If client says "yeah, restart" and has a good token
|
||||
// // Restart program
|
||||
// string consoleResponse = null;
|
||||
// var restart = CrestronConsole.SendControlSystemCommand("progreset -p:" +
|
||||
// InitialParametersClass.ApplicationNumber, ref consoleResponse);
|
||||
// if (!restart) Debug.Console(0, "CAN'T DO THAT YO: {0}", consoleResponse);
|
||||
// }
|
||||
// }
|
||||
|
||||
// void HandleApiPresetsList(OnHttpRequestArgs args)
|
||||
// {
|
||||
// var listPath = PresetsPathPrefix + args.Request.Path.Remove(0, 17);
|
||||
// Debug.Console(2, "Checking for preset list '{0}'", listPath);
|
||||
|
||||
// if (args.Request.Header.RequestType == "GET")
|
||||
// {
|
||||
// if (File.Exists(listPath))
|
||||
// {
|
||||
// Debug.Console(2, "Sending presets file:{0}", listPath);
|
||||
// args.Response.Header.ContentType = EssentialsHttpServer.GetContentType(new FileInfo(listPath).Extension);
|
||||
// args.Response.ContentStream = new FileStream(listPath, FileMode.Open, FileAccess.Read);
|
||||
// }
|
||||
// }
|
||||
// else if (args.Request.Header.RequestType == "POST")
|
||||
// {
|
||||
// // Make sure we're receiving at least good json
|
||||
// Debug.Console(1, "Receving new presets");
|
||||
// if (GetContentStringJson(args) == null)
|
||||
// return;
|
||||
|
||||
// //---------------------------- try to move these into common method
|
||||
// // Move current file aside
|
||||
// var bakPath = listPath + ".new";
|
||||
// Debug.Console(2, "Moving presets file to {0}", bakPath);
|
||||
// if(File.Exists(bakPath))
|
||||
// File.Delete(bakPath);
|
||||
// File.Move(listPath, bakPath);
|
||||
|
||||
// Debug.Console(2, "Writing new file");
|
||||
// // Write the file
|
||||
// using (FileStream fs = File.OpenWrite(listPath))
|
||||
// using (StreamWriter sw = new StreamWriter(fs))
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// Debug.Console(2, "Writing {1}, {0} bytes", args.Request.ContentString.Length, listPath);
|
||||
// sw.Write(args.Request.ContentString);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// string err = string.Format("Error writing received presets file:\r{0}", e);
|
||||
// CrestronConsole.PrintLine(err);
|
||||
// ErrorLog.Warn(err);
|
||||
// // Put file back
|
||||
// File.Move(listPath + ".bak", listPath);
|
||||
// args.Response.Code = 500;
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// void HandleApiGetPresetsLists(HttpServerRequest request, HttpServerResponse response)
|
||||
// {
|
||||
// if (request.Header.RequestType != "GET")
|
||||
// {
|
||||
// response.Code = 404; // This should be a 405 with an allow header
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (Directory.Exists(PresetsPathPrefix))
|
||||
// {
|
||||
// //CrestronConsole.PrintLine("Parsing presets directory");
|
||||
// List<string> files = Directory.GetFiles(PresetsPathPrefix, "*.json")
|
||||
// .ToList().Select(f => Path.GetFileName(f)).ToList();
|
||||
// if (files.Count > 0)
|
||||
// files.Sort();
|
||||
// var json = JsonConvert.SerializeObject(files);
|
||||
// response.Header.ContentType = "application/json";
|
||||
// response.ContentString = json;
|
||||
// }
|
||||
|
||||
// // //CrestronConsole.PrintLine("Found {0} files", files.Count);
|
||||
// // JObject jo = new JObject();
|
||||
// // JArray ja = new JArray();
|
||||
|
||||
// // foreach (var filename in files)
|
||||
// // {
|
||||
// // try
|
||||
// // {
|
||||
// // using (StreamReader sr = new StreamReader(filename))
|
||||
// // {
|
||||
// // JObject tempJo = JObject.Parse(sr.ReadToEnd());
|
||||
// // if (tempJo.Value<string>("content").Equals("presetsList"))
|
||||
// // {
|
||||
// // var jItem = new JObject(); // make a new object
|
||||
// // jItem.Add("Name", tempJo["name"]);
|
||||
// // jItem.Add("File", filename);
|
||||
// // jItem.Add("Url", Uri.EscapeUriString(new Uri(
|
||||
// // filename.Replace("\\html", "")
|
||||
// // .Replace("\\HTML", "")
|
||||
// // .Replace('\\', '/'), UriKind.Relative).ToString()));
|
||||
// // ja.Add(jItem); // add to array
|
||||
// // }
|
||||
// // else
|
||||
// // CrestronConsole.PrintLine("Cannot use presets file '{0}'", filename);
|
||||
// // }
|
||||
// // }
|
||||
// // catch
|
||||
// // {
|
||||
// // // ignore failures - maybe delete them
|
||||
// // CrestronConsole.PrintLine("Unable to read presets file '{0}'", filename);
|
||||
// // }
|
||||
// // }
|
||||
// // jo.Add("PresetChannelLists", ja);
|
||||
// // //CrestronConsole.PrintLine(jo.ToString());
|
||||
// // response.Header.ContentType = "application/json";
|
||||
// // response.ContentString = jo.ToString();
|
||||
// //}
|
||||
// //else
|
||||
// // CrestronConsole.PrintLine("No presets files in directory");
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Simply does what it says
|
||||
// /// </summary>
|
||||
// JObject GetContentStringJson(OnHttpRequestArgs args)
|
||||
// {
|
||||
// //var content = args.Request.ContentString;
|
||||
// //Debug.Console(1, "{0}", content);
|
||||
|
||||
// try
|
||||
// {
|
||||
// // just see if it parses properly
|
||||
// return JObject.Parse(args.Request.ContentString);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// string err = string.Format("JSON Error reading config file:\r{0}", e);
|
||||
// CrestronConsole.PrintLine(err);
|
||||
// ErrorLog.Warn(err);
|
||||
// args.Response.Code = 400; // Bad request
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -166,7 +166,7 @@
|
||||
<Compile Include="ControlSystem.cs" />
|
||||
<Compile Include="Factory\UiDeviceFactory.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleVtc1FusionController.cs" />
|
||||
<Compile Include="HttpApiHandler.cs" />
|
||||
<Compile Include="PluginLoading\PluginLoading.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Room\Config\EssentialsDualDisplayRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsNDisplayRoomPropertiesConfig.cs" />
|
||||
|
||||
444
PepperDashEssentials/PluginLoading/PluginLoading.cs
Normal file
444
PepperDashEssentials/PluginLoading/PluginLoading.cs
Normal file
@@ -0,0 +1,444 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
/// Deals with loading plugins at runtime
|
||||
/// </summary>
|
||||
public static class PluginLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// The complete list of loaded assemblies. Includes Essentials Framework assemblies and plugins
|
||||
/// </summary>
|
||||
public static List<LoadedAssembly> LoadedAssemblies { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of assemblies loaded from the plugins folder
|
||||
/// </summary>
|
||||
static List<LoadedAssembly> LoadedPluginFolderAssemblies;
|
||||
|
||||
/// <summary>
|
||||
/// The directory to look in for .cplz plugin packages
|
||||
/// </summary>
|
||||
static string _pluginDirectory = Global.FilePathPrefix + "plugins";
|
||||
|
||||
/// <summary>
|
||||
/// The directory where plugins will be moved to and loaded from
|
||||
/// </summary>
|
||||
static string _loadedPluginsDirectoryPath = _pluginDirectory + Global.DirectorySeparator + "loadedAssemblies";
|
||||
|
||||
// The temp directory where .cplz archives will be unzipped to
|
||||
static string _tempDirectory = _pluginDirectory + Global.DirectorySeparator + "temp";
|
||||
|
||||
|
||||
static PluginLoader()
|
||||
{
|
||||
LoadedAssemblies = new List<LoadedAssembly>();
|
||||
LoadedPluginFolderAssemblies = new List<LoadedAssembly>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all the loaded assemblies from the program directory
|
||||
/// </summary>
|
||||
public static void AddProgramAssemblies()
|
||||
{
|
||||
Debug.Console(2, "Getting Assemblies loaded with Essentials");
|
||||
// Get the loaded assembly filenames
|
||||
var appDi = new DirectoryInfo(Global.ApplicationDirectoryPathPrefix);
|
||||
var assemblyFiles = appDi.GetFiles("*.dll");
|
||||
|
||||
Debug.Console(2, "Found {0} Assemblies", assemblyFiles.Length);
|
||||
|
||||
foreach (var fi in assemblyFiles)
|
||||
{
|
||||
string version = string.Empty;
|
||||
Assembly assembly = null;
|
||||
|
||||
switch (fi.Name)
|
||||
{
|
||||
case ("PepperDashEssentials.dll"):
|
||||
{
|
||||
version = Global.AssemblyVersion;
|
||||
assembly = Assembly.GetExecutingAssembly();
|
||||
break;
|
||||
}
|
||||
case ("PepperDash_Core.dll"):
|
||||
{
|
||||
version = PepperDash.Core.Debug.PepperDashCoreVersion;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LoadedAssemblies.Add(new LoadedAssembly(fi.Name, version, assembly));
|
||||
}
|
||||
|
||||
if (Debug.Level > 1)
|
||||
{
|
||||
Debug.Console(2, "Loaded Assemblies:");
|
||||
|
||||
foreach (var assembly in LoadedAssemblies)
|
||||
{
|
||||
Debug.Console(2, "Assembly: {0}", assembly.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads an assembly via Reflection and adds it to the list of loaded assemblies
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
static LoadedAssembly LoadAssembly(string filePath)
|
||||
{
|
||||
Debug.Console(2, "Attempting to load {0}", filePath);
|
||||
var assembly = Assembly.LoadFrom(filePath);
|
||||
if (assembly != null)
|
||||
{
|
||||
var assyVersion = GetAssemblyVersion(assembly);
|
||||
|
||||
var loadedAssembly = new LoadedAssembly(assembly.GetName().Name, assyVersion, assembly);
|
||||
LoadedAssemblies.Add(loadedAssembly);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loaded assembly '{0}', version {1}", loadedAssembly.Name, loadedAssembly.Version);
|
||||
return loadedAssembly;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to load assembly: '{0}'", filePath);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the assembly informational version and if not possible gets the version
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
static string GetAssemblyVersion(Assembly assembly)
|
||||
{
|
||||
var ver = assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false);
|
||||
if (ver != null && ver.Length > 0)
|
||||
{
|
||||
// Get the AssemblyInformationalVersion
|
||||
AssemblyInformationalVersionAttribute verAttribute = ver[0] as AssemblyInformationalVersionAttribute;
|
||||
return verAttribute.InformationalVersion;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the AssemblyVersion
|
||||
var version = assembly.GetName().Version;
|
||||
var verStr = string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision);
|
||||
return verStr;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the filename matches an already loaded assembly file's name
|
||||
/// </summary>
|
||||
/// <param name="filename"></param>
|
||||
/// <returns>True if file already matches loaded assembly file.</returns>
|
||||
public static bool CheckIfAssemblyLoaded(string name)
|
||||
{
|
||||
Debug.Console(2, "Checking if assembly: {0} is loaded...", name);
|
||||
var loadedAssembly = LoadedAssemblies.FirstOrDefault(s => s.Name.Equals(name));
|
||||
|
||||
if (loadedAssembly != null)
|
||||
{
|
||||
Debug.Console(2, "Assembly already loaded.");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "Assembly not loaded.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by console command to report the currently loaded assemblies and versions
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
public static void ReportAssemblyVersions(string command)
|
||||
{
|
||||
Debug.Console(0, "Loaded Assemblies:");
|
||||
foreach (var assembly in LoadedAssemblies)
|
||||
{
|
||||
Debug.Console(0, "{0} Version: {1}", assembly.Name, assembly.Version);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves any .dll assemblies not already loaded from the plugins folder to loadedPlugins folder
|
||||
/// </summary>
|
||||
static void MoveDllAssemblies()
|
||||
{
|
||||
Debug.Console(0, "Looking for .dll assemblies from plugins folder...");
|
||||
|
||||
var pluginDi = new DirectoryInfo(_pluginDirectory);
|
||||
var pluginFiles = pluginDi.GetFiles("*.dll");
|
||||
|
||||
if (pluginFiles.Length > 0)
|
||||
{
|
||||
if (!Directory.Exists(_loadedPluginsDirectoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(_loadedPluginsDirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var pluginFile in pluginFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Console(0, "Found .dll: {0}", pluginFile.Name);
|
||||
|
||||
if (!CheckIfAssemblyLoaded(pluginFile.Name))
|
||||
{
|
||||
string filePath = string.Empty;
|
||||
|
||||
filePath = _loadedPluginsDirectoryPath + Global.DirectorySeparator + pluginFile.Name;
|
||||
|
||||
// Check if there is a previous file in the loadedPlugins directory and delete
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
Debug.Console(0, "Found existing file in loadedPlugins: {0} Deleting and moving new file to replace it", filePath);
|
||||
File.Delete(filePath);
|
||||
}
|
||||
|
||||
// Move the file
|
||||
File.Move(pluginFile.FullName, filePath);
|
||||
Debug.Console(2, "Moved {0} to {1}", pluginFile.FullName, filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Skipping assembly: {0}. There is already an assembly with that name loaded.", pluginFile.FullName);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, "Error with plugin file {0} . Exception: {1}", pluginFile.FullName, e);
|
||||
continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, "Done with .dll assemblies");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unzips each .cplz archive into the temp directory and moves any unloaded files into loadedPlugins
|
||||
/// </summary>
|
||||
static void UnzipAndMoveCplzArchives()
|
||||
{
|
||||
Debug.Console(0, "Looking for .cplz archives from plugins folder...");
|
||||
var di = new DirectoryInfo(_pluginDirectory);
|
||||
var zFiles = di.GetFiles("*.cplz");
|
||||
|
||||
if (zFiles.Length > 0)
|
||||
{
|
||||
if (!Directory.Exists(_loadedPluginsDirectoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(_loadedPluginsDirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var zfi in zFiles)
|
||||
{
|
||||
Directory.CreateDirectory(_tempDirectory);
|
||||
var tempDi = new DirectoryInfo(_tempDirectory);
|
||||
|
||||
Debug.Console(0, "Found cplz: {0}. Unzipping into temp plugins directory", zfi.Name);
|
||||
var result = CrestronZIP.Unzip(zfi.FullName, tempDi.FullName);
|
||||
Debug.Console(0, "UnZip Result: {0}", result.ToString());
|
||||
|
||||
var tempFiles = tempDi.GetFiles("*.dll");
|
||||
foreach (var tempFile in tempFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!CheckIfAssemblyLoaded(tempFile.Name))
|
||||
{
|
||||
string filePath = string.Empty;
|
||||
|
||||
filePath = _loadedPluginsDirectoryPath + Global.DirectorySeparator + tempFile.Name;
|
||||
|
||||
// Check if there is a previous file in the loadedPlugins directory and delete
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
Debug.Console(0, "Found existing file in loadedPlugins: {0} Deleting and moving new file to replace it", filePath);
|
||||
File.Delete(filePath);
|
||||
}
|
||||
|
||||
// Move the file
|
||||
File.Move(tempFile.FullName, filePath);
|
||||
Debug.Console(2, "Moved {0} to {1}", tempFile.FullName, filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Skipping assembly: {0}. There is already an assembly with that name loaded.", tempFile.FullName);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, "Assembly {0} is not a custom assembly. Exception: {1}", tempFile.FullName, e);
|
||||
continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the .cplz and the temp directory
|
||||
Directory.Delete(_tempDirectory, true);
|
||||
zfi.Delete();
|
||||
}
|
||||
|
||||
Debug.Console(0, "Done with .cplz archives");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to load the assemblies from the loadedPlugins folder
|
||||
/// </summary>
|
||||
static void LoadPluginAssemblies()
|
||||
{
|
||||
Debug.Console(0, "Loading assemblies from loadedPlugins folder...");
|
||||
var pluginDi = new DirectoryInfo(_loadedPluginsDirectoryPath);
|
||||
var pluginFiles = pluginDi.GetFiles("*.dll");
|
||||
|
||||
Debug.Console(2, "Found {0} plugin assemblies to load", pluginFiles.Length);
|
||||
|
||||
foreach (var pluginFile in pluginFiles)
|
||||
{
|
||||
var loadedAssembly = LoadAssembly(pluginFile.FullName);
|
||||
|
||||
LoadedPluginFolderAssemblies.Add(loadedAssembly);
|
||||
}
|
||||
|
||||
Debug.Console(0, "All Plugins Loaded.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Iterate the loaded assemblies and try to call the LoadPlugin method
|
||||
/// </summary>
|
||||
static void LoadCustomPluginTypes()
|
||||
{
|
||||
Debug.Console(0, "Loading Custom Plugin Types...");
|
||||
foreach (var loadedAssembly in LoadedPluginFolderAssemblies)
|
||||
{
|
||||
// iteratate this assembly's classes, looking for "LoadPlugin()" methods
|
||||
try
|
||||
{
|
||||
var assy = loadedAssembly.Assembly;
|
||||
var types = assy.GetTypes();
|
||||
foreach (var type in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
|
||||
var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin"));
|
||||
if (loadPlugin != null)
|
||||
{
|
||||
Debug.Console(2, "LoadPlugin method found in {0}", type.Name);
|
||||
|
||||
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||
|
||||
var minimumVersion = fields.FirstOrDefault(p => p.Name.Equals("MinimumEssentialsFrameworkVersion"));
|
||||
if (minimumVersion != null)
|
||||
{
|
||||
Debug.Console(2, "MinimumEssentialsFrameworkVersion found");
|
||||
|
||||
var minimumVersionString = minimumVersion.GetValue(null) as string;
|
||||
|
||||
if (!string.IsNullOrEmpty(minimumVersionString))
|
||||
{
|
||||
var passed = Global.IsRunningMinimumVersionOrHigher(minimumVersionString);
|
||||
|
||||
if (!passed)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", minimumVersionString);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", minimumVersionString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion found but not set. Loading plugin, but your mileage may vary.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion not found. Loading plugin, but your mileage may vary.");
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding plugin: {0}", loadedAssembly.Name);
|
||||
loadPlugin.Invoke(null, null);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, "Load Plugin not found. {0} is not a plugin assembly. Exception: {1}", loadedAssembly.Name, e);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, "Error Loading Assembly: {0} Exception: (1) ", loadedAssembly.Name, e);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// plugin dll will be loaded. Any classes in plugin should have a static constructor
|
||||
// that registers that class with the Core.DeviceFactory
|
||||
Debug.Console(0, "Done Loading Custom Plugin Types.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads plugins
|
||||
/// </summary>
|
||||
public static void LoadPlugins()
|
||||
{
|
||||
if (Directory.Exists(_pluginDirectory))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Plugins directory found, checking for plugins");
|
||||
|
||||
// Deal with any .dll files
|
||||
MoveDllAssemblies();
|
||||
|
||||
// Deal with any .cplz files
|
||||
UnzipAndMoveCplzArchives();
|
||||
|
||||
// Load the assemblies from the loadedPlugins folder into the AppDomain
|
||||
LoadPluginAssemblies();
|
||||
|
||||
// Load the types from any custom plugin assemblies
|
||||
LoadCustomPluginTypes();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an assembly loaded at runtime and it's associated metadata
|
||||
/// </summary>
|
||||
public class LoadedAssembly
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
public string Version { get; private set; }
|
||||
public Assembly Assembly { get; private set; }
|
||||
|
||||
public LoadedAssembly(string name, string version, Assembly assembly)
|
||||
{
|
||||
Name = name;
|
||||
Version = version;
|
||||
Assembly = assembly;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,16 +64,23 @@ namespace PepperDash.Essentials.Core.Config
|
||||
|
||||
if (configFiles != null)
|
||||
{
|
||||
Debug.Console(2, "{0} config files found matching pattern", configFiles.Length);
|
||||
|
||||
if (configFiles.Length > 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"****Error: Multiple Portal Configuration files present. Please ensure only a single file exists and reset program.****");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
else if (configFiles.Length == 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Portal config file: '{0}'", filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "No config file found.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -34,18 +34,34 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
List<Crestron.SimplSharpPro.DeviceSupport.Feedback> LinkedCrestronFeedbacks = new List<Crestron.SimplSharpPro.DeviceSupport.Feedback>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the feedback with the Func as described.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge,
|
||||
/// it will NOT reflect an actual value from a device until <seealso cref="FireUpdate"/> has been called
|
||||
/// </remarks>
|
||||
/// <param name="valueFunc">Delegate to invoke when this feedback needs to be updated</param>
|
||||
public BoolFeedback(Func<bool> valueFunc)
|
||||
: this(null, valueFunc)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the feedback with the Func as described.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge,
|
||||
/// it will NOT reflect an actual value from a device until <seealso cref="FireUpdate"/> has been called
|
||||
/// </remarks>
|
||||
/// <param name="key">Key to find this Feedback</param>
|
||||
/// <param name="valueFunc">Delegate to invoke when this feedback needs to be updated</param>
|
||||
public BoolFeedback(string key, Func<bool> valueFunc)
|
||||
: base(key)
|
||||
{
|
||||
ValueFunc = valueFunc;
|
||||
}
|
||||
|
||||
|
||||
public override void FireUpdate()
|
||||
{
|
||||
bool newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
||||
|
||||
@@ -23,11 +23,28 @@ namespace PepperDash.Essentials.Core
|
||||
Func<int> ValueFunc;
|
||||
List<UShortInputSig> LinkedInputSigs = new List<UShortInputSig>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the feedback with the Func as described.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge,
|
||||
/// it will NOT reflect an actual value from a device until <seealso cref="FireUpdate"/> has been called
|
||||
/// </remarks>
|
||||
/// <param name="valueFunc">Delegate to invoke when this feedback needs to be updated</param>
|
||||
public IntFeedback(Func<int> valueFunc)
|
||||
: this(null, valueFunc)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the feedback with the Func as described.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge,
|
||||
/// it will NOT reflect an actual value from a device until <seealso cref="FireUpdate"/> has been called
|
||||
/// </remarks>
|
||||
/// <param name="key">Key to find this Feedback</param>
|
||||
/// <param name="valueFunc">Delegate to invoke when this feedback needs to be updated</param>
|
||||
public IntFeedback(string key, Func<int> valueFunc)
|
||||
: base(key)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ using Crestron.SimplSharpPro;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
|
||||
public class StringFeedback : Feedback
|
||||
{
|
||||
public override string StringValue { get { return _StringValue; } } // ValueFunc.Invoke(); } }
|
||||
@@ -18,16 +19,33 @@ namespace PepperDash.Essentials.Core
|
||||
public string TestValue { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Evalutated on FireUpdate
|
||||
/// Evaluated on FireUpdate
|
||||
/// </summary>
|
||||
public Func<string> ValueFunc { get; private set; }
|
||||
List<StringInputSig> LinkedInputSigs = new List<StringInputSig>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the feedback with the Func as described.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge,
|
||||
/// it will NOT reflect an actual value from a device until <seealso cref="FireUpdate"/> has been called
|
||||
/// </remarks>
|
||||
/// <param name="valueFunc">Delegate to invoke when this feedback needs to be updated</param>
|
||||
public StringFeedback(Func<string> valueFunc)
|
||||
: this(null, valueFunc)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the feedback with the Func as described.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge,
|
||||
/// it will NOT reflect an actual value from a device until <seealso cref="FireUpdate"/> has been called
|
||||
/// </remarks>
|
||||
/// <param name="key">Key to find this Feedback</param>
|
||||
/// <param name="valueFunc">Delegate to invoke when this feedback needs to be updated</param>
|
||||
public StringFeedback(string key, Func<string> valueFunc)
|
||||
: base(key)
|
||||
{
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
Debug.Console(2, "Comparing running version '{0}' to minimum version '{1}'", AssemblyVersion, minimumVersion);
|
||||
|
||||
var runtimeVersion = Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*)$");
|
||||
var runtimeVersion = Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*).*");
|
||||
|
||||
var runtimeVersionMajor = Int16.Parse(runtimeVersion.Groups[1].Value);
|
||||
var runtimeVersionMinor = Int16.Parse(runtimeVersion.Groups[2].Value);
|
||||
@@ -107,7 +107,7 @@ namespace PepperDash.Essentials.Core
|
||||
// Check for beta build version
|
||||
if (runtimeVersionMajor == 0)
|
||||
{
|
||||
Debug.Console(2, "Running Beta Build. Bypassing Dependency Check.");
|
||||
Debug.Console(2, "Running Local Build. Bypassing Dependency Check.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.Diagnostics;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
@@ -19,18 +14,32 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
/// </summary>
|
||||
public class SystemMonitorController : Device
|
||||
{
|
||||
private const long UptimePollTime = 300000;
|
||||
private CTimer _uptimePollTimer;
|
||||
|
||||
private string _uptime;
|
||||
private string _lastStart;
|
||||
|
||||
public event EventHandler<EventArgs> SystemMonitorPropertiesChanged;
|
||||
|
||||
public Dictionary<uint, ProgramStatusFeedbacks> ProgramStatusFeedbackCollection;
|
||||
public Dictionary<short, EthernetStatusFeedbacks> EthernetStatusFeedbackCollection;
|
||||
|
||||
public IntFeedback TimeZoneFeedback { get; set; }
|
||||
public StringFeedback TimeZoneTextFeedback { get; set; }
|
||||
public IntFeedback TimeZoneFeedback { get; protected set; }
|
||||
public StringFeedback TimeZoneTextFeedback { get; protected set; }
|
||||
|
||||
public StringFeedback IoControllerVersionFeedback { get; protected set; }
|
||||
public StringFeedback SnmpVersionFeedback { get; protected set; }
|
||||
public StringFeedback BaCnetAppVersionFeedback { get; protected set; }
|
||||
public StringFeedback ControllerVersionFeedback { get; protected set; }
|
||||
|
||||
//new feedbacks. Issue #50
|
||||
public StringFeedback SerialNumberFeedback { get; protected set; }
|
||||
public StringFeedback ModelFeedback { get; set; }
|
||||
|
||||
public StringFeedback UptimeFeedback { get; set; }
|
||||
public StringFeedback LastStartFeedback { get; set; }
|
||||
|
||||
public StringFeedback IOControllerVersionFeedback { get; set; }
|
||||
public StringFeedback SnmpVersionFeedback { get; set; }
|
||||
public StringFeedback BACnetAppVersionFeedback { get; set; }
|
||||
public StringFeedback ControllerVersionFeedback { get; set; }
|
||||
|
||||
public SystemMonitorController(string key)
|
||||
: base(key)
|
||||
{
|
||||
@@ -38,21 +47,18 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
|
||||
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
||||
|
||||
//CrestronConsole.AddNewConsoleCommand(RefreshSystemMonitorData, "RefreshSystemMonitor", "Refreshes System Monitor Feedbacks", ConsoleAccessLevelEnum.AccessOperator);
|
||||
TimeZoneFeedback = new IntFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneNumber);
|
||||
TimeZoneTextFeedback = new StringFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneName);
|
||||
|
||||
TimeZoneFeedback = new IntFeedback(new Func<int>( () => SystemMonitor.TimeZoneInformation.TimeZoneNumber));
|
||||
TimeZoneTextFeedback = new StringFeedback(new Func<string>( () => SystemMonitor.TimeZoneInformation.TimeZoneName));
|
||||
IoControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.IOPVersion);
|
||||
SnmpVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.SNMPVersion);
|
||||
BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion);
|
||||
ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion);
|
||||
|
||||
IOControllerVersionFeedback = new StringFeedback(new Func<string>( () => SystemMonitor.VersionInformation.IOPVersion));
|
||||
SnmpVersionFeedback = new StringFeedback(new Func<string>( () => SystemMonitor.VersionInformation.SNMPVersion));
|
||||
BACnetAppVersionFeedback = new StringFeedback(new Func<string>( () => SystemMonitor.VersionInformation.BACNetVersion));
|
||||
ControllerVersionFeedback = new StringFeedback(new Func<string>( () => SystemMonitor.VersionInformation.ControlSystemVersion));
|
||||
|
||||
//var status = string.Format("System Monitor Status: \r TimeZone: {0}\rTimeZoneText: {1}\rIOControllerVersion: {2}\rSnmpAppVersionFeedback: {3}\rBACnetAppVersionFeedback: {4}\rControllerVersionFeedback: {5}",
|
||||
// SystemMonitor.TimeZoneInformation.TimeZoneNumber, SystemMonitor.TimeZoneInformation.TimeZoneName, SystemMonitor.VersionInformation.IOPVersion, SystemMonitor.VersionInformation.SNMPVersion,
|
||||
// SystemMonitor.VersionInformation.BACNetVersion, SystemMonitor.VersionInformation.ControlSystemVersion);
|
||||
|
||||
//Debug.Console(1, this, status);
|
||||
SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber);
|
||||
ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName);
|
||||
UptimeFeedback = new StringFeedback(() => _uptime);
|
||||
LastStartFeedback = new StringFeedback(()=> _lastStart);
|
||||
|
||||
ProgramStatusFeedbackCollection = new Dictionary<uint, ProgramStatusFeedbacks>();
|
||||
|
||||
@@ -62,43 +68,132 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
ProgramStatusFeedbackCollection.Add(prog.Number, program);
|
||||
}
|
||||
|
||||
SystemMonitor.ProgramChange += new ProgramStateChangeEventHandler(SystemMonitor_ProgramChange);
|
||||
SystemMonitor.TimeZoneInformation.TimeZoneChange += new TimeZoneChangeEventHandler(TimeZoneInformation_TimeZoneChange);
|
||||
CreateEthernetStatusFeedbacks();
|
||||
UpdateEthernetStatusFeeedbacks();
|
||||
|
||||
_uptimePollTimer = new CTimer(PollUptime,null,0, UptimePollTime);
|
||||
|
||||
SystemMonitor.ProgramChange += SystemMonitor_ProgramChange;
|
||||
SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange;
|
||||
CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler;
|
||||
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironmentOnProgramStatusEventHandler;
|
||||
}
|
||||
|
||||
private void CrestronEnvironmentOnProgramStatusEventHandler(eProgramStatusEventType programEventType)
|
||||
{
|
||||
if (programEventType != eProgramStatusEventType.Stopping) return;
|
||||
|
||||
_uptimePollTimer.Stop();
|
||||
_uptimePollTimer.Dispose();
|
||||
_uptimePollTimer = null;
|
||||
}
|
||||
|
||||
private void PollUptime(object obj)
|
||||
{
|
||||
var consoleResponse = string.Empty;
|
||||
|
||||
CrestronConsole.SendControlSystemCommand("uptime", ref consoleResponse);
|
||||
|
||||
ParseUptime(consoleResponse);
|
||||
|
||||
UptimeFeedback.FireUpdate();
|
||||
LastStartFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
private void ParseUptime(string response)
|
||||
{
|
||||
var splitString = response.Trim().Split('\r', '\n');
|
||||
|
||||
var lastStartRaw = splitString[2];
|
||||
var lastStartIndex = lastStartRaw.IndexOf(':');
|
||||
|
||||
_lastStart = lastStartRaw.Substring(lastStartIndex + 1).Trim();
|
||||
|
||||
var uptimeRaw = splitString[0];
|
||||
|
||||
var forIndex = uptimeRaw.IndexOf("for", StringComparison.Ordinal);
|
||||
|
||||
//4 => "for " to get what's on the right
|
||||
_uptime = uptimeRaw.Substring(forIndex + 4);
|
||||
}
|
||||
|
||||
private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs)
|
||||
{
|
||||
if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return;
|
||||
|
||||
foreach (var fb in EthernetStatusFeedbackCollection)
|
||||
{
|
||||
fb.Value.UpdateEthernetStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateEthernetStatusFeedbacks()
|
||||
{
|
||||
EthernetStatusFeedbackCollection = new Dictionary<short, EthernetStatusFeedbacks>();
|
||||
|
||||
Debug.Console(2, "Creating {0} EthernetStatusFeedbacks", InitialParametersClass.NumberOfEthernetInterfaces);
|
||||
|
||||
for (short i = 0; i < InitialParametersClass.NumberOfEthernetInterfaces; i++)
|
||||
{
|
||||
Debug.Console(2, "Creating EthernetStatusFeedback for Interface {0}", i);
|
||||
var ethernetInterface = new EthernetStatusFeedbacks(i);
|
||||
EthernetStatusFeedbackCollection.Add(i, ethernetInterface);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateEthernetStatusFeeedbacks()
|
||||
{
|
||||
foreach (var iface in EthernetStatusFeedbackCollection)
|
||||
{
|
||||
iface.Value.CurrentIpAddressFeedback.FireUpdate();
|
||||
iface.Value.CurrentSubnetMaskFeedback.FireUpdate();
|
||||
iface.Value.CurrentDefaultGatewayFeedback.FireUpdate();
|
||||
iface.Value.StaticIpAddressFeedback.FireUpdate();
|
||||
iface.Value.StaticSubnetMaskFeedback.FireUpdate();
|
||||
iface.Value.StaticDefaultGatewayFeedback.FireUpdate();
|
||||
iface.Value.HostNameFeedback.FireUpdate();
|
||||
iface.Value.DnsServerFeedback.FireUpdate();
|
||||
iface.Value.DomainFeedback.FireUpdate();
|
||||
iface.Value.DhcpStatusFeedback.FireUpdate();
|
||||
iface.Value.MacAddressFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets data in separate thread
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
void RefreshSystemMonitorData(string command)
|
||||
private void RefreshSystemMonitorData()
|
||||
{
|
||||
// this takes a while, launch a new thread
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
TimeZoneFeedback.FireUpdate();
|
||||
TimeZoneTextFeedback.FireUpdate();
|
||||
IOControllerVersionFeedback.FireUpdate();
|
||||
SnmpVersionFeedback.FireUpdate();
|
||||
BACnetAppVersionFeedback.FireUpdate();
|
||||
ControllerVersionFeedback.FireUpdate();
|
||||
|
||||
OnSystemMonitorPropertiesChanged();
|
||||
}
|
||||
);
|
||||
CrestronInvoke.BeginInvoke(UpdateFeedback);
|
||||
}
|
||||
|
||||
void OnSystemMonitorPropertiesChanged()
|
||||
private void UpdateFeedback(object o)
|
||||
{
|
||||
TimeZoneFeedback.FireUpdate();
|
||||
TimeZoneTextFeedback.FireUpdate();
|
||||
IoControllerVersionFeedback.FireUpdate();
|
||||
SnmpVersionFeedback.FireUpdate();
|
||||
BaCnetAppVersionFeedback.FireUpdate();
|
||||
ControllerVersionFeedback.FireUpdate();
|
||||
SerialNumberFeedback.FireUpdate();
|
||||
ModelFeedback.FireUpdate();
|
||||
|
||||
OnSystemMonitorPropertiesChanged();
|
||||
}
|
||||
|
||||
private void OnSystemMonitorPropertiesChanged()
|
||||
{
|
||||
var handler = SystemMonitorPropertiesChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new EventArgs());
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
RefreshSystemMonitorData(null);
|
||||
RefreshSystemMonitorData();
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
@@ -114,46 +209,41 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args)
|
||||
private void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "Program Change Detected for slot: {0}", sender.Number);
|
||||
Debug.Console(2, this, "Event Type: {0}", args.EventType);
|
||||
|
||||
var program = ProgramStatusFeedbackCollection[sender.Number];
|
||||
|
||||
if (args.EventType == eProgramChangeEventType.OperatingState)
|
||||
switch (args.EventType)
|
||||
{
|
||||
program.ProgramStartedFeedback.FireUpdate();
|
||||
program.ProgramStoppedFeedback.FireUpdate();
|
||||
|
||||
program.ProgramInfo.OperatingState = args.OperatingState;
|
||||
|
||||
//program.GetProgramInfo();
|
||||
|
||||
if (args.OperatingState == eProgramOperatingState.Start)
|
||||
program.GetProgramInfo();
|
||||
else
|
||||
{
|
||||
program.AggregatedProgramInfoFeedback.FireUpdate();
|
||||
program.OnProgramInfoChanged();
|
||||
}
|
||||
case eProgramChangeEventType.OperatingState:
|
||||
program.ProgramStartedFeedback.FireUpdate();
|
||||
program.ProgramStoppedFeedback.FireUpdate();
|
||||
program.ProgramInfo.OperatingState = args.OperatingState;
|
||||
if (args.OperatingState == eProgramOperatingState.Start)
|
||||
program.GetProgramInfo();
|
||||
else
|
||||
{
|
||||
program.AggregatedProgramInfoFeedback.FireUpdate();
|
||||
program.OnProgramInfoChanged();
|
||||
}
|
||||
break;
|
||||
case eProgramChangeEventType.RegistrationState:
|
||||
program.ProgramRegisteredFeedback.FireUpdate();
|
||||
program.ProgramUnregisteredFeedback.FireUpdate();
|
||||
program.ProgramInfo.RegistrationState = args.RegistrationState;
|
||||
program.GetProgramInfo();
|
||||
break;
|
||||
}
|
||||
else if (args.EventType == eProgramChangeEventType.RegistrationState)
|
||||
{
|
||||
program.ProgramRegisteredFeedback.FireUpdate();
|
||||
program.ProgramUnregisteredFeedback.FireUpdate();
|
||||
|
||||
program.ProgramInfo.RegistrationState = args.RegistrationState;
|
||||
|
||||
program.GetProgramInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Responds to time zone changes and updates the appropriate feedbacks
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args)
|
||||
private void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "Time Zone Change Detected.");
|
||||
TimeZoneFeedback.FireUpdate();
|
||||
@@ -162,6 +252,121 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
OnSystemMonitorPropertiesChanged();
|
||||
}
|
||||
|
||||
public class EthernetStatusFeedbacks
|
||||
{
|
||||
public StringFeedback HostNameFeedback { get; protected set; }
|
||||
public StringFeedback DnsServerFeedback { get; protected set; }
|
||||
public StringFeedback DomainFeedback { get; protected set; }
|
||||
public StringFeedback MacAddressFeedback { get; protected set; }
|
||||
public StringFeedback DhcpStatusFeedback { get; protected set; }
|
||||
|
||||
public StringFeedback CurrentIpAddressFeedback { get; protected set; }
|
||||
public StringFeedback CurrentSubnetMaskFeedback { get; protected set; }
|
||||
public StringFeedback CurrentDefaultGatewayFeedback { get; protected set; }
|
||||
|
||||
public StringFeedback StaticIpAddressFeedback { get; protected set; }
|
||||
public StringFeedback StaticSubnetMaskFeedback { get; protected set; }
|
||||
public StringFeedback StaticDefaultGatewayFeedback { get; protected set; }
|
||||
|
||||
public EthernetStatusFeedbacks(short adapterIndex)
|
||||
{
|
||||
Debug.Console(2, "Ethernet Information for interface {0}", adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} Hostname: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex), adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} Current IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex), adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} Current Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex), adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} Current Router: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex), adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} Static IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPADDRESS, adapterIndex), adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} Static Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPMASK, adapterIndex), adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} Static Router: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_ROUTER, adapterIndex), adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} DNS Servers: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex), adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} DHCP State: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex), adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} Domain Name: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex), adapterIndex);
|
||||
Debug.Console(2, "Adapter Index: {1} MAC Address: {0}", CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex), adapterIndex);
|
||||
HostNameFeedback =
|
||||
new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex));
|
||||
|
||||
CurrentIpAddressFeedback =
|
||||
new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex));
|
||||
CurrentDefaultGatewayFeedback =
|
||||
new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex));
|
||||
CurrentSubnetMaskFeedback =
|
||||
new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex));
|
||||
StaticIpAddressFeedback =
|
||||
new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex));
|
||||
StaticDefaultGatewayFeedback =
|
||||
new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex));
|
||||
StaticSubnetMaskFeedback =
|
||||
new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex));
|
||||
DomainFeedback =
|
||||
new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex));
|
||||
DnsServerFeedback =
|
||||
new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex));
|
||||
MacAddressFeedback =
|
||||
new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex));
|
||||
|
||||
DhcpStatusFeedback = new StringFeedback(
|
||||
() =>
|
||||
CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex));
|
||||
}
|
||||
|
||||
public void UpdateEthernetStatus()
|
||||
{
|
||||
HostNameFeedback.FireUpdate();
|
||||
CurrentIpAddressFeedback.FireUpdate();
|
||||
CurrentSubnetMaskFeedback.FireUpdate();
|
||||
CurrentDefaultGatewayFeedback.FireUpdate();
|
||||
StaticIpAddressFeedback.FireUpdate();
|
||||
StaticSubnetMaskFeedback.FireUpdate();
|
||||
StaticDefaultGatewayFeedback.FireUpdate();
|
||||
DomainFeedback.FireUpdate();
|
||||
DnsServerFeedback.FireUpdate();
|
||||
MacAddressFeedback.FireUpdate();
|
||||
DhcpStatusFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ProgramStatusFeedbacks
|
||||
{
|
||||
@@ -192,17 +397,19 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
ProgramInfo.OperatingState = Program.OperatingState;
|
||||
ProgramInfo.RegistrationState = Program.RegistrationState;
|
||||
|
||||
ProgramStartedFeedback = new BoolFeedback(new Func<bool>( () => Program.OperatingState == eProgramOperatingState.Start));
|
||||
ProgramStoppedFeedback = new BoolFeedback(new Func<bool>( () => Program.OperatingState == eProgramOperatingState.Stop));
|
||||
ProgramRegisteredFeedback = new BoolFeedback(new Func<bool>( () => Program.RegistrationState == eProgramRegistrationState.Register));
|
||||
ProgramUnregisteredFeedback = new BoolFeedback(new Func<bool>( () => Program.RegistrationState == eProgramRegistrationState.Unregister));
|
||||
ProgramStartedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Start);
|
||||
ProgramStoppedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Stop);
|
||||
ProgramRegisteredFeedback =
|
||||
new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Register);
|
||||
ProgramUnregisteredFeedback =
|
||||
new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister);
|
||||
|
||||
ProgramNameFeedback = new StringFeedback(new Func<string>(() => ProgramInfo.ProgramFile));
|
||||
ProgramCompileTimeFeedback = new StringFeedback(new Func<string>(() => ProgramInfo.CompileTime));
|
||||
CrestronDataBaseVersionFeedback = new StringFeedback(new Func<string>(() => ProgramInfo.CrestronDB));
|
||||
EnvironmentVersionFeedback = new StringFeedback(new Func<string>(() => ProgramInfo.Environment));
|
||||
ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile);
|
||||
ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime);
|
||||
CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb);
|
||||
EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment);
|
||||
|
||||
AggregatedProgramInfoFeedback = new StringFeedback(new Func<string>(() => JsonConvert.SerializeObject(ProgramInfo)));
|
||||
AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo));
|
||||
|
||||
GetProgramInfo();
|
||||
}
|
||||
@@ -212,74 +419,99 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
/// </summary>
|
||||
public void GetProgramInfo()
|
||||
{
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
CrestronInvoke.BeginInvoke(GetProgramInfo);
|
||||
}
|
||||
|
||||
private void GetProgramInfo(object o)
|
||||
{
|
||||
Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number);
|
||||
|
||||
string response = null;
|
||||
|
||||
if (Program.RegistrationState == eProgramRegistrationState.Unregister || Program.OperatingState == eProgramOperatingState.Stop)
|
||||
{
|
||||
Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number);
|
||||
Debug.Console(2, "Program {0} not registered. Setting default values for program information.",
|
||||
Program.Number);
|
||||
|
||||
string response = null;
|
||||
|
||||
var success = CrestronConsole.SendControlSystemCommand(string.Format("progcomments:{0}", Program.Number), ref response);
|
||||
|
||||
if (success)
|
||||
ProgramInfo = new ProgramInfo(Program.Number)
|
||||
{
|
||||
//Debug.Console(2, "Progcomments Response: \r{0}", response);
|
||||
OperatingState = Program.OperatingState,
|
||||
RegistrationState = Program.RegistrationState
|
||||
};
|
||||
|
||||
if (!response.ToLower().Contains("bad or incomplete"))
|
||||
{
|
||||
// Shared properteis
|
||||
ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n");
|
||||
ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n");
|
||||
ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n");
|
||||
ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
var success = CrestronConsole.SendControlSystemCommand(
|
||||
string.Format("progcomments:{0}", Program.Number), ref response);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number);
|
||||
UpdateFeedbacks();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ProgramInfo.ProgramFile.Contains(".dll"))
|
||||
{
|
||||
// SSP Program
|
||||
ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n");
|
||||
ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n");
|
||||
ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n");
|
||||
ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ", "\n");
|
||||
ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n");
|
||||
}
|
||||
else if (ProgramInfo.ProgramFile.Contains(".smw"))
|
||||
{
|
||||
// SIMPL Windows Program
|
||||
ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n");
|
||||
ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n");
|
||||
ProgramInfo.CrestronDB = ParseConsoleData(response, "CrestronDB", ": ", "\n");
|
||||
ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n");
|
||||
ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n");
|
||||
if (response.ToLower().Contains("bad or incomplete"))
|
||||
{
|
||||
Debug.Console(2,
|
||||
"Program in slot {0} not running. Setting default ProgramInfo for slot: {0}",
|
||||
Program.Number);
|
||||
|
||||
}
|
||||
//Debug.Console(2, "ProgramInfo: \r{0}", JsonConvert.SerializeObject(ProgramInfo));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "Bad or incomplete console command response. Initializing ProgramInfo for slot: {0}", Program.Number);
|
||||
|
||||
// Assume no valid program info. Constructing a new object will wipe all properties
|
||||
ProgramInfo = new ProgramInfo(Program.Number);
|
||||
|
||||
ProgramInfo.OperatingState = Program.OperatingState;
|
||||
ProgramInfo.RegistrationState = Program.RegistrationState;
|
||||
}
|
||||
}
|
||||
else
|
||||
// Assume no valid program info. Constructing a new object will wipe all properties
|
||||
ProgramInfo = new ProgramInfo(Program.Number)
|
||||
{
|
||||
Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number);
|
||||
}
|
||||
OperatingState = Program.OperatingState,
|
||||
RegistrationState = Program.RegistrationState
|
||||
};
|
||||
|
||||
ProgramNameFeedback.FireUpdate();
|
||||
ProgramCompileTimeFeedback.FireUpdate();
|
||||
CrestronDataBaseVersionFeedback.FireUpdate();
|
||||
EnvironmentVersionFeedback.FireUpdate();
|
||||
UpdateFeedbacks();
|
||||
|
||||
AggregatedProgramInfoFeedback.FireUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
OnProgramInfoChanged();
|
||||
});
|
||||
|
||||
// Shared properteis
|
||||
ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n");
|
||||
ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n");
|
||||
ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n");
|
||||
ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n");
|
||||
|
||||
|
||||
if (ProgramInfo.ProgramFile.Contains(".dll"))
|
||||
{
|
||||
// SSP Program
|
||||
ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n");
|
||||
ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n");
|
||||
ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n");
|
||||
ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ",
|
||||
"\n");
|
||||
ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n");
|
||||
}
|
||||
else if (ProgramInfo.ProgramFile.Contains(".smw"))
|
||||
{
|
||||
// SIMPL Windows Program
|
||||
ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n");
|
||||
ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n");
|
||||
ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n");
|
||||
ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n");
|
||||
ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n");
|
||||
}
|
||||
Debug.Console(2, "Program info for slot {0} successfully updated", Program.Number);
|
||||
|
||||
UpdateFeedbacks();
|
||||
}
|
||||
|
||||
private void UpdateFeedbacks()
|
||||
{
|
||||
ProgramNameFeedback.FireUpdate();
|
||||
ProgramCompileTimeFeedback.FireUpdate();
|
||||
CrestronDataBaseVersionFeedback.FireUpdate();
|
||||
EnvironmentVersionFeedback.FireUpdate();
|
||||
|
||||
AggregatedProgramInfoFeedback.FireUpdate();
|
||||
|
||||
OnProgramInfoChanged();
|
||||
}
|
||||
|
||||
public void OnProgramInfoChanged()
|
||||
@@ -294,30 +526,28 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
|
||||
private string ParseConsoleData(string data, string line, string startString, string endString)
|
||||
{
|
||||
string outputData = "";
|
||||
var outputData = "";
|
||||
|
||||
if (data.Length > 0)
|
||||
if (data.Length <= 0) return outputData;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
//Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString);
|
||||
var linePosition = data.IndexOf(line);
|
||||
var startPosition = data.IndexOf(startString, linePosition) + startString.Length;
|
||||
var endPosition = data.IndexOf(endString, startPosition);
|
||||
outputData = data.Substring(startPosition, endPosition - startPosition).Trim();
|
||||
//Debug.Console(2, "ParseConsoleData Return: {0}", outputData);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, "Error Parsing Console Data:\r{0}", e);
|
||||
}
|
||||
//Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString);
|
||||
var linePosition = data.IndexOf(line, StringComparison.Ordinal);
|
||||
var startPosition = data.IndexOf(startString, linePosition, StringComparison.Ordinal) +
|
||||
startString.Length;
|
||||
var endPosition = data.IndexOf(endString, startPosition, StringComparison.Ordinal);
|
||||
outputData = data.Substring(startPosition, endPosition - startPosition).Trim();
|
||||
//Debug.Console(2, "ParseConsoleData Return: {0}", outputData);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, "Error Parsing Console Data:\r{0}", e);
|
||||
}
|
||||
|
||||
return outputData;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -330,32 +560,39 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
[JsonProperty("programNumber")]
|
||||
public uint ProgramNumber { get; private set; }
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonConverter(typeof (StringEnumConverter))]
|
||||
[JsonProperty("operatingState")]
|
||||
public eProgramOperatingState OperatingState { get; set; }
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonConverter(typeof (StringEnumConverter))]
|
||||
[JsonProperty("registrationState")]
|
||||
public eProgramRegistrationState RegistrationState { get; set; }
|
||||
|
||||
[JsonProperty("programFile")]
|
||||
public string ProgramFile { get; set; }
|
||||
|
||||
[JsonProperty("friendlyName")]
|
||||
public string FriendlyName { get; set; }
|
||||
|
||||
[JsonProperty("compilerRevision")]
|
||||
public string CompilerRevision { get; set; }
|
||||
|
||||
[JsonProperty("compileTime")]
|
||||
public string CompileTime { get; set; }
|
||||
|
||||
[JsonProperty("include4Dat")]
|
||||
public string Include4Dat { get; set; }
|
||||
|
||||
// SIMPL Windows properties
|
||||
[JsonProperty("systemName")]
|
||||
public string SystemName { get; set; }
|
||||
|
||||
[JsonProperty("crestronDb")]
|
||||
public string CrestronDB { get; set; }
|
||||
public string CrestronDb { get; set; }
|
||||
|
||||
[JsonProperty("environment")]
|
||||
public string Environment { get; set; }
|
||||
|
||||
[JsonProperty("programmer")]
|
||||
public string Programmer { get; set; }
|
||||
|
||||
@@ -363,10 +600,13 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
// SSP Properties
|
||||
[JsonProperty("applicationName")]
|
||||
public string ApplicationName { get; set; }
|
||||
|
||||
[JsonProperty("programTool")]
|
||||
public string ProgramTool { get; set; }
|
||||
|
||||
[JsonProperty("minFirmwareVersion")]
|
||||
public string MinFirmwareVersion { get; set; }
|
||||
|
||||
[JsonProperty("plugInVersion")]
|
||||
public string PlugInVersion { get; set; }
|
||||
|
||||
@@ -381,7 +621,7 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
Include4Dat = "";
|
||||
|
||||
SystemName = "";
|
||||
CrestronDB = "";
|
||||
CrestronDb = "";
|
||||
Environment = "";
|
||||
Programmer = "";
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
</Reference>
|
||||
<Reference Include="SimplSharpReflectionInterface, Version=1.0.5583.25238, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath>
|
||||
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
||||
Reference in New Issue
Block a user