Compare commits

...

34 commits

Author SHA1 Message Date
Jason DeVito
2586e9502d
Create essentialsplugins-betabuilds-caller.yml 2023-09-26 08:57:39 -05:00
Andrew Welker
0746d309df
Merge pull request #19 from PepperDash/feature/Conditional-Workflows
Multiple Style and Workflow Updates
2022-07-22 11:06:34 -06:00
Trevor Payne
259a71c562 style: renamed classes for consistency
build: updated essentials version

ci: updated workflows

docs: documentation updated

ci: updated nuspec
2022-07-21 12:07:27 -05:00
Trevor Payne
62f959bb25 test workflow syntax 2022-07-21 10:17:56 -05:00
Trevor Payne
62912451e8 fix: Workflow Syntax 2022-07-20 22:15:48 -05:00
Trevor Payne
ee057ad361 fix: Workflow Syntax 2022-07-20 21:47:09 -05:00
Trevor Payne
af7e9ae659 fix: Workflow Syntax 2022-07-20 21:03:26 -05:00
Trevor Payne
f08741efd6 fix: Workflow Syntax 2022-07-20 20:32:42 -05:00
Trevor Payne
1add0c193c fix: Workflow Syntax 2022-07-20 18:34:20 -05:00
Trevor Payne
3d57ac3560 fix: Workflow Syntax 2022-07-20 18:18:07 -05:00
Trevor Payne
856178d920 fix: Workflow Syntax 2022-07-20 17:53:48 -05:00
Trevor Payne
87872b78e2 fix: Workflow Syntax 2022-07-20 17:29:57 -05:00
Trevor Payne
266bf187d9 fix: Workflow Syntax 2022-07-20 17:15:39 -05:00
Trevor Payne
592400cc90 fix: Workflow Syntax 2022-07-20 17:12:21 -05:00
Trevor Payne
baaf7c4a28 fix: Workflow Syntax 2022-07-20 17:11:15 -05:00
Trevor Payne
57a265d27f Made names of classes more consistent internally
Removed obsolete references
2022-07-20 16:48:50 -05:00
Trevor Payne
0cf654ce2d Selective Nuget Package publish 2022-07-20 16:42:25 -05:00
Jason Alborough
24b02b199d Merge branch 'hotfix/Fix-Build-Actions' of https://github.com/PepperDash/EssentialsPluginTemplate into hotfix/Fix-Build-Actions 2022-07-15 14:06:16 -04:00
Jason Alborough
91ff0d8c83 nuspec-TEMPLATE
fix: #17 changes nuspec to nuspec-TEMPALTE
feature: adds brief configuration instructions for nuspec file to readme
2022-07-15 14:06:00 -04:00
Trevor Payne
3b7ddac369 fix: improper CSProj name in solution 2022-07-15 11:48:33 -05:00
Trevor Payne
fcbf710781 fix: updated AssemblyInfo copyright date 2022-07-13 12:30:15 -05:00
Trevor Payne
2ff646e499 fix: updated github workflows 2022-07-13 12:18:08 -05:00
Trevor Payne
c323b982ae fix: added nuspec file 2022-07-13 12:13:15 -05:00
Trevor Payne
d46444e424 fix: update essentials reference to latest 2022-07-13 12:10:03 -05:00
Andrew Welker
6541856958
Merge pull request #15 from PepperDash/feature/add-plugin-request-template
Update issue templates
2021-02-25 12:58:59 -07:00
Andrew Welker
710642bde5 Update issue templates 2021-02-25 12:12:14 -07:00
Neil Dorin
587a647d27
Merge pull request #14 from PepperDash/feature/add-genericqueue-example
Feature/add genericqueue example
2021-02-05 14:02:32 -07:00
Neil Dorin
6fb86d82c8 removes deprecated set-env from build script 2021-02-05 13:43:28 -07:00
Neil Dorin
4143783d2e Adds example of GenericQueue on EssentialsPluginTemplateDevice and updates dependency version to 1.7.5 2021-02-05 10:57:39 -07:00
Andrew Welker
dc0b129277
Merge pull request #13 from PepperDash/feature/clarify-device-creation-cases
Clarify device creation cases
2020-09-30 16:35:58 -06:00
Neil Dorin
26d0497362 Updates readme documentation 2020-09-30 14:18:43 -06:00
Neil Dorin
114d3af162 Adds new classes as examples of the three primary types of device (logic, crestron and third party) 2020-09-30 14:01:59 -06:00
Andrew Welker
fdf989c472
Merge pull request #11 from PepperDash/feature/fix-generate-version-number
Fix GenerateVersionNumber.ps1
2020-09-16 16:33:51 -06:00
Andrew Welker
ca893bf07b
Fix GenerateVersionNumber.ps1 2020-09-16 15:45:20 -06:00
26 changed files with 1672 additions and 849 deletions

View file

@ -0,0 +1,17 @@
---
name: Essentials Plugin Request
about: Request an Essentials Plugin
title: "[REQUEST] - "
labels: plugin request
assignees: ''
---
** Describe the Plugin **
What do you want the plugin to do? Is it for a specific device? If it's for a specific device, include the manufacturer and model, along with links to API documentation if available.
** Does it need to be available in SIMPL Windows? **
If it does, describe the functionality that should be exposed to SIMPL Windows via EISC. This may include an example join map, or other way of documenting the layout of the EISC.
** Additional Features or functionality **
Describe additional features or functionality that this plugin should have.

View file

@ -7,7 +7,8 @@ Foreach ($version in $latestVersions) {
$latestVersion = $version $latestVersion = $version
Write-Host "Setting latest version to: $latestVersion" Write-Host "Setting latest version to: $latestVersion"
} }
} catch { }
catch {
Write-Host "Unable to convert $($version). Skipping" Write-Host "Unable to convert $($version). Skipping"
continue; continue;
} }
@ -18,21 +19,27 @@ $phase = ""
$newVersionString = "" $newVersionString = ""
switch -regex ($Env:GITHUB_REF) { switch -regex ($Env:GITHUB_REF) {
'^refs\/heads\/main*.' { '^refs\/heads\/main*.' {
$newVersionString = "{0}.{1}.{2}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1) $newVersionString = "{0}.{1}.{2}" -f $newVersion.Major, $newVersion.Minor, $newVersion.Build
} }
'^refs\/heads\/feature\/*.' { '^refs\/heads\/feature\/*.' {
$phase = 'alpha' $phase = 'alpha'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
} }
'^refs\/heads\/release\/*.' { '^refs\/heads\/release\/*.' {
$splitRef = $Env:GITHUB_REF -split "/"
$version = [version]($splitRef[-1] -replace "v", "")
$phase = 'rc' $phase = 'rc'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $version.Major, $version.Minor, $version.Build, $phase, $Env:GITHUB_RUN_NUMBER
} }
'^refs\/heads\/development*.' { '^refs\/heads\/dev*.' {
$phase = 'beta' $phase = 'beta'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
} }
'^refs\/heads\/hotfix\/*.' { '^refs\/heads\/hotfix\/*.' {
$phase = 'hotfix' $phase = 'hotfix'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
} }
} }
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
Write-Output $newVersionString Write-Output $newVersionString

View file

@ -10,7 +10,7 @@ Get-ChildItem ($destination)
$exclusions = @(git submodule foreach --quiet 'echo $name') $exclusions = @(git submodule foreach --quiet 'echo $name')
# Trying to get any .json schema files (not currently working) # Trying to get any .json schema files (not currently working)
# Gets any files with the listed extensions. # Gets any files with the listed extensions.
Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz" | ForEach-Object { Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.cplz" | ForEach-Object {
$allowed = $true; $allowed = $true;
# Exclude any files in submodules # Exclude any files in submodules
foreach ($exclude in $exclusions) { foreach ($exclude in $exclusions) {
@ -36,6 +36,7 @@ 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 -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force
} }
} }
Get-ChildItem -Path $destination\*.cplz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" }
Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force
Write-Host "Output Contents post Zip" Write-Host "Output Contents post Zip"
Get-ChildItem -Path $destination Get-ChildItem -Path $destination

View file

@ -1,103 +0,0 @@
name: Branch Build Using Docker
on:
push:
branches:
- feature/*
- hotfix/*
- release/*
- main
- development
env:
# solution path doesn't need slashes unless there it is multiple folders deep
# solution name does not include extension. .sln is assumed
SOLUTION_PATH: PDT.EssentialsPluginTemplate.EPI
SOLUTION_FILE: PDT.EssentialsPluginTemplate.EPI
# Do not edit this, we're just creating it here
VERSION: 0.0.0-buildtype-buildnumber
# Defaults to debug for build type
BUILD_TYPE: Debug
# Defaults to main as the release branch. Change as necessary
RELEASE_BRANCH: main
jobs:
Build_Project:
runs-on: windows-latest
steps:
# First we checkout the source repo
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
# And any submodules
- name: Checkout submodules
shell: bash
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
# Set the BUILD_TYPE environment variable
- name: Set Build to Release if triggered from main
run: |
if("$($Env:GITHUB_REF)".contains("$($Env:RELEASE_BRANCH)")) {
Write-Host "Setting build type to Release"
Write-Output "::set-env name=BUILD_TYPE::Release"
}
# Fetch all tags
- name: Fetch tags
run: git fetch --tags
# Generate the appropriate version number
- name: Set Version Number
shell: powershell
run: |
$version = ./.github/scripts/GenerateVersionNumber.ps1
Write-Output "::set-env name=VERSION::$version"
# Use the version number to set the version of the assemblies
- name: Update AssemblyInfo.cs
shell: powershell
run: |
Write-Output ${{ env.VERSION }}
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
- name: restore Nuget Packages
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
- name: Login to Docker
uses: azure/docker-login@v1
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
# Build the solutions in the docker image
- name: Build Solution
shell: powershell
run: |
Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_PATH)\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
# Zip up the output files as needed
- name: Zip Build Output
shell: powershell
run: ./.github/scripts/ZipBuildOutput.ps1
- name: Upload Build Output
uses: actions/upload-artifact@v1
with:
name: Build
path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
# Create the release on the source repo
- name: Create Release
id: create_release
uses: actions/create-release@v1
with:
tag_name: ${{ env.VERSION }}
release_name: ${{ env.VERSION }}
prerelease: ${{contains('debug', env.BUILD_TYPE)}}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Upload the build package to the release
- name: Upload Release Package
id: upload_release
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
asset_content_type: application/zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -0,0 +1,22 @@
name: Beta Build
on:
push:
branches-ignore:
- "main"
workflow_dispatch:
inputs:
branch:
description: 'Branch to build'
required: true
type: string
jobs:
call-workflow:
uses: PepperDash/workflow-templates/.github/workflows/essentialsplugins-builds.yml@main
secrets: inherit
with:
branch: ${{ github.ref_name }}
default-branch: "main"

View file

@ -0,0 +1,279 @@
name: Branch Build Using Docker
on:
push:
branches:
- feature/*
- hotfix/*
- release/*
- dev*
env:
# Do not edit this, we're just creating it here
VERSION: 0.0.0-buildtype-buildnumber
# Defaults to debug for build type
BUILD_TYPE: Debug
# Defaults to master as the release branch. Change as necessary
RELEASE_BRANCH: main
jobs:
Build_Project:
runs-on: windows-2019
steps:
# First we checkout the source repo
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
# Fetch all tags
- name: Fetch tags
run: git fetch --tags
# Generate the appropriate version number
- name: Set Version Number
shell: powershell
run: |
$latestVersions = $(git tag --merged origin/main)
$latestVersion = [version]"0.0.0"
Foreach ($version in $latestVersions) {
Write-Host $version
try {
if (([version]$version) -ge $latestVersion) {
$latestVersion = $version
Write-Host "Setting latest version to: $latestVersion"
}
}
catch {
Write-Host "Unable to convert $($version). Skipping"
continue;
}
}
$newVersion = [version]$latestVersion
$phase = ""
$newVersionString = ""
switch -regex ($Env:GITHUB_REF) {
'^refs\/heads\/main*.' {
$newVersionString = "{0}.{1}.{2}" -f $newVersion.Major, $newVersion.Minor, $newVersion.Build
}
'^refs\/heads\/feature\/*.' {
$phase = 'alpha'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/release\/*.' {
$splitRef = $Env:GITHUB_REF -split "/"
$version = [version]($splitRef[-1] -replace "v", "")
$phase = 'rc'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $version.Major, $version.Minor, $version.Build, $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/dev*.' {
$phase = 'beta'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/hotfix\/*.' {
$phase = 'hotfix'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
}
}
echo "VERSION=$newVersionString" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Use the version number to set the version of the assemblies
- name: Update AssemblyInfo.cs
shell: powershell
run: |
function Update-SourceVersion {
Param ([string]$Version)
#$fullVersion = $Version
$baseVersion = [regex]::Match($Version, "(\d+.\d+.\d+).*").captures.groups[1].value
$NewAssemblyVersion = 'AssemblyVersion("' + $baseVersion + '.*")'
Write-Output "AssemblyVersion = $NewAssemblyVersion"
$NewAssemblyInformationalVersion = 'AssemblyInformationalVersion("' + $Version + '")'
Write-Output "AssemblyInformationalVersion = $NewAssemblyInformationalVersion"
foreach ($o in $input) {
Write-output $o.FullName
$TmpFile = $o.FullName + ".tmp"
get-content $o.FullName |
ForEach-Object {
$_ -replace 'AssemblyVersion\(".*"\)', $NewAssemblyVersion } |
ForEach-Object {
$_ -replace 'AssemblyInformationalVersion\(".*"\)', $NewAssemblyInformationalVersion
} > $TmpFile
move-item $TmpFile $o.FullName -force
}
}
function Update-AllAssemblyInfoFiles ( $version ) {
foreach ($file in "AssemblyInfo.cs", "AssemblyInfo.vb" ) {
get-childitem -Path $Env:GITHUB_WORKSPACE -recurse | Where-Object { $_.Name -eq $file } | Update-SourceVersion $version ;
}
}
# validate arguments
$r = [System.Text.RegularExpressions.Regex]::Match($Env:VERSION, "\d+\.\d+\.\d+.*");
if ($r.Success) {
Write-Output "Updating Assembly Version to $Env:VERSION ...";
Update-AllAssemblyInfoFiles $Env:VERSION;
}
else {
Write-Output " ";
Write-Output "Error: Input version $Env:VERSION does not match x.y.z format!"
Write-Output " ";
Write-Output "Unable to apply version to AssemblyInfo.cs files";
}
- name: restore Nuget Packages
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
# Set the SOLUTION_PATH
- name: Get SLN Path
shell: powershell
run: |
$solution_path = Get-ChildItem *.sln -recurse
$solution_path = $solution_path.FullName
$solution_path = $solution_path -replace "(?:[^\\]*\\){4}", ""
Write-Output $solution_path
echo "SOLUTION_PATH=$($solution_path)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Set the SOLUTION_FILE
- name: Get SLN File
shell: powershell
run: |
$solution_file = Get-ChildItem .\*.sln -recurse -Path "$($Env:GITHUB_WORKSPACE)"
echo "SOLUTION_FILE=$($solution_file.BaseName)"| Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Login to Docker
- name: Login to Docker
uses: azure/docker-login@v1
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
# Build the solutions in the docker image
- name: Build Solution
shell: powershell
run: |
Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_PATH)"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
# Zip up the output files as needed
- name: Zip Build Output
shell: powershell
run: |
$destination = "$($Env:GITHUB_HOME)\output"
New-Item -ItemType Directory -Force -Path ($destination)
Get-ChildItem ($destination)
$exclusions = "packages"
# Trying to get any .json schema files (not currently working)
# Gets any files with the listed extensions.
Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.nuspec", "*.md" | ForEach-Object {
$allowed = $true;
# Exclude any files in submodules
foreach ($exclude in $exclusions) {
if ((Split-Path $_.FullName -Parent).contains("$($exclude)")) {
$allowed = $false;
break;
}
}
if ($allowed) {
Write-Host "allowing $($_)"
$_;
}
} | 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 {
# 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:"
Write-Host $filenames
if ($filenames.length -gt 0) {
# Attempt to get the files and return them to the output directory
Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force
}
}
Get-ChildItem -Path $destination\*.cplz | 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
# 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 output files
- 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
# Create the release on the source repo
- name: Create Release
id: create_release
uses: fleskesvor/create-release@feature/support-target-commitish
with:
tag_name: ${{ env.VERSION }}
release_name: ${{ env.VERSION }}
prerelease: ${{contains('debug', env.BUILD_TYPE)}}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Upload the build package to the release
- name: Upload Release Package
id: upload_release
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
asset_content_type: application/zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Push_Nuget_Package:
needs: Build_Project
runs-on: windows-2019
steps:
- name: Download Build Version Info
uses: actions/download-artifact@v1
with:
name: Version
- name: Set Version Number
shell: powershell
run: |
Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version"
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- 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
- name: Get nuget File
shell: powershell
run: |
$nuspec_file = (Get-ChildItem *.nuspec -recurse).BaseName
echo "NUSPEC_FILE=$($nuspec_file)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Pulls the nuget builder packages
- name: Add nuget.exe
if: "!contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')"
uses: nuget/setup-nuget@v1
# Creating nuget Packages
- name: Add Github Packages source
if: "!contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')"
run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username Pepperdash -password ${{ secrets.GITHUB_TOKEN }}
- name: Create nuget package
if: "!contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')"
run: nuget pack "./${{ env.NUSPEC_FILE}}.nuspec" -version ${{ env.VERSION }}
# Pushes to internal github registry
- name: Publish nuget package to Github registry
if: "!contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')"
run: nuget push **/*.nupkg -source github
# Pushes to nuget gallery
- name: Add nuget.org API Key
if: github.repository_owner == 'PepperDash' && github.repository_visibility == 'public' && !contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')
run: nuget setApiKey ${{ secrets.NUGET_API_KEY }}
- name: Publish nuget package to nuget.org
if: github.repository_owner == 'PepperDash' && github.repository_visibility == 'public' && !contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json

View file

@ -0,0 +1,227 @@
name: Main Build using Docker
on:
release:
types:
- released
branches:
- main
env:
# Do not edit this, we're just creating it here
VERSION: 0.0.0-buildtype-buildnumber
# Defaults to debug for build type
BUILD_TYPE: Debug
# Defaults to master as the release branch. Change as necessary
RELEASE_BRANCH: main
jobs:
Build_Project:
runs-on: windows-2019
steps:
# First we checkout the source repo
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
# Fetch all tags
- name: Fetch tags
run: git fetch --tags
# Generate the appropriate version number
- name: Set Version Number
shell: powershell
env:
TAG_NAME: ${{ github.event.release.tag_name }}
run: echo "VERSION=$($Env:TAG_NAME)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Use the version number to set the version of the assemblies
- name: Update AssemblyInfo.cs
shell: powershell
run: |
function Update-SourceVersion {
Param ([string]$Version)
#$fullVersion = $Version
$baseVersion = [regex]::Match($Version, "(\d+.\d+.\d+).*").captures.groups[1].value
$NewAssemblyVersion = 'AssemblyVersion("' + $baseVersion + '.*")'
Write-Output "AssemblyVersion = $NewAssemblyVersion"
$NewAssemblyInformationalVersion = 'AssemblyInformationalVersion("' + $Version + '")'
Write-Output "AssemblyInformationalVersion = $NewAssemblyInformationalVersion"
foreach ($o in $input) {
Write-output $o.FullName
$TmpFile = $o.FullName + ".tmp"
get-content $o.FullName |
ForEach-Object {
$_ -replace 'AssemblyVersion\(".*"\)', $NewAssemblyVersion } |
ForEach-Object {
$_ -replace 'AssemblyInformationalVersion\(".*"\)', $NewAssemblyInformationalVersion
} > $TmpFile
move-item $TmpFile $o.FullName -force
}
}
function Update-AllAssemblyInfoFiles ( $version ) {
foreach ($file in "AssemblyInfo.cs", "AssemblyInfo.vb" ) {
get-childitem -Path $Env:GITHUB_WORKSPACE -recurse | Where-Object { $_.Name -eq $file } | Update-SourceVersion $version ;
}
}
# validate arguments
$r = [System.Text.RegularExpressions.Regex]::Match($Env:VERSION, "\d+\.\d+\.\d+.*");
if ($r.Success) {
Write-Output "Updating Assembly Version to $Env:VERSION ...";
Update-AllAssemblyInfoFiles $Env:VERSION;
}
else {
Write-Output " ";
Write-Output "Error: Input version $Env:VERSION does not match x.y.z format!"
Write-Output " ";
Write-Output "Unable to apply version to AssemblyInfo.cs files";
}
- name: restore Nuget Packages
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
# Set the SOLUTION_PATH
- name: Get SLN Path
shell: powershell
run: |
$solution_path = Get-ChildItem *.sln -recurse
$solution_path = $solution_path.FullName
$solution_path = $solution_path -replace "(?:[^\\]*\\){4}", ""
Write-Output $solution_path
echo "SOLUTION_PATH=$($solution_path)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Set the SOLUTION_FILE
- name: Get SLN File
shell: powershell
run: |
$solution_file = Get-ChildItem .\*.sln -recurse -Path "$($Env:GITHUB_WORKSPACE)"
echo "SOLUTION_FILE=$($solution_file.BaseName)"| Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Login to Docker
- name: Login to Docker
uses: azure/docker-login@v1
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
# Build the solutions in the docker image
- name: Build Solution
shell: powershell
run: |
Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_PATH)"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
# Zip up the output files as needed
- name: Zip Build Output
shell: powershell
run: |
$destination = "$($Env:GITHUB_HOME)\output"
New-Item -ItemType Directory -Force -Path ($destination)
Get-ChildItem ($destination)
$exclusions = "packages"
# Trying to get any .json schema files (not currently working)
# Gets any files with the listed extensions.
Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.nuspec", "*.md" | ForEach-Object {
$allowed = $true;
# Exclude any files in submodules
foreach ($exclude in $exclusions) {
if ((Split-Path $_.FullName -Parent).contains("$($exclude)")) {
$allowed = $false;
break;
}
}
if ($allowed) {
Write-Host "allowing $($_)"
$_;
}
} | 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 {
# 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:"
Write-Host $filenames
if ($filenames.length -gt 0) {
# Attempt to get the files and return them to the output directory
Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force
}
}
Get-ChildItem -Path $destination\*.cplz | 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
# 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 output files
- 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
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
asset_content_type: application/zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Push_Nuget_Package:
needs: Build_Project
runs-on: windows-2019
steps:
- name: Download Build Version Info
uses: actions/download-artifact@v1
with:
name: Version
- name: Set Version Number
shell: powershell
run: |
Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version"
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- 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
- name: Get nuget File
shell: powershell
run: |
$nuspec_file = (Get-ChildItem *.nuspec -recurse).BaseName
echo "NUSPEC_FILE=$($nuspec_file)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Pulls the nuget builder packages
- name: Add nuget.exe
if: "!contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')"
uses: nuget/setup-nuget@v1
# Creating nuget Packages
- name: Add Github Packages source
if: "!contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')"
run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username Pepperdash -password ${{ secrets.GITHUB_TOKEN }}
- name: Create nuget package
if: "!contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')"
run: nuget pack "./${{ env.NUSPEC_FILE}}.nuspec" -version ${{ env.VERSION }}
# Pushes to internal github registry
- name: Publish nuget package to Github registry
if: "!contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')"
run: nuget push **/*.nupkg -source github
# Pushes to nuget gallery
- name: Add nuget.org API Key
if: github.repository_owner == 'PepperDash' && github.repository_visibility == 'public' && !contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')
run: nuget setApiKey ${{ secrets.NUGET_API_KEY }}
- name: Publish nuget package to nuget.org
if: github.repository_owner == 'PepperDash' && github.repository_visibility == 'public' && !contains(env.NUSPEC_FILE, 'EssentialsPluginTemplate')
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json

2
GetPackages.BAT Normal file
View file

@ -0,0 +1,2 @@
@Echo ON
nuget install .\packages.config -OutputDirectory .\packages -excludeVersion

View file

@ -1,246 +0,0 @@
// For Basic SIMPL# Classes
// For Basic SIMPL#Pro classes
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
namespace EssentialsPluginTemplate
{
/// <summary>
/// Plugin device
/// </summary>
/// <remarks>
/// Rename the class to match the device plugin being developed.
/// </remarks>
/// <example>
/// "EssentialsPluginDeviceTemplate" renamed to "SamsungMdcDevice"
/// </example>
public class EssentialsPluginDeviceTemplate : EssentialsBridgeableDevice
{
// TODO [ ] Add, modify, remove properties and fields as needed for the plugin being developed
private readonly IBasicCommunication _comms;
private readonly GenericCommunicationMonitor _commsMonitor;
// _comms gather for ASCII based API's
// TODO [ ] If not using an ASCII based API, delete the properties below
private readonly CommunicationGather _commsGather;
private const string CommsDelimiter = "\r";
// _comms byte buffer for HEX/byte based API's
// TODO [ ] If not using an HEX/byte based API, delete the properties below
private byte[] _commsByteBuffer = { };
private EssentialsPluginConfigObjectTemplate _config;
/// <summary>
/// Connects/disconnects the comms of the plugin device
/// </summary>
/// <remarks>
/// triggers the _comms.Connect/Disconnect as well as thee comms monitor start/stop
/// </remarks>
public bool Connect
{
get { return _comms.IsConnected; }
set
{
if (value)
{
_comms.Connect();
_commsMonitor.Start();
}
else
{
_comms.Disconnect();
_commsMonitor.Stop();
}
}
}
/// <summary>
/// Reports connect feedback through the bridge
/// </summary>
public BoolFeedback ConnectFeedback { get; private set; }
/// <summary>
/// Reports online feedback through the bridge
/// </summary>
public BoolFeedback OnlineFeedback { get; private set; }
/// <summary>
/// Reports socket status feedback through the bridge
/// </summary>
public IntFeedback StatusFeedback { get; private set; }
/// <summary>
/// Plugin device constructor
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="config"></param>
/// <param name="comms"></param>
public EssentialsPluginDeviceTemplate(string key, string name, EssentialsPluginConfigObjectTemplate config, IBasicCommunication comms)
: base(key, name)
{
Debug.Console(0, this, "Constructing new {0} instance", name);
// TODO [ ] Update the constructor as needed for the plugin device being developed
_config = config;
ConnectFeedback = new BoolFeedback(() => Connect);
OnlineFeedback = new BoolFeedback(() => _commsMonitor.IsOnline);
StatusFeedback = new IntFeedback(() => (int)_commsMonitor.Status);
_comms = comms;
_commsMonitor = new GenericCommunicationMonitor(this, _comms, _config.PollTimeMs, _config.WarningTimeoutMs, _config.ErrorTimeoutMs, Poll);
var socket = _comms as ISocketStatus;
if (socket != null)
{
// device comms is IP **ELSE** device comms is RS232
socket.ConnectionChange += socket_ConnectionChange;
Connect = true;
}
// _comms gather for ASCII based API's
// TODO [ ] If not using an ASCII based API, delete the properties below
_commsGather = new CommunicationGather(_comms, CommsDelimiter);
AddPostActivationAction(() => _commsGather.LineReceived += Handle_LineRecieved);
// _comms byte buffer for HEX/byte based API's
// TODO [ ] If not using an HEX/byte based API, delete the properties below
_comms.BytesReceived += Handle_BytesReceived;
AddPostActivationAction(() => _comms.BytesReceived += Handle_BytesReceived);
}
#region Overrides of EssentialsBridgeableDevice
/// <summary>
/// Links the plugin device to the EISC bridge
/// </summary>
/// <param name="trilist"></param>
/// <param name="joinStart"></param>
/// <param name="joinMapKey"></param>
/// <param name="bridge"></param>
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new EssentialsPluginBridgeJoinMapTemplate(joinStart);
// This adds the join map to the collection on the bridge
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
if (customJoins != null)
{
joinMap.SetCustomJoinData(customJoins);
}
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Bridge Type {0}", GetType().Name);
// TODO [ ] Implement bridge links as needed
// links to bridge
trilist.SetString(joinMap.DeviceName.JoinNumber, Name);
trilist.SetBoolSigAction(joinMap.Connect.JoinNumber, sig => Connect = sig);
ConnectFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Connect.JoinNumber]);
StatusFeedback.LinkInputSig(trilist.UShortInput[joinMap.Status.JoinNumber]);
OnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
UpdateFeedbacks();
trilist.OnlineStatusChange += (o, a) =>
{
if (!a.DeviceOnLine) return;
trilist.SetString(joinMap.DeviceName.JoinNumber, Name);
UpdateFeedbacks();
};
}
private void UpdateFeedbacks()
{
// TODO [ ] Update as needed for the plugin being developed
ConnectFeedback.FireUpdate();
OnlineFeedback.FireUpdate();
StatusFeedback.FireUpdate();
}
#endregion
private void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs args)
{
if (ConnectFeedback != null)
ConnectFeedback.FireUpdate();
if (StatusFeedback != null)
StatusFeedback.FireUpdate();
}
// TODO [ ] If not using an ASCII based API, delete the properties below
private void Handle_LineRecieved(object sender, GenericCommMethodReceiveTextArgs args)
{
// TODO [ ] Implement method
throw new System.NotImplementedException();
}
// TODO [ ] If not using an HEX/byte based API, delete the properties below
private void Handle_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs args)
{
// TODO [ ] Implement method
throw new System.NotImplementedException();
}
// TODO [ ] If not using an ACII based API, delete the properties below
/// <summary>
/// Sends text to the device plugin comms
/// </summary>
/// <remarks>
/// Can be used to test commands with the device plugin using the DEVPROPS and DEVJSON console commands
/// </remarks>
/// <param name="text">Command to be sent</param>
public void SendText(string text)
{
if (string.IsNullOrEmpty(text)) return;
_comms.SendText(string.Format("{0}{1}", text, CommsDelimiter));
}
// TODO [ ] If not using an HEX/byte based API, delete the properties below
/// <summary>
/// Sends bytes to the device plugin comms
/// </summary>
/// <remarks>
/// Can be used to test commands with the device plugin using the DEVPROPS and DEVJSON console commands
/// </remarks>
/// <param name="bytes">Bytes to be sent</param>
public void SendBytes(byte[] bytes)
{
if (bytes == null) return;
_comms.SendBytes(bytes);
}
/// <summary>
/// Polls the device
/// </summary>
/// <remarks>
/// Poll method is used by the communication monitor. Update the poll method as needed for the plugin being developed
/// </remarks>
public void Poll()
{
// TODO [ ] Update Poll method as needed for the plugin being developed
throw new System.NotImplementedException();
}
}
}

View file

@ -1,92 +0,0 @@
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace EssentialsPluginTemplate
{
/// <summary>
/// Plugin device factory
/// </summary>
/// <remarks>
/// Rename the class to match the device plugin being developed
/// </remarks>
/// <example>
/// "EssentialsPluginFactoryTemplate" renamed to "SamsungMdcFactory"
/// </example>
public class EssentialsPluginFactoryTemplate : EssentialsPluginDeviceFactory<EssentialsPluginDeviceTemplate>
{
/// <summary>
/// Plugin device factory constructor
/// </summary>
/// <remarks>
/// Update the MinimumEssentialsFrameworkVersion & TypeNames as needed when creating a plugin
/// </remarks>
/// <example>
/// <code>
/// // Set the minimum Essentials Framework Version
/// MinimumEssentialsFrameworkVersion = "1.5.5";
/// // In the constructor we initialize the list with the typenames that will build an instance of this device
#pragma warning disable 1570
/// TypeNames = new List<string>() { "SamsungMdc", "SamsungMdcDisplay" };
#pragma warning restore 1570
/// </code>
/// </example>
public EssentialsPluginFactoryTemplate()
{
// Set the minimum Essentials Framework Version
// TODO [ ] Update the Essentials minimum framework version which this plugin has been tested against
MinimumEssentialsFrameworkVersion = "1.6.4";
// In the constructor we initialize the list with the typenames that will build an instance of this device
// TODO [ ] Update the TypeNames for the plugin being developed
TypeNames = new List<string>() { "examplePluginDevice" };
}
/// <summary>
/// Builds and returns an instance of EssentialsPluginDeviceTemplate
/// </summary>
/// <param name="dc">device configuration</param>
/// <returns>plugin device or null</returns>
/// <remarks>
/// The example provided below takes the device key, name, properties config and the comms device created.
/// Modify the EssetnialsPlugingDeviceTemplate constructor as needed to meet the requirements of the plugin device.
/// </remarks>
/// <seealso cref="PepperDash.Core.eControlMethod"/>
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
{
Debug.Console(1, "[{0}] Factory Attempting to create new device from type: {1}", dc.Key, dc.Type);
// get the plugin device properties configuration object & check for null
var propertiesConfig = dc.Properties.ToObject<EssentialsPluginConfigObjectTemplate>();
if (propertiesConfig == null)
{
Debug.Console(0, "[{0}] Factory: failed to read properties config for {1}", dc.Key, dc.Name);
return null;
}
// TODO [ ] Discuss with Andrew/Neil on recommended best practice
// Method 1
//var username = dc.Properties["control"].Value<TcpSshPropertiesConfig>("tcpSshProperties").Username;
//var password = dc.Properties["control"].Value<TcpSshPropertiesConfig>("tcpSshProperties").Password;
//var method = dc.Properties["control"].Value<string>("method");
// Method 2 - Returns a JValue, has to be casted to string
var username = (string)dc.Properties["control"]["tcpSshProperties"]["username"];
var password = (string)dc.Properties["control"]["tcpSshProperties"]["password"];
var method = (string)dc.Properties["control"]["method"];
// build the plugin device comms & check for null
// TODO { ] As of PepperDash Core 1.0.41, HTTP and HTTPS are not valid eControlMethods and will throw an exception.
var comms = CommFactory.CreateCommForDevice(dc);
if (comms == null)
{
Debug.Console(0, "[{0}] Factory: failed to create comm for {1}", dc.Key, dc.Name);
return null;
}
return new EssentialsPluginDeviceTemplate(dc.Key, dc.Name, propertiesConfig, comms);
}
}
}

View file

@ -1,5 +0,0 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DeployDeviceID>E282E6BE-C7C3-4ece-916A-88FB1CF8AF3C</DeployDeviceID>
</PropertyGroup>
</Project>

View file

@ -1,63 +0,0 @@
8/30/2019 3:01:01 PM, Info: Initializing SIMPLSharp Services...
8/30/2019 3:01:01 PM, Info: ProjectInfo successfully initialized.
8/30/2019 3:01:02 PM, Info: Saving project information...
8/30/2019 3:01:02 PM, Info: Saving project information...
8/30/2019 3:01:02 PM, Info: Saving project information...
8/30/2019 3:01:02 PM, Info: Saving project information...
8/30/2019 3:01:02 PM, Info: Saving project information...
8/30/2019 3:01:02 PM, Info: Saving project information...
8/30/2019 3:04:48 PM, Info: Validating assembly C:\Users\JTA\Documents\Stash Folder\KPMG\SLN103-AVNoc\SLN103-AVNoc.Plugins\NvxUrlRoutingClient.Epi\essentials-builds\PepperDashEssentials.dll...
8/30/2019 3:05:10 PM, Info: Saving project information...
8/30/2019 3:05:10 PM, Info: Saving project information...
8/30/2019 3:05:10 PM, Info: Saving project information...
8/30/2019 3:05:39 PM, Info: Validating assembly C:\Users\JTA\Documents\Stash Folder\KPMG\SLN103-AVNoc\SLN103-AVNoc.Plugins\NvxUrlRoutingClient.Epi\essentials-builds\PepperDash_Core.dll...
8/30/2019 3:05:39 PM, Info: Validating assembly C:\Users\JTA\Documents\Stash Folder\KPMG\SLN103-AVNoc\SLN103-AVNoc.Plugins\NvxUrlRoutingClient.Epi\essentials-builds\PepperDash_Essentials_Core.dll...
8/30/2019 3:05:40 PM, Info: Validating assembly C:\Users\JTA\Documents\Stash Folder\KPMG\SLN103-AVNoc\SLN103-AVNoc.Plugins\NvxUrlRoutingClient.Epi\essentials-builds\PepperDash_Essentials_DM.dll...
8/30/2019 3:06:24 PM, Info: Saving project information...
8/30/2019 3:06:24 PM, Info: Saving project information...
8/30/2019 3:06:24 PM, Info: Saving project information...
8/30/2019 3:06:24 PM, Info: Saving project information...
8/30/2019 3:06:24 PM, Info: Saving project information...
8/30/2019 3:06:24 PM, Info: Saving project information...
8/30/2019 3:06:36 PM, Info: Saving project information...
8/30/2019 3:06:36 PM, Info: Saving project information...
8/30/2019 3:06:36 PM, Info: Saving project information...
8/30/2019 3:06:36 PM, Info: Saving project information...
8/30/2019 3:06:36 PM, Info: Saving project information...
8/30/2019 3:06:36 PM, Info: Saving project information...
8/30/2019 3:08:54 PM, Info: Saving project information...
8/30/2019 3:08:54 PM, Info: Saving project information...
8/30/2019 3:08:54 PM, Info: Saving project information...
8/30/2019 3:08:54 PM, Info: Saving project information...
8/30/2019 3:08:54 PM, Info: Saving project information...
8/30/2019 3:08:54 PM, Info: Saving project information...
8/30/2019 3:09:39 PM, Info: Validating assembly C:\Users\JTA\Documents\Stash Folder\KPMG\SLN103-AVNoc\SLN103-AVNoc.Plugins\NvxUrlRoutingClient.Epi\essentials-builds\PepperDash_Essentials_Core.dll...
8/30/2019 3:10:10 PM, Info: Saving project information...
8/30/2019 3:10:10 PM, Info: Saving project information...
8/30/2019 3:10:10 PM, Info: Saving project information...
8/30/2019 3:15:10 PM, Info: Saving project information...
8/30/2019 3:15:10 PM, Info: Saving project information...
8/30/2019 3:15:10 PM, Info: Saving project information...
8/30/2019 3:20:10 PM, Info: Saving project information...
8/30/2019 3:20:10 PM, Info: Saving project information...
8/30/2019 3:20:10 PM, Info: Saving project information...
8/30/2019 3:25:10 PM, Info: Saving project information...
8/30/2019 3:25:10 PM, Info: Saving project information...
8/30/2019 3:25:10 PM, Info: Saving project information...
8/30/2019 3:30:10 PM, Info: Saving project information...
8/30/2019 3:30:10 PM, Info: Saving project information...
8/30/2019 3:30:10 PM, Info: Saving project information...
8/30/2019 3:35:10 PM, Info: Saving project information...
8/30/2019 3:35:10 PM, Info: Saving project information...
8/30/2019 3:35:10 PM, Info: Saving project information...
8/30/2019 3:35:38 PM, Info: Saving project information...
8/30/2019 3:35:38 PM, Info: Saving project information...
8/30/2019 3:35:38 PM, Info: Saving project information...
8/30/2019 3:35:38 PM, Info: Saving project information...
8/30/2019 3:35:38 PM, Info: Saving project information...
8/30/2019 3:35:38 PM, Info: Saving project information...
8/30/2019 3:36:52 PM, Info: Validating assembly C:\Users\JTA\Documents\Stash Folder\KPMG\SLN103-AVNoc\SLN103-AVNoc.Plugins\NvxUrlRoutingClient.Epi\NvxUrlRoutingClientEpi\bin\Debug\NvxUrlRoutingClientEpi.dll...
8/30/2019 3:36:52 PM, Info: Verifying assembly C:\Users\JTA\Documents\Stash Folder\KPMG\SLN103-AVNoc\SLN103-AVNoc.Plugins\NvxUrlRoutingClient.Epi\NvxUrlRoutingClientEpi\bin\Debug\NvxUrlRoutingClientEpi.dll
8/30/2019 3:36:52 PM, Info: Creating Archive C:\Users\JTA\Documents\Stash Folder\KPMG\SLN103-AVNoc\SLN103-AVNoc.Plugins\NvxUrlRoutingClient.Epi\NvxUrlRoutingClientEpi\bin\Debug\NvxUrlRoutingClientEpi.cplz...
8/30/2019 3:36:53 PM, Info: Saving project information...
9/2/2019 8:34:46 AM, Info: Terminating SIMPLSharp Services

View file

@ -8,6 +8,15 @@ Provided under MIT license
Fork this repo when creating a new plugin for Essentials. For more information about plugins, refer to the Essentials Wiki [Plugins](https://github.com/PepperDash/Essentials/wiki/Plugins) article. Fork this repo when creating a new plugin for Essentials. For more information about plugins, refer to the Essentials Wiki [Plugins](https://github.com/PepperDash/Essentials/wiki/Plugins) article.
This repo contains example classes for the three main categories of devices:
* `EssentialsPluginTemplateDevice`: Used for most third party devices which require communication over a streaming mechanism such as a Com port, TCP/SSh/UDP socket, CEC, etc
* `EssentialsPluginTemplateLogicDevice`: Used for devices that contain logic, but don't require any communication with third parties outside the program
* `EssentialsPluginTemplateCrestronDevice`: Used for devices that represent a piece of Crestron hardware
There are matching factory classes for each of the three categories of devices. The `EssentialsPluginTemplateConfigObject` should be used as a template and modified for any of the categories of device. Same goes for the `EssentialsPluginTemplateBridgeJoinMap`.
This also illustrates how a plugin can contain multiple devices.
## Cloning Instructions ## Cloning Instructions
After forking this repository into your own GitHub space, you can create a new repository using this one as the template. Then you must install the necessary dependencies as indicated below. After forking this repository into your own GitHub space, you can create a new repository using this one as the template. Then you must install the necessary dependencies as indicated below.
@ -20,6 +29,7 @@ The [Essentials](https://github.com/PepperDash/Essentials) libraries are require
To install dependencies once nuget.exe is installed, run the following command from the root directory of your repository: To install dependencies once nuget.exe is installed, run the following command from the root directory of your repository:
`nuget install .\packages.config -OutputDirectory .\packages -excludeVersion`. `nuget install .\packages.config -OutputDirectory .\packages -excludeVersion`.
Alternatively, you can simply run the `GetPackages.bat` file.
To verify that the packages installed correctly, open the plugin solution in your repo and make sure that all references are found, then try and build it. To verify that the packages installed correctly, open the plugin solution in your repo and make sure that all references are found, then try and build it.
### Installing Different versions of PepperDash Core ### Installing Different versions of PepperDash Core
@ -28,6 +38,21 @@ If you need a different version of PepperDash Core, use the command `nuget insta
### Instructions for Renaming Solution and Files ### Instructions for Renaming Solution and Files
See the Task List in Visual Studio for a guide on how to start using the templage. There is extensive inline documentation and examples as well. See the Task List in Visual Studio for a guide on how to start using the template. There is extensive inline documentation and examples as well.
For renaming instructions in particular, see the XML `remarks` tags on class definitions For renaming instructions in particular, see the XML `remarks` tags on class definitions
## Build Instructions (PepperDash Internal)
## Generating Nuget Package
In the solution folder is a file named "PDT.EssentialsPluginTemplate.nuspec"
1. Rename the file to match your plugin solution name
2. Edit the file to include your project specifics including
1. <id>PepperDash.Essentials.Plugin.MakeModel</id> Convention is to use the prefix "PepperDash.Essentials.Plugin" and include the MakeModel of the device.
2. <projectUrl>https://github.com/PepperDash/EssentialsPluginTemplate</projectUrl> Change to your url to the project repo
There is no longer a requirement to adjust workflow files for nuget generation for private and public repositories. This is now handled automatically in the workflow.
__If you do not make these changes to the nuspec file, the project will not generate a nuget package__

View file

@ -1,3 +1,3 @@
<packages> <packages>
<package id="PepperDashEssentials" version="1.6.4" targetFramework="net35" allowedVersions="[1.0,2.0)"/> <package id="PepperDashEssentials" version="1.10.2" targetFramework="net35" allowedVersions="[1.0,2.0)"/>
</packages> </packages>

View file

@ -12,7 +12,7 @@ namespace EssentialsPluginTemplate
/// <example> /// <example>
/// "EssentialsPluginBridgeJoinMapTemplate" renamed to "SamsungMdcBridgeJoinMap" /// "EssentialsPluginBridgeJoinMapTemplate" renamed to "SamsungMdcBridgeJoinMap"
/// </example> /// </example>
public class EssentialsPluginBridgeJoinMapTemplate : JoinMapBaseAdvanced public class EssentialsPluginTemplateBridgeJoinMap : JoinMapBaseAdvanced
{ {
#region Digital #region Digital
@ -93,8 +93,8 @@ namespace EssentialsPluginTemplate
/// Plugin device BridgeJoinMap constructor /// Plugin device BridgeJoinMap constructor
/// </summary> /// </summary>
/// <param name="joinStart">This will be the join it starts on the EISC bridge</param> /// <param name="joinStart">This will be the join it starts on the EISC bridge</param>
public EssentialsPluginBridgeJoinMapTemplate(uint joinStart) public EssentialsPluginTemplateBridgeJoinMap(uint joinStart)
: base(joinStart, typeof(EssentialsPluginBridgeJoinMapTemplate)) : base(joinStart, typeof(EssentialsPluginTemplateBridgeJoinMap))
{ {
} }
} }

View file

@ -14,7 +14,7 @@ namespace EssentialsPluginTemplate
/// "EssentialsPluginConfigObjectTemplate" renamed to "SamsungMdcConfig" /// "EssentialsPluginConfigObjectTemplate" renamed to "SamsungMdcConfig"
/// </example> /// </example>
[ConfigSnippet("\"properties\":{\"control\":{}")] [ConfigSnippet("\"properties\":{\"control\":{}")]
public class EssentialsPluginConfigObjectTemplate public class EssentialsPluginTemplateConfigObject
{ {
/// <summary> /// <summary>
/// JSON control object /// JSON control object
@ -139,7 +139,7 @@ namespace EssentialsPluginTemplate
/// </code> /// </code>
/// </example> /// </example>
[JsonProperty("DeviceDictionary")] [JsonProperty("DeviceDictionary")]
public Dictionary<string, EssentialsPluginConfigObjectDictionaryTemplate> DeviceDictionary { get; set; } public Dictionary<string, EssentialsPluginTemplateConfigObjectDictionary> DeviceDictionary { get; set; }
/// <summary> /// <summary>
/// Constuctor /// Constuctor
@ -148,9 +148,9 @@ namespace EssentialsPluginTemplate
/// If using a collection you must instantiate the collection in the constructor /// If using a collection you must instantiate the collection in the constructor
/// to avoid exceptions when reading the configuration file /// to avoid exceptions when reading the configuration file
/// </remarks> /// </remarks>
public EssentialsPluginConfigObjectTemplate() public EssentialsPluginTemplateConfigObject()
{ {
DeviceDictionary = new Dictionary<string, EssentialsPluginConfigObjectDictionaryTemplate>(); DeviceDictionary = new Dictionary<string, EssentialsPluginTemplateConfigObjectDictionary>();
} }
} }
@ -172,7 +172,7 @@ namespace EssentialsPluginTemplate
/// } /// }
/// </code> /// </code>
/// </example> /// </example>
public class EssentialsPluginConfigObjectDictionaryTemplate public class EssentialsPluginTemplateConfigObjectDictionary
{ {
/// <summary> /// <summary>
/// Serializes collection name property /// Serializes collection name property

View file

@ -0,0 +1,99 @@
// For Basic SIMPL# Classes
// For Basic SIMPL#Pro classes
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
namespace EssentialsPluginTemplate
{
/// <summary>
/// Plugin device
/// </summary>
/// <remarks>
/// Rename the class to match the device plugin being developed.
/// </remarks>
/// <example>
/// "EssentialsPluginDeviceTemplate" renamed to "SamsungMdcDevice"
/// </example>
public class EssentialsPluginTemplateCrestronDevice : CrestronGenericBridgeableBaseDevice
{
/// <summary>
/// It is often desirable to store the config
/// </summary>
private EssentialsPluginTemplateConfigObject _config;
#region Constructor for Devices without IBasicCommunication. Remove if not needed
/// <summary>
/// Plugin device constructor for Crestron devices
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="config"></param>
/// <param name="hardware"></param>
public EssentialsPluginTemplateCrestronDevice(string key, string name, EssentialsPluginTemplateConfigObject config, GenericBase hardware)
: base(key, name, hardware)
{
Debug.Console(0, this, "Constructing new {0} instance", name);
// The base class takes care of registering the hardware device for you
// TODO [ ] Update the constructor as needed for the plugin device being developed
_config = config;
}
#endregion
#region Overrides of EssentialsBridgeableDevice
/// <summary>
/// Links the plugin device to the EISC bridge
/// </summary>
/// <param name="trilist"></param>
/// <param name="joinStart"></param>
/// <param name="joinMapKey"></param>
/// <param name="bridge"></param>
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new EssentialsPluginTemplateBridgeJoinMap(joinStart);
// This adds the join map to the collection on the bridge
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
if (customJoins != null)
{
joinMap.SetCustomJoinData(customJoins);
}
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Bridge Type {0}", GetType().Name);
// TODO [ ] Implement bridge links as needed
// links to bridge
trilist.SetString(joinMap.DeviceName.JoinNumber, Name);
trilist.OnlineStatusChange += (o, a) =>
{
if (!a.DeviceOnLine) return;
trilist.SetString(joinMap.DeviceName.JoinNumber, Name);
};
}
#endregion
}
}

View file

@ -0,0 +1,299 @@
// For Basic SIMPL# Classes
// For Basic SIMPL#Pro classes
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Queues;
namespace EssentialsPluginTemplate
{
/// <summary>
/// Plugin device template for third party devices that use IBasicCommunication
/// </summary>
/// <remarks>
/// Rename the class to match the device plugin being developed.
/// </remarks>
/// <example>
/// "EssentialsPluginDeviceTemplate" renamed to "SamsungMdcDevice"
/// </example>
public class EssentialsPluginTemplateDevice : EssentialsBridgeableDevice
{
/// <summary>
/// It is often desirable to store the config
/// </summary>
private EssentialsPluginTemplateConfigObject _config;
/// <summary>
/// Provides a queue and dedicated worker thread for processing feedback messages from a device.
/// </summary>
private GenericQueue ReceiveQueue;
#region IBasicCommunication Properties and Constructor. Remove if not needed.
// TODO [ ] Add, modify, remove properties and fields as needed for the plugin being developed
private readonly IBasicCommunication _comms;
private readonly GenericCommunicationMonitor _commsMonitor;
// _comms gather for ASCII based API's
// TODO [ ] If not using an ASCII based API, delete the properties below
private readonly CommunicationGather _commsGather;
/// <summary>
/// Set this value to that of the delimiter used by the API (if applicable)
/// </summary>
private const string CommsDelimiter = "\r";
// _comms byte buffer for HEX/byte based API's
// TODO [ ] If not using an HEX/byte based API, delete the properties below
private byte[] _commsByteBuffer = { };
/// <summary>
/// Connects/disconnects the comms of the plugin device
/// </summary>
/// <remarks>
/// triggers the _comms.Connect/Disconnect as well as thee comms monitor start/stop
/// </remarks>
public bool Connect
{
get { return _comms.IsConnected; }
set
{
if (value)
{
_comms.Connect();
_commsMonitor.Start();
}
else
{
_comms.Disconnect();
_commsMonitor.Stop();
}
}
}
/// <summary>
/// Reports connect feedback through the bridge
/// </summary>
public BoolFeedback ConnectFeedback { get; private set; }
/// <summary>
/// Reports online feedback through the bridge
/// </summary>
public BoolFeedback OnlineFeedback { get; private set; }
/// <summary>
/// Reports socket status feedback through the bridge
/// </summary>
public IntFeedback StatusFeedback { get; private set; }
/// <summary>
/// Plugin device constructor for devices that need IBasicCommunication
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="config"></param>
/// <param name="comms"></param>
public EssentialsPluginTemplateDevice(string key, string name, EssentialsPluginTemplateConfigObject config, IBasicCommunication comms)
: base(key, name)
{
Debug.Console(0, this, "Constructing new {0} instance", name);
// TODO [ ] Update the constructor as needed for the plugin device being developed
_config = config;
ReceiveQueue = new GenericQueue(key + "-rxqueue"); // If you need to set the thread priority, use one of the available overloaded constructors.
ConnectFeedback = new BoolFeedback(() => Connect);
OnlineFeedback = new BoolFeedback(() => _commsMonitor.IsOnline);
StatusFeedback = new IntFeedback(() => (int)_commsMonitor.Status);
_comms = comms;
_commsMonitor = new GenericCommunicationMonitor(this, _comms, _config.PollTimeMs, _config.WarningTimeoutMs, _config.ErrorTimeoutMs, Poll);
var socket = _comms as ISocketStatus;
if (socket != null)
{
// device comms is IP **ELSE** device comms is RS232
socket.ConnectionChange += socket_ConnectionChange;
Connect = true;
}
#region Communication data event handlers. Comment out any that don't apply to the API type
// Only one of the below handlers should be necessary.
// _comms gather for any API that has a defined delimiter
// TODO [ ] If not using an ASCII based API, remove the line below
_commsGather = new CommunicationGather(_comms, CommsDelimiter);
_commsGather.LineReceived += Handle_LineRecieved;
// _comms byte buffer for HEX/byte based API's with no delimiter
// TODO [ ] If not using an HEX/byte based API, remove the line below
_comms.BytesReceived += Handle_BytesReceived;
// _comms byte buffer for HEX/byte based API's with no delimiter
// TODO [ ] If not using an HEX/byte based API, remove the line below
_comms.TextReceived += Handle_TextReceived;
#endregion
}
private void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs args)
{
if (ConnectFeedback != null)
ConnectFeedback.FireUpdate();
if (StatusFeedback != null)
StatusFeedback.FireUpdate();
}
// TODO [ ] If not using an API with a delimeter, delete the method below
private void Handle_LineRecieved(object sender, GenericCommMethodReceiveTextArgs args)
{
// TODO [ ] Implement method
// Enqueues the message to be processed in a dedicated thread, but the specified method
ReceiveQueue.Enqueue(new ProcessStringMessage(args.Text, ProcessFeedbackMessage));
}
// TODO [ ] If not using an HEX/byte based API with no delimeter, delete the method below
private void Handle_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs args)
{
// TODO [ ] Implement method
throw new System.NotImplementedException();
}
// TODO [ ] If not using an ASCII based API with no delimeter, delete the method below
void Handle_TextReceived(object sender, GenericCommMethodReceiveTextArgs e)
{
// TODO [ ] Implement method
throw new System.NotImplementedException();
}
/// <summary>
/// This method should perform any necessary parsing of feedback messages from the device
/// </summary>
/// <param name="message"></param>
void ProcessFeedbackMessage(string message)
{
}
// TODO [ ] If not using an ACII based API, delete the properties below
/// <summary>
/// Sends text to the device plugin comms
/// </summary>
/// <remarks>
/// Can be used to test commands with the device plugin using the DEVPROPS and DEVJSON console commands
/// </remarks>
/// <param name="text">Command to be sent</param>
public void SendText(string text)
{
if (string.IsNullOrEmpty(text)) return;
_comms.SendText(string.Format("{0}{1}", text, CommsDelimiter));
}
// TODO [ ] If not using an HEX/byte based API, delete the properties below
/// <summary>
/// Sends bytes to the device plugin comms
/// </summary>
/// <remarks>
/// Can be used to test commands with the device plugin using the DEVPROPS and DEVJSON console commands
/// </remarks>
/// <param name="bytes">Bytes to be sent</param>
public void SendBytes(byte[] bytes)
{
if (bytes == null) return;
_comms.SendBytes(bytes);
}
/// <summary>
/// Polls the device
/// </summary>
/// <remarks>
/// Poll method is used by the communication monitor. Update the poll method as needed for the plugin being developed
/// </remarks>
public void Poll()
{
// TODO [ ] Update Poll method as needed for the plugin being developed
// Example: SendText("getstatus");
throw new System.NotImplementedException();
}
#endregion
#region Overrides of EssentialsBridgeableDevice
/// <summary>
/// Links the plugin device to the EISC bridge
/// </summary>
/// <param name="trilist"></param>
/// <param name="joinStart"></param>
/// <param name="joinMapKey"></param>
/// <param name="bridge"></param>
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new EssentialsPluginTemplateBridgeJoinMap(joinStart);
// This adds the join map to the collection on the bridge
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
if (customJoins != null)
{
joinMap.SetCustomJoinData(customJoins);
}
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Bridge Type {0}", GetType().Name);
// TODO [ ] Implement bridge links as needed
// links to bridge
trilist.SetString(joinMap.DeviceName.JoinNumber, Name);
trilist.SetBoolSigAction(joinMap.Connect.JoinNumber, sig => Connect = sig);
ConnectFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Connect.JoinNumber]);
StatusFeedback.LinkInputSig(trilist.UShortInput[joinMap.Status.JoinNumber]);
OnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
UpdateFeedbacks();
trilist.OnlineStatusChange += (o, a) =>
{
if (!a.DeviceOnLine) return;
trilist.SetString(joinMap.DeviceName.JoinNumber, Name);
UpdateFeedbacks();
};
}
private void UpdateFeedbacks()
{
// TODO [ ] Update as needed for the plugin being developed
ConnectFeedback.FireUpdate();
OnlineFeedback.FireUpdate();
StatusFeedback.FireUpdate();
}
#endregion
}
}

View file

@ -0,0 +1,239 @@
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using Crestron.SimplSharpPro.UI;
namespace EssentialsPluginTemplate
{
/// <summary>
/// Plugin device factory for devices that use IBasicCommunication
/// </summary>
/// <remarks>
/// Rename the class to match the device plugin being developed
/// </remarks>
/// <example>
/// "EssentialsPluginFactoryTemplate" renamed to "MyDeviceFactory"
/// </example>
public class EssentialsPluginTemplateFactory : EssentialsPluginDeviceFactory<EssentialsPluginTemplateDevice>
{
/// <summary>
/// Plugin device factory constructor
/// </summary>
/// <remarks>
/// Update the MinimumEssentialsFrameworkVersion & TypeNames as needed when creating a plugin
/// </remarks>
/// <example>
/// Set the minimum Essentials Framework Version
/// <code>
/// MinimumEssentialsFrameworkVersion = "1.6.4;
/// </code>
/// In the constructor we initialize the list with the typenames that will build an instance of this device
/// <code>
/// TypeNames = new List<string>() { "SamsungMdc", "SamsungMdcDisplay" };
/// </code>
/// </example>
public EssentialsPluginTemplateFactory()
{
// Set the minimum Essentials Framework Version
// TODO [ ] Update the Essentials minimum framework version which this plugin has been tested against
MinimumEssentialsFrameworkVersion = "1.6.4";
// In the constructor we initialize the list with the typenames that will build an instance of this device
// TODO [ ] Update the TypeNames for the plugin being developed
TypeNames = new List<string>() { "examplePluginDevice" };
}
/// <summary>
/// Builds and returns an instance of EssentialsPluginDeviceTemplate
/// </summary>
/// <param name="dc">device configuration</param>
/// <returns>plugin device or null</returns>
/// <remarks>
/// The example provided below takes the device key, name, properties config and the comms device created.
/// Modify the EssetnialsPlugingDeviceTemplate constructor as needed to meet the requirements of the plugin device.
/// </remarks>
/// <seealso cref="PepperDash.Core.eControlMethod"/>
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
{
Debug.Console(1, "[{0}] Factory Attempting to create new device from type: {1}", dc.Key, dc.Type);
// get the plugin device properties configuration object & check for null
var propertiesConfig = dc.Properties.ToObject<EssentialsPluginTemplateConfigObject>();
if (propertiesConfig == null)
{
Debug.Console(0, "[{0}] Factory: failed to read properties config for {1}", dc.Key, dc.Name);
return null;
}
// attempt build the plugin device comms device & check for null
// TODO { ] As of PepperDash Core 1.0.41, HTTP and HTTPS are not valid eControlMethods and will throw an exception.
var comms = CommFactory.CreateCommForDevice(dc);
if (comms == null)
{
Debug.Console(1, "[{0}] Factory Notice: No control object present for device {1}", dc.Key, dc.Name);
return null;
}
else
{
return new EssentialsPluginTemplateDevice(dc.Key, dc.Name, propertiesConfig, comms);
}
}
}
/// <summary>
/// Plugin device factory for logic devices that don't communicate
/// </summary>
/// <remarks>
/// Rename the class to match the device plugin being developed
/// </remarks>
/// <example>
/// "EssentialsPluginFactoryTemplate" renamed to "MyLogicDeviceFactory"
/// </example>
public class EssentialsPluginTemplateFactoryLogicDevice : EssentialsPluginDeviceFactory<EssentialsPluginTemplateLogicDevice>
{
/// <summary>
/// Plugin device factory constructor
/// </summary>
/// <remarks>
/// Update the MinimumEssentialsFrameworkVersion & TypeNames as needed when creating a plugin
/// </remarks>
/// <example>
/// Set the minimum Essentials Framework Version
/// <code>
/// MinimumEssentialsFrameworkVersion = "1.6.4;
/// </code>
/// In the constructor we initialize the list with the typenames that will build an instance of this device
/// <code>
/// TypeNames = new List<string>() { "SamsungMdc", "SamsungMdcDisplay" };
/// </code>
/// </example>
public EssentialsPluginTemplateFactoryLogicDevice()
{
// Set the minimum Essentials Framework Version
// TODO [ ] Update the Essentials minimum framework version which this plugin has been tested against
MinimumEssentialsFrameworkVersion = "1.6.4";
// In the constructor we initialize the list with the typenames that will build an instance of this device
// TODO [ ] Update the TypeNames for the plugin being developed
TypeNames = new List<string>() { "examplePluginLogicDevice" };
}
/// <summary>
/// Builds and returns an instance of EssentialsPluginTemplateLogicDevice
/// </summary>
/// <param name="dc">device configuration</param>
/// <returns>plugin device or null</returns>
/// <remarks>
/// The example provided below takes the device key, name, properties config and the comms device created.
/// Modify the EssetnialsPlugingDeviceTemplate constructor as needed to meet the requirements of the plugin device.
/// </remarks>
/// <seealso cref="PepperDash.Core.eControlMethod"/>
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
{
Debug.Console(1, "[{0}] Factory Attempting to create new device from type: {1}", dc.Key, dc.Type);
// get the plugin device properties configuration object & check for null
var propertiesConfig = dc.Properties.ToObject<EssentialsPluginTemplateConfigObject>();
if (propertiesConfig == null)
{
Debug.Console(0, "[{0}] Factory: failed to read properties config for {1}", dc.Key, dc.Name);
return null;
}
var controlConfig = CommFactory.GetControlPropertiesConfig(dc);
if (controlConfig == null)
{
return new EssentialsPluginTemplateLogicDevice(dc.Key, dc.Name, propertiesConfig);
}
else
{
Debug.Console(0, "[{0}] Factory: Unable to get control properties from device config for {1}", dc.Key, dc.Name);
return null;
}
}
}
/// <summary>
/// Plugin device factory for Crestron wrapper devices
/// </summary>
/// <remarks>
/// Rename the class to match the device plugin being developed
/// </remarks>
/// <example>
/// "EssentialsPluginFactoryTemplate" renamed to "MyCrestronDeviceFactory"
/// </example>
public class EssentialsPluginTemplateFactoryCrestronDevice : EssentialsPluginDeviceFactory<EssentialsPluginTemplateCrestronDevice>
{
/// <summary>
/// Plugin device factory constructor
/// </summary>
/// <remarks>
/// Update the MinimumEssentialsFrameworkVersion & TypeNames as needed when creating a plugin
/// </remarks>
/// <example>
/// Set the minimum Essentials Framework Version
/// <code>
/// MinimumEssentialsFrameworkVersion = "1.6.4;
/// </code>
/// In the constructor we initialize the list with the typenames that will build an instance of this device
/// <code>
/// TypeNames = new List<string>() { "SamsungMdc", "SamsungMdcDisplay" };
/// </code>
/// </example>
public EssentialsPluginTemplateFactoryCrestronDevice()
{
// Set the minimum Essentials Framework Version
// TODO [ ] Update the Essentials minimum framework version which this plugin has been tested against
MinimumEssentialsFrameworkVersion = "1.7.5";
// In the constructor we initialize the list with the typenames that will build an instance of this device
// TODO [ ] Update the TypeNames for the plugin being developed
TypeNames = new List<string>() { "examplePluginCrestronDevice" };
}
/// <summary>
/// Builds and returns an instance of EssentialsPluginTemplateCrestronDevice
/// </summary>
/// <param name="dc">device configuration</param>
/// <returns>plugin device or null</returns>
/// <remarks>
/// The example provided below takes the device key, name, properties config and the comms device created.
/// Modify the EssetnialsPlugingDeviceTemplate constructor as needed to meet the requirements of the plugin device.
/// </remarks>
/// <seealso cref="PepperDash.Core.eControlMethod"/>
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
{
Debug.Console(1, "[{0}] Factory Attempting to create new device from type: {1}", dc.Key, dc.Type);
// get the plugin device properties configuration object & check for null
var propertiesConfig = dc.Properties.ToObject<EssentialsPluginTemplateConfigObject>();
if (propertiesConfig == null)
{
Debug.Console(0, "[{0}] Factory: failed to read properties config for {1}", dc.Key, dc.Name);
return null;
}
var controlConfig = CommFactory.GetControlPropertiesConfig(dc);
if (controlConfig == null)
{
var myTouchpanel = new Tsw760(controlConfig.IpIdInt, Global.ControlSystem);
return new EssentialsPluginTemplateCrestronDevice(dc.Key, dc.Name, propertiesConfig, myTouchpanel);
}
else
{
Debug.Console(0, "[{0}] Factory: Unable to get control properties from device config for {1}", dc.Key, dc.Name);
return null;
}
}
}
}

View file

@ -0,0 +1,86 @@
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
namespace EssentialsPluginTemplate
{
/// <summary>
/// Plugin device template for logic devices that don't communicate outside the program
/// </summary>
/// <remarks>
/// Rename the class to match the device plugin being developed.
/// </remarks>
/// <example>
/// "EssentialsPluginTemplateLogicDevice" renamed to "SamsungMdcDevice"
/// </example>
public class EssentialsPluginTemplateLogicDevice : EssentialsBridgeableDevice
{
/// <summary>
/// It is often desirable to store the config
/// </summary>
private EssentialsPluginTemplateConfigObject _config;
/// <summary>
/// Plugin device constructor
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="config"></param>
public EssentialsPluginTemplateLogicDevice(string key, string name, EssentialsPluginTemplateConfigObject config)
: base(key, name)
{
Debug.Console(0, this, "Constructing new {0} instance", name);
// TODO [ ] Update the constructor as needed for the plugin device being developed
_config = config;
}
#region Overrides of EssentialsBridgeableDevice
/// <summary>
/// Links the plugin device to the EISC bridge
/// </summary>
/// <param name="trilist"></param>
/// <param name="joinStart"></param>
/// <param name="joinMapKey"></param>
/// <param name="bridge"></param>
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new EssentialsPluginTemplateBridgeJoinMap(joinStart);
// This adds the join map to the collection on the bridge
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
if (customJoins != null)
{
joinMap.SetCustomJoinData(customJoins);
}
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Bridge Type {0}", GetType().Name);
// TODO [ ] Implement bridge links as needed
// links to bridge
trilist.SetString(joinMap.DeviceName.JoinNumber, Name);
trilist.OnlineStatusChange += (o, a) =>
{
if (!a.DeviceOnLine) return;
trilist.SetString(joinMap.DeviceName.JoinNumber, Name);
};
}
#endregion
}
}

View file

@ -46,6 +46,10 @@
<GenerateSerializationAssemblies>off</GenerateSerializationAssemblies> <GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Crestron.SimplSharpPro.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
</Reference>
<Reference Include="Essentials Devices Common, Version=1.6.2.33892, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Essentials Devices Common, Version=1.6.2.33892, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\PepperDashEssentials\lib\net35\Essentials Devices Common.dll</HintPath> <HintPath>..\packages\PepperDashEssentials\lib\net35\Essentials Devices Common.dll</HintPath>
@ -95,6 +99,8 @@
<Reference Include="System.Data" /> <Reference Include="System.Data" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="EssentialsPluginTemplateLogicDevice.cs" />
<Compile Include="EssentialsPluginTemplateCrestronDevice.cs" />
<Compile Include="EssentialsPluginTemplateBridgeJoinMap.cs" /> <Compile Include="EssentialsPluginTemplateBridgeJoinMap.cs" />
<Compile Include="EssentialsPluginTemplateConfigObject.cs" /> <Compile Include="EssentialsPluginTemplateConfigObject.cs" />
<Compile Include="EssentialsPluginTemplateFactory.cs" /> <Compile Include="EssentialsPluginTemplateFactory.cs" />

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<package >
<metadata>
<id>PDT.EssentialsPluginTemplate</id>
<readme>docs\README.md</readme>
<version>2.0.2</version>
<title>Essentials Plugin Template</title>
<authors>PepperDash Technologies</authors>
<owners>pepperdash</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/PepperDash/EssentialsPluginTemplate</projectUrl>
<copyright>Copyright 2022</copyright>
<description>This software iserves as a template for generating new Essentials-Compliant plugins</description>
<tags>crestron 3series 4series essentials pepperdash pepperdashessentials epi essentials plugin</tags>
<repository type="git" url="https://github.com/PepperDash/EssentialsPluginTemplate"/>
</metadata>
<files>
<file src="**" target="lib\net35"/>
<file src="**" target="lib\net47"/>
<file src="README.md" target="docs\"/>
</files>
</package>

View file

@ -3,6 +3,6 @@
[assembly: AssemblyTitle("EssentialsPluginTemplateEpi")] [assembly: AssemblyTitle("EssentialsPluginTemplateEpi")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EssentialsPluginTemplateEpi")] [assembly: AssemblyProduct("EssentialsPluginTemplateEpi")]
[assembly: AssemblyCopyright("Copyright © 2019")] [assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyVersion("1.0.0.*")] [assembly: AssemblyVersion("1.0.0.*")]