diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 2b020d2e..b8ac2660 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -70,7 +70,7 @@ jobs:
#configuration: [Debug, Release]
configuration: [Release]
- runs-on: windows-latest # For a list of available runner types, refer to
+ runs-on: windows-2022 # For a list of available runner types, refer to
# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
env:
@@ -87,9 +87,9 @@ jobs:
# Install the .NET Core workload
- name: Install .NET Core
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4.2.0
with:
- dotnet-version: 6.0.x
+ dotnet-version: 8.0.x
# Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
#- name: Setup MSBuild.exe
@@ -112,24 +112,42 @@ jobs:
dotnet restore "src\\HASS.Agent\\HASS.Agent\\HASS.Agent.csproj"
dotnet restore "src\\HASS.Agent\\HASS.Agent.Satellite.Service\\HASS.Agent.Satellite.Service.csproj"
- - name: Build & Publish HASS.Agent
+ - name: Build & Publish HASS.Agent x64
working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent\\HASS.Agent"
- run: "dotnet publish -c Release -f net6.0-windows10.0.19041.0 -o bin\\Publish-x64\\Release\\ --no-self-contained -r win-x64 -p:Platform=x64"
+ run: "dotnet publish -c Release -f net8.0-windows10.0.22621.0 -o bin\\Publish-x64\\Release\\ --no-self-contained -r win-x64 -p:Platform=x64"
- - name: Build & Publish HASS.Agent.Satellite.Service
+ - name: Build & Publish HASS.Agent.Satellite.Service x64
working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent\\HASS.Agent.Satellite.Service"
- run: "dotnet publish -c Release -f net6.0-windows10.0.19041.0 -o bin\\Publish-x64\\Release\\ --no-self-contained -r win-x64 -p:Platform=x64"
+ run: "dotnet publish -c Release -f net8.0-windows10.0.22621.0 -o bin\\Publish-x64\\Release\\ --no-self-contained -r win-x64 -p:Platform=x64"
- - name: Compile InnoSetup Installer - Satellite Service
+ - name: Compile InnoSetup Installer - Satellite Service x64
working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent.Installer"
run: |
& "${Env:ProgramFiles(x86)}\\Inno Setup 6\\iscc.exe" InstallerScript-Service.iss
- - name: Compile InnoSetup Installer - Client
+ - name: Compile InnoSetup Installer - Client x64
working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent.Installer"
run: |
& "${Env:ProgramFiles(x86)}\\Inno Setup 6\\iscc.exe" InstallerScript.iss
+
+ - name: Build & Publish HASS.Agent x86
+ working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent\\HASS.Agent"
+ run: "dotnet publish -c Release -f net8.0-windows10.0.22621.0 -o bin\\Publish-x86\\Release\\ --no-self-contained -r win-x86 -p:Platform=x86"
+
+ - name: Build & Publish HASS.Agent.Satellite.Service x86
+ working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent\\HASS.Agent.Satellite.Service"
+ run: "dotnet publish -c Release -f net8.0-windows10.0.22621.0 -o bin\\Publish-x86\\Release\\ --no-self-contained -r win-x86 -p:Platform=x86"
+ - name: Compile InnoSetup Installer - Satellite Service x86
+ working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent.Installer"
+ run: |
+ & "${Env:ProgramFiles(x86)}\\Inno Setup 6\\iscc.exe" InstallerScript-Service-x86.iss
+
+ - name: Compile InnoSetup Installer - Client x86
+ working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent.Installer"
+ run: |
+ & "${Env:ProgramFiles(x86)}\\Inno Setup 6\\iscc.exe" InstallerScript-x86.iss
+
- name: Decode the pfx
working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent.Installer"
run: |
@@ -137,42 +155,68 @@ jobs:
$certificatePath = [IO.Path]::GetFullPath(".\\HASS.Agent.Installer.pfx")
[IO.File]::WriteAllBytes($certificatePath, $pfxBytes)
- - name: Sign the installer
+ - name: Sign the x64 installer
working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent.Installer"
run: |
$certificatePassword = ConvertTo-SecureString "${{ secrets.BASE64_ENCODED_PFX_PASSWORD }}" -AsPlainText -Force
$certificate = Get-PfxCertificate -FilePath ".\\HASS.Agent.Installer.pfx" -Password $certificatePassword
Set-AuthenticodeSignature -FilePath ".\\bin\\HASS.Agent.Installer.exe" -Certificate $certificate -HashAlgorithm SHA256 -TimestampServer http://timestamp.digicert.com
+
+ - name: Sign the x86 installer
+ working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent.Installer"
+ run: |
+ $certificatePassword = ConvertTo-SecureString "${{ secrets.BASE64_ENCODED_PFX_PASSWORD }}" -AsPlainText -Force
+ $certificate = Get-PfxCertificate -FilePath ".\\HASS.Agent.Installer.pfx" -Password $certificatePassword
+ Set-AuthenticodeSignature -FilePath ".\\bin\\HASS.Agent.Installer.x86.exe" -Certificate $certificate -HashAlgorithm SHA256 -TimestampServer http://timestamp.digicert.com
- name: Remove the pfx
working-directory: "D:\\a\\HASS.Agent\\HASS.Agent\\src\\HASS.Agent.Installer"
run: Remove-Item -path ".\\HASS.Agent.Installer.pfx"
- #Upload project artifacts: https://github.com/marketplace/actions/upload-a-build-artifact
- - name: Upload build artifacts (HASS Agent)
+ # Upload x64 project artifacts: https://github.com/marketplace/actions/upload-a-build-artifact
+ - name: Upload build artifacts x64 (HASS Agent)
uses: actions/upload-artifact@v4.6.0
with:
name: HASS.Agent
path: "src\\HASS.Agent\\HASS.Agent\\bin\\Publish-x64\\Release"
- - name: Upload build artifacts (HASS Agent Satellite Service)
+ - name: Upload build artifacts x64 (HASS Agent Satellite Service)
uses: actions/upload-artifact@v4.6.0
with:
name: HASS.Agent.Satellite.Service
path: "src\\HASS.Agent\\HASS.Agent.Satellite.Service\\bin\\Publish-x64\\Release"
- - name: Upload build artifacts (HASS Agent Installer)
+ - name: Upload build artifacts x64 (HASS Agent Installer)
uses: actions/upload-artifact@v4.6.0
with:
name: HASS.Agent.Installer
path: "src\\HASS.Agent.Installer\\bin\\HASS.Agent.Installer.exe"
+ # Upload x86 project artifacts
+ - name: Upload build artifacts x86 (HASS Agent)
+ uses: actions/upload-artifact@v4.6.0
+ with:
+ name: HASS.Agent.x86
+ path: "src\\HASS.Agent\\HASS.Agent\\bin\\Publish-x86\\Release"
+
+ - name: Upload build artifacts x86 (HASS Agent Satellite Service)
+ uses: actions/upload-artifact@v4.6.0
+ with:
+ name: HASS.Agent.Satellite.Service.x86
+ path: "src\\HASS.Agent\\HASS.Agent.Satellite.Service\\bin\\Publish-x86\\Release"
+
+ - name: Upload build artifacts x86 (HASS Agent Installer)
+ uses: actions/upload-artifact@v4.6.0
+ with:
+ name: HASS.Agent.Installer.x86
+ path: "src\\HASS.Agent.Installer\\bin\\HASS.Agent.Installer.x86.exe"
+
#- name: Debugging artifact paths
# run: |
# Set-Location src\HASS.Agent
# Get-Childitem
- #draft a release, https://github.com/actions/create-release
+ # Draft a release, https://github.com/actions/create-release
publish:
runs-on: ubuntu-latest
needs: [build]
@@ -184,43 +228,62 @@ jobs:
mkdir HASS.Agent
mkdir HASS.Agent.Satellite.Service
mkdir HASS.Agent.Installer
+ mkdir HASS.Agent.x86
+ mkdir HASS.Agent.Satellite.Service.x86
+ mkdir HASS.Agent.Installer.x86
ls -la
- - name: Download Build Artifacts (HASS Agent)
+ # x64 download
+ - name: Download Build Artifacts x64 (HASS Agent)
uses: actions/download-artifact@v4.1.8
with:
name: HASS.Agent
path: HASS.Agent
- - name: Download Build Artifacts (HASS Agent Satellite Service)
+ - name: Download Build Artifacts x64 (HASS Agent Satellite Service)
uses: actions/download-artifact@v4.1.8
with:
name: HASS.Agent.Satellite.Service
path: HASS.Agent.Satellite.Service
- - name: Download Build Artifacts (HASS Agent Installer)
+ - name: Download Build Artifacts x64 (HASS Agent Installer)
uses: actions/download-artifact@v4.1.8
with:
name: HASS.Agent.Installer
path: HASS.Agent.Installer
+
+ # x86 download
+ - name: Download Build Artifacts x86 (HASS Agent)
+ uses: actions/download-artifact@v4.1.8
+ with:
+ name: HASS.Agent.x86
+ path: HASS.Agent.x86
+
+ - name: Download Build Artifacts x86 (HASS Agent Satellite Service)
+ uses: actions/download-artifact@v4.1.8
+ with:
+ name: HASS.Agent.Satellite.Service.x86
+ path: HASS.Agent.Satellite.Service.x86
+
+ - name: Download Build Artifacts x86 (HASS Agent Installer)
+ uses: actions/download-artifact@v4.1.8
+ with:
+ name: HASS.Agent.Installer.x86
+ path: HASS.Agent.Installer.x86
- name: Compress HASS Agent directories for manual install
run: |
- cd HASS.Agent
ls -la
- zip -r HASS.Agent.zip ./
- cd ../
- cd HASS.Agent.Satellite.Service
+ zip -r HASS.Agent.Standalone.zip HASS.Agent HASS.Agent.Satellite.Service HASS.Agent.x86 HASS.Agent.Satellite.Service.x86
ls -la
- zip -r HASS.Agent.Satellite.Service.zip ./
- name: Create Draft Release and Upload Build Artifacts
- uses: ncipollo/release-action@v1.10.0
+ uses: ncipollo/release-action@v1.15.0
with:
name: ${{ github.event.inputs.releasetitle }}
draft: true
prerelease: ${{ github.event.inputs.prerelease }}
tag: ${{ github.event.inputs.releasetag }}
artifacts:
- HASS.Agent/HASS.Agent.zip,HASS.Agent.Satellite.Service/HASS.Agent.Satellite.Service.zip,HASS.Agent.Installer/HASS.Agent.Installer.exe
+ HASS.Agent.Installer/HASS.Agent.Installer.exe,HASS.Agent.Installer.x86/HASS.Agent.Installer.x86.exe,HASS.Agent.Standalone.zip
diff --git a/README.md b/README.md
index 9dea2c20..4fdb9a15 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,18 @@
[](https://github.com/hass-agent/HASS.Agent/releases/)
[](#license)
[](https://www.microsoft.com/ "Go to Microsoft homepage")
-[](https://img.shields.io/badge/.NET-6.0-blue)
+[](https://img.shields.io/badge/.NET-8.0-blue)


[](https://discord.com/invite/JfZj98xqJr)
-
-
+
+
+
# HASS.Agent
-HASS.Agent is a Windows-based client (*companion*) application for [Home Assistant](https://www.home-assistant.io), developed in .NET 6.
+HASS.Agent is a Windows-based client (*companion*) application for [Home Assistant](https://www.home-assistant.io), developed in .NET 8.
Click [here](https://github.com/hass-agent/HASS.Agent/releases/latest/download/HASS.Agent.Installer.exe) to download the latest installer.
@@ -52,6 +53,14 @@ The original HASS.Agent has been created by [Sam](https://github.com/LAB02-Admin
Unfortunately due to some time constraints, they're not able to provide the constant support and feature updates. That's where we step in - trying to keep HASS.Agent bug free (dreams need to be big right?) and to introduce new features here and there!
+#### Note on the organization and project name
+*"Why this project is named the same as original HASS.Agent, it's confusing"*
+
+Yes, I agree, you're right. The initial idea after Sam's disappearance was to continue the work and offer it to Sam once they're back.
+Well, now that's more than unlikely since it's been quite a long time we last spoke with Sam.
+
+Knowing what we do now, we've probably made a different decision but doing it now it'll only create more confusion. We have a full rewrite project going and it has been already decided the name is going to be altered.
+
----
### Functionality
@@ -72,7 +81,7 @@ Summary of the core functions:
* **WebView**: quickly show any website, anywhere - no browser required, for instance a HA dashboard.
-* **Satellite Service**: use the service to collect sensordata and execute commands, even when you're not logged in (**not all commands/sensors are available for Satellite Service**)
+* **Satellite Service**: use the service to collect sensor data and execute commands, even when you're not logged in (**not all commands/sensors are available for Satellite Service**)
* All entities are dynamically acquired from your Home Assistant instance.
@@ -88,8 +97,8 @@ Notification examples:

-

+
WebView example, showing a dashboard when right-clicking the tray icon:
@@ -124,11 +133,11 @@ You'll be guided through the configuration options during onboarding:
### Installation
-Installing HASS.Agent is easy; just [download the latest installer](https://github.com/hass-agent/HASS.Agent/releases/latest/download/HASS.Agent.Installer.exe), run it and you're done! The installer is signed by us and won't download or do weird stuff - it just places everything where it should, and launches with the right parameter. (optionally installing .NET6)
+Installing HASS.Agent is easy; just [download the latest installer](https://github.com/hass-agent/HASS.Agent/releases/latest/download/HASS.Agent.Installer.exe), run it and you're done! The installer is signed by us and won't download or do weird stuff - it just places everything where it should, and launches with the right parameter. (optionally installing .NET8)
After installing, the onboarding process will help you get everything configured, step by step. If you want an introduction into HASS.Agent, be sure to read the [introduction docs](https://www.hass-agent.io/latest/getting-started/).
-Original HASS.Agent documentation is available [here](https://hassagent.readthedocs.io/en/latest/introduction/) - please bear in mind however that it may not represent state of things present in this version.
+Original HASS.Agent documentation is available [here](https://www.hass-agent.io/latest/getting-started/#introduction) - please bear in mind however that it may not represent state of things present in this version.
[Click here to download the latest installer](https://github.com/hass-agent/HASS.Agent/releases/latest/download/HASS.Agent.Installer.exe)
@@ -158,7 +167,7 @@ If you want to help with the development of HASS.Agent, check out the [Helping O
### Articles
-### Original HASS.Agent
+### Original HASS.Agent by Sam/LAB02 Research
Liam Alexander Colman from [Home Assistant Guide](https://home-assistant-guide.com) was kind enough to write an article about HASS.Agent: [Integrate Home Assistant with Windows using HASS.Agent](https://home-assistant-guide.com/2022/04/20/integrate-home-assistant-with-windows-using-hass-agent/). The website's full of useful articles, worth having a look :)
@@ -166,11 +175,15 @@ Liam Alexander Colman from [Home Assistant Guide](https://home-assistant-guide.c
### What it's not
-A Linux/macOS client!
+A Linux/macOS client (at least yet)!
+
+Without getting into much of the details, it's not as easy as you think.
+
+With HASS.Agent "2.X" version it's basically impossible. We are thinking about cross-platform support for the "v3 rewrite" but as of now it's only a hopeful wish.
-This question comes up a lot, understandably. However it's currently focussed on being a Windows-based client. Even though .NET 6 allows for Linux/macOS development, it's not as easy as pressing a button. The interface would have to be redesigned from the ground up, sensors and commands would need multiple codebases for each OS, testing would take way more time, every OS handles notifications differently, etc.
+You can try the [official companion app](https://apps.apple.com/us/app/home-assistant/id1099568401) for macOS, or [IoPC](https://github.com/maksimkurb/IoPC) which runs on Linux.
-You can use the [official companion app](https://apps.apple.com/us/app/home-assistant/id1099568401) for macOS, or [IoPC](https://github.com/maksimkurb/IoPC) which runs on Linux. Note: We haven't tested either.
+#### Note: We haven't tested either and we do not track the development efforts.
----
@@ -180,6 +193,21 @@ The best way to help out is to test as much as you can (or even join the beta pr
Same goes for sharing ideas for new (or improved) functionality! If you want, you can [join on Discord](https://discord.com/invite/JfZj98xqJr) to discuss your ideas.
+#### Feature PR Submissions
+
+While all feature PR submissions are welcome, please note that their merging is at ***sole discretion*** of the main developers.
+
+When designing the new feature please take into account:
+- **how they fit with the codebase/codestyle** (yes, we are aware the codebase has it's flaws - hence the rewrite efforts)
+- **is the feature agnostic enough and will benefit all users**
+- **the smaller the PR the better the chance of it being merged**
+
+#### AI Usage
+
+Fully "vibe-coded" submissions will most likely be rejected.
+
+While personal opinions on AI usage and it's impact can vary person-to-person, we'd rather put the effort writing code than reviewing fully AI generated and copy-pasted code.
+
----
### Credits and Licensing
@@ -208,12 +236,14 @@ Everything on the HASS.Agent platform is released under the [MIT license](https:
### Legacy
-HASS.Agent is a .NET 6 application. If for some reason you can't install .NET 6, you can use the last .NET Framework 4.8 version:
+HASS.Agent is a .NET 8 application. If for some reason you can't install .NET 8, you can use the last .NET Framework 4.8 version also developed by Sam:
[v2022.3.8](https://github.com/LAB02-Research/HASS.Agent/releases/tag/v2022.3.8)
-It's pretty feature complete if you just want commands, sensors, quickactions and notifications.
+Per it's release time it was pretty feature complete if you just want commands, sensors, quickactions and notifications.
You'll need to have .NET Framework 4.8 installed on your PC, which you can [download here](https://dotnet.microsoft.com/en-us/download/dotnet-framework/thank-you/net48-web-installer).
-If you find any bugs, feel free to [create a ticket](https://github.com/LAB02-Research/HASS.Agent/issues) and I'll try to patch it.
+#### Please note
+- .NET Framework version is considered legacy and unsupported
+- All issues/requests regarding the .NET Framework version of HASS.Agent will be closed
\ No newline at end of file
diff --git a/assets/logo_128.png b/assets/logo_128.png
new file mode 100644
index 00000000..37e6f839
Binary files /dev/null and b/assets/logo_128.png differ
diff --git a/assets/new_quickaction_example.png b/assets/new_quickaction_example.png
new file mode 100644
index 00000000..14a9078f
Binary files /dev/null and b/assets/new_quickaction_example.png differ
diff --git a/assets/new_sensor_example.png b/assets/new_sensor_example.png
new file mode 100644
index 00000000..5761a8eb
Binary files /dev/null and b/assets/new_sensor_example.png differ
diff --git a/assets/notification_example_1.png b/assets/notification_example_1.png
new file mode 100644
index 00000000..6855dd79
Binary files /dev/null and b/assets/notification_example_1.png differ
diff --git a/assets/notification_example_2.png b/assets/notification_example_2.png
new file mode 100644
index 00000000..1d7ea76c
Binary files /dev/null and b/assets/notification_example_2.png differ
diff --git a/assets/notification_example_3.png b/assets/notification_example_3.png
new file mode 100644
index 00000000..595dc326
Binary files /dev/null and b/assets/notification_example_3.png differ
diff --git a/assets/quickactions_example.png b/assets/quickactions_example.png
new file mode 100644
index 00000000..5bc34ae1
Binary files /dev/null and b/assets/quickactions_example.png differ
diff --git a/assets/satellite_config_example.png b/assets/satellite_config_example.png
new file mode 100644
index 00000000..4ed80a18
Binary files /dev/null and b/assets/satellite_config_example.png differ
diff --git a/assets/sensors_example.png b/assets/sensors_example.png
new file mode 100644
index 00000000..1fb4dbad
Binary files /dev/null and b/assets/sensors_example.png differ
diff --git a/assets/webview_example.png b/assets/webview_example.png
new file mode 100644
index 00000000..01d49ab9
Binary files /dev/null and b/assets/webview_example.png differ
diff --git a/src/HASS.Agent.Installer/BeforeInstallNotice.rtf b/src/HASS.Agent.Installer/BeforeInstallNotice.rtf
index 6499df36..0e67a650 100644
--- a/src/HASS.Agent.Installer/BeforeInstallNotice.rtf
+++ b/src/HASS.Agent.Installer/BeforeInstallNotice.rtf
@@ -1,5 +1,5 @@
{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch0\stshfloch31506\stshfhich31506\stshfbi31506\deflang2057\deflangfe2057\themelang1045\themelangfe0\themelangcs1025{\fonttbl{\f0\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
-{\f34\fbidi \froman\fcharset238\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f43\fbidi \fswiss\fcharset238\fprq2{\*\panose 020b0604030504040204}Tahoma;}
+{\f34\fbidi \froman\fcharset238\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f43\fbidi \fswiss\fcharset238\fprq2{\*\panose 00000000000000000000}Tahoma;}
{\flomajor\f31500\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fhimajor\f31502\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0302020204030204}Calibri Light;}{\fbimajor\f31503\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\flominor\f31504\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
@@ -43,8 +43,8 @@
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31506\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive
\rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf19 \sbasedon10 \sunhideused \styrsid490208 Hyperlink;}{\*\cs16 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \cf20\chshdng0\chcfpat0\chcbpat21 \sbasedon10 \ssemihidden \sunhideused \styrsid490208 Unresolved Mention;}}}}
-{\*\rsidtbl \rsid227266\rsid490208\rsid1446401\rsid2324250\rsid3874449\rsid4072052\rsid5209844\rsid5534268\rsid7356386\rsid7820567\rsid12408085\rsid16263522}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1
-\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Amadeo}{\operator Amadeo}{\creatim\yr2023\mo11\dy27\hr16\min53}{\revtim\yr2024\mo9\dy27\hr20\min54}{\version10}{\edmins6}{\nofpages1}{\nofwords136}{\nofchars776}{\nofcharsws911}{\vern81}}
+{\*\rsidtbl \rsid227266\rsid490208\rsid1010640\rsid1446401\rsid2324250\rsid3874449\rsid4072052\rsid5209844\rsid5534268\rsid7356386\rsid7820567\rsid12408085\rsid16263522}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0
+\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Amadeo}{\operator Amadeo}{\creatim\yr2023\mo11\dy27\hr16\min53}{\revtim\yr2025\mo5\dy11\hr20\min29}{\version11}{\edmins6}{\nofpages1}{\nofwords112}{\nofchars640}{\nofcharsws751}{\vern81}}
{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\margl1417\margr1417\margt1417\margb1417\gutter0\ltrsect
\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1
\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1417\dgvorigin1417\dghshow1\dgvshow1
@@ -57,19 +57,16 @@
\f31506\fs22\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid227266 \line }{\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid490208\charrsid4072052 Welcome to HASS.Agent Installer!
\par This version is maintained by the }{\field{\*\fldinst {\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid2324250 HYPERLINK "https://github.com/hass-agent/" }{\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid2324250 {\*\datafield
00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b56000000680074007400700073003a002f002f006700690074006800750062002e0063006f006d002f0068006100730073002d006100670065006e0074002f000000795881f43b1d7f48af2c825dc485276300000000
-a5ab000300}}}{\fldrslt {\rtlch\fcs1 \af43 \ltrch\fcs0 \cs15\f43\fs16\ul\cf19\insrsid490208\charrsid2324250 HASS.Agent Team}}}\sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid16263522\sftnbj {\rtlch\fcs1
-\af43 \ltrch\fcs0 \f43\fs16\insrsid490208\charrsid4072052 and is a fork of the }{\field\flddirty{\*\fldinst {\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid490208\charrsid4072052 HYPERLINK "https://github.com/LAB02-Research/HASS.Agent" }{\rtlch\fcs1
-\af43 \ltrch\fcs0 \f43\fs16\insrsid490208\charrsid4072052 {\*\datafield
+a5ab00030000}}}{\fldrslt {\rtlch\fcs1 \af43 \ltrch\fcs0 \cs15\f43\fs16\ul\cf19\insrsid490208\charrsid2324250 HASS.Agent Team}}}\sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid16263522\sftnbj {
+\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid490208\charrsid4072052 and is a fork of the }{\field\flddirty{\*\fldinst {\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid490208\charrsid4072052 HYPERLINK "https://github.com/LAB02-Research/HASS.Agent" }{
+\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid490208\charrsid4072052 {\*\datafield
00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b72000000680074007400700073003a002f002f006700690074006800750062002e0063006f006d002f004c0041004200300032002d00520065007300650061007200630068002f0048004100530053002e0041006700
-65006e0074000000795881f43b1d7f48af2c825dc485276300000000a5ab00030064d96621af0000}}}{\fldrslt {\rtlch\fcs1 \af43 \ltrch\fcs0 \cs15\f43\fs16\ul\cf19\insrsid490208\charrsid4072052 original}}}\sectd \ltrsect
+65006e0074000000795881f43b1d7f48af2c825dc485276300000000a5ab00030064d96621af000000}}}{\fldrslt {\rtlch\fcs1 \af43 \ltrch\fcs0 \cs15\f43\fs16\ul\cf19\insrsid490208\charrsid4072052 original}}}\sectd \ltrsect
\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid16263522\sftnbj {\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid490208\charrsid4072052 version by LAB02-Research.
\par The intention of this version is to provide bug-fix and feature updated until the development of original version is resumed.
\par We've tried our best to maintain compatibility with the original version but some breaking changes are unavoidable.
\par The installer has an option to migrate current installation configuration for seamless transition, please remember that some settings (like MQTT configuration) may need
- to be changed if you'd like to run two instances of HASS.Agent - forked and original one.}{\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid12408085
-\par }{\rtlch\fcs1 \af43 \ltrch\fcs0 \b\f43\fs16\insrsid5534268\charrsid1446401 Please note:}{\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid5534268 the }{\rtlch\fcs1 \af43 \ltrch\fcs0 \b\f43\fs16\insrsid5534268\charrsid1446401 migration}{\rtlch\fcs1 \af43
-\ltrch\fcs0 \f43\fs16\insrsid5534268 option should be used }{\rtlch\fcs1 \af43 \ltrch\fcs0 \b\f43\fs16\insrsid5534268\charrsid5534268 only once}{\rtlch\fcs1 \af43 \ltrch\fcs0 \b\f43\fs16\insrsid5534268 . }{\rtlch\fcs1 \af43 \ltrch\fcs0
-\f43\fs16\insrsid5534268 Using it more than once will once again try to copy the configuration from the original HASS.Agent.}{\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid5534268\charrsid5534268
+ to be changed if you'd like to run two instances of HASS.Agent - forked and original one.}{\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid5534268\charrsid5534268
\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
@@ -214,8 +211,8 @@ fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000503f
-ad9e0e11db01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
+ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000b09a
+eb9fa2c2db01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000105000000000000}}
\ No newline at end of file
diff --git a/src/HASS.Agent.Installer/DotNet8Notice.rtf b/src/HASS.Agent.Installer/DotNet8Notice.rtf
new file mode 100644
index 00000000..271cf46f
--- /dev/null
+++ b/src/HASS.Agent.Installer/DotNet8Notice.rtf
@@ -0,0 +1,226 @@
+{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang2057\deflangfe2057\themelang2057\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\f2\fbidi \fmodern\fcharset238\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\fbidi \froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f10\fbidi \fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}
+{\f34\fbidi \froman\fcharset238\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f42\fbidi \fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Segoe UI Emoji;}
+{\f43\fbidi \fswiss\fcharset238\fprq2{\*\panose 00000000000000000000}Tahoma;}{\flomajor\f31500\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\fdbmajor\f31501\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0302020204030204}Calibri Light;}
+{\fbimajor\f31503\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\fdbminor\f31505\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0502020204030204}Calibri;}
+{\fbiminor\f31507\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f46\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\f45\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\f47\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f48\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f49\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f50\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\f51\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f52\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f66\fbidi \fmodern\fcharset0\fprq1 Courier New;}{\f65\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}
+{\f67\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f68\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f69\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f70\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}
+{\f71\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f72\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f386\fbidi \froman\fcharset0\fprq2 Cambria Math;}{\f385\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}
+{\f387\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f388\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f391\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f392\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}
+{\f416\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\f415\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f417\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f418\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
+{\f419\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f420\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\f421\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f422\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}
+{\f476\fbidi \fswiss\fcharset0\fprq2 Tahoma;}{\f475\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f477\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}{\f478\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;}
+{\f479\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f480\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f481\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f482\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}
+{\f483\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
+{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
+{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
+{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \fswiss\fcharset0\fprq2 Calibri Light;}
+{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}
+{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}
+{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
+{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
+{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
+{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \froman\fcharset0\fprq2 Times New Roman;}
+{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
+{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
+{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}
+{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}
+{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}
+{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
+{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;
+\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;
+\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }
+\noqfpromote {\upr{\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0
+\fs22\lang2057\langfe2057\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
+\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe2057\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 \snext11 \ssemihidden \sunhideused
+Normal Table;}}{\*\ud\uc0{\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0
+\fs22\lang2057\langfe2057\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
+\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe2057\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 \snext11 \ssemihidden \sunhideused
+Normal Table;}}}}{\*\listtable{\list\listtemplateid651192760\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid134807553\'01{\uc1\u-3913 ?};}{\levelnumbers;}
+\f3\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807555\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\lin1440 }
+{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807557\'01{\uc1\u-3929 ?};}{\levelnumbers;}\f10\fbias0 \fi-360\li2160\lin2160 }{\listlevel\levelnfc23
+\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807553\'01{\uc1\u-3913 ?};}{\levelnumbers;}\f3\fbias0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0
+\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807555\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1
+\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807557\'01{\uc1\u-3929 ?};}{\levelnumbers;}\f10\fbias0 \fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative
+\levelspace360\levelindent0{\leveltext\leveltemplateid134807553\'01{\uc1\u-3913 ?};}{\levelnumbers;}\f3\fbias0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0
+{\leveltext\leveltemplateid134807555\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807557
+\'01{\uc1\u-3929 ?};}{\levelnumbers;}\f10\fbias0 \fi-360\li6480\lin6480 }{\listname ;}\listid1037851123}}{\*\listoverridetable{\listoverride\listid1037851123\listoverridecount0\ls1}}{\*\rsidtbl \rsid4395212\rsid14366970\rsid15153285\rsid16274723}{\mmathPr
+\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator Amadeo}{\creatim\yr2025\mo5\dy11\hr19\min54}{\revtim\yr2025\mo5\dy11\hr20\min25}{\version4}{\edmins2}{\nofpages1}
+{\nofwords47}{\nofchars268}{\nofcharsws314}{\vern81}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\margl1417\margr1417\margt1417\margb1417\gutter0\ltrsect
+\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701
+\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot14366970 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid16263522\sftnbj
+{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}
+{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8
+\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid16274723 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe2057\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 {\rtlch\fcs1 \af43
+\ltrch\fcs0 \f43\fs16\insrsid16274723
+\par }{\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid16274723 \hich\af43\dbch\af31505\loch\f43 Starting with version }{\rtlch\fcs1 \af43 \ltrch\fcs0 \b\f43\fs16\insrsid16274723\charrsid16274723 \hich\af43\dbch\af31505\loch\f43 2.2.0}{\rtlch\fcs1 \af43
+\ltrch\fcs0 \f43\fs16\insrsid16274723 \hich\af43\dbch\af31505\loch\f43 , \hich\af43\dbch\af31505\loch\f43 HASS.Agent no longer uses .NET6 but instead ut\hich\af43\dbch\af31505\loch\f43 ilize\hich\af43\dbch\af31505\loch\f43 s }{\rtlch\fcs1 \af43
+\ltrch\fcs0 \b\f43\fs16\insrsid16274723\charrsid4395212 \hich\af43\dbch\af31505\loch\f43 .NET8}{\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid16274723 .
+\par \hich\af43\dbch\af31505\loch\f43 If you do not have \hich\af43\dbch\af31505\loch\f43 .NET8 libraries already installed \hich\af43\dbch\af31505\loch\f43 b\hich\af43\dbch\af31505\loch\f43 y another software, \hich\af43\dbch\af31505\loch\f43 installer will
+\hich\af43\dbch\af31505\loch\f43 download and install it fo\hich\af43\dbch\af31505\loch\f43 r you.
+\par \hich\af43\dbch\af31505\loch\f43 There \hich\af43\dbch\af31505\loch\f43 is n\hich\af43\dbch\af31505\loch\f43 o special action required from your side\hich\af43\dbch\af31505\loch\f43 , \hich\af43\dbch\af31505\loch\f43
+we just wanted to provide an additional \loch\af43\dbch\af31505\hich\f43 \'93\hich\af43\dbch\af31505\loch\f43 FYI\loch\af43\dbch\af31505\hich\f43 \'94\hich\af43\dbch\af31505\loch\f43 }{\rtlch\fcs1 \af42 \ltrch\fcs0
+\fs16\loch\af42\hich\af42\dbch\af42\insrsid16274723\charrsid16274723 \loch\af42\dbch\af42\hich\f42 \u-10179\'3f\u-8694\'3f}{\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid16274723\charrsid16274723
+\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16274723\charrsid11156998
+\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15153285\charrsid16274723
+\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
+9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
+5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
+b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
+0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
+a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
+c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
+0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
+a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
+6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
+4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
+4757e8d3f729e245eb2b260a0238fd010000ffff0300504b03041400060008000000210041daf6e5a6070000e6200000160000007468656d652f7468656d652f
+7468656d65312e786d6cec59cd8b1bc915bf07f23f347d97f5d5ad8fc1f222b524cfda33f660c90e7bac914add65557789aed28cc56208de532e81c026e49085
+bded21842cecc22eb9e48f31d8249b3f22afaa5bdd5552c9f3810326cc0886eed2efbdfad57bafde7baabaffd9ab983a1738e584253db77eafe63a3899b13949
+c29efb7c3aae745c870b94cc116509eeb91bccddcf1efcfa57f7d19188708c1d904ff811eab99110aba36a95cf6018f17b6c8513f86ec1d21809784dc3ea3c45
+97a037a6d546add6aac68824ae93a018d49e32b1b974566849b0583b4f170b32c3ee83ed24230a332582cb81194d27720a9c4b9e29195d64beac4b20dff080a6
+ce05a23d17a69db3cb297e255c87222ee08b9e5b537f6ef5c1fd2a3aca85a83820abc98dd55f2e970bcc970d35671a9e17937a9eefb5fa857e05a0621f376a8f
+5aa356a14f01d06c060bceb8983adb8dc0cbb11a287bb4e81eb687cdba81d7f437f738f77df931f00a94e9f7f6f0e371005634f00a94e1fd3dbc3fe80e86a67e
+05caf0ad3d7cbbd61f7a6d43bf02459424cb3d74cd6f3583ed6a0bc882d1632bbceb7be37623575ea2201a8a2093532c5822ae08b918bd64e91870124f912089
+23362bbc403388ed0051729e12e7848411c4df0a258cc370ad511bd79af05f7e3cf5a41c8b8e30d2a4253d20c4f786242d87cf52b2123df711687535c8bb9f7f
+7efbe6c7b76f7e7afbd5576fdffc3d9f5ba932e48e5112ea72bf7cf787ff7cf35be7df3f7cfbcbd77fcca6dec5731dfffe6fbf7bff8f7f7e483dacb834c5bb3f
+7dfffec7efdffdf9f7fffaebd716edfd149debf0298931779ee04be7198b618116fef83cbd99c434424497e82721470992b358f48f4464a09f6c104516dc009b
+767c9142c6b1011fae5f1a842751ba16c4a2f171141bc053c6e880a5562b3c967369669eae93d03e79bad671cf10bab0cd1da0c4f0f268bd828c4b6c2a83081b
+34cf284a040a71828523bf634b8c2dabfb8210c3aea7649632ce16c2f982380344ac26999273239a4aa16312835f363682e06fc336a72f9c01a3b6550ff18589
+84bd81a885fc1453c38c0fd15aa0d8a6728a62aa1bfc0489c84672b249673a6ec405783ac49439a339e6dc26f33485f56a4e7f0c69c6eef653ba894d642ac8d2
+a6f30431a623876c1944285ed9b01392443af673be841045ce191336f8293377887c073fa0e4a0bb5f402fa04f707536780e1956972803447eb34e2dbe7c8899
+11bf930d5d206c4b35fd3436526c3f25d6e818ac4323b44f30a6e812cd31769e7f6e6130602bc3e625e947116495636c0bac47c88c55f99e608e1dd5e3ece7c9
+13c28d909de0901de073bad9493c1b94c4283da4f909785db7f9084a5d6c0b80a774b6d4814f087486102f56a33ce5a0430bee835acf22641430f9ceedf1ba49
+0dff5d678fc1be7c69d0b8c6be04197c631948ecbacc076d3345d498a00c9829822ec3966e41c4707f29228bab125b5be516e6a62ddd004d92d1f4c424b9b203
+dae97dfcff5def031dc6bbbf7c63d96c1fa7dfb12b3692d50d3b9d43c9e478a7bf3984dbed6a0296cec9a7dfd40cd13a39c35047f633d65d4f73d7d3b8fff73d
+cda1fd7cd7c91cea37ee3a19173a8cbb4e263f5cf9389d4cd9bc405f230f3cb2f31e75fa135f75f8b320944ec486e213aece7f38fcac998f61508aabe3505c9c
+09ae227894d50ee63170618a948c9332f11b22a249845670485477a59290e7aa43eeac1887b323356cd52df1741d9fb27976f459afcb63ceacc07224caf19a5f
+8cc37995c8d0ad76799c57a8576c4375faba2520656f42429bcc24d1b490686f07a591d4592f18cd4242adeca3b0e85a5874a4faadabf65800b5c22bf0bbdb81
+5feb3dd7f7400484e0580e7af4b9f453e6eaad7795333fa6a70f19d38800e8b3b711507aba2bb91e5c9e5c5d166ad7f0b441420b379384b28ceaf37804bf86f3
+e894a3d7a171535f774b971af4a429d47c105a258d76e7432c6eeb6b90dbcd0d34d133054d9ccb9edb6afa103233b4eab90b383b86c77805b1c3e54f2f4443b8
+96998934dbf0b7c92cab948b21e25166709574b26c101381538792b8e7cae5176ea089ca218a5bbd0109e19325d785b4f2a99103a79b4ec68b059e09ddedda88
+b474f60a193ecb15d66f95f8edc15292adc1dd93687ee99cd375fa0c4188f9edba34e09c70b842a867d69c13b81a2b1259197f3b85294fbbfadd948aa16c1cd1
+5584f28aa227f30cae52794147bd1536d0def23583413593e485f03c94055637aa514d8baa9171385875af169296d3926659338dac22aba63d8b19336ccbc08e
+2d6f57e435565b13434ed32b7c96ba77536e779beb76fa84a24a80c10bfb59aaee350a8246ad9ccca02619efa76199b3f351b3766c177805b5eb14092debb7b6
+6a77ec56d408eb743078abca0f72bb510b438b6d7ba92cadaed4f5db6e76fe1292c7109add35155cb9122eb153040dd144f52459da802df24ae45b039e9c754a
+7aee9735bfef050d3fa8d43afea8e235bd5aa5e3f79b95beef37eb23bf5e1b0e1aafa1b08828aefbd975fe18ee31e826bfd457e37b17fbf1f6aae6de8cc555a6
+aeeaab8ab8bad8af378c8bfdec2adf99ca1b7bd7219074be6c35c6dd6677d0aa749bfd71c51b0e3a956ed01a5486ada03d1c0f03bfd31dbf769d0b05f6facdc0
+6b8d3a95563d082a5eab26e977ba95b6d768f4bd76bf33f2faaff33606569ea58fdc16605ec5ebc17f010000ffff0300504b0304140006000800000021000dd1
+909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277
+086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b
+64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996
+509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff
+0000001c0200001300000000000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7
+c0000000360100000b00000000000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000
+001c00000000000000000000000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210041
+daf6e5a6070000e62000001600000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d0014000600080000
+0021000dd1909fb60000001b0100002700000000000000000000000000b00a00007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000ab0b00000000}
+{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
+617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
+6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
+656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
+{\*\latentstyles\lsdstimax375\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9;
+\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;
+\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;
+\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;
+\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
+\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;
+\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;
+\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;
+\lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
+\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4;
+\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4;
+\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1;
+\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1;
+\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2;
+\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2;
+\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3;
+\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4;
+\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4;
+\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5;
+\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5;
+\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6;
+\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6;
+\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark;
+\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1;
+\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1;
+\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2;
+\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3;
+\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3;
+\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4;
+\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4;
+\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
+\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
+\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
+\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;}}{\*\datastore 010500000200000018000000
+4d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
+d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e500000000000000000000000060fa
+e211a2c2db01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000105000000000000}}
\ No newline at end of file
diff --git a/src/HASS.Agent.Installer/InstallerScript-Service-x86.iss b/src/HASS.Agent.Installer/InstallerScript-Service-x86.iss
new file mode 100644
index 00000000..d34a5ec6
--- /dev/null
+++ b/src/HASS.Agent.Installer/InstallerScript-Service-x86.iss
@@ -0,0 +1,135 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+; Modified to suit HASS.Agent requirements :)
+
+; InnoDependencyInstaller
+; Thanks to https://github.com/DomGries/InnoDependencyInstaller for the amazing work!
+#define public Dependency_Path_NetCoreCheck "dependencies\"
+#include "CodeDependencies.iss"
+
+; Standard installation constants
+#define MyAppName "HASS.Agent Satellite Service"
+#define MyAppVersion "2.2.1"
+#define MyAppPublisher "HASS.Agent Team"
+#define MyAppURL "https://hass-agent.io"
+#define MyAppExeName "HASS.Agent.Satellite.Service.exe"
+#define ServiceName "hass.agent.svc"
+#define ServiceDisplayName "HASS.Agent - Satellite Service"
+#define ServiceDescription "Satellite service for HASS.Agent: a Windows based Home Assistant client. This service processes commands and sensors without the requirement of a logged-in user."
+
+[Setup]
+;SetupMutex=Global\HASS.Agent.Setup.Satellite.Mutex,HASS.Agent.Satellite.Setup.Mutex
+AppMutex=Global\\HASS.Agent.Service.Mutex
+AppId={{4004588E-F411-41C2-ABD8-A898B0A14B93}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+;AppVerName={#MyAppName} {#MyAppVersion}
+AppPublisher={#MyAppPublisher}
+AppPublisherURL={#MyAppURL}
+AppSupportURL={#MyAppURL}
+AppUpdatesURL={#MyAppURL}
+DefaultDirName={commonpf32}\{#MyAppName}\Service
+DisableProgramGroupPage=yes
+LicenseFile=..\..\LICENSE.md
+InfoBeforeFile=.\BeforeInstallNotice-Service.rtf
+InfoAfterFile=.\AfterInstallNotice-Service.rtf
+PrivilegesRequired=admin
+OutputDir=.\bin
+OutputBaseFilename=HASS.Agent.Service.Installer.x86
+SetupIconFile=..\HASS.Agent\HASS.Agent.Shared\hassagent.ico
+Compression=lzma
+SolidCompression=yes
+WizardStyle=modern
+CloseApplications=yes
+CloseApplicationsFilter=*.*
+UninstallDisplayIcon={app}\{#MyAppExeName}
+UninstallDisplayName={#MyAppName} {#MyAppVersion}
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+[Files]
+; Service files
+Source: "..\HASS.Agent\HASS.Agent.Satellite.Service\bin\Publish-x86\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; BeforeInstall: StopSatelliteService()
+
+[Run]
+Filename: "{sys}\sc.exe"; Parameters: "start {#ServiceName}"; Description: "Start Satellite Service"; Flags: postinstall runhidden runascurrentuser
+
+[Registry]
+Root: HKLM; Subkey: "SOFTWARE\HASSAgent\SatelliteService"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"; Flags: createvalueifdoesntexist uninsdeletevalue
+
+; Ensure LibreHardwareMonitor/WinRing0 files are removed if left due to any reason by previous installs
+[InstallDelete]
+Type: files; Name: "{app}\LibreHardwareMonitorLib.dll"
+Type: files; Name: "{app}\HASS.Agent.Satellite.Service.sys"
+
+; Service registration and removal
+[Run]
+Filename: "{sys}\sc.exe"; Parameters: "create {#ServiceName} binpath= ""\""{app}\{#MyAppExeName}""\"""; Flags: runhidden
+Filename: "{sys}\sc.exe"; Parameters: "failure {#ServiceName} reset= 86400 actions= restart/60000/restart/60000//1000"; Flags: runhidden
+Filename: "{sys}\sc.exe"; Parameters: "description {#ServiceName} ""{#ServiceDescription}"""; Flags: runhidden
+Filename: "{sys}\sc.exe"; Parameters: "config {#ServiceName} DisplayName= ""{#ServiceDisplayName}"""; Flags: runhidden
+Filename: "{sys}\sc.exe"; Parameters: "config {#ServiceName} start= auto"; Flags: runhidden
+Filename: "{sys}\sc.exe"; Parameters: "config {#ServiceName} binpath= ""\""{app}\{#MyAppExeName}""\"""; Flags: runhidden
+[UninstallRun]
+Filename: "{sys}\net.exe"; Parameters: "stop {#ServiceName}"; RunOnceId: StopService; Flags: runhidden
+Filename: "{sys}\timeout.exe"; Parameters: "5"; RunOnceId: Delay1; Flags:runhidden
+Filename: "{sys}\sc.exe"; Parameters: "delete {#ServiceName}" ; RunOnceId: DeleteService; Flags: runhidden
+Filename: "{sys}\timeout.exe"; Parameters: "5"; RunOnceId: Delay2; Flags:runhidden
+
+[Code]
+function InitializeSetup: Boolean;
+begin
+ Dependency_ForceX86 := True;
+ Dependency_AddDotNet80Desktop;
+ Result := True;
+end;
+
+procedure CurStepChanged(CurStep: TSetupStep);
+var
+ ProgressPage: TOutputProgressWizardPage;
+ I, Step, Wait, ResultCode: Integer;
+begin
+ if CurStep = ssInstall then
+ begin
+ //thanks to https://stackoverflow.com/a/39827761
+ Wait := 5000;
+ Step := 100;
+ ProgressPage :=
+ CreateOutputProgressPage(
+ WizardForm.PageNameLabel.Caption,
+ WizardForm.PageDescriptionLabel.Caption);
+ ProgressPage.SetText('Making sure the satellite service is stopped...', '');
+ ProgressPage.SetProgress(0, Wait);
+ ProgressPage.Show;
+
+ Exec(ExpandConstant('{sys}') + '\net.exe', 'stop ' + ExpandConstant('{#ServiceName}'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
+
+ try
+ for I := 0 to Wait div Step do
+ begin
+ ProgressPage.SetProgress(I * Step, Wait);
+ Sleep(Step);
+ end;
+ finally
+ ProgressPage.Hide;
+ ProgressPage.Free;
+ end;
+
+ Exec(ExpandConstant('{sys}') + '\net.exe', 'stop ' + ExpandConstant('{#ServiceName}'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
+ //Exec(ExpandConstant('{sys}\taskkill.exe'), '/f /im ' + '"' + ExpandConstant('{#MyAppExeName}') + '"', ExpandConstant('{sys}'), SW_HIDE, ewWaitUntilTerminated, ResultCode);
+
+ end;
+end;
+
+procedure StopSatelliteService();
+var
+ ResultCode: Integer;
+begin
+ Exec(ExpandConstant('{sys}') + '\net.exe', 'stop ' + ExpandConstant('{#ServiceName}'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
+
+ //Ensure LibreHardwareMonitor/WinRing0 files are removed
+ DeleteFile(ExpandConstant('{app}\LibreHardwareMonitorLib.dll'));
+ DeleteFile(ExpandConstant('{app}\HASS.Agent.Satellite.Service.sys'));
+end;
\ No newline at end of file
diff --git a/src/HASS.Agent.Installer/InstallerScript-Service.iss b/src/HASS.Agent.Installer/InstallerScript-Service.iss
index 7270347e..f9c44adb 100644
--- a/src/HASS.Agent.Installer/InstallerScript-Service.iss
+++ b/src/HASS.Agent.Installer/InstallerScript-Service.iss
@@ -9,7 +9,7 @@
; Standard installation constants
#define MyAppName "HASS.Agent Satellite Service"
-#define MyAppVersion "2.1.1"
+#define MyAppVersion "2.2.1"
#define MyAppPublisher "HASS.Agent Team"
#define MyAppURL "https://hass-agent.io"
#define MyAppExeName "HASS.Agent.Satellite.Service.exe"
@@ -41,7 +41,7 @@ SetupIconFile=..\HASS.Agent\HASS.Agent.Shared\hassagent.ico
Compression=lzma
SolidCompression=yes
WizardStyle=modern
-CloseApplications=force
+CloseApplications=yes
CloseApplicationsFilter=*.*
UninstallDisplayIcon={app}\{#MyAppExeName}
UninstallDisplayName={#MyAppName} {#MyAppVersion}
@@ -52,14 +52,19 @@ Name: "english"; MessagesFile: "compiler:Default.isl"
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Files]
; Service files
-Source: "..\HASS.Agent\HASS.Agent.Satellite.Service\bin\Publish-x64\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: "..\HASS.Agent\HASS.Agent.Satellite.Service\bin\Publish-x64\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; BeforeInstall: StopSatelliteService()
[Run]
-Filename: "{sys}\sc.exe"; Parameters: "start {#ServiceName}"; Description: "Start Satellite Service"; Flags: postinstall runhidden runascurrentuser
+Filename: "{sys}\sc.exe"; Parameters: "start {#ServiceName}"; Description: "Start Satellite Service"; Flags: postinstall runhidden runascurrentuser
[Registry]
Root: HKLM; Subkey: "SOFTWARE\HASSAgent\SatelliteService"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"; Flags: createvalueifdoesntexist uninsdeletevalue
+; Ensure LibreHardwareMonitor/WinRing0 files are removed if left due to any reason by previous installs
+[InstallDelete]
+Type: files; Name: "{app}\LibreHardwareMonitorLib.dll"
+Type: files; Name: "{app}\HASS.Agent.Satellite.Service.sys"
+
; Service registration and removal
[Run]
Filename: "{sys}\sc.exe"; Parameters: "create {#ServiceName} binpath= ""\""{app}\{#MyAppExeName}""\"""; Flags: runhidden
@@ -69,7 +74,7 @@ Filename: "{sys}\sc.exe"; Parameters: "config {#ServiceName} DisplayName= ""{#Se
Filename: "{sys}\sc.exe"; Parameters: "config {#ServiceName} start= auto"; Flags: runhidden
Filename: "{sys}\sc.exe"; Parameters: "config {#ServiceName} binpath= ""\""{app}\{#MyAppExeName}""\"""; Flags: runhidden
[UninstallRun]
-Filename: "{sys}\sc.exe"; Parameters: "stop {#ServiceName}"; RunOnceId: StopService; Flags: runhidden
+Filename: "{sys}\net.exe"; Parameters: "stop {#ServiceName}"; RunOnceId: StopService; Flags: runhidden
Filename: "{sys}\timeout.exe"; Parameters: "5"; RunOnceId: Delay1; Flags:runhidden
Filename: "{sys}\sc.exe"; Parameters: "delete {#ServiceName}" ; RunOnceId: DeleteService; Flags: runhidden
Filename: "{sys}\timeout.exe"; Parameters: "5"; RunOnceId: Delay2; Flags:runhidden
@@ -78,7 +83,7 @@ Filename: "{sys}\timeout.exe"; Parameters: "5"; RunOnceId: Delay2; Flags:runhidd
function InitializeSetup: Boolean;
begin
Dependency_ForceX86 := False;
- Dependency_AddDotNet60Desktop;
+ Dependency_AddDotNet80Desktop;
Result := True;
end;
@@ -89,8 +94,6 @@ var
begin
if CurStep = ssInstall then
begin
- Exec(ExpandConstant('{sys}') + '\sc.exe', 'stop ' + ExpandConstant('{#ServiceName}'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
-
//thanks to https://stackoverflow.com/a/39827761
Wait := 5000;
Step := 100;
@@ -101,6 +104,9 @@ begin
ProgressPage.SetText('Making sure the satellite service is stopped...', '');
ProgressPage.SetProgress(0, Wait);
ProgressPage.Show;
+
+ Exec(ExpandConstant('{sys}') + '\net.exe', 'stop ' + ExpandConstant('{#ServiceName}'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
+
try
for I := 0 to Wait div Step do
begin
@@ -111,5 +117,20 @@ begin
ProgressPage.Hide;
ProgressPage.Free;
end;
+
+ Exec(ExpandConstant('{sys}') + '\net.exe', 'stop ' + ExpandConstant('{#ServiceName}'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
+ //Exec(ExpandConstant('{sys}\taskkill.exe'), '/f /im ' + '"' + ExpandConstant('{#MyAppExeName}') + '"', ExpandConstant('{sys}'), SW_HIDE, ewWaitUntilTerminated, ResultCode);
+
end;
+end;
+
+procedure StopSatelliteService();
+var
+ ResultCode: Integer;
+begin
+ Exec(ExpandConstant('{sys}') + '\net.exe', 'stop ' + ExpandConstant('{#ServiceName}'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
+
+ //Ensure LibreHardwareMonitor/WinRing0 files are removed
+ DeleteFile(ExpandConstant('{app}\LibreHardwareMonitorLib.dll'));
+ DeleteFile(ExpandConstant('{app}\HASS.Agent.Satellite.Service.sys'));
end;
\ No newline at end of file
diff --git a/src/HASS.Agent.Installer/InstallerScript-x86.iss b/src/HASS.Agent.Installer/InstallerScript-x86.iss
new file mode 100644
index 00000000..75927faa
--- /dev/null
+++ b/src/HASS.Agent.Installer/InstallerScript-x86.iss
@@ -0,0 +1,145 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+; Modified to suit HASS.Agent requirements :)
+
+; InnoDependencyInstaller
+; Thanks to https://github.com/DomGries/InnoDependencyInstaller for the amazing work!
+#define public Dependency_Path_NetCoreCheck "dependencies\"
+#include "CodeDependencies.iss"
+
+; Standard installation constants
+#define MyAppName "HASS.Agent"
+#define MyAppVersion "2.2.1"
+#define MyAppPublisher "HASS.Agent Team"
+#define MyAppURL "https://hass-agent.io"
+#define MyAppExeName "HASS.Agent.exe"
+
+#define MigrationNotice "MigrationNotice.rtf"
+#define DotNet8Notice "DotNet8Notice.rtf"
+
+[Setup]
+SetupMutex=Global\HASS.Agent.Setup.Mutex,HASS.Agent.Setup.Mutex
+AppMutex=HASS.Agent.App.Mutex
+AppId={{7BBED458-609B-4D13-AD9E-4FF219DF8644}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+;AppVerName={#MyAppName} {#MyAppVersion}
+AppPublisher={#MyAppPublisher}
+AppPublisherURL={#MyAppURL}
+AppSupportURL={#MyAppURL}
+AppUpdatesURL={#MyAppURL}
+DefaultDirName={localappdata}\{#MyAppName}\Client
+DisableProgramGroupPage=yes
+LicenseFile=..\..\LICENSE.md
+InfoBeforeFile=.\BeforeInstallNotice.rtf
+InfoAfterFile=.\AfterInstallNotice.rtf
+; Uncomment the following line to run in non administrative install mode (install for current user only.)
+PrivilegesRequired=lowest
+OutputDir=.\bin
+OutputBaseFilename=HASS.Agent.Installer.x86
+SetupIconFile=..\HASS.Agent\HASS.Agent.Shared\hassagent.ico
+Compression=lzma
+SolidCompression=yes
+WizardStyle=modern
+CloseApplications=force
+CloseApplicationsFilter=*.*
+UninstallDisplayIcon={app}\{#MyAppExeName}
+UninstallDisplayName={#MyAppName} {#MyAppVersion}
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+[Files]
+; Client files
+Source: "..\HASS.Agent\HASS.Agent\bin\Publish-x86\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: "{#MigrationNotice}"; Flags: dontcopy
+Source: "{#DotNet8Notice}"; Flags: dontcopy
+; Service installer
+Source: ".\bin\HASS.Agent.Service.Installer.x86.exe"; DestDir: "{tmp}"; Flags: ignoreversion
+
+[Icons]
+Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
+Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
+
+[Run]
+Filename: "{app}\{#MyAppExeName}"; Parameters: "compat_migrate"; Description: "Try to migrate configuration - use only once (administrative permissions required)"; Flags: postinstall runascurrentuser unchecked
+Filename: "{tmp}\HASS.Agent.Service.Installer.x86.exe"; Parameters: "{code:GetCmdLineParams}"; Description: "Install Satellite Service (administrative permissions required)"; Flags: postinstall runascurrentuser
+Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: postinstall skipifsilent nowait
+
+[Code]
+var
+ OriginalCmdLine: String;
+
+function GetCmdLineParams(Param: String): String;
+begin
+ Result := OriginalCmdLine;
+end;
+
+procedure InitializeWizard;
+var
+ AfterID: Integer;
+ MigrationNotice: AnsiString;
+ DotNet8Notice: AnsiString;
+begin
+ OriginalCmdLine := GetCmdTail;
+
+ AfterID := wpSelectTasks;
+
+ ExtractTemporaryFile('{#MigrationNotice}');
+ LoadStringFromFile(ExpandConstant('{tmp}\{#MigrationNotice}'), MigrationNotice);
+ AfterID := CreateOutputMsgMemoPage(AfterID, 'Configuration migration', 'Please read carefully before proceeding.', 'Ignoring below message might cause you to loose your configuration.' , MigrationNotice).ID
+
+ ExtractTemporaryFile('{#DotNet8Notice}');
+ LoadStringFromFile(ExpandConstant('{tmp}\{#DotNet8Notice}'), DotNet8Notice);
+ AfterID := CreateOutputMsgMemoPage(AfterID, '.NET 8', 'New .NET version required with this HASS.Agent version.', '' , DotNet8Notice).ID
+end;
+
+function InitializeSetup: Boolean;
+begin
+ Dependency_ForceX86 := True;
+ Dependency_AddDotNet80Desktop;
+ Result := True;
+end;
+
+function NextButtonClick(CurPageID: Integer): Boolean;
+var
+ Msg: string;
+begin
+ if CurPageID = wpFinished then
+ begin
+ if WizardForm.RunList.Checked[0] then
+ begin;
+ Msg := 'Migration requires original HASS.Agent and Satellite Service to be stopped, do you wish to proceed?';
+ Result := (MsgBox(Msg, mbConfirmation, MB_YESNO) = IDYES)
+ end
+ else
+ begin
+ Result := True;
+ end
+ end
+ else
+ begin
+ Result := True;
+ end
+end;
+
+procedure CurUninstallStepChanged (CurUninstallStep: TUninstallStep);
+var
+ mres : integer;
+ serviceUninstallerPath : String;
+ ResultCode : integer;
+begin
+ case CurUninstallStep of
+ usPostUninstall:
+ begin
+ mres := MsgBox('Do you want to uninstall the Satellite Service? (administrative permissions required)', mbConfirmation, MB_YESNO or MB_DEFBUTTON2)
+ if mres = IDYES then
+ RegQueryStringValue(HKLM, 'SOFTWARE\HASSAgent\SatelliteService', 'InstallPath', serviceUninstallerPath);
+ Exec(serviceUninstallerPath + '\unins000.exe', '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
+ end;
+ end;
+end;
diff --git a/src/HASS.Agent.Installer/InstallerScript.iss b/src/HASS.Agent.Installer/InstallerScript.iss
index 1dee32b1..335f0338 100644
--- a/src/HASS.Agent.Installer/InstallerScript.iss
+++ b/src/HASS.Agent.Installer/InstallerScript.iss
@@ -9,11 +9,14 @@
; Standard installation constants
#define MyAppName "HASS.Agent"
-#define MyAppVersion "2.1.1"
+#define MyAppVersion "2.2.1"
#define MyAppPublisher "HASS.Agent Team"
#define MyAppURL "https://hass-agent.io"
#define MyAppExeName "HASS.Agent.exe"
+#define MigrationNotice "MigrationNotice.rtf"
+#define DotNet8Notice "DotNet8Notice.rtf"
+
[Setup]
ArchitecturesInstallIn64BitMode=x64
SetupMutex=Global\HASS.Agent.Setup.Mutex,HASS.Agent.Setup.Mutex
@@ -54,6 +57,8 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
[Files]
; Client files
Source: "..\HASS.Agent\HASS.Agent\bin\Publish-x64\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: "{#MigrationNotice}"; Flags: dontcopy
+Source: "{#DotNet8Notice}"; Flags: dontcopy
; Service installer
Source: ".\bin\HASS.Agent.Service.Installer.exe"; DestDir: "{tmp}"; Flags: ignoreversion
@@ -61,16 +66,48 @@ Source: ".\bin\HASS.Agent.Service.Installer.exe"; DestDir: "{tmp}"; Flags: ignor
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
+; Ensure LibreHardwareMonitor/WinRing0 files are removed
+[InstallDelete]
+Type: files; Name: "{app}\LibreHardwareMonitorLib.dll"
+Type: files; Name: "{app}\HASS.Agent.sys"
+
[Run]
-Filename: "{app}\{#MyAppExeName}"; Parameters: "compat_migrate"; Description: "Try to migrate configuration - use only once (administrative permissions required)"; Flags: postinstall skipifsilent runascurrentuser unchecked
-Filename: "{tmp}\HASS.Agent.Service.Installer.exe"; Description: "Install Satellite Service (administrative permissions required)"; Flags: postinstall runascurrentuser
+Filename: "{app}\{#MyAppExeName}"; Parameters: "compat_migrate"; Description: "Try to migrate configuration - use only once (administrative permissions required)"; Flags: postinstall runascurrentuser unchecked
+Filename: "{tmp}\HASS.Agent.Service.Installer.exe"; Parameters: "{code:GetCmdLineParams}"; Description: "Install Satellite Service (administrative permissions required)"; Flags: postinstall runascurrentuser
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: postinstall skipifsilent nowait
[Code]
+var
+ OriginalCmdLine: String;
+
+function GetCmdLineParams(Param: String): String;
+begin
+ Result := OriginalCmdLine;
+end;
+
+procedure InitializeWizard;
+var
+ AfterID: Integer;
+ MigrationNotice: AnsiString;
+ DotNet8Notice: AnsiString;
+begin
+ OriginalCmdLine := GetCmdTail;
+
+ AfterID := wpSelectTasks;
+
+ ExtractTemporaryFile('{#MigrationNotice}');
+ LoadStringFromFile(ExpandConstant('{tmp}\{#MigrationNotice}'), MigrationNotice);
+ AfterID := CreateOutputMsgMemoPage(AfterID, 'Configuration migration', 'Please read carefully before proceeding.', 'Ignoring below message might cause you to loose your configuration.' , MigrationNotice).ID
+
+ ExtractTemporaryFile('{#DotNet8Notice}');
+ LoadStringFromFile(ExpandConstant('{tmp}\{#DotNet8Notice}'), DotNet8Notice);
+ AfterID := CreateOutputMsgMemoPage(AfterID, '.NET 8', 'New .NET version required with this HASS.Agent version.', '' , DotNet8Notice).ID
+end;
+
function InitializeSetup: Boolean;
begin
Dependency_ForceX86 := False;
- Dependency_AddDotNet60Desktop;
+ Dependency_AddDotNet80Desktop;
Result := True;
end;
diff --git a/src/HASS.Agent.Installer/MigrationNotice.rtf b/src/HASS.Agent.Installer/MigrationNotice.rtf
new file mode 100644
index 00000000..c5e8ac71
--- /dev/null
+++ b/src/HASS.Agent.Installer/MigrationNotice.rtf
@@ -0,0 +1,231 @@
+{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang2057\deflangfe2057\themelang2057\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\f2\fbidi \fmodern\fcharset238\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\fbidi \froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f10\fbidi \fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}
+{\f34\fbidi \froman\fcharset238\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f43\fbidi \fswiss\fcharset238\fprq2{\*\panose 00000000000000000000}Tahoma;}
+{\flomajor\f31500\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\fhimajor\f31502\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0302020204030204}Calibri Light;}{\fbimajor\f31503\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\flominor\f31504\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\fhiminor\f31506\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f46\fbidi \froman\fcharset0\fprq2 Times New Roman;}
+{\f45\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f47\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f48\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f49\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
+{\f50\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f51\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f52\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f66\fbidi \fmodern\fcharset0\fprq1 Courier New;}
+{\f65\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}{\f67\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f68\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f69\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}
+{\f70\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}{\f71\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f72\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f386\fbidi \froman\fcharset0\fprq2 Cambria Math;}
+{\f385\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f387\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f388\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f391\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}
+{\f392\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f416\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\f415\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f417\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}
+{\f418\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f419\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f420\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\f421\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
+{\f422\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\f476\fbidi \fswiss\fcharset0\fprq2 Tahoma;}{\f475\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f477\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}
+{\f478\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;}{\f479\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f480\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f481\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}
+{\f482\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f483\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
+{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
+{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
+{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \fswiss\fcharset0\fprq2 Calibri Light;}
+{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}
+{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}
+{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
+{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
+{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
+{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \froman\fcharset0\fprq2 Times New Roman;}
+{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
+{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
+{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}
+{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}
+{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}
+{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
+{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;
+\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;
+\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\red5\green99\blue193;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\upr{\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025
+\ltrch\fcs0 \fs22\lang2057\langfe2057\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
+\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe2057\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 \snext11 \ssemihidden \sunhideused
+Normal Table;}{\*\cs15 \additive \ul\cf19 \sunhideused \styrsid11156998 Hyperlink;}}{\*\ud\uc0{\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025
+\ltrch\fcs0 \fs22\lang2057\langfe2057\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
+\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe2057\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 \snext11 \ssemihidden \sunhideused
+Normal Table;}{\*\cs15 \additive \ul\cf19 \sunhideused \styrsid11156998 Hyperlink;}}}}{\*\listtable{\list\listtemplateid651192760\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0
+{\leveltext\leveltemplateid134807553\'01{\uc1\u-3913 ?};}{\levelnumbers;}\f3\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext
+\leveltemplateid134807555\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807557
+\'01{\uc1\u-3929 ?};}{\levelnumbers;}\f10\fbias0 \fi-360\li2160\lin2160 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807553
+\'01{\uc1\u-3913 ?};}{\levelnumbers;}\f3\fbias0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807555\'01o;}{\levelnumbers;}
+\f2\fbias0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807557\'01{\uc1\u-3929 ?};}{\levelnumbers;}\f10\fbias0
+\fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807553\'01{\uc1\u-3913 ?};}{\levelnumbers;}\f3\fbias0 \fi-360\li5040\lin5040 }
+{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807555\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23
+\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid134807557\'01{\uc1\u-3929 ?};}{\levelnumbers;}\f10\fbias0 \fi-360\li6480\lin6480 }{\listname ;}\listid1037851123}}{\*\listoverridetable
+{\listoverride\listid1037851123\listoverridecount0\ls1}}{\*\rsidtbl \rsid11156998\rsid14366970\rsid15153285}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info
+{\operator Amadeo}{\creatim\yr2025\mo5\dy11\hr19\min54}{\revtim\yr2025\mo5\dy11\hr20\min22}{\version3}{\edmins10}{\nofpages1}{\nofwords54}{\nofchars314}{\nofcharsws367}{\vern81}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}
+\paperw11906\paperh16838\margl1417\margr1417\margt1417\margb1417\gutter0\ltrsect
+\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701
+\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot14366970 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid16263522\sftnbj
+{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}
+{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8
+\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11156998 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe2057\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp2057\langfenp2057 {\rtlch\fcs1 \af43
+\ltrch\fcs0 \f43\fs16\insrsid11156998
+\par \hich\af43\dbch\af31505\loch\f43 After HASS.Agent i\hich\af43\dbch\af31505\loch\f43 s installed, you have an\hich\af43\dbch\af31505\loch\f43 option to migrate configuration f\hich\af43\dbch\af31505\loch\f43 rom the origi\hich\af43\dbch\af31505\loch\f43
+nal \loch\af43\dbch\af31505\hich\f43 \'93\hich\af43\dbch\af31505\loch\f43 LAB\hich\af43\dbch\af31505\loch\f43 02\hich\af43\dbch\af31505\loch\f43 \hich\af43\dbch\af31505\loch\f43 Resea\hich\af43\dbch\af31505\loch\f43 rch\loch\af43\dbch\af31505\hich\f43
+\'94\hich\af43\dbch\af31505\loch\f43 \hich\af43\dbch\af31505\loch\f43 installation.
+\par }{\rtlch\fcs1 \af43 \ltrch\fcs0 \b\f43\fs16\insrsid11156998\charrsid11156998 \hich\af43\dbch\af31505\loch\f43 Unless you know what\hich\af43\dbch\af31505\loch\f43 you\loch\af43\dbch\af31505\hich\f43 \rquote \hich\af43\dbch\af31505\loch\f43 re doing, d
+\hich\af43\dbch\af31505\loch\f43 o not use this option\hich\af43\dbch\af31505\loch\f43 :
+\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af43\afs22 \ltrch\fcs0 \f3\fs16\insrsid11156998 \loch\af3\dbch\af31505\hich\f3 \'b7\tab}}\pard \ltrpar\ql \fi-360\li720\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin720\itap0\pararsid11156998 {\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid11156998 \hich\af43\dbch\af31505\loch\f43 M\hich\af43\dbch\af31505\loch\f43 ore
+\hich\af43\dbch\af31505\loch\f43 than onc\hich\af43\dbch\af31505\loch\f43 e
+\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af43\afs22 \ltrch\fcs0 \f3\fs16\insrsid11156998 \loch\af3\dbch\af31505\hich\f3 \'b7\tab}\hich\af43\dbch\af31505\loch\f43 If you\loch\af43\dbch\af31505\hich\f43 \rquote \hich\af43\dbch\af31505\loch\f43 ve
+\hich\af43\dbch\af31505\loch\f43 nev\hich\af43\dbch\af31505\loch\f43 er\hich\af43\dbch\af31505\loch\f43 installed\hich\af43\dbch\af31505\loch\f43 \hich\af43\dbch\af31505\loch\f43 original\hich\af43\dbch\af31505\loch\f43
+\loch\af43\dbch\af31505\hich\f43 \'93\hich\af43\dbch\af31505\loch\f43 LAB02 \hich\af43\dbch\af31505\loch\f43 Research\loch\af43\dbch\af31505\hich\f43 \'94\hich\af43\dbch\af31505\loch\f43 HASS.Agent ver\hich\af43\dbch\af31505\loch\f43 sion
+\par }\pard \ltrpar\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11156998 {\rtlch\fcs1 \af43 \ltrch\fcs0 \f43\fs16\insrsid11156998 \hich\af43\dbch\af31505\loch\f43
+During migration, all current configuration is replaced with the \hich\af43\dbch\af31505\loch\f43 old one \loch\af43\dbch\af31505\hich\f43 \endash \hich\af43\dbch\af31505\loch\f43 }{\rtlch\fcs1 \af43 \ltrch\fcs0
+\b\f43\fs16\insrsid11156998\charrsid11156998 \hich\af43\dbch\af31505\loch\f43 you \hich\af43\dbch\af31505\loch\f43 have been warned.}{\rtlch\fcs1 \af43 \ltrch\fcs0 \b\f43\fs16\insrsid11156998\charrsid11156998
+\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15153285\charrsid11156998
+\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
+9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
+5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
+b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
+0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
+a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
+c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
+0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
+a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
+6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
+4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
+4757e8d3f729e245eb2b260a0238fd010000ffff0300504b03041400060008000000210041daf6e5a6070000e6200000160000007468656d652f7468656d652f
+7468656d65312e786d6cec59cd8b1bc915bf07f23f347d97f5d5ad8fc1f222b524cfda33f660c90e7bac914add65557789aed28cc56208de532e81c026e49085
+bded21842cecc22eb9e48f31d8249b3f22afaa5bdd5552c9f3810326cc0886eed2efbdfad57bafde7baabaffd9ab983a1738e584253db77eafe63a3899b13949
+c29efb7c3aae745c870b94cc116509eeb91bccddcf1efcfa57f7d19188708c1d904ff811eab99110aba36a95cf6018f17b6c8513f86ec1d21809784dc3ea3c45
+97a037a6d546add6aac68824ae93a018d49e32b1b974566849b0583b4f170b32c3ee83ed24230a332582cb81194d27720a9c4b9e29195d64beac4b20dff080a6
+ce05a23d17a69db3cb297e255c87222ee08b9e5b537f6ef5c1fd2a3aca85a83820abc98dd55f2e970bcc970d35671a9e17937a9eefb5fa857e05a0621f376a8f
+5aa356a14f01d06c060bceb8983adb8dc0cbb11a287bb4e81eb687cdba81d7f437f738f77df931f00a94e9f7f6f0e371005634f00a94e1fd3dbc3fe80e86a67e
+05caf0ad3d7cbbd61f7a6d43bf02459424cb3d74cd6f3583ed6a0bc882d1632bbceb7be37623575ea2201a8a2093532c5822ae08b918bd64e91870124f912089
+23362bbc403388ed0051729e12e7848411c4df0a258cc370ad511bd79af05f7e3cf5a41c8b8e30d2a4253d20c4f786242d87cf52b2123df711687535c8bb9f7f
+7efbe6c7b76f7e7afbd5576fdffc3d9f5ba932e48e5112ea72bf7cf787ff7cf35be7df3f7cfbcbd77fcca6dec5731dfffe6fbf7bff8f7f7e483dacb834c5bb3f
+7dfffec7efdffdf9f7fffaebd716edfd149debf0298931779ee04be7198b618116fef83cbd99c434424497e82721470992b358f48f4464a09f6c104516dc009b
+767c9142c6b1011fae5f1a842751ba16c4a2f171141bc053c6e880a5562b3c967369669eae93d03e79bad671cf10bab0cd1da0c4f0f268bd828c4b6c2a83081b
+34cf284a040a71828523bf634b8c2dabfb8210c3aea7649632ce16c2f982380344ac26999273239a4aa16312835f363682e06fc336a72f9c01a3b6550ff18589
+84bd81a885fc1453c38c0fd15aa0d8a6728a62aa1bfc0489c84672b249673a6ec405783ac49439a339e6dc26f33485f56a4e7f0c69c6eef653ba894d642ac8d2
+a6f30431a623876c1944285ed9b01392443af673be841045ce191336f8293377887c073fa0e4a0bb5f402fa04f707536780e1956972803447eb34e2dbe7c8899
+11bf930d5d206c4b35fd3436526c3f25d6e818ac4323b44f30a6e812cd31769e7f6e6130602bc3e625e947116495636c0bac47c88c55f99e608e1dd5e3ece7c9
+13c28d909de0901de073bad9493c1b94c4283da4f909785db7f9084a5d6c0b80a774b6d4814f087486102f56a33ce5a0430bee835acf22641430f9ceedf1ba49
+0dff5d678fc1be7c69d0b8c6be04197c631948ecbacc076d3345d498a00c9829822ec3966e41c4707f29228bab125b5be516e6a62ddd004d92d1f4c424b9b203
+dae97dfcff5def031dc6bbbf7c63d96c1fa7dfb12b3692d50d3b9d43c9e478a7bf3984dbed6a0296cec9a7dfd40cd13a39c35047f633d65d4f73d7d3b8fff73d
+cda1fd7cd7c91cea37ee3a19173a8cbb4e263f5cf9389d4cd9bc405f230f3cb2f31e75fa135f75f8b320944ec486e213aece7f38fcac998f61508aabe3505c9c
+09ae227894d50ee63170618a948c9332f11b22a249845670485477a59290e7aa43eeac1887b323356cd52df1741d9fb27976f459afcb63ceacc07224caf19a5f
+8cc37995c8d0ad76799c57a8576c4375faba2520656f42429bcc24d1b490686f07a591d4592f18cd4242adeca3b0e85a5874a4faadabf65800b5c22bf0bbdb81
+5feb3dd7f7400484e0580e7af4b9f453e6eaad7795333fa6a70f19d38800e8b3b711507aba2bb91e5c9e5c5d166ad7f0b441420b379384b28ceaf37804bf86f3
+e894a3d7a171535f774b971af4a429d47c105a258d76e7432c6eeb6b90dbcd0d34d133054d9ccb9edb6afa103233b4eab90b383b86c77805b1c3e54f2f4443b8
+96998934dbf0b7c92cab948b21e25166709574b26c101381538792b8e7cae5176ea089ca218a5bbd0109e19325d785b4f2a99103a79b4ec68b059e09ddedda88
+b474f60a193ecb15d66f95f8edc15292adc1dd93687ee99cd375fa0c4188f9edba34e09c70b842a867d69c13b81a2b1259197f3b85294fbbfadd948aa16c1cd1
+5584f28aa227f30cae52794147bd1536d0def23583413593e485f03c94055637aa514d8baa9171385875af169296d3926659338dac22aba63d8b19336ccbc08e
+2d6f57e435565b13434ed32b7c96ba77536e779beb76fa84a24a80c10bfb59aaee350a8246ad9ccca02619efa76199b3f351b3766c177805b5eb14092debb7b6
+6a77ec56d408eb743078abca0f72bb510b438b6d7ba92cadaed4f5db6e76fe1292c7109add35155cb9122eb153040dd144f52459da802df24ae45b039e9c754a
+7aee9735bfef050d3fa8d43afea8e235bd5aa5e3f79b95beef37eb23bf5e1b0e1aafa1b08828aefbd975fe18ee31e826bfd457e37b17fbf1f6aae6de8cc555a6
+aeeaab8ab8bad8af378c8bfdec2adf99ca1b7bd7219074be6c35c6dd6677d0aa749bfd71c51b0e3a956ed01a5486ada03d1c0f03bfd31dbf769d0b05f6facdc0
+6b8d3a95563d082a5eab26e977ba95b6d768f4bd76bf33f2faaff33606569ea58fdc16605ec5ebc17f010000ffff0300504b0304140006000800000021000dd1
+909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277
+086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b
+64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996
+509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff
+0000001c0200001300000000000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7
+c0000000360100000b00000000000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000
+001c00000000000000000000000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210041
+daf6e5a6070000e62000001600000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d0014000600080000
+0021000dd1909fb60000001b0100002700000000000000000000000000b00a00007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000ab0b00000000}
+{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
+617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
+6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
+656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
+{\*\latentstyles\lsdstimax375\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9;
+\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;
+\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;
+\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;
+\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
+\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;
+\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;
+\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;
+\lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
+\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4;
+\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4;
+\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1;
+\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1;
+\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2;
+\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2;
+\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3;
+\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4;
+\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4;
+\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5;
+\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5;
+\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6;
+\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6;
+\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark;
+\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1;
+\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1;
+\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2;
+\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3;
+\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3;
+\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4;
+\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4;
+\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
+\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
+\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
+\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;}}{\*\datastore 010500000200000018000000
+4d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
+d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e50000000000000000000000006023
+a8b5a1c2db01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000105000000000000}}
\ No newline at end of file
diff --git a/src/HASS.Agent.sln b/src/HASS.Agent.sln
index b2da0434..4317c9ab 100644
--- a/src/HASS.Agent.sln
+++ b/src/HASS.Agent.sln
@@ -19,34 +19,48 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Debug|x64.ActiveCfg = Debug|x64
- {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Debug|x64.Build.0 = Debug|x64
+ {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Debug|x64.Build.0 = Debug|Any CPU
{6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Debug|x86.ActiveCfg = Debug|x86
{6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Debug|x86.Build.0 = Debug|x86
- {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Release|x64.ActiveCfg = Release|x64
- {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Release|x64.Build.0 = Release|x64
+ {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Release|x64.ActiveCfg = Release|Any CPU
+ {6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Release|x64.Build.0 = Release|Any CPU
{6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Release|x86.ActiveCfg = Release|x86
{6CB1FA4F-4798-4939-B8DF-7E908FD23242}.Release|x86.Build.0 = Release|x86
- {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Debug|x64.ActiveCfg = Debug|x64
- {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Debug|x64.Build.0 = Debug|x64
+ {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Debug|x64.Build.0 = Debug|Any CPU
{3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Debug|x86.ActiveCfg = Debug|x86
{3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Debug|x86.Build.0 = Debug|x86
- {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Release|x64.ActiveCfg = Release|x64
- {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Release|x64.Build.0 = Release|x64
+ {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Release|x64.ActiveCfg = Release|Any CPU
+ {3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Release|x64.Build.0 = Release|Any CPU
{3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Release|x86.ActiveCfg = Release|x86
{3EE6337D-63D6-4AE0-9B8C-788F7598D076}.Release|x86.Build.0 = Release|x86
- {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Debug|x64.ActiveCfg = Debug|x64
- {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Debug|x64.Build.0 = Debug|x64
+ {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Debug|x64.Build.0 = Debug|Any CPU
{C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Debug|x86.ActiveCfg = Debug|x86
{C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Debug|x86.Build.0 = Debug|x86
- {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Release|x64.ActiveCfg = Release|x64
- {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Release|x64.Build.0 = Release|x64
+ {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Release|x64.ActiveCfg = Release|Any CPU
+ {C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Release|x64.Build.0 = Release|Any CPU
{C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Release|x86.ActiveCfg = Release|x86
{C4138592-B05C-4B3D-B55C-A1337E97CDDD}.Release|x86.Build.0 = Release|x86
EndGlobalSection
@@ -54,7 +68,7 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
- VisualSVNWorkingCopyRoot = .
SolutionGuid = {C17243F4-9756-47EF-9AA8-86C64B7582A6}
+ VisualSVNWorkingCopyRoot = .
EndGlobalSection
EndGlobal
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/Commands/CommandsManager.cs b/src/HASS.Agent/HASS.Agent.Satellite.Service/Commands/CommandsManager.cs
index 875eb8e5..c27a3b67 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/Commands/CommandsManager.cs
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/Commands/CommandsManager.cs
@@ -50,7 +50,7 @@ internal static async void Initialize()
/// Unpublishes all commands
///
///
- internal static async Task UnpublishAllCommands()
+ internal static async Task UnpublishAllCommands(bool migration = false)
{
try
{
@@ -60,7 +60,7 @@ internal static async Task UnpublishAllCommands()
var count = 0;
foreach (var command in Variables.Commands)
{
- await command.UnPublishAutoDiscoveryConfigAsync();
+ await command.UnPublishAutoDiscoveryConfigAsync(migration);
await Variables.MqttManager.UnsubscribeAsync(command);
command.ClearAutoDiscoveryConfig();
count++;
@@ -76,6 +76,25 @@ internal static async Task UnpublishAllCommands()
{
Log.Fatal(ex, "[COMMANDSMANAGER] Error while unpublishing: {err}", ex.Message);
}
+
+ _discoveryPublished = false;
+ }
+
+ ///
+ /// Publishes all commands
+ ///
+ ///
+ internal static async Task ForcePublishAllCommands()
+ {
+ if (!CommandsPresent())
+ return;
+
+ foreach (var command in Variables.Commands)
+ {
+ await command.PublishAutoDiscoveryConfigAsync();
+ }
+
+ _discoveryPublished = true;
}
///
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/Extensions/RpcExtensions.cs b/src/HASS.Agent/HASS.Agent.Satellite.Service/Extensions/RpcExtensions.cs
index a57b6c07..70fe5591 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/Extensions/RpcExtensions.cs
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/Extensions/RpcExtensions.cs
@@ -182,7 +182,8 @@ public static ServiceMqttSettings ConvertToServiceMqttSettings(this RpcServiceMq
MqttUseRetainFlag = rpcServiceMqttSettings.MqttUseRetainFlag,
MqttRootCertificate = rpcServiceMqttSettings.MqttRootCertificate,
MqttClientCertificate = rpcServiceMqttSettings.MqttClientCertificate,
- MqttClientId = rpcServiceMqttSettings.MqttClientId
+ MqttClientId = rpcServiceMqttSettings.MqttClientId,
+ MqttUseWebSocket = rpcServiceMqttSettings.MqttUseWebSocket
};
return serviceMqttSettings;
@@ -207,7 +208,8 @@ public static RpcServiceMqttSettings ConvertToRpcServiceMqttSettings(this Servic
MqttUseRetainFlag = serviceMqttSettings.MqttUseRetainFlag,
MqttRootCertificate = serviceMqttSettings.MqttRootCertificate,
MqttClientCertificate = serviceMqttSettings.MqttClientCertificate,
- MqttClientId = serviceMqttSettings.MqttClientId
+ MqttClientId = serviceMqttSettings.MqttClientId,
+ MqttUseWebSocket = serviceMqttSettings.MqttUseWebSocket
};
return rpcServiceMqttSettings;
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/Functions/HelperFunctions.cs b/src/HASS.Agent/HASS.Agent.Satellite.Service/Functions/HelperFunctions.cs
index c969eecb..61e1b19c 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/Functions/HelperFunctions.cs
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/Functions/HelperFunctions.cs
@@ -3,6 +3,7 @@
using System.Text.RegularExpressions;
using HASS.Agent.Satellite.Service.Commands;
using HASS.Agent.Satellite.Service.Sensors;
+using HASS.Agent.Shared.Managers.Audio;
using Serilog;
namespace HASS.Agent.Satellite.Service.Functions
@@ -59,6 +60,9 @@ internal static async Task ShutdownAsync(TimeSpan waitBeforeClosing)
// log our demise
Log.Information("[SYSTEM] Service shutting down");
+ //stop audio manager
+ AudioManager.Shutdown();
+
// stop mqtt
await Variables.MqttManager.AnnounceAvailabilityAsync(true);
Variables.MqttManager.Disconnect();
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/HASS.Agent.Satellite.Service.csproj b/src/HASS.Agent/HASS.Agent.Satellite.Service/HASS.Agent.Satellite.Service.csproj
index 2be6c92a..4464d5b6 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/HASS.Agent.Satellite.Service.csproj
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/HASS.Agent.Satellite.Service.csproj
@@ -1,14 +1,14 @@
- net6.0-windows10.0.19041.0
+ net8.0-windows10.0.22621.0
true
enable
enable
dotnet-HASSAgentSatelliteService-6E4FA50A-3AC9-4E66-8671-9FAB92372154
- x64
- x64;x86
- 2.1.1
+ anycpu
+ x64;x86;AnyCPU
+ 2.2.1
HASS.Agent Team
HASS.Agent Satellite Service
HASS.Agent.Satellite.Service
@@ -17,9 +17,9 @@
https://github.com/hass-agent/HASS.Agent
https://github.com/hass-agent/HASS.Agent
hass.png
- 2.1.1
+ 2.2.1
hass.ico
- 2.1.1
+ 2.2.1
10.0.17763.0
false
@@ -29,26 +29,26 @@
-
+
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/MQTT/MqttManager.cs b/src/HASS.Agent/HASS.Agent.Satellite.Service/MQTT/MqttManager.cs
index 6758dd7f..fc54d1e1 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/MQTT/MqttManager.cs
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/MQTT/MqttManager.cs
@@ -126,7 +126,7 @@ private async Task OnMqttDisconnected(MqttClientDisconnectedEventArgs arg)
if (IsConnected())
{
_isReady = true;
-
+
return;
}
@@ -357,7 +357,7 @@ public async Task PublishAsync(MqttApplicationMessage message)
///
///
///
- public async Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discoverable, string domain, bool clearConfig = false)
+ public async Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discoverable, string domain, bool clearConfig = false, bool migration = false)
{
if (!IsConnected())
return;
@@ -394,7 +394,8 @@ public async Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discover
if (clearConfig)
{
- messageBuilder.WithPayload(Array.Empty());
+ var payload = migration ? Encoding.UTF8.GetBytes("{\"migrate_discovery\": true }") : Array.Empty();
+ messageBuilder.WithPayload(payload);
}
else
{
@@ -601,13 +602,22 @@ public async Task UnsubscribeAsync(AbstractCommand command)
var clientOptionsBuilder = new MqttClientOptionsBuilder()
.WithClientId(Variables.ServiceMqttSettings.MqttClientId)
- .WithTcpServer(Variables.ServiceMqttSettings.MqttAddress, Variables.ServiceMqttSettings.MqttPort)
.WithCleanSession()
.WithWillTopic($"{Variables.ServiceMqttSettings.MqttDiscoveryPrefix}/sensor/{Variables.DeviceConfig.Name}/availability")
.WithWillPayload("offline")
.WithWillRetain(Variables.ServiceMqttSettings.MqttUseRetainFlag)
.WithKeepAlivePeriod(TimeSpan.FromSeconds(15));
+ if (Variables.ServiceMqttSettings.MqttUseWebSocket)
+ {
+ clientOptionsBuilder.WithWebSocketServer(o => o.WithUri($"{Variables.ServiceMqttSettings.MqttAddress}:{Variables.ServiceMqttSettings.MqttPort}"));
+ Log.Information("[MQTT] Using WebSocket for the connection");
+ }
+ else
+ {
+ clientOptionsBuilder.WithTcpServer(Variables.ServiceMqttSettings.MqttAddress, Variables.ServiceMqttSettings.MqttPort);
+ }
+
if (!string.IsNullOrEmpty(Variables.ServiceMqttSettings.MqttUsername))
clientOptionsBuilder.WithCredentials(Variables.ServiceMqttSettings.MqttUsername, Variables.ServiceMqttSettings.MqttPassword);
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/RPC/Protos/hassagentsatellite.proto b/src/HASS.Agent/HASS.Agent.Satellite.Service/RPC/Protos/hassagentsatellite.proto
index a21c9157..f261aa30 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/RPC/Protos/hassagentsatellite.proto
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/RPC/Protos/hassagentsatellite.proto
@@ -120,6 +120,7 @@ message RpcServiceMqttSettings {
string mqttRootCertificate = 9;
string mqttClientCertificate = 10;
string mqttClientId = 11;
+ bool mqttUseWebSocket = 12;
}
message RpcConfiguredServerSensor {
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/Sensors/SensorsManager.cs b/src/HASS.Agent/HASS.Agent.Satellite.Service/Sensors/SensorsManager.cs
index 867fd2ae..ea2430fb 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/Sensors/SensorsManager.cs
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/Sensors/SensorsManager.cs
@@ -49,7 +49,7 @@ internal static async void Initialize()
/// Unpublishes all single- and multivalue sensors
///
///
- internal static async Task UnpublishAllSensors()
+ internal static async Task UnpublishAllSensors(bool migration = false)
{
try
{
@@ -61,7 +61,7 @@ internal static async Task UnpublishAllSensors()
{
foreach (var sensor in Variables.SingleValueSensors)
{
- await sensor.UnPublishAutoDiscoveryConfigAsync();
+ await sensor.UnPublishAutoDiscoveryConfigAsync(migration);
sensor.ClearAutoDiscoveryConfig();
singleCount++;
}
@@ -71,7 +71,7 @@ internal static async Task UnpublishAllSensors()
{
foreach (var sensor in Variables.MultiValueSensors)
{
- await sensor.UnPublishAutoDiscoveryConfigAsync();
+ await sensor.UnPublishAutoDiscoveryConfigAsync(migration);
sensor.ClearAutoDiscoveryConfig();
multiCount++;
}
@@ -87,6 +87,32 @@ internal static async Task UnpublishAllSensors()
{
Log.Fatal(ex, "[SENSORSMANAGER] Error while unpublishing: {err}", ex.Message);
}
+
+ _discoveryPublished = false;
+ }
+
+ ///
+ /// Publishes all single- and multivalue sensors
+ ///
+ ///
+ internal static async Task ForcePublishAllSensors()
+ {
+ if (SingleValueSensorsPresent())
+ {
+ foreach (var sensor in Variables.SingleValueSensors)
+ {
+ await sensor.PublishAutoDiscoveryConfigAsync();
+ }
+ }
+ if (MultiValueSensorsPresent())
+ {
+ foreach (var sensor in Variables.MultiValueSensors)
+ {
+ await sensor.PublishAutoDiscoveryConfigAsync();
+ }
+ }
+
+ _discoveryPublished = true;
}
///
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/SettingsManager.cs b/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/SettingsManager.cs
index 139cd5c4..26bc4b67 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/SettingsManager.cs
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/SettingsManager.cs
@@ -101,7 +101,7 @@ private static bool LoadServiceSettings()
// set shared config
AgentSharedBase.SetDeviceName(Variables.ServiceSettings.DeviceName);
AgentSharedBase.SetCustomExecutorBinary(Variables.ServiceSettings.CustomExecutorBinary);
-
+
// done
Log.Information("[SETTINGS] Configuration loaded");
return true;
@@ -192,7 +192,7 @@ private static bool StoreInitialMqttSettings(bool storeSettings = true)
try
{
Log.Information("[SETTINGS] No MQTT config found, storing default settings");
-
+
// default settings
Variables.ServiceMqttSettings = new ServiceMqttSettings();
@@ -225,7 +225,7 @@ internal static bool Store()
// store app settings
var ok = StoreServiceSettings();
if (!ok) allGood = false;
-
+
// store commands
ok = StoredCommands.Store();
if (!ok) allGood = false;
@@ -289,10 +289,10 @@ internal static bool ProcessReceivedServiceMqttSettings(ServiceMqttSettings serv
return true;
}
}
-
+
// bind received settings
Variables.ServiceMqttSettings = serviceMqttSettings;
-
+
// store
var stored = StoreServiceSettings();
if (stored) Log.Information("[SETTINGS] Received MQTT settings stored");
@@ -313,19 +313,19 @@ internal static bool ProcessReceivedServiceMqttSettings(ServiceMqttSettings serv
///
/// Changes the device's name internally and with HA
///
- ///
+ ///
[SuppressMessage("ReSharper", "CompareOfFloatsByEqualityOperator")]
- internal static async void ProcessNameChange(string deviceName)
+ internal static async void ProcessNameChange(string newDeviceName)
{
Variables.ServiceSettings ??= new ServiceSettings();
- if (deviceName == Variables.ServiceSettings.DeviceName)
+ if (newDeviceName == Variables.ServiceSettings.DeviceName)
{
Log.Information("[SETTINGS] Name change requested, but name is same as before, ignoring");
return;
}
- Log.Information("[SETTINGS] Processing name change to: {name}", deviceName);
+ Log.Information("[SETTINGS] Processing name change to: {name}", newDeviceName);
Log.Information("[SETTINGS] Previous name: {name}", Variables.ServiceSettings.DeviceName);
// make sure the managers stop publishing
@@ -335,7 +335,27 @@ internal static async void ProcessNameChange(string deviceName)
// give the managers some time to stop
await Task.Delay(250);
- // unpublish all entities
+ // signal migration to HA MQTT integration
+ await SensorsManager.UnpublishAllSensors(migration: true);
+ await CommandsManager.UnpublishAllCommands(migration: true);
+
+ await Task.Delay(250);
+
+ // mock new device name and publish new discovery messages
+ if (Variables.DeviceConfig != null) //Note(Amadeo): ugly, should be cleaned up but doesn't make sense due to full rewrite
+ {
+ Variables.DeviceConfig.Name = newDeviceName;
+ }
+ await SensorsManager.ForcePublishAllSensors();
+ await CommandsManager.ForcePublishAllCommands();
+
+ await Task.Delay(250);
+
+ // restore previous device name and clear migration messages
+ if (Variables.DeviceConfig != null) //Note(Amadeo): ugly, should be cleaned up but doesn't make sense due to full rewrite
+ {
+ Variables.DeviceConfig.Name = Variables.ServiceSettings.DeviceName;
+ }
await SensorsManager.UnpublishAllSensors();
await CommandsManager.UnpublishAllCommands();
@@ -346,7 +366,7 @@ internal static async void ProcessNameChange(string deviceName)
await Task.Delay(250);
// set the name
- Variables.ServiceSettings.DeviceName = deviceName;
+ Variables.ServiceSettings.DeviceName = newDeviceName;
// store
var stored = StoreServiceSettings();
@@ -354,7 +374,7 @@ internal static async void ProcessNameChange(string deviceName)
else Log.Error("[SETTINGS] Errors while storing new name");
// config shared functions
- AgentSharedBase.SetDeviceName(deviceName);
+ AgentSharedBase.SetDeviceName(newDeviceName);
// restart mqtt
Variables.MqttManager.ReloadConfiguration();
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/StoredCommands.cs b/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/StoredCommands.cs
index 3ff0d54e..de838048 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/StoredCommands.cs
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/StoredCommands.cs
@@ -1,4 +1,4 @@
-using HASS.Agent.Shared.Enums;
+using HASS.Agent.Shared.Enums;
using HASS.Agent.Shared.Models.Config;
using HASS.Agent.Shared.HomeAssistant.Commands;
using HASS.Agent.Shared.HomeAssistant.Commands.CustomCommands;
@@ -56,7 +56,10 @@ internal static async Task LoadAsync()
// convert to abstract commands
await Task.Run(delegate
{
- foreach (var abstractCommand in configuredCommands.Select(ConvertConfiguredToAbstract)) Variables.Commands.Add(abstractCommand!);
+ foreach (var abstractCommand in configuredCommands.Select(ConvertConfiguredToAbstract))
+ {
+ if (abstractCommand != null) Variables.Commands.Add(abstractCommand);
+ }
});
// all good
@@ -141,6 +144,9 @@ await Task.Run(delegate
case CommandType.MonitorSleepCommand:
abstractCommand = new MonitorSleepCommand(command.EntityName, command.Name, command.EntityType, command.Id.ToString());
break;
+ case CommandType.MonitorSleepPowerPlanCommand:
+ abstractCommand = new MonitorSleepCommand(command.EntityName, command.Name, command.EntityType, command.Id.ToString());
+ break;
case CommandType.MonitorWakeCommand:
abstractCommand = new MonitorWakeCommand(command.EntityName, command.Name, command.EntityType, command.Id.ToString());
break;
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/StoredSensors.cs b/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/StoredSensors.cs
index 398b3a9d..556c8086 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/StoredSensors.cs
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/Settings/StoredSensors.cs
@@ -1,4 +1,4 @@
-using HASS.Agent.Shared.Enums;
+using HASS.Agent.Shared.Enums;
using HASS.Agent.Shared.Models.Config;
using HASS.Agent.Satellite.Service.Extensions;
using HASS.Agent.Shared.HomeAssistant.Sensors;
@@ -9,7 +9,6 @@
using HASS.Agent.Shared.Models.HomeAssistant;
using Newtonsoft.Json;
using Serilog;
-using LibreHardwareMonitor.Hardware;
using SensorType = HASS.Agent.Shared.Enums.SensorType;
namespace HASS.Agent.Satellite.Service.Settings
@@ -62,8 +61,16 @@ await Task.Run(delegate
{
foreach (var sensor in configuredSensors)
{
- if (sensor.IsSingleValue()) Variables.SingleValueSensors.Add(ConvertConfiguredToAbstractSingleValue(sensor)!);
- else Variables.MultiValueSensors.Add(ConvertConfiguredToAbstractMultiValue(sensor)!);
+ if (sensor.IsSingleValue())
+ {
+ var abstractSensor = ConvertConfiguredToAbstractSingleValue(sensor);
+ if (abstractSensor != null) Variables.SingleValueSensors.Add(abstractSensor);
+ }
+ else
+ {
+ var abstractSensor = ConvertConfiguredToAbstractMultiValue(sensor);
+ if (abstractSensor != null) Variables.MultiValueSensors.Add(abstractSensor);
+ }
}
});
@@ -110,6 +117,9 @@ await Task.Run(delegate
case SensorType.NamedWindowSensor:
abstractSensor = new NamedWindowSensor(sensor.WindowName, sensor.EntityName, sensor.Name, sensor.UpdateInterval, sensor.Id.ToString(), sensor.AdvancedSettings);
break;
+ case SensorType.NamedActiveWindowSensor:
+ abstractSensor = new NamedActiveWindowSensor(sensor.WindowName, sensor.EntityName, sensor.Name, sensor.UpdateInterval, sensor.Id.ToString(), sensor.AdvancedSettings);
+ break;
case SensorType.LastActiveSensor:
abstractSensor = new LastActiveSensor(sensor.ApplyRounding, sensor.Round, sensor.UpdateInterval, sensor.EntityName, sensor.Name, sensor.Id.ToString(), sensor.AdvancedSettings);
break;
@@ -259,6 +269,22 @@ internal static ConfiguredSensor ConvertAbstractSingleValueToConfigured(Abstract
};
}
+ case NamedActiveWindowSensor namedActiveWindowSensor:
+ {
+ _ = Enum.TryParse(namedActiveWindowSensor.GetType().Name, out var type);
+ return new ConfiguredSensor
+ {
+ Id = Guid.Parse(namedActiveWindowSensor.Id),
+ EntityName = namedActiveWindowSensor.EntityName,
+ Name = namedActiveWindowSensor.Name,
+ Type = type,
+ UpdateInterval = namedActiveWindowSensor.UpdateIntervalSeconds,
+ IgnoreAvailability = namedActiveWindowSensor.IgnoreAvailability,
+ WindowName = namedActiveWindowSensor.WindowName,
+ AdvancedSettings = namedActiveWindowSensor.AdvancedSettings
+ };
+ }
+
case PerformanceCounterSensor performanceCounterSensor:
{
_ = Enum.TryParse(performanceCounterSensor.GetType().Name, out var type);
diff --git a/src/HASS.Agent/HASS.Agent.Satellite.Service/Worker.cs b/src/HASS.Agent/HASS.Agent.Satellite.Service/Worker.cs
index 11743d4c..d5cf887a 100644
--- a/src/HASS.Agent/HASS.Agent.Satellite.Service/Worker.cs
+++ b/src/HASS.Agent/HASS.Agent.Satellite.Service/Worker.cs
@@ -1,12 +1,15 @@
-using HASS.Agent.Shared;
+using System.Diagnostics;
+using System.Security.Principal;
using HASS.Agent.Satellite.Service.Commands;
using HASS.Agent.Satellite.Service.Functions;
using HASS.Agent.Satellite.Service.Managers;
using HASS.Agent.Satellite.Service.RPC;
using HASS.Agent.Satellite.Service.Sensors;
using HASS.Agent.Satellite.Service.Settings;
-using Serilog;
+using HASS.Agent.Shared;
using HASS.Agent.Shared.Managers;
+using HASS.Agent.Shared.Managers.Audio;
+using Serilog;
namespace HASS.Agent.Satellite.Service
{
@@ -40,7 +43,11 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_log.LogInformation("[WORKER] Startup completed, commencing execution ..");
- HardwareManager.Initialize();
+ var runningUser = WindowsIdentity.GetCurrent();
+ if(runningUser.User?.Value != "S-1-5-18")
+ {
+ _log.LogWarning("[WORKER] Service is not running as 'System' user but rather '{user}', this may cause permission issues!", runningUser.Name);
+ }
// load stored settings (if any)
var launched = await SettingsManager.LoadAsync();
@@ -59,6 +66,9 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
// initialize the RPC server
_ = Task.Run(RpcManager.Initialize, stoppingToken);
+ // initialize the audio manager
+ _ = Task.Run(AudioManager.Initialize, stoppingToken);
+
// initialize the mqtt manager
_ = Task.Run(Variables.MqttManager.Initialize, stoppingToken);
@@ -99,8 +109,6 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
}
finally
{
- HardwareManager.Shutdown();
-
// stop the application
_hostApplicationLifetime.StopApplication();
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Enums/CommandType.cs b/src/HASS.Agent/HASS.Agent.Shared/Enums/CommandType.cs
index a25ca5b1..ca6549f7 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Enums/CommandType.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Enums/CommandType.cs
@@ -65,6 +65,10 @@ public enum CommandType
[EnumMember(Value = "MonitorSleepCommand")]
MonitorSleepCommand,
+ [LocalizedDescription("CommandType_MonitorSleepPowerPlanCommand", typeof(Languages))]
+ [EnumMember(Value = "MonitorSleepPowerPlanCommand")]
+ MonitorSleepPowerPlanCommand,
+
[LocalizedDescription("CommandType_MonitorWakeCommand", typeof(Languages))]
[EnumMember(Value = "MonitorWakeCommand")]
MonitorWakeCommand,
@@ -127,6 +131,10 @@ public enum CommandType
[LocalizedDescription("CommandType_RadioCommand", typeof(Languages))]
[EnumMember(Value = "RadioCommand")]
- RadioCommand
+ RadioCommand,
+
+ [LocalizedDescription("CommandType_WinformsSleepCommand", typeof(Languages))]
+ [EnumMember(Value = "WinformsSleepCommand")]
+ WinformsSleepCommand
}
}
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Enums/HassDomain.cs b/src/HASS.Agent/HASS.Agent.Shared/Enums/HassDomain.cs
index 4b453b34..8bd710ca 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Enums/HassDomain.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Enums/HassDomain.cs
@@ -62,6 +62,16 @@ public enum HassDomain
[LocalizedDescription("HassDomain_Button", typeof(Languages))]
[Category("button")]
[EnumMember(Value = "Button")]
- Button
+ Button,
+
+ [LocalizedDescription("HassDomain_InputButton", typeof(Languages))]
+ [Category("input_button")]
+ [EnumMember(Value = "InputButton")]
+ InputButton,
+
+ [LocalizedDescription("HassDomain_Fan", typeof(Languages))]
+ [Category("fan")]
+ [EnumMember(Value = "Fan")]
+ Fan
}
}
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Enums/SensorType.cs b/src/HASS.Agent/HASS.Agent.Shared/Enums/SensorType.cs
index 65348afa..d6fab954 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Enums/SensorType.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Enums/SensorType.cs
@@ -19,6 +19,10 @@ public enum SensorType
[EnumMember(Value = "ActiveDesktopSensor")]
ActiveDesktopSensor,
+ [LocalizedDescription("SensorType_AccentColorSensor", typeof(Languages))]
+ [EnumMember(Value = "AccentColorSensor")]
+ AccentColorSensor,
+
[LocalizedDescription("SensorType_AudioSensors", typeof(Languages))]
[EnumMember(Value = "AudioSensors")]
AudioSensors,
@@ -107,6 +111,10 @@ public enum SensorType
[EnumMember(Value = "NamedWindowSensor")]
NamedWindowSensor,
+ [LocalizedDescription("SensorType_NamedActiveWindowSensor", typeof(Languages))]
+ [EnumMember(Value = "NamedActiveWindowSensor")]
+ NamedActiveWindowSensor,
+
[LocalizedDescription("SensorType_NetworkSensors", typeof(Languages))]
[EnumMember(Value = "NetworkSensors")]
NetworkSensors,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HASS.Agent.Shared.csproj b/src/HASS.Agent/HASS.Agent.Shared/HASS.Agent.Shared.csproj
index 90565d05..31336c84 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HASS.Agent.Shared.csproj
+++ b/src/HASS.Agent/HASS.Agent.Shared/HASS.Agent.Shared.csproj
@@ -1,8 +1,8 @@
- net6.0-windows10.0.19041.0
- x64;x86
+ net8.0-windows10.0.22621.0
+ x64;x86;AnyCPU
HASS.Agent.Shared
HASS.Agent.Shared
HASS.Agent Team
@@ -10,9 +10,9 @@
Shared functions and models for the HASS.Agent platform.
https://github.com/hass-agent/HASS.Agent
https://github.com/hass-agent/HASS.Agent
- 2.1.1
- 2.1.1
- 2.1.1
+ 2.2.1
+ 2.2.1
+ 2.2.1
logo_128.png
True
hassagent.ico
@@ -32,21 +32,21 @@
-
-
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/CustomCommand.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/CustomCommand.cs
index 8436a446..76a4152e 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/CustomCommand.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/CustomCommand.cs
@@ -74,7 +74,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return new CommandDiscoveryConfigModel()
+ return new CommandDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommand.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommand.cs
index 48d4cee7..a7511e17 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommand.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommand.cs
@@ -44,7 +44,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return new CommandDiscoveryConfigModel()
+ return new CommandDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/MonitorSleepPowerPlanCommand.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/MonitorSleepPowerPlanCommand.cs
new file mode 100644
index 00000000..d71bc152
--- /dev/null
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/MonitorSleepPowerPlanCommand.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Threading;
+using System.Windows.Forms;
+using System.Windows.Input;
+using HASS.Agent.Shared.Enums;
+using HASS.Agent.Shared.Functions;
+using Serilog;
+using Vanara.PInvoke;
+using static Vanara.PInvoke.PowrProf;
+
+namespace HASS.Agent.Shared.HomeAssistant.Commands.InternalCommands
+{
+ ///
+ /// Command to put all monitors to sleep
+ ///
+ [SuppressMessage("ReSharper", "InconsistentNaming")]
+ public class MonitorSleepPowerPlanCommand : InternalCommand
+ {
+ private static readonly HKEY s_key = new HKEY();
+
+ private const string DefaultName = "monitorsleep-pp";
+
+ public MonitorSleepPowerPlanCommand(string entityName = DefaultName, string name = DefaultName, CommandEntityType entityType = CommandEntityType.Button, string id = default) : base(entityName ?? DefaultName, name ?? null, string.Empty, entityType, id)
+ {
+ State = "OFF";
+ }
+
+ public override void TurnOn()
+ {
+ State = "ON";
+
+ try
+ {
+ var win32Error = PowerGetActiveScheme(out var activeScheme);
+ if (win32Error != Win32Error.ERROR_SUCCESS)
+ throw new Exception("cannot get active power scheme");
+
+ var schemes = PowerEnumerate(null, null);
+ var removalError = false;
+ foreach (var scheme in schemes)
+ {
+ var name = PowerReadFriendlyName(scheme);
+ if (name.EndsWith(" - HASS.Agent Monitor Sleep"))
+ {
+ win32Error = PowerDeleteScheme(s_key, scheme);
+ if (win32Error != Win32Error.ERROR_SUCCESS)
+ removalError = true;
+ }
+ }
+
+ if (removalError)
+ Log.Warning("[MONITORSLEEP-PP] [{name}] Error occurred while trying to remove HASS.Agent temp power plan/s", EntityName, EntityName);
+
+
+ win32Error = PowerDuplicateScheme(s_key, activeScheme, out var duplicateScheme);
+ if (win32Error != Win32Error.ERROR_SUCCESS)
+ throw new Exception("cannot duplicate current power scheme");
+
+ var duplicatedSchemeGuid = duplicateScheme.ToStructure();
+ var newDuplicatedName = PowerReadFriendlyName(activeScheme) + " - HASS.Agent Monitor Sleep";
+ win32Error = PowerWriteFriendlyName(duplicatedSchemeGuid, null, null, newDuplicatedName);
+ if (win32Error != Win32Error.ERROR_SUCCESS)
+ throw new Exception("error setting new name to the duplicated power plan");
+
+ win32Error = PowerWriteACValueIndex(s_key, duplicatedSchemeGuid, GUID_VIDEO_SUBGROUP, GUID_VIDEO_POWERDOWN_TIMEOUT, 1);
+ if (win32Error != Win32Error.ERROR_SUCCESS)
+ throw new Exception("error changing the power plan timeout value");
+
+ win32Error = PowerSetActiveScheme(s_key, duplicatedSchemeGuid);
+ if (win32Error != Win32Error.ERROR_SUCCESS)
+ throw new Exception("error activating the temporary power plan");
+
+ Thread.Sleep(1500); //TODO(Amadeo): ugly...
+
+ win32Error = PowerSetActiveScheme(s_key, activeScheme);
+ if (win32Error != Win32Error.ERROR_SUCCESS)
+ throw new Exception("error activating the original power plan");
+
+ win32Error = PowerDeleteScheme(s_key, duplicatedSchemeGuid);
+ if (win32Error != Win32Error.ERROR_SUCCESS)
+ throw new Exception("error removing the duplicated power plan");
+ }
+ catch (Exception ex)
+ {
+ Log.Error("[MONITORSLEEP-PP] [{name}] Error activating the command: {msg}", EntityName, ex.Message);
+ }
+ finally
+ {
+ State = "OFF";
+ }
+ }
+ }
+}
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/SetApplicationVolumeCommand.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/SetApplicationVolumeCommand.cs
index cdb39cdc..a1ada486 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/SetApplicationVolumeCommand.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/SetApplicationVolumeCommand.cs
@@ -1,7 +1,6 @@
using HASS.Agent.Shared.Enums;
using HASS.Agent.Shared.Managers;
using HASS.Agent.Shared.Managers.Audio;
-using HidSharp;
using Newtonsoft.Json;
using Serilog;
using System;
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommand.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommand.cs
index 592eeb19..08871f22 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommand.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommand.cs
@@ -19,7 +19,7 @@ public class KeyCommand : AbstractCommand
private const string DefaultName = "key";
public string State { get; protected set; }
-
+
public VirtualKeyShort KeyCode { get; set; }
public KeyCommand(VirtualKeyShort keyCode, string entityName = DefaultName, string name = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(entityName ?? DefaultName, name ?? null, entityType, id)
@@ -35,7 +35,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return new CommandDiscoveryConfigModel
+ return new CommandDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
@@ -52,31 +52,59 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
public override void TurnOff()
{
- //
- }
-
- public override void TurnOn()
- {
- State = "ON";
-
- var inputs = new INPUT[2];
+ var inputs = new INPUT[1];
inputs[0].type = InputType.INPUT_KEYBOARD;
inputs[0].U.ki.wVk = KeyCode;
-
- inputs[1].type = InputType.INPUT_KEYBOARD;
- inputs[1].U.ki.wVk = KeyCode;
- inputs[1].U.ki.dwFlags = KEYEVENTF.KEYUP;
+ inputs[0].U.ki.dwFlags = KEYEVENTF.KEYUP;
var ret = SendInput((uint)inputs.Length, inputs, INPUT.Size);
if (ret != inputs.Length)
{
var error = Marshal.GetLastWin32Error();
- Log.Error($"[{DefaultName}] Error simulating key press for {KeyCode}: {error}");
+ Log.Error($"[{DefaultName}] Error lifting key {KeyCode}: {error}");
}
State = "OFF";
}
+ public override void TurnOn()
+ {
+ State = "ON";
+
+ if (EntityType == CommandEntityType.Switch)
+ {
+ var inputs = new INPUT[1];
+ inputs[0].type = InputType.INPUT_KEYBOARD;
+ inputs[0].U.ki.wVk = KeyCode;
+
+ var ret = SendInput((uint)inputs.Length, inputs, INPUT.Size);
+ if (ret != inputs.Length)
+ {
+ var error = Marshal.GetLastWin32Error();
+ Log.Error($"[{DefaultName}] Error pressing down key {KeyCode}: {error}");
+ }
+ }
+ else
+ {
+ var inputs = new INPUT[2];
+ inputs[0].type = InputType.INPUT_KEYBOARD;
+ inputs[0].U.ki.wVk = KeyCode;
+
+ inputs[1].type = InputType.INPUT_KEYBOARD;
+ inputs[1].U.ki.wVk = KeyCode;
+ inputs[1].U.ki.dwFlags = KEYEVENTF.KEYUP;
+
+ var ret = SendInput((uint)inputs.Length, inputs, INPUT.Size);
+ if (ret != inputs.Length)
+ {
+ var error = Marshal.GetLastWin32Error();
+ Log.Error($"[{DefaultName}] Error simulating key press for {KeyCode}: {error}");
+ }
+
+ State = "OFF";
+ }
+ }
+
public override void TurnOnWithAction(string action)
{
//
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/MultipleKeysCommand.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/MultipleKeysCommand.cs
index 3d56a286..9689f761 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/MultipleKeysCommand.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/MultipleKeysCommand.cs
@@ -33,7 +33,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return new CommandDiscoveryConfigModel
+ return new CommandDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/PowershellCommand.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/PowershellCommand.cs
index e3179b49..b004bda5 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/PowershellCommand.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Commands/PowershellCommand.cs
@@ -73,7 +73,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return new CommandDiscoveryConfigModel()
+ return new CommandDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/AudioSensors.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/AudioSensors.cs
index 4c6ecb97..87988493 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/AudioSensors.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/AudioSensors.cs
@@ -9,7 +9,6 @@
using HASS.Agent.Shared.Managers.Audio;
using HASS.Agent.Shared.Models.HomeAssistant;
using HASS.Agent.Shared.Models.Internal;
-using HidSharp;
using Newtonsoft.Json;
using Serilog;
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeBoolSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeBoolSensor.cs
index 93781b0d..9fd8d778 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeBoolSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeBoolSensor.cs
@@ -45,7 +45,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- var model = new SensorDiscoveryConfigModel()
+ var model = new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeDoubleSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeDoubleSensor.cs
index b0fbc741..0f4460fb 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeDoubleSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeDoubleSensor.cs
@@ -50,7 +50,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- var model = new SensorDiscoveryConfigModel()
+ var model = new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeIntSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeIntSensor.cs
index 0a9ec4e6..a9d04b2c 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeIntSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeIntSensor.cs
@@ -49,7 +49,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- var model = new SensorDiscoveryConfigModel()
+ var model = new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeStringSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeStringSensor.cs
index be61b13b..3a173218 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeStringSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DataTypes/DataTypeStringSensor.cs
@@ -49,7 +49,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- var model = new SensorDiscoveryConfigModel()
+ var model = new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ActiveWindowSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ActiveWindowSensor.cs
index 46b689e3..c44a21fa 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ActiveWindowSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ActiveWindowSensor.cs
@@ -27,7 +27,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
if (deviceConfig == null)
return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/CurrentVolumeSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/CurrentVolumeSensor.cs
index 659db848..94bac4a5 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/CurrentVolumeSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/CurrentVolumeSensor.cs
@@ -23,7 +23,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/DummySensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/DummySensor.cs
index 45afb306..939eb97c 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/DummySensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/DummySensor.cs
@@ -18,7 +18,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuLoadSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuLoadSensor.cs
index e4b4e92a..00f54708 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuLoadSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuLoadSensor.cs
@@ -1,8 +1,9 @@
-using System.Globalization;
+using System.Diagnostics;
+using System.Globalization;
using System.Linq;
+using System.Threading;
using HASS.Agent.Shared.Managers;
using HASS.Agent.Shared.Models.HomeAssistant;
-using LibreHardwareMonitor.Hardware;
namespace HASS.Agent.Shared.HomeAssistant.Sensors.GeneralSensors.SingleValue;
@@ -11,54 +12,61 @@ namespace HASS.Agent.Shared.HomeAssistant.Sensors.GeneralSensors.SingleValue;
///
public class GpuLoadSensor : AbstractSingleValueSensor
{
- private const string DefaultName = "gpuload";
- private readonly IHardware _gpu;
+ private const string DefaultName = "gpuload";
- public GpuLoadSensor(int? updateInterval = null, string entityName = DefaultName, string name = DefaultName, string id = default, string advancedSettings = default) : base(entityName ?? DefaultName, name ?? null, updateInterval ?? 30, id, advancedSettings: advancedSettings)
- {
- _gpu = HardwareManager.Hardware.FirstOrDefault(
- h => h.HardwareType == HardwareType.GpuAmd ||
- h.HardwareType == HardwareType.GpuNvidia ||
- h.HardwareType == HardwareType.GpuIntel
- );
- }
+ public GpuLoadSensor(int? updateInterval = null, string entityName = DefaultName, string name = DefaultName, string id = default, string advancedSettings = default) : base(entityName ?? DefaultName, name ?? null, updateInterval ?? 30, id, advancedSettings: advancedSettings)
+ {
- public override DiscoveryConfigModel GetAutoDiscoveryConfig()
- {
- if (Variables.MqttManager == null)
- return null;
+ }
- var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
- if (deviceConfig == null)
- return null;
+ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
+ {
+ if (Variables.MqttManager == null)
+ return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
- {
- EntityName = EntityName,
- Name = Name,
- Unique_id = Id,
- Device = deviceConfig,
- State_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{Domain}/{deviceConfig.Name}/{ObjectId}/state",
- Unit_of_measurement = "%",
+ var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
+ if (deviceConfig == null)
+ return null;
+
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
+ {
+ EntityName = EntityName,
+ Name = Name,
+ Unique_id = Id,
+ Device = deviceConfig,
+ State_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{Domain}/{deviceConfig.Name}/{ObjectId}/state",
+ Unit_of_measurement = "%",
State_class = "measurement",
Availability_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{Domain}/{deviceConfig.Name}/availability"
- });
- }
-
- public override string GetState()
- {
- if (_gpu == null)
- return null;
+ });
+ }
- _gpu.Update();
+ public override string GetState()
+ {
+ return GetGPUUsage().ToString("#.##", CultureInfo.InvariantCulture);
+ }
- var sensor = _gpu.Sensors.FirstOrDefault(s => s.SensorType == SensorType.Load);
+ public override string GetAttributes() => string.Empty;
- if (sensor?.Value == null)
- return null;
+ public float GetGPUUsage()
+ {
+ try
+ {
+ var category = new PerformanceCounterCategory("GPU Engine");
+ var gpuCounters = category.GetInstanceNames()
+ .Where(name => name.EndsWith("engtype_3D"))
+ .SelectMany(name => category.GetCounters(name))
+ .Where(counter => counter.CounterName.Equals("Utilization Percentage"))
+ .ToList();
- return sensor.Value.HasValue ? sensor.Value.Value.ToString("#.##", CultureInfo.InvariantCulture) : null;
- }
+ gpuCounters.ForEach(x => { _ = x.NextValue(); });
+ Thread.Sleep(10); //TODO(Amadeo): fix this
- public override string GetAttributes() => string.Empty;
+ return gpuCounters.Sum(x => x.NextValue());
+ }
+ catch
+ {
+ return 0;
+ }
+ }
}
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuTemperatureSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuTemperatureSensor.cs
index 8204c3d9..747c070c 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuTemperatureSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuTemperatureSensor.cs
@@ -2,7 +2,6 @@
using System.Linq;
using HASS.Agent.Shared.Managers;
using HASS.Agent.Shared.Models.HomeAssistant;
-using LibreHardwareMonitor.Hardware;
namespace HASS.Agent.Shared.HomeAssistant.Sensors.GeneralSensors.SingleValue
{
@@ -12,15 +11,15 @@ namespace HASS.Agent.Shared.HomeAssistant.Sensors.GeneralSensors.SingleValue
public class GpuTemperatureSensor : AbstractSingleValueSensor
{
private const string DefaultName = "gputemperature";
- private readonly IHardware _gpu;
+ //private readonly IHardware _gpu;
public GpuTemperatureSensor(int? updateInterval = null, string entityName = DefaultName, string name = DefaultName, string id = default, string advancedSettings = default) : base(entityName ?? DefaultName, name ?? null, updateInterval ?? 30, id, advancedSettings: advancedSettings)
{
- _gpu = HardwareManager.Hardware.FirstOrDefault(
+/* _gpu = HardwareManager.Hardware.FirstOrDefault(
h => h.HardwareType == HardwareType.GpuAmd ||
h.HardwareType == HardwareType.GpuNvidia ||
h.HardwareType == HardwareType.GpuIntel
- );
+ );*/
}
public override DiscoveryConfigModel GetAutoDiscoveryConfig()
@@ -30,7 +29,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
@@ -46,7 +45,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
public override string GetState()
{
- if (_gpu == null)
+/* if (_gpu == null)
return null;
_gpu.Update();
@@ -56,7 +55,8 @@ public override string GetState()
if (sensor?.Value == null)
return null;
- return sensor.Value.HasValue ? sensor.Value.Value.ToString("#.##", CultureInfo.InvariantCulture) : null;
+ return sensor.Value.HasValue ? sensor.Value.Value.ToString("#.##", CultureInfo.InvariantCulture) : null;*/
+ return "0";
}
public override string GetAttributes() => string.Empty;
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastActiveSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastActiveSensor.cs
index bd67b9d6..5d7de85e 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastActiveSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastActiveSensor.cs
@@ -38,7 +38,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
if (deviceConfig == null)
return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
@@ -86,12 +86,12 @@ private static DateTime GetLastInputTime()
lastInputInfo.cbSize = Marshal.SizeOf(lastInputInfo);
lastInputInfo.dwTime = 0;
- var envTicks = Environment.TickCount;
+ var envTicks = Environment.TickCount64;
if (!GetLastInputInfo(ref lastInputInfo))
return DateTime.Now;
- var lastInputTick = Convert.ToDouble(lastInputInfo.dwTime);
+ var lastInputTick = (long)lastInputInfo.dwTime;
var idleTime = envTicks - lastInputTick;
return idleTime > 0 ? DateTime.Now - TimeSpan.FromMilliseconds(idleTime) : DateTime.Now;
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastBootSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastBootSensor.cs
index c8e6429c..3a4ae1a0 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastBootSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastBootSensor.cs
@@ -22,7 +22,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastSystemStateChangeSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastSystemStateChangeSensor.cs
index 482c0fad..f1572a0d 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastSystemStateChangeSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastSystemStateChangeSensor.cs
@@ -19,7 +19,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LoggedUserSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LoggedUserSensor.cs
index ba14ba5b..c35010b2 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LoggedUserSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LoggedUserSensor.cs
@@ -19,7 +19,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LoggedUsersSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LoggedUsersSensor.cs
index e10c958e..4f7e2a61 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LoggedUsersSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LoggedUsersSensor.cs
@@ -27,7 +27,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/MicrophoneActiveSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/MicrophoneActiveSensor.cs
index 5d630ef6..453ceb22 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/MicrophoneActiveSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/MicrophoneActiveSensor.cs
@@ -25,7 +25,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/MicrophoneProcessSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/MicrophoneProcessSensor.cs
index c7b89615..aab53dc6 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/MicrophoneProcessSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/MicrophoneProcessSensor.cs
@@ -39,7 +39,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
return null;
}
- var model = new SensorDiscoveryConfigModel()
+ var model = new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/NamedActiveWindowSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/NamedActiveWindowSensor.cs
new file mode 100644
index 00000000..29bedee7
--- /dev/null
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/NamedActiveWindowSensor.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using HASS.Agent.Shared.Functions;
+using HASS.Agent.Shared.Models.HomeAssistant;
+
+namespace HASS.Agent.Shared.HomeAssistant.Sensors.GeneralSensors.SingleValue
+{
+ ///
+ /// Sensor indicating whether the currently focused window contains the configured name
+ ///
+ public class NamedActiveWindowSensor : AbstractSingleValueSensor
+ {
+ private const string DefaultName = "namedactivewindow";
+ public string WindowName { get; protected set; }
+
+ public NamedActiveWindowSensor(string windowName, string entityName = DefaultName, string name = DefaultName, int? updateInterval = 10, string id = default, string advancedSettings = default) : base(entityName ?? DefaultName, name ?? null, updateInterval ?? 30, id, advancedSettings: advancedSettings)
+ {
+ Domain = "binary_sensor";
+ WindowName = windowName;
+ }
+
+ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
+ {
+ if (Variables.MqttManager == null) return null;
+
+ var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
+ if (deviceConfig == null) return null;
+
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
+ {
+ EntityName = EntityName,
+ Name = Name,
+ Unique_id = Id,
+ Device = deviceConfig,
+ State_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{Domain}/{deviceConfig.Name}/{ObjectId}/state",
+ Availability_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/sensor/{deviceConfig.Name}/availability"
+ });
+ }
+
+ public override string GetState()
+ {
+ var windowHandle = GetForegroundWindow();
+ var windowTitle = GetWindowTitle(windowHandle);
+
+ return windowTitle.ToUpper().Contains(WindowName.ToUpper()) ? "ON" : "OFF";
+ }
+
+ public override string GetAttributes() => string.Empty;
+
+ [DllImport("user32.dll")]
+ private static extern IntPtr GetForegroundWindow();
+
+ [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ private static extern int GetWindowTextLength(IntPtr hWnd);
+
+ [DllImport("user32.dll", CharSet = CharSet.Auto)]
+ private static extern int GetWindowText(IntPtr hWnd, StringBuilder builder, int count);
+
+ private static string GetWindowTitle(IntPtr windowHandle)
+ {
+ var titleLength = GetWindowTextLength(windowHandle) + 1;
+ var builder = new StringBuilder(titleLength);
+ var windowTitle = GetWindowText(windowHandle, builder, titleLength) > 0 ? builder.ToString() : string.Empty;
+
+ return windowTitle.Length > 255 ? windowTitle[..255] : windowTitle; //Note(Amadeo): to make sure we don't exceed HA limitation of 255 payload length
+ }
+ }
+}
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/NamedWindowSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/NamedWindowSensor.cs
index b3f494c7..e2363c89 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/NamedWindowSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/NamedWindowSensor.cs
@@ -25,7 +25,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ProcessActiveSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ProcessActiveSensor.cs
index 09d51781..eceb1534 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ProcessActiveSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ProcessActiveSensor.cs
@@ -29,7 +29,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ScreenshotSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ScreenshotSensor.cs
index fa2dd172..fd73dbd1 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ScreenshotSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ScreenshotSensor.cs
@@ -42,7 +42,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
if (deviceConfig == null)
return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new CameraSensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new CameraSensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ServiceStateSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ServiceStateSensor.cs
index f3655606..ebe8b77f 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ServiceStateSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/ServiceStateSensor.cs
@@ -24,7 +24,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/SessionStateSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/SessionStateSensor.cs
index 9f698e0e..17d52e5c 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/SessionStateSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/SessionStateSensor.cs
@@ -19,7 +19,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/UserNotificationStateSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/UserNotificationStateSensor.cs
index ee66f883..1713fe8f 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/UserNotificationStateSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/UserNotificationStateSensor.cs
@@ -20,7 +20,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WebcamActiveSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WebcamActiveSensor.cs
index 372f8a1c..eb9ae233 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WebcamActiveSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WebcamActiveSensor.cs
@@ -30,7 +30,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WebcamProcessSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WebcamProcessSensor.cs
index 8dbfbccd..fe5a4a5f 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WebcamProcessSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WebcamProcessSensor.cs
@@ -34,7 +34,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- var model = new SensorDiscoveryConfigModel()
+ var model = new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WindowStateSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WindowStateSensor.cs
index b07eccc6..2c5d234a 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WindowStateSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/WindowStateSensor.cs
@@ -27,7 +27,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PerfCounterSensors/SingleValue/CpuLoadSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PerfCounterSensors/SingleValue/CpuLoadSensor.cs
index 245c143e..0a05af95 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PerfCounterSensors/SingleValue/CpuLoadSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PerfCounterSensors/SingleValue/CpuLoadSensor.cs
@@ -18,9 +18,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- var asd = ObjectId;
-
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PerformanceCounterSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PerformanceCounterSensor.cs
index cde16828..a52ee5c0 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PerformanceCounterSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PerformanceCounterSensor.cs
@@ -47,7 +47,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PowershellSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PowershellSensor.cs
index 832f7e66..4d6d7578 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PowershellSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/PowershellSensor.cs
@@ -34,7 +34,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
if (deviceConfig == null)
return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiQuerySensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiQuerySensor.cs
index 3c2fb43d..80382cd3 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiQuerySensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiQuerySensor.cs
@@ -58,7 +58,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
if (deviceConfig == null)
return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiSensors/SingleValue/CurrentClockSpeedSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiSensors/SingleValue/CurrentClockSpeedSensor.cs
index 23770359..f34c9fa2 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiSensors/SingleValue/CurrentClockSpeedSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiSensors/SingleValue/CurrentClockSpeedSensor.cs
@@ -27,7 +27,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiSensors/SingleValue/MemoryUsageSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiSensors/SingleValue/MemoryUsageSensor.cs
index eaf79098..83212595 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiSensors/SingleValue/MemoryUsageSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/HomeAssistant/Sensors/WmiSensors/SingleValue/MemoryUsageSensor.cs
@@ -20,7 +20,7 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig()
var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
- return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
+ return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel(Domain)
{
EntityName = EntityName,
Name = Name,
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Managers/Audio/AudioManager.cs b/src/HASS.Agent/HASS.Agent.Shared/Managers/Audio/AudioManager.cs
index 12e13d7f..aa404f60 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Managers/Audio/AudioManager.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Managers/Audio/AudioManager.cs
@@ -10,7 +10,6 @@
using HASS.Agent.Shared.Managers.Audio.Internal;
using Serilog;
using NAudio.CoreAudioApi.Interfaces;
-using HidSharp;
using Microsoft.VisualBasic.ApplicationServices;
namespace HASS.Agent.Shared.Managers.Audio;
@@ -25,6 +24,9 @@ public static class AudioManager
private static readonly Dictionary _applicationNameCache = new();
+ private static bool _noDefaultInputLogged = false;
+ private static bool _noDefaultOutputLogged = false;
+
private static void InitializeDevices()
{
_enumerator = new MMDeviceEnumerator();
@@ -208,6 +210,18 @@ public static void CleanupDevices()
Log.Debug("[AUDIOMGR] cleanup completed");
}
+ private static MMDevice GetDefaultMultimediaDevice(DataFlow dataFlow)
+ {
+ MMDevice device = null;
+ try
+ {
+ device = _enumerator.GetDefaultAudioEndpoint(dataFlow, Role.Multimedia);
+ }
+ catch { }
+
+ return device;
+ }
+
public static List GetDevices()
{
var audioDevices = new List();
@@ -217,11 +231,29 @@ public static List GetDevices()
try
{
- using var defaultInputDevice = _enumerator.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Multimedia);
- using var defaultOutputDevice = _enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
+ using var defaultInputDevice = GetDefaultMultimediaDevice(DataFlow.Capture);
+ if (defaultInputDevice == null && !_noDefaultInputLogged)
+ {
+ Log.Information("[AUDIOMGR] no default input device detected");
+ _noDefaultInputLogged = true;
+ }
+ else if (defaultInputDevice != null)
+ {
+ _noDefaultInputLogged = false;
+ }
+
+ using var defaultOutputDevice = GetDefaultMultimediaDevice(DataFlow.Render);
+ if (defaultOutputDevice == null && !_noDefaultOutputLogged)
+ {
+ Log.Information("[AUDIOMGR] no default output device detected");
+ _noDefaultOutputLogged = true;
+ }else if (defaultOutputDevice != null)
+ {
+ _noDefaultOutputLogged = false;
+ }
- var defaultInputDeviceId = defaultInputDevice.ID;
- var defaultOutputDeviceId = defaultOutputDevice.ID;
+ var defaultInputDeviceId = defaultInputDevice != null ? defaultInputDevice.ID : string.Empty;
+ var defaultOutputDeviceId = defaultOutputDevice != null ? defaultOutputDevice.ID : string.Empty;
foreach (var (deviceId, deviceName) in _devices)
{
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Managers/HardwareManager.cs b/src/HASS.Agent/HASS.Agent.Shared/Managers/HardwareManager.cs
deleted file mode 100644
index a692a598..00000000
--- a/src/HASS.Agent/HASS.Agent.Shared/Managers/HardwareManager.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using LibreHardwareMonitor.Hardware;
-
-namespace HASS.Agent.Shared.Managers;
-public static class HardwareManager
-{
- private static Computer s_computer;
- public static void Initialize()
- {
- //Note(Amadeo): for "performance" reasons only GPU is selected below, enable additional ones if required by new sensors/commands
- s_computer = new Computer()
- {
- IsCpuEnabled = false,
- IsGpuEnabled = true,
- IsMemoryEnabled = false,
- IsMotherboardEnabled = false,
- IsControllerEnabled = false,
- IsNetworkEnabled = false,
- IsStorageEnabled = false,
- };
-
- s_computer.Open();
- }
-
- public static IList Hardware => s_computer.Hardware;
-
- public static void Shutdown() => s_computer?.Close();
-}
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Models/Config/Service/ServiceMqttSettings.cs b/src/HASS.Agent/HASS.Agent.Shared/Models/Config/Service/ServiceMqttSettings.cs
index 9b4ee401..dfbb3254 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Models/Config/Service/ServiceMqttSettings.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Models/Config/Service/ServiceMqttSettings.cs
@@ -9,6 +9,7 @@ public ServiceMqttSettings()
public string MqttAddress { get; set; } = "homeassistant.local";
public int MqttPort { get; set; } = 1883;
+ public bool MqttUseWebSocket { get; set; } = false;
public bool MqttUseTls { get; set; }
public bool MqttAllowUntrustedCertificates { get; set; } = true;
public string MqttUsername { get; set; } = string.Empty;
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractCommand.cs b/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractCommand.cs
index 5dc55fa7..5514d7cf 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractCommand.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractCommand.cs
@@ -83,10 +83,12 @@ public async Task PublishAutoDiscoveryConfigAsync()
await Variables.MqttManager.AnnounceAutoDiscoveryConfigAsync(this, Domain);
}
- public async Task UnPublishAutoDiscoveryConfigAsync()
+ public async Task UnPublishAutoDiscoveryConfigAsync(bool migration = false)
{
- if (Variables.MqttManager == null) return;
- await Variables.MqttManager.AnnounceAutoDiscoveryConfigAsync(this, Domain, true);
+ if (Variables.MqttManager == null)
+ return;
+
+ await Variables.MqttManager.AnnounceAutoDiscoveryConfigAsync(this, Domain, true, migration);
}
public abstract void TurnOn();
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractMultiValueSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractMultiValueSensor.cs
index 6a243d38..49f231ed 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractMultiValueSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractMultiValueSensor.cs
@@ -68,9 +68,9 @@ public async Task PublishAutoDiscoveryConfigAsync()
foreach (var sensor in Sensors) await sensor.Value.PublishAutoDiscoveryConfigAsync();
}
- public async Task UnPublishAutoDiscoveryConfigAsync()
+ public async Task UnPublishAutoDiscoveryConfigAsync(bool migration = false)
{
- foreach (var sensor in Sensors) await sensor.Value.UnPublishAutoDiscoveryConfigAsync();
+ foreach (var sensor in Sensors) await sensor.Value.UnPublishAutoDiscoveryConfigAsync(migration);
}
}
}
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractSingleValueSensor.cs b/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractSingleValueSensor.cs
index e3d3f267..9a941e36 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractSingleValueSensor.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/AbstractSingleValueSensor.cs
@@ -160,11 +160,11 @@ public async Task PublishAutoDiscoveryConfigAsync()
await Variables.MqttManager.AnnounceAutoDiscoveryConfigAsync(this, Domain);
}
- public async Task UnPublishAutoDiscoveryConfigAsync()
+ public async Task UnPublishAutoDiscoveryConfigAsync(bool migration = false)
{
if (Variables.MqttManager == null)
return;
- await Variables.MqttManager.AnnounceAutoDiscoveryConfigAsync(this, Domain, true);
+ await Variables.MqttManager.AnnounceAutoDiscoveryConfigAsync(this, Domain, true, migration);
}
}
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/DiscoveryConfigModel.cs b/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/DiscoveryConfigModel.cs
index 8d2cd9f5..454bd77b 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/DiscoveryConfigModel.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Models/HomeAssistant/DiscoveryConfigModel.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
-using System.Text.Json.Serialization;
+using Newtonsoft.Json;
namespace HASS.Agent.Shared.Models.HomeAssistant
{
@@ -12,9 +12,12 @@ namespace HASS.Agent.Shared.Models.HomeAssistant
public abstract class DiscoveryConfigModel
{
///
- /// (Optional) The MQTT topic subscribed to receive availability (online/offline) updates.
+ /// Domain of the entity, used to create default object id property.
///
///
+ [Newtonsoft.Json.JsonIgnore]
+ public string Domain { get; set; }
+
public string Availability_topic { get; set; }
///
@@ -41,6 +44,16 @@ public abstract class DiscoveryConfigModel
///
///
public string State_topic { get; set; }
+
+ protected DiscoveryConfigModel(string domain)
+ {
+ if (string.IsNullOrWhiteSpace(domain))
+ {
+ throw new ArgumentException("domain cannot be null or empty string/whitespace");
+ }
+
+ Domain = domain;
+ }
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
@@ -133,9 +146,16 @@ public string Object_id
return $"{Device.Name}_{EntityName}";
}
- set { _objectId = value; }
+
+ set => _objectId = value;
}
+ //TODO(Amadeo): move Object_id logic here once it's fully deprecated in HA (or even better, finish v3 rewrite and abandon this monstrosity of a code...)
+ ///
+ /// Default object id parameter required starting with HA 2025.10
+ ///
+ public string Default_entity_id => $"{Domain}.{Object_id}";
+
///
/// (Optional) Defines the units of measurement of the sensor, if any.
///
@@ -147,6 +167,8 @@ public string Object_id
///
///
public string Value_template { get; set; }
+
+ public SensorDiscoveryConfigModel(string domain) :base(domain) { }
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
@@ -161,6 +183,8 @@ public class CameraSensorDiscoveryConfigModel : SensorDiscoveryConfigModel
/// (Optional) The encoding of the image payloads received.
///
public string Image_encoding { get; set; }
+
+ public CameraSensorDiscoveryConfigModel(string domain) : base(domain) { }
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
@@ -259,14 +283,23 @@ public string Object_id
return $"{Device.Name}_{EntityName}";
}
- set { _objectId = value; }
+
+ set => _objectId = value;
}
+ //TODO(Amadeo): move Object_id logic here once it's fully deprecated in HA (or even better, finish v3 rewrite and abandon this monstrosity of a code...)
+ ///
+ /// Default object id parameter required starting with HA 2025.10
+ ///
+ public string Default_entity_id => $"{Domain}.{Object_id}";
+
///
/// (Optional) Defines a template to extract the value.
///
///
public string Value_template { get; set; }
+
+ public CommandDiscoveryConfigModel(string domain) : base(domain) { }
}
///
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Mqtt/IMqttManager.cs b/src/HASS.Agent/HASS.Agent.Shared/Mqtt/IMqttManager.cs
index d41673e7..17bfc4b1 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Mqtt/IMqttManager.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Mqtt/IMqttManager.cs
@@ -17,7 +17,7 @@ public interface IMqttManager
void Initialize();
void CreateDeviceConfigModel();
Task PublishAsync(MqttApplicationMessage message);
- Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discoverable, string domain, bool clearConfig = false);
+ Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discoverable, string domain, bool clearConfig = false, bool migration = false);
MqttStatus GetStatus();
Task AnnounceAvailabilityAsync(bool offline = false);
Task ClearDeviceConfigAsync();
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.Designer.cs b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.Designer.cs
index 931858fa..fba85dfc 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.Designer.cs
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.Designer.cs
@@ -495,6 +495,16 @@ internal static string CommandsManager_MonitorSleepCommandDescription {
}
}
+ ///
+ /// Looks up a localized string similar to Puts all monitors in sleep (low power) mode using alternative approach of power plan modification.
+ ///Should provide better experience with new systems with "modern S0ix sleep" and not put the system to sleep..
+ ///
+ internal static string CommandsManager_MonitorSleepPowerPlanCommandDescription {
+ get {
+ return ResourceManager.GetString("CommandsManager_MonitorSleepPowerPlanCommandDescription", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Tries to wake up all monitors by simulating a 'arrow up' keypress..
///
@@ -607,6 +617,17 @@ internal static string CommandsManager_WebViewCommandDescription {
}
}
+ ///
+ /// Looks up a localized string similar to Puts the machine to sleep using WinForms API.
+ ///
+ ///Note: due to "Modern Sleep" the sleep commands might behave differently depending on the device OEM and OS configuration..
+ ///
+ internal static string CommandsManager_WinformsSleepCommandDescription {
+ get {
+ return ResourceManager.GetString("CommandsManager_WinformsSleepCommandDescription", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Configure Command &Parameters.
///
@@ -1212,6 +1233,15 @@ internal static string CommandType_MonitorSleepCommand {
}
}
+ ///
+ /// Looks up a localized string similar to MonitorSleepPowerPlan.
+ ///
+ internal static string CommandType_MonitorSleepPowerPlanCommand {
+ get {
+ return ResourceManager.GetString("CommandType_MonitorSleepPowerPlanCommand", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to MonitorWake.
///
@@ -1356,6 +1386,15 @@ internal static string CommandType_WebViewCommand {
}
}
+ ///
+ /// Looks up a localized string similar to WinformsSleep.
+ ///
+ internal static string CommandType_WinformsSleepCommand {
+ get {
+ return ResourceManager.GetString("CommandType_WinformsSleepCommand", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Connecting...
///
@@ -3515,6 +3554,15 @@ internal static string HassDomain_Cover {
}
}
+ ///
+ /// Looks up a localized string similar to Fan.
+ ///
+ internal static string HassDomain_Fan {
+ get {
+ return ResourceManager.GetString("HassDomain_Fan", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to HASS.Agent Commands.
///
@@ -3533,6 +3581,15 @@ internal static string HassDomain_InputBoolean {
}
}
+ ///
+ /// Looks up a localized string similar to InputButton.
+ ///
+ internal static string HassDomain_InputButton {
+ get {
+ return ResourceManager.GetString("HassDomain_InputButton", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Light.
///
@@ -4410,7 +4467,7 @@ internal static string OnboardingDone_LblInfo2 {
}
///
- /// Looks up a localized string similar to There's a lot more to tinker with, so make sure you take a look at the Configuration Wwindow!
+ /// Looks up a localized string similar to There's a lot more to tinker with, so make sure you take a look at the Configuration Window!
///
///
///Thank you for using HASS.Agent, hopefully it'll be useful for you :-)
@@ -4423,7 +4480,8 @@ internal static string OnboardingDone_LblInfo3 {
}
///
- /// Looks up a localized string similar to Developing and maintaining this tool (and everything that surrounds it) takes up a lot of time. Like most developers, I run on caffeïne - so if you can spare it, a cup of coffee is always very much appreciated!.
+ /// Looks up a localized string similar to Currently, we (HASS.Agent Team maintaining the fork) do not accept donations in any form :)
+ ///Please however feel free to donate to the original author of HASS.Agent - Sam! Wherever they currently are, cup of coffee might brighten their day..
///
internal static string OnboardingDone_LblInfo6 {
get {
@@ -5713,7 +5771,10 @@ internal static string SensorsManager_GpuLoadSensorDescription {
}
///
- /// Looks up a localized string similar to Provides the current temperature of the first GPU..
+ /// Looks up a localized string similar to NOTE: This is a non-functioning sensor.
+ ///
+ ///Due to the security concerns regarding Libre Hardware Monitor (library allowing HASS.Agent to access GPU temperature data) this sensor is left for backward compatibility reasons and will always return 0.
+ ///Please see documentation for alternative options..
///
internal static string SensorsManager_GpuTemperatureSensorDescription {
get {
@@ -5816,6 +5877,15 @@ internal static string SensorsManager_MonitorPowerStateSensorDescription {
}
}
+ ///
+ /// Looks up a localized string similar to Provides an ON/OFF value based on whether the focused window name contains configured string..
+ ///
+ internal static string SensorsManager_NamedActiveWindowSensorDescription {
+ get {
+ return ResourceManager.GetString("SensorsManager_NamedActiveWindowSensorDescription", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Provides an ON/OFF value based on whether the window is currently open (doesn't have to be active)..
///
@@ -6510,6 +6580,15 @@ internal static string SensorsMod_WmiTestFailed {
}
}
+ ///
+ /// Looks up a localized string similar to AccentColor.
+ ///
+ internal static string SensorType_AccentColorSensor {
+ get {
+ return ResourceManager.GetString("SensorType_AccentColorSensor", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to ActiveDesktop.
///
@@ -6726,6 +6805,15 @@ internal static string SensorType_MonitorPowerStateSensor {
}
}
+ ///
+ /// Looks up a localized string similar to NamedActiveWindow.
+ ///
+ internal static string SensorType_NamedActiveWindowSensor {
+ get {
+ return ResourceManager.GetString("SensorType_NamedActiveWindowSensor", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to NamedWindow.
///
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.de.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.de.resx
index c5179acd..163a3652 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.de.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.de.resx
@@ -2174,7 +2174,10 @@ Nimmt derzeit die Lautstärke deines Standardgeräts.
Liefert die aktuelle Auslastung der ersten GPU in Prozent.
- Liefert die aktuelle Temperatur der ersten GPU.
+ HINWEIS: Dieser Sensor funktioniert nicht.
+
+Aufgrund von Sicherheitsbedenken bezüglich Libre Hardware Monitor (Bibliothek, die HASS.Agent Zugriff auf GPU-Temperaturdaten ermöglicht) wurde dieser Sensor aus Gründen der Abwärtskompatibilität beibehalten und gibt immer 0 zurück.
+Weitere Optionen finden Sie in der Dokumentation.
Stellt einen datetime-Wert bereit, der den letzten Moment enthält, in dem der Benutzer eine Eingabe gemacht hat.
@@ -3213,7 +3216,8 @@ Sind Sie sicher, dass Sie diesen Schlüssel trotzdem verwenden möchten?
Bist Du sicher, dass Du es so verwenden möchtest?
- Die Entwicklung und Wartung dieses Tools (und alles, was es umgibt) nimmt viel Zeit in Anspruch. Wie die meisten Entwickler verwende ich Koffein – wenn Du es also entbehren kannst, ist eine Tasse Kaffee immer sehr willkommen!
+ Derzeit nehmen wir (das HASS.Agent-Team, das die Abspaltung betreut) keinerlei Spenden an. :)
+Sie können aber gerne dem ursprünglichen Autor von HASS.Agent – Sam – eine Spende zukommen lassen! Wo auch immer er sich gerade befindet, eine Tasse Kaffee könnte ihm den Tag verschönern.
Tipp: Andere Spendenmethoden sind im Über-Fenster verfügbar.
@@ -3376,4 +3380,31 @@ Willst Du den Runtime Installer herunterladen?
Presse
+
+ Stellt einen EIN/AUS-Wert bereit, basierend darauf, ob der fokussierte Fenstername eine konfigurierte Zeichenfolge enthält.
+
+
+ BenanntesAktivesFenster
+
+
+ Akzentfarbe
+
+
+ Lüfter
+
+
+ Versetzt den Rechner mithilfe der WinForms-API in den Ruhezustand.
+
+Hinweis: Aufgrund des „Modern Sleep“-Modus können sich die Ruhezustandsbefehle je nach Geräte-OEM und Betriebssystemkonfiguration unterschiedlich verhalten.
+
+
+ WinformsSleep
+
+
+ Versetzt alle Monitore in den Energiesparmodus (niedriger Stromverbrauch) mithilfe einer alternativen Methode zur Änderung des Energiesparplans.
+Sollte bei neuen Systemen mit „modernem S0ix-Schlafmodus“ eine bessere Benutzererfahrung bieten und das System nicht in den Ruhezustand versetzen.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.en.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.en.resx
index f881bf80..ab3ac347 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.en.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.en.resx
@@ -524,7 +524,7 @@ The certificate of the downloaded file will get checked before running,you will
HASS.Agent GitHub page
- There's a lot more to tinker with, so make sure you take a look at the Configuration Wwindow!
+ There's a lot more to tinker with, so make sure you take a look at the Configuration Window!
Thank you for using HASS.Agent, hopefully it'll be useful for you :-)
@@ -2054,7 +2054,10 @@ Currently takes the volume of your default device.
Provides the current load of the first GPU as a percentage.
- Provides the current temperature of the first GPU.
+ NOTE: This is a non-functioning sensor.
+
+Due to the security concerns regarding Libre Hardware Monitor (library allowing HASS.Agent to access GPU temperature data) this sensor is left for backward compatibility reasons and will always return 0.
+Please see documentation for alternative options.
Provides a datetime value containing the last moment the user provided any input.
@@ -3089,7 +3092,8 @@ Are you sure you want to use this key anyway?
Are you sure you want to use this URI anyway?
- Developing and maintaining this tool (and everything that surrounds it) takes up a lot of time. Like most developers, I run on caffeïne - so if you can spare it, a cup of coffee is always very much appreciated!
+ Currently, we (HASS.Agent Team maintaining the fork) do not accept donations in any form :)
+Please however feel free to donate to the original author of HASS.Agent - Sam! Wherever they currently are, cup of coffee might brighten their day.
Tip: Other donation methods are available on the About Window.
@@ -3252,4 +3256,34 @@ Do you want to download the runtime installer?
Button
+
+ NamedActiveWindow
+
+
+ Provides an ON/OFF value based on whether the focused window name contains configured string.
+
+
+ AccentColor
+
+
+ InputButton
+
+
+ Fan
+
+
+ Puts the machine to sleep using WinForms API.
+
+Note: due to "Modern Sleep" the sleep commands might behave differently depending on the device OEM and OS configuration.
+
+
+ WinformsSleep
+
+
+ MonitorSleepPowerPlan
+
+
+ Puts all monitors in sleep (low power) mode using alternative approach of power plan modification.
+Should provide better experience with new systems with "modern S0ix sleep" and not put the system to sleep.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.es.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.es.resx
index 2ea0d91a..eba8c949 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.es.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.es.resx
@@ -2059,7 +2059,10 @@ Actualmente toma el volumen de su dispositivo predeterminado.
Proporciona la carga actual de la primera GPU como porcentaje.
- Proporciona la temperatura actual de la primera GPU.
+ NOTA: Este sensor no funciona.
+
+Debido a problemas de seguridad relacionados con Libre Hardware Monitor (biblioteca que permite a HASS.Agent acceder a los datos de temperatura de la GPU), este sensor se mantiene por compatibilidad con versiones anteriores y siempre devolverá 0.
+Consulte la documentación para ver opciones alternativas.
Proporciona un valor de fecha y hora que contiene el último momento en que el usuario proporcionó una entrada.
@@ -3089,7 +3092,8 @@ Debería contener tres secciones (separadas por dos puntos).
¿Está seguro de que quiere usarlo así?
- Desarrollar y mantener esta herramienta (y todo lo que la rodea) requiere mucho tiempo. Al igual que la mayoría de los desarrolladores, funciono a base de cafeína, así que, si puede dedicarle un poco de tiempo, ¡una taza de café es siempre muy apreciada!
+ Actualmente, nosotros (el equipo de HASS.Agent que mantiene esta versión) no aceptamos donaciones de ningún tipo :)
+Sin embargo, no duden en donar al autor original de HASS.Agent, ¡Sam! Esté donde esté, una taza de café podría alegrarle el día.
Sugerencia: hay otros métodos de donación disponibles en la ventana Acerca de.
@@ -3252,4 +3256,31 @@ Oculta, Maximizada, Minimizada, Normal y Desconocida.
Prensa
+
+ Proporciona un valor de ENCENDIDO/APAGADO según si el nombre de la ventana enfocada contiene una cadena configurada.
+
+
+ Ventana activa con nombre
+
+
+ Color de acento
+
+
+ Admirador
+
+
+ Pone la máquina en suspensión mediante la API de WinForms.
+
+Nota: Debido al modo de suspensión moderno, los comandos de suspensión pueden comportarse de forma diferente según el fabricante del dispositivo y la configuración del sistema operativo.
+
+
+ WinformsSleep
+
+
+ Pone todos los monitores en modo de suspensión (bajo consumo de energía) utilizando un método alternativo de modificación del plan de energía.
+Esto debería proporcionar una mejor experiencia con los nuevos sistemas con "suspensión moderna S0ix" y evitar que el sistema entre en modo de suspensión completa.
+
+
+ Plan de energía para el sueño del monitor
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.fr.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.fr.resx
index 27c3ec38..2860c004 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.fr.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.fr.resx
@@ -2089,7 +2089,10 @@ Indique le volume de votre appareil par défaut.
Fournit la charge actuelle du premier GPU sous forme de pourcentage.
- Fournit la température actuelle du premier GPU.
+ REMARQUE : Ce capteur est non fonctionnel.
+
+Pour des raisons de sécurité concernant Libre Hardware Monitor (bibliothèque permettant à HASS.Agent d'accéder aux données de température du GPU), ce capteur est conservé pour des raisons de rétrocompatibilité et renvoie toujours 0.
+Veuillez consulter la documentation pour connaître les autres options.
Fournit la date et l'heure de la dernière utilisation d'un périphérique par l'utilisateur.
@@ -3122,7 +3125,8 @@ Etes-vous sûr de vouloir l'utiliser comme ça ?
Etes-vous sûr de vouloir l'utiliser ainsi ?
- Développer et maintenir cet outil (et tout ce qui l'entoure) prend beaucoup de temps. Comme la plupart des développeurs, je fonctionne à la caféine - donc si vous pouvez vous le permettre, une tasse de café est toujours très appréciée !
+ Actuellement, nous (l'équipe HASS.Agent qui maintient cette version dérivée) n'acceptons aucune donation, sous quelque forme que ce soit.
+N'hésitez cependant pas à faire un don à l'auteur original de HASS.Agent, Sam ! Où qu'il soit actuellement, une tasse de café pourrait lui faire plaisir.
Astuce : d'autres méthodes de dons sont disponibles dans la fenêtre À propos.
@@ -3285,4 +3289,31 @@ Do you want to download the runtime installer?
Presse
+
+ Fournit une valeur ON/OFF selon que le nom de la fenêtre focalisée contient ou non une chaîne configurée.
+
+
+ Fenêtre active nommée
+
+
+ AccentColor
+
+
+ Ventilateur
+
+
+ Met la machine en veille à l'aide de l'API WinForms.
+
+Remarque : en raison de la fonction « Modern Sleep », les commandes de mise en veille peuvent se comporter différemment selon le fabricant de l'appareil et la configuration du système d'exploitation.
+
+
+ WinformsSleep
+
+
+ Met tous les moniteurs en mode veille (basse consommation) en utilisant une approche alternative de modification du plan d'alimentation.
+Cela devrait offrir une meilleure expérience avec les nouveaux systèmes dotés du mode veille moderne « S0ix » et éviter de mettre le système en veille complète.
+
+
+ Surveillance du mode veille/alimentation
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.nl.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.nl.resx
index 3a9871c4..962d4cb6 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.nl.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.nl.resx
@@ -2070,7 +2070,10 @@ Pakt momenteel het volume van je standaardapparaat.
Geeft de huidige belasting van de eerste GPU als een percentage.
- Geeft de huidige temperatuur van de eerste GPU.
+ OPMERKING: Dit is een niet-functionerende sensor.
+
+Vanwege beveiligingsproblemen met Libre Hardware Monitor (bibliotheek die HASS.Agent toegang geeft tot GPU-temperatuurgegevens) wordt deze sensor om redenen van achterwaartse compatibiliteit niet gebruikt en retourneert altijd 0.
+Raadpleeg de documentatie voor alternatieve opties.
Geeft een datetime waarde met het laatste moment dat de gebruiker invoer geleverd heeft.
@@ -3111,7 +3114,8 @@ Weet je zeker dat je 'm zo wilt gebruiken?
Weet je zeker dat je 'm zo wilt gebruiken?
- Het ontwikkelen en onderhouden van deze tool (en alles wat erbij komt kijken, zoals support, deze vertaling en de documentatie) neemt een hoop tijd in beslag. Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt missen, wordt een kop koffie altijd erg gewaardeerd!
+ Momenteel accepteren wij (het HASS.Agent-team dat de fork beheert) geen donaties in welke vorm dan ook :)
+Voel je echter vrij om te doneren aan de oorspronkelijke auteur van HASS.Agent - Sam! Waar ze zich ook bevinden, een kopje koffie kan hun dag misschien opvrolijken.
Tip: andere donatie methodes zijn beschikbaar in het Over scherm.
@@ -3274,4 +3278,31 @@ Wil je de runtime installatie downloaden?
Pers
+
+ Geeft een AAN/UIT-waarde op basis van het al dan niet bevatten van de focusvensternaam van een geconfigureerde tekenreeks.
+
+
+ SchermActiefNaam
+
+
+ Accentkleur
+
+
+ Fan
+
+
+ Zet de machine in slaapstand met behulp van de WinForms API.
+
+Opmerking: vanwege "Modern Sleep" kunnen de slaapopdrachten zich anders gedragen, afhankelijk van de OEM van het apparaat en de configuratie van het besturingssysteem.
+
+
+ WinformsSleep
+
+
+ Zet alle monitoren in de slaapstand (laag energieverbruik) met behulp van een alternatieve aanpak voor het aanpassen van het energiebeheerschema.
+Zou een betere ervaring moeten bieden met nieuwe systemen met een "moderne S0ix-slaapstand" en het systeem niet in de slaapstand zetten.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.pl.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.pl.resx
index 6947c51d..dcf1b18a 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.pl.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.pl.resx
@@ -2163,7 +2163,10 @@ Obecnie zwraca głośność domyślnego urządzenia.
Zwraca obciążenie pierwszego GPU w procentach.
- Zwraca temperaturę pierwszego GPU.
+ UWAGA: Ten czujnik nie działa.
+
+Ze względu na obawy dotyczące bezpieczeństwa Libre Hardware Monitor (biblioteki umożliwiającej HASS.Agent dostęp do danych o temperaturze GPU), ten czujnik został pozostawiony ze względu na kompatybilność wsteczną i zawsze będzie zwracał wartość 0.
+Informacje o alternatywnych opcjach znajdują się w dokumentacji.
Zwraca czas (datetime value) w którym użytkownik dokonał jakiejkolwiek czynności.
@@ -3199,7 +3202,8 @@ Czy jesteś pewien, że chcesz użyć tego klucza?
Czy jesteś pewien, że chcesz użyć tego linku URL?
- Tworzenie i utrzymanie aplikacji (i wszystko dookoła, jak wsparcie i dokumentacja) zajmuje sporo czasu. Jak większość deweloperów moim paliwem jest kofeina, więc jeżeli możesz postawić mi kubek kawy będę bardzo wdzięczny!
+ Obecnie my (zespół HASS.Agent, odpowiedzialny za utrzymywanie tej wersji) nie przyjmujemy żadnych darowizn :)
+Prosimy jednak o wsparcie finansowe oryginalnego autora HASS.Agent – Sama! Gdziekolwiek się teraz znajduje, filiżanka kawy z pewnością umili mu dzień.
Wskazówka: Inne sposoby wsparcia dostępne są w zakładce O.
@@ -3362,4 +3366,31 @@ Czy chcesz pobrać plik instalacyjny?
Naciśnij
+
+ Zapewnia wartość WŁ./WYŁ. w zależności od tego, czy nazwa wybranego okna zawiera skonfigurowany ciąg znaków.
+
+
+ NazwaAktywnegoOkna
+
+
+ Kolor akcentu
+
+
+ Wiatrak
+
+
+ Uśpij maszynę za pomocą interfejsu API WinForms.
+
+Uwaga: ze względu na „Modern Sleep” polecenia uśpienia mogą zachowywać się inaczej w zależności od producenta OEM urządzenia i konfiguracji systemu operacyjnego.
+
+
+ WinformsSleep
+
+
+ Przełącza wszystkie monitory w tryb uśpienia (niskiego poboru mocy) za pomocą alternatywnej metody modyfikacji planu zasilania.
+Powinno to zapewnić lepsze działanie w przypadku nowych systemów z „nowoczesnym trybem uśpienia S0ix” i zapobiec przejściu systemu w stan uśpienia.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.pt-br.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.pt-br.resx
index a7b67ecb..2e6f62f1 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.pt-br.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.pt-br.resx
@@ -1730,7 +1730,8 @@ Se você encontrar algum problema, crie um ticket na página do GitHub.
Fuzzy
- Desenvolver e manter essa ferramenta (e tudo o que a envolve, como suporte e documentação) leva muito tempo. Como a maioria dos desenvolvedores, eu amo café - então se você puder me doar um cafezinho serei muito agradecido!
+ Atualmente, nós (a equipa do HASS.Agent que mantém o fork) não aceitamos donativos de qualquer forma :)
+No entanto, sinta-se à vontade para doar ao autor original do HASS.Agent - Sam! Onde quer que ele esteja, uma chávena de café pode alegrar o seu dia.
Dica: outros tipos de doação estão disponíveis na janela Sobre.
@@ -2215,7 +2216,10 @@ Dependendo da sua versão do Windows, isso pode ser encontrado no novo painel de
Fornece a carga atual da GPU como uma porcentagem.
- Fornece a temperatura atual da GPU.
+ NOTA: Este sensor não está a funcionar.
+
+Devido a questões de segurança relacionadas com o Libre Hardware Monitor (biblioteca que permite ao HASS.Agent aceder aos dados de temperatura da GPU), este sensor foi mantido por motivos de compatibilidade com versões anteriores e irá sempre retornar 0.
+Consulte a documentação para obter opções alternativas.
Fornece um valor de data e hora contendo o último momento em que o usuário forneceu qualquer entrada.
@@ -3299,4 +3303,31 @@ Deseja baixar o Microsoft WebView2 runtime?
Imprensa
+
+ Fornece um valor ON/OFF com base na presença ou não de uma string configurada no nome da janela em foco.
+
+
+ JanelaAtiva Nomeada
+
+
+ Cor de destaque
+
+
+ Fã
+
+
+ Coloca a máquina em modo de espera utilizando a API do WinForms.
+
+Nota: devido ao "Modern Sleep", os comandos de espera podem comportar-se de forma diferente, dependendo do fabricante do dispositivo e da configuração do sistema operativo.
+
+
+ WinformsSleep
+
+
+ Coloca todos os monitores em modo de suspensão (baixo consumo de energia) utilizando uma abordagem alternativa de modificação do plano de energia.
+Deve proporcionar uma melhor experiência com novos sistemas com "suspensão S0ix moderna" e não colocar o sistema em modo de suspensão.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.resx
index 8fc95014..2b24e3c1 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.resx
@@ -1147,7 +1147,10 @@ Currently takes the volume of your default device.
Provides the current load of the first GPU as a percentage.
- Provides the current temperature of the first GPU.
+ NOTE: This is a non-functioning sensor.
+
+Due to the security concerns regarding Libre Hardware Monitor (library allowing HASS.Agent to access GPU temperature data) this sensor is left for backward compatibility reasons and will always return 0.
+Please see documentation for alternative options.
Provides a datetime value containing the last moment the user provided any input.
@@ -3057,10 +3060,11 @@ Tip: if you're using the HA addon, you can probably use the preset address - jus
Enable &Notifications
- Developing and maintaining this tool (and everything that surrounds it) takes up a lot of time. Like most developers, I run on caffeïne - so if you can spare it, a cup of coffee is always very much appreciated!
+ Currently, we (HASS.Agent Team maintaining the fork) do not accept donations in any form :)
+Please however feel free to donate to the original author of HASS.Agent - Sam! Wherever they currently are, cup of coffee might brighten their day.
- There's a lot more to tinker with, so make sure you take a look at the Configuration Wwindow!
+ There's a lot more to tinker with, so make sure you take a look at the Configuration Window!
Thank you for using HASS.Agent, hopefully it'll be useful for you :-)
@@ -3235,4 +3239,34 @@ Do you want to download the runtime installer?
Button
+
+ NamedActiveWindow
+
+
+ Provides an ON/OFF value based on whether the focused window name contains configured string.
+
+
+ AccentColor
+
+
+ InputButton
+
+
+ Fan
+
+
+ Puts the machine to sleep using WinForms API.
+
+Note: due to "Modern Sleep" the sleep commands might behave differently depending on the device OEM and OS configuration.
+
+
+ WinformsSleep
+
+
+ MonitorSleepPowerPlan
+
+
+ Puts all monitors in sleep (low power) mode using alternative approach of power plan modification.
+Should provide better experience with new systems with "modern S0ix sleep" and not put the system to sleep.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.ru.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.ru.resx
index 6f5d7c6e..9098b171 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.ru.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.ru.resx
@@ -2113,7 +2113,10 @@ Home Assistant version: {0}
Показывает текущую загрузку первого графического процессора в процентах.
- Показывает текущую температуру первого графического процессора.
+ ПРИМЕЧАНИЕ: Это неработающий датчик.
+
+Из-за проблем безопасности, связанных с Libre Hardware Monitor (библиотекой, позволяющей HASS.Agent получать доступ к данным о температуре графического процессора), этот датчик оставлен в целях обратной совместимости и всегда будет возвращать 0.
+Альтернативные варианты см. в документации.
Предоставляет значение даты и времени, содержащее последний момент, когда пользователь предоставил какие-либо входные данные.
@@ -3157,7 +3160,8 @@ Home Assistant.
Вы уверены, что все равно хотите использовать этот URI?
- Разработка и обслуживание этого инструмента (и всего, что его окружает) отнимает много времени. Как и большинство разработчиков, я работаю на кофеине - так что, если вы можете поделиться им, чашка кофе всегда очень ценится!
+ В настоящее время мы (команда HASS.Agent, поддерживающая форк) не принимаем пожертвования в какой-либо форме :)
+Однако, пожалуйста, не стесняйтесь сделать пожертвование оригинальному автору HASS.Agent — Сэму! Где бы он сейчас ни находился, чашка кофе может скрасить его день.
Совет: Другие способы пожертвования доступны в окне 'О программе'.
@@ -3320,4 +3324,31 @@ Home Assistant.
Нажимать
+
+ Предоставляет значение ВКЛ/ВЫКЛ в зависимости от того, содержит ли имя окна в фокусе настроенную строку.
+
+
+ ИменованноеАктивноеОкно
+
+
+ Акцентный цвет
+
+
+ Вентилятор
+
+
+ Переводит устройство в спящий режим с помощью API WinForms.
+
+Примечание: из-за «Modern Sleep» команды перехода в спящий режим могут работать по-разному в зависимости от производителя устройства и конфигурации ОС.
+
+
+ WinformsSleep
+
+
+ Переводит все мониторы в спящий режим (режим пониженного энергопотребления), используя альтернативный подход к изменению схемы управления питанием.
+Это должно обеспечить лучшую работу на новых системах с «современным спящим режимом S0ix» и предотвратить переход системы в спящий режим.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.sl.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.sl.resx
index 1edd421c..345c8167 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.sl.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.sl.resx
@@ -1788,7 +1788,8 @@ Hvala, ker uporabljate HASS.Agent. Upam, da vam bo koristil :-)
Fuzzy
- Razvoj in vzdrževanje tega dodatka (in vsega, kar spada zraven, kot je podpora, navodila) vzame veliko časa. Kot večina razvijalcev tudi jaz delam na kofein - zato bi bil zelo hvaležen kake skodelice kave, če jo lahko pogrešate!
+ Trenutno (ekipa HASS.Agent, ki vzdržuje forum) ne sprejema donacij v nobeni obliki :)
+Vendar pa lahko brez zadržkov donirate izvirnemu avtorju HASS.Agent - Samu! Kjerkoli že je, mu lahko skodelica kave polepša dan.
Namig: ostale možnosti donacij so na voljo v zavihku "Vizitka".
@@ -2292,7 +2293,10 @@ Glede na verzijo Windows-ov se to lahko nahaja v Nadzorna plošča --> Sistem
Zagotavlja trenutno obremenitev prvega GPU-ja v odstotkih.
- Zagotavlja trenutno temperaturo prvega GPU-ja.
+ OPOMBA: To je nedelujoč senzor.
+
+Zaradi varnostnih pomislekov glede Libre Hardware Monitor (knjižnica, ki omogoča HASS.Agent dostop do podatkov o temperaturi GPU) je ta senzor ostal zaradi združljivosti s prejšnjimi različicami in bo vedno vrnil vrednost 0.
+Za alternativne možnosti glejte dokumentacijo.
Zagotavlja vrednost datuma in časa, ki vsebuje zadnji trenutek, ko je uporabnik vnesel kakršen koli vnos.
@@ -3401,4 +3405,31 @@ Ali želite prenesti runtime installer?
Pritisnite
+
+ Zagotavlja vrednost VKLOP/IZKLOP glede na to, ali ime okna v fokusu vsebuje konfiguriran niz.
+
+
+ PoimenovanoAktivnoOkno
+
+
+ Barva poudarka
+
+
+ Ventilator
+
+
+ Preklopi računalnik v stanje mirovanja z uporabo WinForms API-ja.
+
+Opomba: Zaradi »modernega mirovanja« se lahko ukazi za mirovanje obnašajo drugače, odvisno od proizvajalca originalne opreme naprave in konfiguracije operacijskega sistema.
+
+
+ WinformsSleep
+
+
+ Preklopi vse monitorje v način mirovanja (nizka poraba energije) z uporabo alternativnega pristopa k spreminjanju načrta porabe energije.
+Omogoča boljšo izkušnjo z novimi sistemi s »sodobnim načinom mirovanja S0ix« in ne preklopi sistema v stanje mirovanja.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.tr.resx b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.tr.resx
index 28956a1c..4a877f6b 100644
--- a/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.tr.resx
+++ b/src/HASS.Agent/HASS.Agent.Shared/Resources/Localization/Languages.tr.resx
@@ -1846,7 +1846,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku
Yüzde olarak ilk GPU'nun mevcut yükünü sağlar.
- İlk GPU'nun mevcut sıcaklığını sağlar.
+ NOT: Bu, çalışmayan bir sensördür.
+
+Libre Donanım İzleyicisi (HASS.Agent'ın GPU sıcaklık verilerine erişmesine izin veren kütüphane) ile ilgili güvenlik endişeleri nedeniyle, bu sensör geriye dönük uyumluluk nedeniyle bırakılmıştır ve her zaman 0 döndürecektir.
+Alternatif seçenekler için lütfen belgelere bakın.
Kullanıcının herhangi bir girdi sağladığı son anı içeren bir tarih saat değeri sağlar.
@@ -2728,7 +2731,8 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku
Sağladığınız URI geçerli görünmüyor, geçerli bir URI aşağıdakilerden biri gibi görünebilir: - http://homeassistant.local:8123 - http://192.168.0.1:8123 Kullanmak istediğinizden emin misiniz? yine de bu URI?
- Bu aracı (ve onu çevreleyen her şeyi) geliştirmek ve sürdürmek çok zaman alır. Çoğu geliştirici gibi, ben de kafein kullanıyorum - bu yüzden eğer onu ayırabilirseniz, bir fincan kahve her zaman çok değerlidir!
+ Şu anda (çatalın bakımını üstlenen HASS.Agent Ekibi) hiçbir şekilde bağış kabul etmiyoruz :)
+Ancak lütfen HASS.Agent'ın orijinal yazarı Sam'e bağış yapmaktan çekinmeyin! Şu anda nerede olurlarsa olsunlar, bir fincan kahve günlerini güzelleştirebilir.
İpucu: Hakkında Penceresinde başka bağış yöntemleri de mevcuttur.
@@ -2859,4 +2863,31 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku
Basmak
+
+ Odaklanan pencere adının yapılandırılmış dizeyi içerip içermediğine bağlı olarak bir AÇIK/KAPALI değeri sağlar.
+
+
+ AdlandırılmışAktifPencere
+
+
+ Vurgu Rengi
+
+
+ Fan
+
+
+ WinForms API'sini kullanarak makineyi uyku moduna geçirir.
+
+Not: "Modern Uyku" nedeniyle uyku komutları, cihazın OEM ve işletim sistemi yapılandırmasına bağlı olarak farklı davranabilir.
+
+
+ WinformsSleep
+
+
+ Güç planı değişikliği gibi alternatif bir yaklaşım kullanarak tüm monitörleri uyku moduna (düşük güç) alır.
+"Modern S0ix uyku" özelliğine sahip yeni sistemlerde daha iyi bir deneyim sağlamalı ve sistemi uyku moduna almamalıdır.
+
+
+ MonitörUykuGüçPlanı
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/API/ApiEndpoints.cs b/src/HASS.Agent/HASS.Agent/API/ApiEndpoints.cs
index ab28e889..6e7387cc 100644
--- a/src/HASS.Agent/HASS.Agent/API/ApiEndpoints.cs
+++ b/src/HASS.Agent/HASS.Agent/API/ApiEndpoints.cs
@@ -2,10 +2,12 @@
using Grapevine;
using HASS.Agent.Enums;
using HASS.Agent.Extensions;
+using HASS.Agent.Functions;
using HASS.Agent.Managers;
using HASS.Agent.Media;
using HASS.Agent.Models.HomeAssistant;
using HASS.Agent.MQTT;
+using HASS.Agent.Shared.Models.HomeAssistant;
using Newtonsoft.Json;
using Serilog;
using HttpMethod = System.Net.Http.HttpMethod;
@@ -24,6 +26,21 @@ public class ApiEndpoints : ApiDeserialization
///
public static async Task DeviceInfoRoute(IHttpContext context)
{
+ if (Variables.DeviceConfig == null)
+ {
+ var name = HelperFunctions.GetConfiguredDeviceName();
+ Log.Information("[LOCALAPI] Device configuration missing, creating and identifying as device: {name}", name);
+
+ Variables.DeviceConfig = new DeviceConfigModel
+ {
+ Name = name,
+ Identifiers = "hass.agent-" + name,
+ Manufacturer = "HASS.Agent Team",
+ Model = Environment.OSVersion.ToString(),
+ Sw_version = Variables.Version
+ };
+ }
+
context.Response.ContentType = "application/json";
await context.Response.SendResponseAsync(JsonConvert.SerializeObject(new
{
@@ -36,7 +53,7 @@ await context.Response.SendResponseAsync(JsonConvert.SerializeObject(new
}
}, MqttManager.JsonSerializerSettings));
}
-
+
///
/// Notification route, handles all incoming notifications on '/notify'
///
diff --git a/src/HASS.Agent/HASS.Agent/Commands/CommandsManager.cs b/src/HASS.Agent/HASS.Agent/Commands/CommandsManager.cs
index f9a47fd9..dc7e4200 100644
--- a/src/HASS.Agent/HASS.Agent/Commands/CommandsManager.cs
+++ b/src/HASS.Agent/HASS.Agent/Commands/CommandsManager.cs
@@ -58,20 +58,37 @@ internal static async void Initialize()
/// Unpublishes all commands
///
///
- internal static async Task UnpublishAllCommands()
+ internal static async Task UnpublishAllCommands(bool migration = false)
{
if (!CommandsPresent())
return;
foreach (var command in Variables.Commands)
{
- await command.UnPublishAutoDiscoveryConfigAsync();
+ await command.UnPublishAutoDiscoveryConfigAsync(migration);
await Variables.MqttManager.UnsubscribeAsync(command);
}
_discoveryPublished = false;
}
+ ///
+ /// Publishes all commands
+ ///
+ ///
+ internal static async Task ForcePublishAllCommands()
+ {
+ if (!CommandsPresent())
+ return;
+
+ foreach (var command in Variables.Commands)
+ {
+ await command.PublishAutoDiscoveryConfigAsync();
+ }
+
+ _discoveryPublished = false;
+ }
+
///
/// Generates new ID's for all commands
///
@@ -416,6 +433,14 @@ internal static void LoadCommandInfo()
// =================================
+ commandInfoCard = new CommandInfoCard(CommandType.MonitorSleepPowerPlanCommand,
+ Languages.CommandsManager_MonitorSleepPowerPlanCommandDescription,
+ true, false, false);
+
+ CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard);
+
+ // =================================
+
commandInfoCard = new CommandInfoCard(CommandType.MonitorWakeCommand,
Languages.CommandsManager_MonitorWakeCommandDescription,
true, false, false);
@@ -448,6 +473,14 @@ internal static void LoadCommandInfo()
// =================================
+ commandInfoCard = new CommandInfoCard(CommandType.RadioCommand,
+ Languages.CommandsManager_RadioCommandDescription,
+ true, false, true);
+
+ CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard);
+
+ // =================================
+
commandInfoCard = new CommandInfoCard(CommandType.RestartCommand,
Languages.CommandsManager_RestartCommandDescription,
true, true, false);
@@ -520,24 +553,24 @@ internal static void LoadCommandInfo()
// =================================
- commandInfoCard = new CommandInfoCard(CommandType.WebViewCommand,
- Languages.CommandsManager_WebViewCommandDescription,
- true, false, true);
+ commandInfoCard = new CommandInfoCard(CommandType.TrayWebViewCommand,
+ Languages.CommandsManager_TrayWebViewCommandDescription,
+ true, false, false);
CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard);
// =================================
- commandInfoCard = new CommandInfoCard(CommandType.TrayWebViewCommand,
- Languages.CommandsManager_TrayWebViewCommandDescription,
+ commandInfoCard = new CommandInfoCard(CommandType.WinformsSleepCommand,
+ Languages.CommandsManager_WinformsSleepCommandDescription,
true, false, false);
CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard);
// =================================
- commandInfoCard = new CommandInfoCard(CommandType.RadioCommand,
- Languages.CommandsManager_RadioCommandDescription,
+ commandInfoCard = new CommandInfoCard(CommandType.WebViewCommand,
+ Languages.CommandsManager_WebViewCommandDescription,
true, false, true);
CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard);
diff --git a/src/HASS.Agent/HASS.Agent/Compatibility/MigrateCompatibilityTask.cs b/src/HASS.Agent/HASS.Agent/Compatibility/MigrateCompatibilityTask.cs
index f299a454..0c291874 100644
--- a/src/HASS.Agent/HASS.Agent/Compatibility/MigrateCompatibilityTask.cs
+++ b/src/HASS.Agent/HASS.Agent/Compatibility/MigrateCompatibilityTask.cs
@@ -255,6 +255,38 @@ private void MigrateCommands(string commandsFile)
Log.Information("[COMPATTASK] Commands configuration migrated");
}
+
+ private void CreateForkConfigBackup()
+ {
+ var backupFolderName = $"migrationBackup_{DateTime.Now.ToString("ddMMyy_HHmmss")}";
+ Log.Information("[COMPATTASK] Creating backup of existing forked version configuration (client) into {bf}", backupFolderName);
+
+ var destination = Path.Combine(Variables.ConfigPath, backupFolderName);
+ Directory.CreateDirectory(destination);
+
+ var currentConfigFiles = new DirectoryInfo(Variables.ConfigPath).GetFiles();
+ foreach (var file in currentConfigFiles)
+ {
+ Log.Information("[COMPATTASK] Backing up {fn}", file.FullName);
+ file.CopyTo(Path.Combine(destination, file.Name), true);
+ }
+
+ Log.Information("[COMPATTASK] Creating backup of existing forked version configuration (service) into {bf}", backupFolderName);
+
+ var serviceConfigPath = Path.Combine(ServiceManager.GetInstallPath(), "config");
+ destination = Path.Combine(serviceConfigPath, backupFolderName);
+ Directory.CreateDirectory(destination);
+
+ currentConfigFiles = new DirectoryInfo(serviceConfigPath).GetFiles();
+ foreach (var file in currentConfigFiles)
+ {
+ Log.Information("[COMPATTASK] Backing up {fn}", file.FullName);
+ file.CopyTo(Path.Combine(destination, file.Name), true);
+ }
+
+ Log.Information("[COMPATTASK] Creating backup of existing forked version configuration completed");
+ }
+
public async Task<(bool, string)> Perform()
{
try
@@ -265,6 +297,8 @@ private void MigrateCommands(string commandsFile)
StopOriginalInstances();
+ CreateForkConfigBackup();
+
MigrateServiceConfig();
MigrateClientConfig();
MigrateRegistryConfig();
diff --git a/src/HASS.Agent/HASS.Agent/Compatibility/NameCompatibilityTask.cs b/src/HASS.Agent/HASS.Agent/Compatibility/NameCompatibilityTask.cs
index ef3fd03b..0fa21df6 100644
--- a/src/HASS.Agent/HASS.Agent/Compatibility/NameCompatibilityTask.cs
+++ b/src/HASS.Agent/HASS.Agent/Compatibility/NameCompatibilityTask.cs
@@ -10,8 +10,6 @@
using HASS.Agent.Shared.Functions;
using HASS.Agent.Shared.Models.Config;
using HASS.Agent.Shared.Models.HomeAssistant;
-using HidSharp.Utility;
-using LibreHardwareMonitor.Hardware;
using Octokit;
using Serilog;
using System;
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigMqtt.Designer.cs b/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigMqtt.Designer.cs
index 670ddf22..d404552a 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigMqtt.Designer.cs
+++ b/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigMqtt.Designer.cs
@@ -37,6 +37,7 @@ private void InitializeComponent()
this.TbMqttRootCertificate = new System.Windows.Forms.TextBox();
this.LblRootCert = new System.Windows.Forms.Label();
this.CbUseRetainFlag = new System.Windows.Forms.CheckBox();
+ this.CbUseWebSocket = new System.Windows.Forms.CheckBox();
this.CbAllowUntrustedCertificates = new System.Windows.Forms.CheckBox();
this.BtnMqttClearConfig = new Syncfusion.WinForms.Controls.SfButton();
this.LblTip1 = new System.Windows.Forms.Label();
@@ -138,13 +139,27 @@ private void InitializeComponent()
this.CbUseRetainFlag.AccessibleRole = System.Windows.Forms.AccessibleRole.CheckButton;
this.CbUseRetainFlag.AutoSize = true;
this.CbUseRetainFlag.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.CbUseRetainFlag.Location = new System.Drawing.Point(412, 451);
+ this.CbUseRetainFlag.Location = new System.Drawing.Point(412, 431);
this.CbUseRetainFlag.Name = "CbUseRetainFlag";
this.CbUseRetainFlag.Size = new System.Drawing.Size(114, 23);
this.CbUseRetainFlag.TabIndex = 10;
this.CbUseRetainFlag.Text = Languages.ConfigMqtt_CbUseRetainFlag;
this.CbUseRetainFlag.UseVisualStyleBackColor = true;
//
+ // CbUseWebSocketFlag
+ //
+ this.CbUseWebSocket.AccessibleDescription = "Use WebSocket for MQTT connection instead of direct one.";
+ this.CbUseWebSocket.AccessibleName = "WebSocket flag";
+ this.CbUseWebSocket.AccessibleRole = System.Windows.Forms.AccessibleRole.CheckButton;
+ this.CbUseWebSocket.AutoSize = true;
+ this.CbUseWebSocket.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
+ this.CbUseWebSocket.Location = new System.Drawing.Point(412, 469);
+ this.CbUseWebSocket.Name = "CbUseWebSocketFlag";
+ this.CbUseWebSocket.Size = new System.Drawing.Size(114, 23);
+ this.CbUseWebSocket.TabIndex = 57;
+ this.CbUseWebSocket.Text = Languages.ConfigMqtt_CbUseWebSocket;
+ this.CbUseWebSocket.UseVisualStyleBackColor = true;
+ //
// CbAllowUntrustedCertificates
//
this.CbAllowUntrustedCertificates.AccessibleDescription = "Enable allowing untrusted certificates when connecting.";
@@ -500,6 +515,7 @@ private void InitializeComponent()
this.Controls.Add(TbMqttRootCertificate);
this.Controls.Add(LblRootCert);
this.Controls.Add(CbUseRetainFlag);
+ this.Controls.Add(CbUseWebSocket);
this.Controls.Add(CbAllowUntrustedCertificates);
this.Controls.Add(BtnMqttClearConfig);
this.Controls.Add(LblTip1);
@@ -540,6 +556,7 @@ private void InitializeComponent()
internal System.Windows.Forms.TextBox TbMqttClientCertificate;
internal System.Windows.Forms.TextBox TbMqttRootCertificate;
internal System.Windows.Forms.CheckBox CbUseRetainFlag;
+ internal System.Windows.Forms.CheckBox CbUseWebSocket;
internal System.Windows.Forms.CheckBox CbAllowUntrustedCertificates;
internal Syncfusion.WinForms.Controls.SfButton BtnMqttClearConfig;
internal System.Windows.Forms.TextBox TbMqttDiscoveryPrefix;
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigMqtt.cs b/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigMqtt.cs
index 83354e26..cf85f27d 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigMqtt.cs
+++ b/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigMqtt.cs
@@ -47,6 +47,7 @@ private void BtnMqttClearConfig_Click(object sender, EventArgs e)
TbMqttClientCertificate.Text = string.Empty;
CbAllowUntrustedCertificates.CheckState = CheckState.Checked;
CbUseRetainFlag.CheckState = CheckState.Checked;
+ CbUseWebSocket.CheckState = CheckState.Unchecked;
}
private void ConfigMqtt_Load(object sender, EventArgs e)
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigTrayIcon.Designer.cs b/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigTrayIcon.Designer.cs
index 8fec92e9..3ef31079 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigTrayIcon.Designer.cs
+++ b/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigTrayIcon.Designer.cs
@@ -1,4 +1,5 @@
using HASS.Agent.Resources.Localization;
+using Syncfusion.Windows.Forms.Tools;
namespace HASS.Agent.Controls.Configuration
{
@@ -39,14 +40,16 @@ private void InitializeComponent()
LblX = new Label();
LblWebViewSize = new Label();
BtnShowWebViewPreview = new Syncfusion.WinForms.Controls.SfButton();
- NumWebViewWidth = new Syncfusion.Windows.Forms.Tools.NumericUpDownExt();
- NumWebViewHeight = new Syncfusion.Windows.Forms.Tools.NumericUpDownExt();
+ NumWebViewWidth = new NumericUpDownExt();
+ NumWebViewHeight = new NumericUpDownExt();
BtnWebViewReset = new Syncfusion.WinForms.Controls.SfButton();
CbWebViewKeepLoaded = new CheckBox();
LblInfo2 = new Label();
CbWebViewShowMenuOnLeftClick = new CheckBox();
+ NumWebViewScreen = new ComboBoxAdv();
((System.ComponentModel.ISupportInitialize)NumWebViewWidth).BeginInit();
((System.ComponentModel.ISupportInitialize)NumWebViewHeight).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)NumWebViewScreen).BeginInit();
SuspendLayout();
//
// LblInfo1
@@ -142,7 +145,7 @@ private void InitializeComponent()
LblX.AccessibleRole = AccessibleRole.StaticText;
LblX.AutoSize = true;
LblX.Font = new Font("Segoe UI", 10F);
- LblX.Location = new Point(184, 350);
+ LblX.Location = new Point(176, 350);
LblX.Name = "LblX";
LblX.Size = new Size(17, 19);
LblX.TabIndex = 53;
@@ -170,9 +173,9 @@ private void InitializeComponent()
BtnShowWebViewPreview.Enabled = false;
BtnShowWebViewPreview.Font = new Font("Segoe UI", 10F);
BtnShowWebViewPreview.ForeColor = Color.FromArgb(241, 241, 241);
- BtnShowWebViewPreview.Location = new Point(405, 348);
+ BtnShowWebViewPreview.Location = new Point(494, 348);
BtnShowWebViewPreview.Name = "BtnShowWebViewPreview";
- BtnShowWebViewPreview.Size = new Size(206, 26);
+ BtnShowWebViewPreview.Size = new Size(117, 26);
BtnShowWebViewPreview.Style.BackColor = Color.FromArgb(63, 63, 70);
BtnShowWebViewPreview.Style.FocusedBackColor = Color.FromArgb(63, 63, 70);
BtnShowWebViewPreview.Style.FocusedForeColor = Color.FromArgb(241, 241, 241);
@@ -222,7 +225,7 @@ private void InitializeComponent()
NumWebViewHeight.Enabled = false;
NumWebViewHeight.Font = new Font("Segoe UI", 10F);
NumWebViewHeight.ForeColor = Color.FromArgb(241, 241, 241);
- NumWebViewHeight.Location = new Point(218, 348);
+ NumWebViewHeight.Location = new Point(197, 348);
NumWebViewHeight.Maximum = new decimal(new int[] { 65535, 0, 0, 0 });
NumWebViewHeight.MaxLength = 10;
NumWebViewHeight.MetroColor = SystemColors.WindowFrame;
@@ -243,7 +246,7 @@ private void InitializeComponent()
BtnWebViewReset.Font = new Font("Segoe UI", 10F);
BtnWebViewReset.ForeColor = Color.FromArgb(241, 241, 241);
BtnWebViewReset.ImageSize = new Size(24, 24);
- BtnWebViewReset.Location = new Point(317, 348);
+ BtnWebViewReset.Location = new Point(289, 348);
BtnWebViewReset.Name = "BtnWebViewReset";
BtnWebViewReset.Size = new Size(51, 26);
BtnWebViewReset.Style.BackColor = Color.FromArgb(63, 63, 70);
@@ -305,9 +308,25 @@ private void InitializeComponent()
CbWebViewShowMenuOnLeftClick.Text = Languages.ConfigTrayIcon_CbWebViewShowMenuOnLeftClick;
CbWebViewShowMenuOnLeftClick.UseVisualStyleBackColor = true;
//
- // ConfigTrayIcon
- //
- AccessibleDescription = "Panel containing the tray icon configuration.";
+ // NumWebViewScreen
+ //
+ NumWebViewScreen.AccessibleDescription = "Dropdown containing the screens to choose for tray web view display.";
+ NumWebViewScreen.AccessibleName = "Display on which to show the tray web view";
+ NumWebViewScreen.BeforeTouchSize = new Size(142, 23);
+ NumWebViewScreen.Font = new Font("Segoe UI", 10F);
+ NumWebViewScreen.Location = new Point(346, 348);
+ NumWebViewScreen.Name = "NumWebViewScreen";
+ NumWebViewScreen.Size = new Size(142, 23);
+ NumWebViewScreen.TabIndex = 78;
+ NumWebViewScreen.Text = Languages.ConfigTrayIcon_NumWebViewScreen;
+ NumWebViewScreen.SelectedValueChanged += domainUpDown1_SelectedItemChanged;
+ NumWebViewScreen.BackColor = Color.FromArgb(63, 63, 70);
+ NumWebViewScreen.Border3DStyle = Border3DStyle.Flat;
+ NumWebViewScreen.ForeColor = Color.FromArgb(241, 241, 241);
+ //
+ // ConfigTrayIcon
+ //
+ AccessibleDescription = "Panel containing the tray icon configuration.";
AccessibleName = "Tray icon";
AccessibleRole = AccessibleRole.Pane;
AutoScaleDimensions = new SizeF(96F, 96F);
@@ -328,6 +347,7 @@ private void InitializeComponent()
Controls.Add(LblInfo1);
Controls.Add(CbDefaultMenu);
Controls.Add(CbUseModernIcon);
+ Controls.Add(NumWebViewScreen);
ForeColor = Color.FromArgb(241, 241, 241);
Margin = new Padding(4);
Name = "ConfigTrayIcon";
@@ -335,25 +355,27 @@ private void InitializeComponent()
Load += ConfigTrayIcon_Load;
((System.ComponentModel.ISupportInitialize)NumWebViewWidth).EndInit();
((System.ComponentModel.ISupportInitialize)NumWebViewHeight).EndInit();
+ ((System.ComponentModel.ISupportInitialize)NumWebViewScreen).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
- private System.Windows.Forms.Label LblInfo1;
- internal System.Windows.Forms.CheckBox CbUseModernIcon;
- internal System.Windows.Forms.CheckBox CbDefaultMenu;
+ private Label LblInfo1;
+ internal CheckBox CbUseModernIcon;
+ internal CheckBox CbDefaultMenu;
internal CheckBox CbShowWebView;
internal TextBox TbWebViewUrl;
internal Syncfusion.WinForms.Controls.SfButton BtnShowWebViewPreview;
internal Label LblWebViewUrl;
internal Label LblX;
internal Label LblWebViewSize;
- internal Syncfusion.Windows.Forms.Tools.NumericUpDownExt NumWebViewWidth;
- internal Syncfusion.Windows.Forms.Tools.NumericUpDownExt NumWebViewHeight;
+ internal NumericUpDownExt NumWebViewWidth;
+ internal NumericUpDownExt NumWebViewHeight;
internal Syncfusion.WinForms.Controls.SfButton BtnWebViewReset;
internal CheckBox CbWebViewKeepLoaded;
internal Label LblInfo2;
internal CheckBox CbWebViewShowMenuOnLeftClick;
+ internal ComboBoxAdv NumWebViewScreen;
}
}
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigTrayIcon.cs b/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigTrayIcon.cs
index 88575ef8..9757ebfb 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigTrayIcon.cs
+++ b/src/HASS.Agent/HASS.Agent/Controls/Configuration/ConfigTrayIcon.cs
@@ -1,11 +1,13 @@
-using System.Diagnostics;
-using HASS.Agent.Functions;
+using HASS.Agent.Functions;
using HASS.Agent.Models.Internal;
+using Syncfusion.Windows.Forms.Tools;
namespace HASS.Agent.Controls.Configuration
{
public partial class ConfigTrayIcon : UserControl
{
+ internal int SelectedScreen { get; set; }
+
public ConfigTrayIcon()
{
InitializeComponent();
@@ -14,6 +16,33 @@ public ConfigTrayIcon()
private void ConfigTrayIcon_Load(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(TbWebViewUrl.Text)) TbWebViewUrl.Text = Variables.AppSettings.HassUri;
+ InitMultiScreenConfig();
+ }
+
+ private void InitMultiScreenConfig()
+ {
+ if (Variables.AppSettings.TrayIconWebViewScreen == -1)
+ {
+ HelperFunctions.InitMultiScreenConfig();
+ }
+
+ if (Screen.AllScreens.Length == 1)
+ {
+ NumWebViewScreen.Visible = true;
+ NumWebViewScreen.Items.Add("Single Screen Mode");
+ NumWebViewScreen.Enabled = false;
+ }
+ else
+ {
+ foreach (var display in Screen.AllScreens)
+ {
+ var label = display.Primary ? $"{display.DeviceName} (Primary)" : display.DeviceName;
+ NumWebViewScreen.Items.Add(label);
+ }
+ }
+
+ NumWebViewScreen.SelectedIndex = Variables.AppSettings.TrayIconWebViewScreen;
+ SelectedScreen = Variables.AppSettings.TrayIconWebViewScreen;
}
private void CbDefaultMenu_CheckedChanged(object sender, EventArgs e)
@@ -45,8 +74,7 @@ private void BtnShowWebViewPreview_Click(object sender, EventArgs e)
IsTrayIconWebView = true,
IsTrayIconPreview = true
};
-
- HelperFunctions.LaunchTrayIconWebView(webView);
+ HelperFunctions.LaunchTrayIconWebView(webView, NumWebViewScreen.SelectedIndex);
}
private void BtnWebViewReset_Click(object sender, EventArgs e)
@@ -54,5 +82,10 @@ private void BtnWebViewReset_Click(object sender, EventArgs e)
NumWebViewWidth.Value = 700;
NumWebViewHeight.Value = 560;
}
+
+ private void domainUpDown1_SelectedItemChanged(object sender, EventArgs e)
+ {
+ SelectedScreen = ((ComboBoxAdv)sender).SelectedIndex;
+ }
}
}
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.de.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.de.resx
index deb06fac..d216376e 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.de.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.de.resx
@@ -1,14 +1,23 @@
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Um zu erfahren, welche Entitäten Sie konfiguriert haben, und um schnelle Aktionen zu senden, verwendet HASS.Agent die API von Home Assistant.
+
+Bitte geben Sie einen langlebigen Zugriffstoken und die Adresse Ihrer Home Assistant-Instanz an.
+Sie erhalten einen Token in Home Assistant, indem Sie unten links auf Ihr Profilbild klicken, oben auf den Sicherheits-Tab wechseln und zum unteren Seitenrand navigieren, bis die Schaltfläche „TOKEN ERSTELLEN“ angezeigt wird.
+
+Bitte beachten Sie, dass Sie für die Benachrichtigungsfunktion einen Administrator-Konto-Token angeben müssen.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.en.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.en.resx
index deb06fac..bf2328a9 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.en.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.en.resx
@@ -1,14 +1,26 @@
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ To learn which entities you have configured and to send quick actions, HASS.Agent uses
+Home Assistant's API.
+
+Please provide a long-lived access token and the address of your Home Assistant instance.
+You can get a token in Home Assistant by clicking your profile picture at the bottom-left
+switch to the security tab at the top and navigating to the bottom of the page until you
+see the 'CREATE TOKEN' button.
+
+Please note, that for actionable notification functionality you need to provide admin account token.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.es.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.es.resx
index deb06fac..617c2683 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.es.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.es.resx
@@ -1,14 +1,23 @@
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Para saber qué entidades has configurado y enviar acciones rápidas, HASS.Agent utiliza la API de Home Assistant.
+
+Proporciona un token de acceso de larga duración y la dirección de tu instancia de Home Assistant.
+Puedes obtener un token en Home Assistant haciendo clic en tu foto de perfil en la esquina inferior izquierda, cambiando a la pestaña de seguridad en la parte superior y navegando hasta el final de la página hasta que veas el botón "CREAR TOKEN".
+
+Ten en cuenta que para la función de notificaciones procesables, debes proporcionar el token de la cuenta de administrador.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.fr.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.fr.resx
index deb06fac..3417cf4d 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.fr.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.fr.resx
@@ -1,14 +1,23 @@
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Pour connaître les entités que vous avez configurées et envoyer des actions rapides, HASS.Agent utilise l'API de Home Assistant.
+
+Veuillez fournir un jeton d'accès longue durée et l'adresse de votre instance Home Assistant.
+Vous pouvez obtenir un jeton dans Home Assistant en cliquant sur votre photo de profil en bas à gauche, en passant à l'onglet Sécurité en haut et en naviguant vers le bas de la page jusqu'à ce que le bouton « CRÉER UN JETON » apparaisse.
+
+Veuillez noter que pour bénéficier de la fonctionnalité de notification, vous devez fournir un jeton de compte administrateur.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.nl.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.nl.resx
index deb06fac..ad0df29e 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.nl.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.nl.resx
@@ -1,14 +1,26 @@
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Om te zien welke entiteiten je hebt geconfigureerd en om snelle acties te versturen, gebruikt HASS.Agent de API van
+Home Assistant.
+
+Geef een toegangstoken met een lange levensduur en het adres van je Home Assistant-instantie op.
+Je kunt een token in Home Assistant verkrijgen door linksonder op je profielfoto te klikken,
+naar het tabblad Beveiliging bovenaan te gaan en naar de onderkant van de pagina te navigeren totdat je
+de knop 'TOKEN AANMAKEN' ziet.
+
+Houd er rekening mee dat je voor actieve meldingen een beheerdersaccounttoken moet opgeven.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.pl.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.pl.resx
index deb06fac..cecb80b2 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.pl.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.pl.resx
@@ -1,14 +1,26 @@
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Aby dowiedzieć się, które jednostki zostały skonfigurowane i wysłać szybkie akcje, HASS.Agent korzysta z
+API Home Assistant.
+
+Podaj długoterminowy token dostępu i adres swojej instancji Home Assistant.
+Możesz uzyskać token w Home Assistant, klikając swoje zdjęcie profilowe w lewym dolnym rogu,
+przechodząc do zakładki bezpieczeństwa u góry i przechodząc na dół strony, aż zobaczysz
+przycisk „UTWÓRZ TOKEN”.
+
+Pamiętaj, że aby korzystać z funkcji powiadomień z możliwością wykonania akcji, musisz podać token konta administratora.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.pt-br.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.pt-br.resx
index deb06fac..d728b209 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.pt-br.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.pt-br.resx
@@ -1,14 +1,26 @@
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Para saber quais as entidades que configurou e enviar ações rápidas, o HASS.Agent utiliza
+a API do Home Assistant.
+
+Forneça um token de acesso de longa duração e o endereço da sua instância do Home Assistant.
+Pode obter um token no Home Assistant clicando na sua fotografia de perfil no canto inferior esquerdo,
+mude para o separador de segurança na parte superior e navegue até ao final da página até
+ver o botão "CRIAR TOKEN".
+
+Note que, para a funcionalidade de notificação acionável, precisa de fornecer o token da conta de administrador.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.resx
index f9ee09c4..d99bf07c 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.resx
@@ -63,8 +63,9 @@ Home Assistant's API.
Please provide a long-lived access token and the address of your Home Assistant instance.
You can get a token in Home Assistant by clicking your profile picture at the bottom-left
-and navigating to the bottom of the page until you see the 'CREATE TOKEN' button.
+switch to the security tab at the top and navigating to the bottom of the page until you
+see the 'CREATE TOKEN' button.
Please note, that for actionable notification functionality you need to provide admin account token.
-
\ No newline at end of file
+
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.ru.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.ru.resx
index deb06fac..a163bd96 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.ru.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.ru.resx
@@ -1,14 +1,25 @@
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Чтобы узнать, какие сущности вы настроили, и отправлять быстрые действия, HASS.Agent использует
+API Home Assistant.
+
+Укажите долгосрочный токен доступа и адрес вашего экземпляра Home Assistant.
+Вы можете получить токен в Home Assistant, нажав на изображение своего профиля в левом нижнем углу,
+переключившись на вкладку «Безопасность» в верхней части страницы и перейдя вниз, пока не увидите кнопку «СОЗДАТЬ ТОКЕН».
+
+Обратите внимание, что для работы функции уведомлений с действиями вам необходимо предоставить токен учетной записи администратора.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.sl.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.sl.resx
index deb06fac..5d0df84d 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.sl.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.sl.resx
@@ -1,14 +1,26 @@
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Če želite izvedeti, katere entitete ste konfigurirali, in poslati hitra dejanja, HASS.Agent uporablja
+API Home Assistant.
+
+Navedite žeton za dolgotrajen dostop in naslov vašega primerka Home Assistant.
+Žeton v Home Assistant lahko dobite tako, da kliknete svojo profilno sliko spodaj levo,
+preklopite na zavihek varnost na vrhu in se pomaknete na dno strani, dokler ne
+zagledate gumba »USTVARITE ŽETON«.
+
+Upoštevajte, da morate za funkcionalnost obvestil, ki omogočajo ukrepanje, navesti žeton skrbniškega računa.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.tr.resx b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.tr.resx
index deb06fac..795c1a10 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.tr.resx
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-3-API.tr.resx
@@ -1,14 +1,23 @@
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Hangi varlıkları yapılandırdığınızı öğrenmek ve hızlı eylemler göndermek için HASS.Agent, Home Assistant API'sini kullanır.
+
+Lütfen uzun ömürlü bir erişim belirteci ve Home Assistant örneğinizin adresini sağlayın.
+Home Assistant'ta, sol alt köşedeki profil resminize tıklayarak, üstteki güvenlik sekmesine geçerek ve 'JETON OLUŞTUR' düğmesini görene kadar sayfanın en altına giderek bir belirteç alabilirsiniz.
+
+Eylemsel bildirim işlevi için yönetici hesabı belirteci sağlamanız gerektiğini lütfen unutmayın.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-4-MQTT.Designer.cs b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-4-MQTT.Designer.cs
index 286871ea..fa3859e2 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-4-MQTT.Designer.cs
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-4-MQTT.Designer.cs
@@ -48,6 +48,8 @@ private void InitializeComponent()
this.NumMqttPort = new Syncfusion.Windows.Forms.Tools.NumericUpDownExt();
this.PbShow = new System.Windows.Forms.PictureBox();
this.CbEnableMqtt = new System.Windows.Forms.CheckBox();
+ this.CbUseWebSocket = new System.Windows.Forms.CheckBox();
+ this.BtnTest = new Syncfusion.WinForms.Controls.SfButton();
((System.ComponentModel.ISupportInitialize)(this.PbHassAgentLogo)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.NumMqttPort)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.PbShow)).BeginInit();
@@ -126,6 +128,20 @@ private void InitializeComponent()
this.CbMqttTls.UseVisualStyleBackColor = true;
this.CbMqttTls.CheckedChanged += new System.EventHandler(this.CbMqttTls_CheckedChanged);
//
+ // CbUseWebSocketFlag
+ //
+ this.CbUseWebSocket.AccessibleDescription = "Use WebSocket for MQTT connection instead of direct one.";
+ this.CbUseWebSocket.AccessibleName = "WebSocket flag";
+ this.CbUseWebSocket.AccessibleRole = System.Windows.Forms.AccessibleRole.CheckButton;
+ this.CbUseWebSocket.AutoSize = true;
+ this.CbUseWebSocket.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
+ this.CbUseWebSocket.Location = new System.Drawing.Point(371, 148);
+ this.CbUseWebSocket.Name = "CbUseWebSocketFlag";
+ this.CbUseWebSocket.Size = new System.Drawing.Size(114, 23);
+ this.CbUseWebSocket.TabIndex = 104;
+ this.CbUseWebSocket.Text = Languages.ConfigMqtt_CbUseWebSocket;
+ this.CbUseWebSocket.UseVisualStyleBackColor = true;
+ //
// LblPassword
//
this.LblPassword.AccessibleDescription = "Password textbox description.";
@@ -306,6 +322,29 @@ private void InitializeComponent()
this.CbEnableMqtt.Text = Languages.OnboardingMqtt_CbEnableMqtt;
this.CbEnableMqtt.UseVisualStyleBackColor = true;
//
+ // BtnTest
+ //
+ BtnTest.AccessibleDescription = "Perform a test connection with your MQTT instance.";
+ BtnTest.AccessibleName = "Test connection";
+ BtnTest.AccessibleRole = AccessibleRole.PushButton;
+ BtnTest.BackColor = Color.FromArgb(63, 63, 70);
+ BtnTest.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point);
+ BtnTest.ForeColor = Color.FromArgb(241, 241, 241);
+ BtnTest.Location = new Point(558, 349);
+ BtnTest.Name = "BtnTest";
+ BtnTest.Size = new Size(180, 23);
+ BtnTest.Style.BackColor = Color.FromArgb(63, 63, 70);
+ BtnTest.Style.FocusedBackColor = Color.FromArgb(63, 63, 70);
+ BtnTest.Style.FocusedForeColor = Color.FromArgb(241, 241, 241);
+ BtnTest.Style.ForeColor = Color.FromArgb(241, 241, 241);
+ BtnTest.Style.HoverBackColor = Color.FromArgb(63, 63, 70);
+ BtnTest.Style.HoverForeColor = Color.FromArgb(241, 241, 241);
+ BtnTest.Style.PressedForeColor = Color.Black;
+ BtnTest.TabIndex = 103;
+ BtnTest.Text = Languages.OnboardingApi_BtnTest;
+ BtnTest.UseVisualStyleBackColor = false;
+ BtnTest.Click += BtnTest_Click;
+ //
// OnboardingMqtt
//
this.AccessibleDescription = "Panel containing the onboarding MQTT configuration.";
@@ -325,12 +364,14 @@ private void InitializeComponent()
this.Controls.Add(this.TbMqttUsername);
this.Controls.Add(this.TbMqttAddress);
this.Controls.Add(this.CbMqttTls);
+ this.Controls.Add(this.CbUseWebSocket);
this.Controls.Add(this.LblPassword);
this.Controls.Add(this.LblUsername);
this.Controls.Add(this.LblPort);
this.Controls.Add(this.LblIpAdress);
this.Controls.Add(this.LblInfo1);
this.Controls.Add(this.PbHassAgentLogo);
+ this.Controls.Add(this.BtnTest);
this.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241)))));
this.Margin = new System.Windows.Forms.Padding(4);
this.Name = "OnboardingMqtt";
@@ -350,6 +391,7 @@ private void InitializeComponent()
private System.Windows.Forms.TextBox TbMqttUsername;
private System.Windows.Forms.TextBox TbMqttAddress;
private System.Windows.Forms.CheckBox CbMqttTls;
+ private System.Windows.Forms.CheckBox CbUseWebSocket;
private System.Windows.Forms.Label LblPassword;
private System.Windows.Forms.Label LblUsername;
private System.Windows.Forms.Label LblPort;
@@ -359,7 +401,8 @@ private void InitializeComponent()
private System.Windows.Forms.Label LblDiscoveryPrefix;
private System.Windows.Forms.Label LblTip1;
private System.Windows.Forms.Label LblTip2;
- internal Syncfusion.Windows.Forms.Tools.NumericUpDownExt NumMqttPort;
+ private Syncfusion.WinForms.Controls.SfButton BtnTest;
+ private Syncfusion.Windows.Forms.Tools.NumericUpDownExt NumMqttPort;
private PictureBox PbShow;
internal CheckBox CbEnableMqtt;
}
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-4-MQTT.cs b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-4-MQTT.cs
index a2dd465b..849c7bc0 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-4-MQTT.cs
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-4-MQTT.cs
@@ -1,4 +1,10 @@
-using Serilog;
+using System.Windows.Forms;
+using HASS.Agent.HomeAssistant;
+using HASS.Agent.MQTT;
+using HASS.Agent.Resources.Localization;
+using HASS.Agent.Shared.Functions;
+using Serilog;
+using Syncfusion.Windows.Forms;
namespace HASS.Agent.Controls.Onboarding
{
@@ -27,12 +33,18 @@ private void OnboardingMqtt_Load(object sender, EventArgs e)
Log.Error("[MQTT] Unable to parse URI {uri}: {msg}", Variables.AppSettings.HassUri, ex.Message);
}
}
-
+
// if the above process failed somewhere, just enter the entire address (if any)
- if (string.IsNullOrEmpty(TbMqttAddress.Text)) TbMqttAddress.Text = Variables.AppSettings.MqttAddress;
+ if (string.IsNullOrEmpty(TbMqttAddress.Text))
+ {
+ TbMqttAddress.Text = Variables.AppSettings.MqttAddress;
+ }
// optionally set default port
- if (Variables.AppSettings.MqttPort < 1) Variables.AppSettings.MqttPort = 1883;
+ if (Variables.AppSettings.MqttPort < 1)
+ {
+ Variables.AppSettings.MqttPort = 1883;
+ }
NumMqttPort.Value = Variables.AppSettings.MqttPort;
CbMqttTls.Checked = Variables.AppSettings.MqttUseTls;
@@ -55,15 +67,62 @@ internal bool Store()
Variables.AppSettings.MqttPassword = TbMqttPassword.Text;
Variables.AppSettings.MqttDiscoveryPrefix = TbMqttDiscoveryPrefix.Text;
Variables.AppSettings.MqttEnabled = CbEnableMqtt.CheckState == CheckState.Checked;
+
return true;
}
private void CbMqttTls_CheckedChanged(object sender, EventArgs e)
{
- if (_initializing) return;
+ if (_initializing)
+ {
+ return;
+ }
+
NumMqttPort.Value = CbMqttTls.Checked ? 8883 : 1883;
}
private void PbShow_Click(object sender, EventArgs e) => TbMqttPassword.UseSystemPasswordChar = !TbMqttPassword.UseSystemPasswordChar;
+
+ private async void BtnTest_Click(object sender, EventArgs e)
+ {
+ var address = TbMqttAddress.Text.Trim();
+ var port = (int)NumMqttPort.Value;
+ var username = TbMqttUsername.Text.Trim();
+ var password = TbMqttPassword.Text.Trim();
+ var useTls = CbMqttTls.Checked;
+ var useWebSocket = CbUseWebSocket.Checked;
+
+ CbEnableMqtt.Enabled = false;
+ CbUseWebSocket.Enabled = false;
+ CbMqttTls.Enabled = false;
+ TbMqttAddress.Enabled = false;
+ NumMqttPort.Enabled = false;
+ TbMqttUsername.Enabled = false;
+ TbMqttPassword.Enabled = false;
+ TbMqttDiscoveryPrefix.Enabled = false;
+ BtnTest.Enabled = false;
+ BtnTest.Text = Languages.OnboardingApi_BtnTest_Testing;
+
+ var result = await MqttManager.TestConnection(address, port, useTls, useWebSocket, username, password);
+ if (!result)
+ {
+ MessageBoxAdv.Show(this, Languages.OnboardingMqtt_BtnTest_MessageError, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ else
+ {
+ MessageBoxAdv.Show(this, Languages.OnboardingMqtt_BtnTest_MessageOk, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+
+ CbEnableMqtt.Enabled = true;
+ CbUseWebSocket.Enabled = true;
+ CbMqttTls.Enabled = true;
+ TbMqttAddress.Enabled = true;
+ NumMqttPort.Enabled = true;
+ TbMqttUsername.Enabled = true;
+ TbMqttPassword.Enabled = true;
+ TbMqttDiscoveryPrefix.Enabled = true;
+ BtnTest.Enabled = true;
+ BtnTest.Text = Languages.OnboardingApi_BtnTest;
+ }
}
}
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-6-HotKey.cs b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-6-HotKey.cs
index 2d1e6d25..a8c556f7 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-6-HotKey.cs
+++ b/src/HASS.Agent/HASS.Agent/Controls/Onboarding/Onboarding-6-HotKey.cs
@@ -1,12 +1,13 @@
using HASS.Agent.Functions;
-using WK.Libraries.HotkeyListenerNS;
+using System.Windows.Forms;
namespace HASS.Agent.Controls.Onboarding
{
public partial class OnboardingHotKey : UserControl
{
- private readonly HotkeySelector _hotkeySelector = new();
-
+ private Keys _key = Keys.None;
+ private Keys _modifiers = Keys.None;
+
public OnboardingHotKey()
{
InitializeComponent();
@@ -14,41 +15,51 @@ public OnboardingHotKey()
private void OnboardingHotKey_Load(object sender, EventArgs e)
{
- // config quick actions hotkey selector
- _hotkeySelector.Enable(TbQuickActionsHotkey);
-
- // if nothing set, load default
- if (string.IsNullOrEmpty(Variables.AppSettings.QuickActionsHotKey)) LoadDefault();
- // if set to empty, show empty
- else if (Variables.AppSettings.QuickActionsHotKey == _hotkeySelector.EmptyHotkeyText) TbQuickActionsHotkey.Text = _hotkeySelector.EmptyHotkeyText;
- // show set value
- else LoadSetValue();
- }
+ TbQuickActionsHotkey.ReadOnly = true;
+ TbQuickActionsHotkey.KeyDown += TbQuickActionsHotkey_KeyDown;
- private void LoadDefault()
- {
- if (!HelperFunctions.InputLanguageCheckDiffers(out var knownToCollide, out var warning))
+ if (string.IsNullOrEmpty(Variables.AppSettings.QuickActionsHotKey))
{
- TbQuickActionsHotkey.Text = "Control, Alt + Q";
- LblLanguageWarning.Visible = false;
- return;
+ // if nothing set, load default
+ LoadDefault();
}
-
- if (knownToCollide)
+ else if (Variables.AppSettings.QuickActionsHotKey == string.Empty)
{
- // the system's input language collides with our hotkey, let the user know and set empty key
- LblLanguageWarning.Text = warning;
- TbQuickActionsHotkey.Text = _hotkeySelector.EmptyHotkeyText;
- return;
+ // if set to empty, show empty
+ TbQuickActionsHotkey.Text = string.Empty;
+ }
+ else
+ {
+ // show set value
+ LoadSetValue();
}
+ }
+
+ private void LoadDefault()
+ {
+ /* if (!HelperFunctions.InputLanguageCheckDiffers(out var knownToCollide, out var warning))
+ {
+ TbQuickActionsHotkey.Text = "Shift, Control + Q";
+ LblLanguageWarning.Visible = false;
+ return;
+ }
+
+ if (knownToCollide)
+ {
+ // the system's input language collides with our hotkey, let the user know and set empty key
+ LblLanguageWarning.Text = warning;
+ TbQuickActionsHotkey.Text = _hotkeySelector.EmptyHotkeyText;
+ return;
+ }*/
+ //Amadeo(Note): above was commented out when we changed default hotkey to ctrl+shift+q, leaving this here because reasons
// the system's input language is unknown, we're presetting the default but warn the user
// deprecated, we're not doing this anymore
- //TbQuickActionsHotkey.Text = "Control, Alt + Q";
+ //TbQuickActionsHotkey.Text = "Shift, Control + Q";
//LblLanguageWarning.ForeColor = Color.DarkOrange;
//LblLanguageWarning.Text = warning;
- TbQuickActionsHotkey.Text = "Control, Alt + Q";
+ TbQuickActionsHotkey.Text = "Shift, Control + Q";
LblLanguageWarning.Visible = false;
}
@@ -56,24 +67,75 @@ private void LoadSetValue()
{
TbQuickActionsHotkey.Text = Variables.AppSettings.QuickActionsHotKey;
- if (!HelperFunctions.InputLanguageCheckDiffers(out var knownToCollide, out var warning)) return;
+ if (!HelperFunctions.InputLanguageCheckDiffers(out var knownToCollide, out var warning))
+ return;
// the system's input language is unknown or collides with our hotkey, let the user know if it's set to default
- if (Variables.AppSettings.QuickActionsHotKey != "Control, Alt + Q") return;
+ if (Variables.AppSettings.QuickActionsHotKey != "Shift, Control + Q")
+ return;
- if (knownToCollide) LblLanguageWarning.Text = warning;
+ if (knownToCollide)
+ LblLanguageWarning.Text = warning;
}
internal bool Store()
{
Variables.AppSettings.QuickActionsHotKey = TbQuickActionsHotkey.Text;
- _hotkeySelector.Dispose();
+ TbQuickActionsHotkey.KeyDown -= TbQuickActionsHotkey_KeyDown;
return true;
}
private void BtnClear_Click(object sender, EventArgs e)
{
- TbQuickActionsHotkey.Text = _hotkeySelector.EmptyHotkeyText;
+ TbQuickActionsHotkey.Text = string.Empty;
+ }
+
+ private void TbQuickActionsHotkey_KeyDown(object sender, KeyEventArgs e)
+ {
+ e.SuppressKeyPress = true;
+
+ var key = e.KeyCode;
+
+ if (key is Keys.LControlKey or Keys.RControlKey
+ or Keys.LShiftKey or Keys.RShiftKey
+ or Keys.LWin or Keys.RWin
+ or Keys.Alt)
+ {
+ key = Keys.None;
+ }
+
+ if (key == Keys.Escape)
+ {
+ _key = Keys.None;
+ _modifiers = Keys.None;
+ TbQuickActionsHotkey.Text = string.Empty;
+
+ return;
+ }
+
+ _key = key;
+ TbQuickActionsHotkey.Text = FormatHotkey(_key, e.Modifiers);
+ }
+
+ private string FormatHotkey(Keys key, Keys modifiers)
+ {
+ var parts = new List();
+ if ((modifiers & Keys.Shift) != 0)
+ {
+ parts.Add(nameof(Keys.Shift));
+ }
+
+ if ((modifiers & Keys.Control) != 0)
+ {
+ parts.Add(nameof(Keys.Control));
+ }
+
+ if ((modifiers & Keys.Alt) != 0)
+ {
+ parts.Add(nameof(Keys.Alt));
+ }
+
+ return parts.Count > 0 ? string.Join(", ", parts) + " + " + key : key.ToString();
}
}
}
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Service/ServiceMQTT.Designer.cs b/src/HASS.Agent/HASS.Agent/Controls/Service/ServiceMQTT.Designer.cs
index f69435c0..554f8d96 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Service/ServiceMQTT.Designer.cs
+++ b/src/HASS.Agent/HASS.Agent/Controls/Service/ServiceMQTT.Designer.cs
@@ -40,6 +40,7 @@ private void InitializeComponent()
this.TbMqttRootCertificate = new System.Windows.Forms.TextBox();
this.LblRootCert = new System.Windows.Forms.Label();
this.CbUseRetainFlag = new System.Windows.Forms.CheckBox();
+ this.CbUseWebSocket = new System.Windows.Forms.CheckBox();
this.CbAllowUntrustedCertificates = new System.Windows.Forms.CheckBox();
this.BtnMqttClearConfig = new Syncfusion.WinForms.Controls.SfButton();
this.LblTip1 = new System.Windows.Forms.Label();
@@ -206,7 +207,7 @@ private void InitializeComponent()
//
// CbUseRetainFlag
//
- this.CbUseRetainFlag.AccessibleDescription = "Enable using the retain flag for messages.";
+ this.CbUseRetainFlag.AccessibleDescription = "Use WebSocket for MQTT connection instead of direct one.";
this.CbUseRetainFlag.AccessibleName = "Retain flag";
this.CbUseRetainFlag.AccessibleRole = System.Windows.Forms.AccessibleRole.CheckButton;
this.CbUseRetainFlag.AutoSize = true;
@@ -218,6 +219,20 @@ private void InitializeComponent()
this.CbUseRetainFlag.Text = global::HASS.Agent.Resources.Localization.Languages.ServiceMqtt_CbUseRetainFlag;
this.CbUseRetainFlag.UseVisualStyleBackColor = true;
//
+ // CbUseWebSocket
+ //
+ this.CbUseWebSocket.AccessibleDescription = "Enable using the retain flag for messages.";
+ this.CbUseWebSocket.AccessibleName = "WebSocket flag";
+ this.CbUseWebSocket.AccessibleRole = System.Windows.Forms.AccessibleRole.CheckButton;
+ this.CbUseWebSocket.AutoSize = true;
+ this.CbUseWebSocket.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
+ this.CbUseWebSocket.Location = new System.Drawing.Point(506, 393);
+ this.CbUseWebSocket.Name = "CbUseWebSocket";
+ this.CbUseWebSocket.Size = new System.Drawing.Size(114, 23);
+ this.CbUseWebSocket.TabIndex = 14;
+ this.CbUseWebSocket.Text = global::HASS.Agent.Resources.Localization.Languages.ServiceMqtt_CbUseWebSocket;
+ this.CbUseWebSocket.UseVisualStyleBackColor = true;
+ //
// CbAllowUntrustedCertificates
//
this.CbAllowUntrustedCertificates.AccessibleDescription = "Enable allowing untrusted certificates when connecting.";
@@ -546,6 +561,7 @@ private void InitializeComponent()
this.Controls.Add(this.TbMqttRootCertificate);
this.Controls.Add(this.LblRootCert);
this.Controls.Add(this.CbUseRetainFlag);
+ this.Controls.Add(this.CbUseWebSocket);
this.Controls.Add(this.CbAllowUntrustedCertificates);
this.Controls.Add(this.BtnMqttClearConfig);
this.Controls.Add(this.LblTip1);
@@ -584,6 +600,7 @@ private void InitializeComponent()
internal TextBox TbMqttRootCertificate;
private Label LblRootCert;
internal CheckBox CbUseRetainFlag;
+ internal CheckBox CbUseWebSocket;
internal CheckBox CbAllowUntrustedCertificates;
internal Syncfusion.WinForms.Controls.SfButton BtnMqttClearConfig;
private Label LblTip1;
diff --git a/src/HASS.Agent/HASS.Agent/Controls/Service/ServiceMqtt.cs b/src/HASS.Agent/HASS.Agent/Controls/Service/ServiceMqtt.cs
index 5b034dc7..af677bec 100644
--- a/src/HASS.Agent/HASS.Agent/Controls/Service/ServiceMqtt.cs
+++ b/src/HASS.Agent/HASS.Agent/Controls/Service/ServiceMqtt.cs
@@ -125,6 +125,7 @@ public void SetConfig(ServiceMqttSettings mqttSettings)
TbMqttClientCertificate.Text = mqttSettings.MqttClientCertificate;
CbAllowUntrustedCertificates.Checked = mqttSettings.MqttAllowUntrustedCertificates;
CbUseRetainFlag.Checked = mqttSettings.MqttUseRetainFlag;
+ CbUseWebSocket.Checked = mqttSettings.MqttUseWebSocket;
}
///
@@ -145,6 +146,7 @@ private void BtnCopy_Click(object sender, EventArgs e)
TbMqttClientCertificate.Text = Variables.AppSettings.MqttClientCertificate;
CbAllowUntrustedCertificates.Checked = Variables.AppSettings.MqttAllowUntrustedCertificates;
CbUseRetainFlag.Checked = Variables.AppSettings.MqttUseRetainFlag;
+ CbUseWebSocket.Checked = Variables.AppSettings.MqttUseWebSocket;
}
///
@@ -165,6 +167,7 @@ private void BtnMqttClearConfig_Click(object sender, EventArgs e)
TbMqttClientCertificate.Text = string.Empty;
CbAllowUntrustedCertificates.Checked = true;
CbUseRetainFlag.Checked = true;
+ CbUseWebSocket.Checked = false;
}
private async void BtnStore_Click(object sender, EventArgs e)
@@ -188,7 +191,8 @@ private async void BtnStore_Click(object sender, EventArgs e)
MqttRootCertificate = TbMqttRootCertificate.Text,
MqttClientCertificate = TbMqttClientCertificate.Text,
MqttAllowUntrustedCertificates = CbAllowUntrustedCertificates.Checked,
- MqttUseRetainFlag = CbUseRetainFlag.Checked
+ MqttUseRetainFlag = CbUseRetainFlag.Checked,
+ MqttUseWebSocket = CbUseWebSocket.Checked
};
// store
diff --git a/src/HASS.Agent/HASS.Agent/Extensions/RpcExtensions.cs b/src/HASS.Agent/HASS.Agent/Extensions/RpcExtensions.cs
index d36c4879..caab3545 100644
--- a/src/HASS.Agent/HASS.Agent/Extensions/RpcExtensions.cs
+++ b/src/HASS.Agent/HASS.Agent/Extensions/RpcExtensions.cs
@@ -183,7 +183,8 @@ public static ServiceMqttSettings ConvertToServiceMqttSettings(this RpcServiceMq
MqttUseRetainFlag = rpcServiceMqttSettings.MqttUseRetainFlag,
MqttRootCertificate = rpcServiceMqttSettings.MqttRootCertificate,
MqttClientCertificate = rpcServiceMqttSettings.MqttClientCertificate,
- MqttClientId = rpcServiceMqttSettings.MqttClientId
+ MqttClientId = rpcServiceMqttSettings.MqttClientId,
+ MqttUseWebSocket = rpcServiceMqttSettings.MqttUseWebSocket
};
return serviceMqttSettings;
@@ -208,7 +209,8 @@ public static RpcServiceMqttSettings ConvertToRpcServiceMqttSettings(this Servic
MqttUseRetainFlag = serviceMqttSettings.MqttUseRetainFlag,
MqttRootCertificate = serviceMqttSettings.MqttRootCertificate,
MqttClientCertificate = serviceMqttSettings.MqttClientCertificate,
- MqttClientId = serviceMqttSettings.MqttClientId
+ MqttClientId = serviceMqttSettings.MqttClientId,
+ MqttUseWebSocket = serviceMqttSettings.MqttUseWebSocket
};
return rpcServiceMqttSettings;
diff --git a/src/HASS.Agent/HASS.Agent/Forms/Commands/CommandConfig/WebViewCommandConfig.Designer.cs b/src/HASS.Agent/HASS.Agent/Forms/Commands/CommandConfig/WebViewCommandConfig.Designer.cs
index 718b80ee..cba67b64 100644
--- a/src/HASS.Agent/HASS.Agent/Forms/Commands/CommandConfig/WebViewCommandConfig.Designer.cs
+++ b/src/HASS.Agent/HASS.Agent/Forms/Commands/CommandConfig/WebViewCommandConfig.Designer.cs
@@ -243,11 +243,8 @@ private void InitializeComponent()
this.NumLocationX.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.NumLocationX.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241)))));
this.NumLocationX.Location = new System.Drawing.Point(34, 160);
- this.NumLocationX.Maximum = new decimal(new int[] {
- 65535,
- 0,
- 0,
- 0});
+ this.NumLocationX.Maximum = new decimal(Int32.MaxValue);
+ this.NumLocationX.Minimum = new decimal(Int32.MinValue);
this.NumLocationX.MaxLength = 10;
this.NumLocationX.MetroColor = System.Drawing.SystemColors.WindowFrame;
this.NumLocationX.Name = "NumLocationX";
@@ -269,11 +266,8 @@ private void InitializeComponent()
this.NumLocationY.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.NumLocationY.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241)))));
this.NumLocationY.Location = new System.Drawing.Point(149, 160);
- this.NumLocationY.Maximum = new decimal(new int[] {
- 65535,
- 0,
- 0,
- 0});
+ this.NumLocationY.Maximum = new decimal(Int32.MaxValue);
+ this.NumLocationY.Minimum = new decimal(Int32.MinValue);
this.NumLocationY.MaxLength = 10;
this.NumLocationY.MetroColor = System.Drawing.SystemColors.WindowFrame;
this.NumLocationY.Name = "NumLocationY";
diff --git a/src/HASS.Agent/HASS.Agent/Forms/Commands/CommandsMod.cs b/src/HASS.Agent/HASS.Agent/Forms/Commands/CommandsMod.cs
index a14d80bc..de248bda 100644
--- a/src/HASS.Agent/HASS.Agent/Forms/Commands/CommandsMod.cs
+++ b/src/HASS.Agent/HASS.Agent/Forms/Commands/CommandsMod.cs
@@ -28,7 +28,9 @@ public partial class CommandsMod : MetroForm
private bool _interfaceLockedWrongType;
private bool _loading = true;
- private readonly Dictionary _commandEntityTypes = new();
+ private bool _escapeLock = true;
+
+ private readonly Dictionary _commandEntityTypes = new();
private readonly Dictionary _radioDevices = new();
public CommandsMod(ConfiguredCommand command, bool serviceMode = false, string serviceDeviceName = "")
@@ -977,11 +979,21 @@ private void LblIntegrityInfo_Click(object sender, EventArgs e)
private void CommandsMod_KeyUp(object sender, KeyEventArgs e)
{
- if (e.KeyCode != Keys.Escape)
- return;
+ if (e.KeyCode != Keys.Escape)
+ {
+ _escapeLock = true;
+ return;
+ }
- Close();
- }
+ if (_escapeLock)
+ {
+ _escapeLock = false;
+ }
+ else
+ {
+ Close();
+ }
+ }
private void CommandsMod_Layout(object sender, LayoutEventArgs e)
{
diff --git a/src/HASS.Agent/HASS.Agent/Forms/Configuration.cs b/src/HASS.Agent/HASS.Agent/Forms/Configuration.cs
index 2f83e22a..cf1f6baa 100644
--- a/src/HASS.Agent/HASS.Agent/Forms/Configuration.cs
+++ b/src/HASS.Agent/HASS.Agent/Forms/Configuration.cs
@@ -8,16 +8,15 @@
using HASS.Agent.Settings;
using HASS.Agent.Shared;
using HASS.Agent.Shared.Functions;
-using WK.Libraries.HotkeyListenerNS;
using Task = System.Threading.Tasks.Task;
using ConfigSatelliteService = HASS.Agent.Controls.Configuration.ConfigService;
+using HASS.Agent.MQTT;
namespace HASS.Agent.Forms
{
public partial class Configuration : MetroForm
{
- private readonly HotkeySelector _hotkeySelector = new();
- private readonly Hotkey _previousHotkey = Variables.QuickActionsHotKey;
+ private readonly string _previousHotkey = Variables.QuickActionsHotKey;
private readonly string _previousDeviceName = Variables.AppSettings.DeviceName;
private readonly int _previousLocalApiPort = Variables.AppSettings.LocalApiPort;
@@ -40,6 +39,9 @@ public partial class Configuration : MetroForm
private bool _initializing = true;
+ private Keys _key = Keys.None;
+ private Keys _modifiers = Keys.None;
+
public Configuration()
{
InitializeComponent();
@@ -51,7 +53,7 @@ private void Configuration_Load(object sender, EventArgs e)
KeyPreview = true;
// suspend global hotkeys
- Variables.HotKeyListener.Suspend();
+ Variables.HotKeyListener.IsEnabled = false;
// load controls
TabGeneral.Controls.Add(_general);
@@ -78,18 +80,21 @@ private void Configuration_Load(object sender, EventArgs e)
LoadSettings();
// config quick actions hotkey selector
- if (Variables.QuickActionsHotKey != null) _hotkeySelector.Enable(_hotKey.TbQuickActionsHotkey, Variables.QuickActionsHotKey);
- else _hotkeySelector.Enable(_hotKey.TbQuickActionsHotkey);
+ _hotKey.TbQuickActionsHotkey.ReadOnly = true;
+ _hotKey.TbQuickActionsHotkey.KeyDown += TbQuickActionsHotkey_KeyDown;
+ if (Variables.QuickActionsHotKey != null)
+ {
+ _hotKey.TbQuickActionsHotkey.Text = Variables.QuickActionsHotKey;
+ }
}
private void Configuration_FormClosing(object sender, FormClosingEventArgs e)
{
// resume global hotkeys
- Variables.HotKeyListener.Resume();
+ Variables.HotKeyListener.IsEnabled = true;
- // remove hotkey selector
- _hotkeySelector?.Disable(_hotKey.TbQuickActionsHotkey);
- _hotkeySelector?.Dispose();
+ // clean hotkey selector
+ _hotKey.TbQuickActionsHotkey.KeyDown -= TbQuickActionsHotkey_KeyDown;
// dispose controls
_general.Dispose();
@@ -109,14 +114,62 @@ private void Configuration_FormClosing(object sender, FormClosingEventArgs e)
_nfc.Dispose();
}
+ private void TbQuickActionsHotkey_KeyDown(object sender, KeyEventArgs e)
+ {
+ e.SuppressKeyPress = true;
+
+ var key = e.KeyCode;
+
+ if (key is Keys.LControlKey or Keys.RControlKey
+ or Keys.LShiftKey or Keys.RShiftKey
+ or Keys.LWin or Keys.RWin
+ or Keys.Alt)
+ {
+ key = Keys.None;
+ }
+
+ if (key == Keys.Escape)
+ {
+ _key = Keys.None;
+ _modifiers = Keys.None;
+ _hotKey.TbQuickActionsHotkey.Text = string.Empty;
+
+ return;
+ }
+
+ _key = key;
+ _hotKey.TbQuickActionsHotkey.Text = FormatHotkey(_key, e.Modifiers);
+ }
+
+ private string FormatHotkey(Keys key, Keys modifiers)
+ {
+ var parts = new List();
+ if ((modifiers & Keys.Shift) != 0)
+ {
+ parts.Add(nameof(Keys.Shift));
+ }
+
+ if ((modifiers & Keys.Control) != 0)
+ {
+ parts.Add(nameof(Keys.Control));
+ }
+
+ if ((modifiers & Keys.Alt) != 0)
+ {
+ parts.Add(nameof(Keys.Alt));
+ }
+
+ return parts.Count > 0 ? string.Join(", ", parts) + " + " + key : key.ToString();
+ }
+
private void BindEvents()
{
// hass
_homeAssistantApi.CbHassAutoClientCertificate.CheckedChanged += CbHassAutoClientCertificate_CheckedChanged;
-
+
// mqtt
_mqtt.CbMqttTls.CheckedChanged += CbMqttTls_CheckedChanged;
-
+
// hotkey
_hotKey.BtnClearHotKey.Click += BtnClearHotKey_Click;
}
@@ -147,7 +200,8 @@ private async void ProcessChanges()
BtnStore.Text = Languages.Configuration_BtnStore_Busy;
// optionally sanitize device name
- if (_general.CbEnableDeviceNameSanitation.Checked) _general.TbDeviceName.Text = SharedHelperFunctions.GetSafeValue(_general.TbDeviceName.Text);
+ if (_general.CbEnableDeviceNameSanitation.Checked)
+ _general.TbDeviceName.Text = SharedHelperFunctions.GetSafeValue(_general.TbDeviceName.Text);
// store settings
await StoreSettingsAsync();
@@ -171,7 +225,21 @@ private async void ProcessChanges()
// give the managers some time to stop
await Task.Delay(250);
- // unpublish all entities
+ // signal migration to HA MQTT integration
+ await SensorsManager.UnpublishAllSensors(migration: true);
+ await CommandsManager.UnpublishAllCommands(migration: true);
+
+ await Task.Delay(250);
+
+ // mock new device name and publish new discovery messages
+ Variables.DeviceConfig.Name = Variables.AppSettings.DeviceName;
+ await SensorsManager.ForcePublishAllSensors();
+ await CommandsManager.ForcePublishAllCommands();
+
+ await Task.Delay(250);
+
+ // restore previous device name and clear migration messages
+ Variables.DeviceConfig.Name = _previousDeviceName;
await SensorsManager.UnpublishAllSensors();
await CommandsManager.UnpublishAllCommands();
@@ -183,28 +251,32 @@ private async void ProcessChanges()
// disconnect mqtt so we don't get announced again
await Task.Run(Variables.MqttManager.Disconnect);
-
+
forceRestart = true;
}
// reserve the new local api's port if it's changed
if (Variables.AppSettings.LocalApiPort != _previousLocalApiPort)
{
- MessageBoxAdv.Show(this, Languages.Configuration_ProcessChanges_MessageBox2, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information);
+ MessageBoxAdv.Show(this, Languages.Configuration_ProcessChanges_MessageBox2, Variables.MessageBoxTitle,
+ MessageBoxButtons.OK, MessageBoxIcon.Information);
// try to reserve elevated
if (!ApiManager.ExecuteElevatedPortReservation())
{
// failed, copy the command onto the clipboard
- Clipboard.SetText($"netsh http add urlacl url=http://+:{Variables.AppSettings.LocalApiPort}/ user=\"{SharedHelperFunctions.EveryoneLocalizedAccountName()}\"");
+ Clipboard.SetText(
+ $"netsh http add urlacl url=http://+:{Variables.AppSettings.LocalApiPort}/ user=\"{SharedHelperFunctions.EveryoneLocalizedAccountName()}\"");
// notify the user
- MessageBoxAdv.Show(this, Languages.Configuration_ProcessChanges_MessageBox3, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ MessageBoxAdv.Show(this, Languages.Configuration_ProcessChanges_MessageBox3,
+ Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
// notify the user
- MessageBoxAdv.Show(this, Languages.Configuration_ProcessChanges_MessageBox4, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information);
+ MessageBoxAdv.Show(this, Languages.Configuration_ProcessChanges_MessageBox4,
+ Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information);
// we need to restart, so go ahead, otherwise it's starting to look like popup-spam ..
forceRestart = true;
@@ -215,17 +287,22 @@ private async void ProcessChanges()
{
// prepare the restart without asking
var restartPrepared = HelperFunctions.Restart();
- if (!restartPrepared) MessageBoxAdv.Show(this, Languages.Configuration_MessageBox_RestartManually, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ if (!restartPrepared)
+ MessageBoxAdv.Show(this, Languages.Configuration_MessageBox_RestartManually,
+ Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
// ask the user if they want to restart
- var question = MessageBoxAdv.Show(this, Languages.Configuration_ProcessChanges_MessageBox5, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
+ var question = MessageBoxAdv.Show(this, Languages.Configuration_ProcessChanges_MessageBox5,
+ Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (question == DialogResult.Yes)
{
// prepare the restart
var restartPrepared = HelperFunctions.Restart();
- if (!restartPrepared) MessageBoxAdv.Show(this, Languages.Configuration_MessageBox_RestartManually, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ if (!restartPrepared)
+ MessageBoxAdv.Show(this, Languages.Configuration_MessageBox_RestartManually,
+ Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
@@ -245,7 +322,8 @@ private bool CheckValues()
{
if (!SharedHelperFunctions.CheckHomeAssistantApiToken(hassApi))
{
- var q = MessageBoxAdv.Show(this, Languages.Configuration_CheckValues_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
+ var q = MessageBoxAdv.Show(this, Languages.Configuration_CheckValues_MessageBox1,
+ Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
if (q != DialogResult.Yes) return false;
}
}
@@ -256,7 +334,8 @@ private bool CheckValues()
{
if (!SharedHelperFunctions.CheckHomeAssistantUri(hassUri))
{
- var q = MessageBoxAdv.Show(this, Languages.Configuration_CheckValues_MessageBox2, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
+ var q = MessageBoxAdv.Show(this, Languages.Configuration_CheckValues_MessageBox2,
+ Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
if (q != DialogResult.Yes) return false;
}
}
@@ -267,7 +346,8 @@ private bool CheckValues()
{
if (!SharedHelperFunctions.CheckMqttBrokerUri(mqttUri))
{
- var q = MessageBoxAdv.Show(this, Languages.Configuration_CheckValues_MessageBox3, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
+ var q = MessageBoxAdv.Show(this, Languages.Configuration_CheckValues_MessageBox3,
+ Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
if (q != DialogResult.Yes) return false;
}
}
@@ -283,28 +363,42 @@ private void LoadSettings()
{
// general
_general.TbDeviceName.Text = Variables.AppSettings.DeviceName;
- _general.CbEnableDeviceNameSanitation.CheckState = Variables.AppSettings.SanitizeName ? CheckState.Checked : CheckState.Unchecked;
+ _general.CbEnableDeviceNameSanitation.CheckState =
+ Variables.AppSettings.SanitizeName ? CheckState.Checked : CheckState.Unchecked;
_general.NumDisconnectGrace.Value = Variables.AppSettings.DisconnectedGracePeriodSeconds;
- _general.CbEnableStateNotifications.CheckState = Variables.AppSettings.EnableStateNotifications ? CheckState.Checked : CheckState.Unchecked;
+ _general.CbEnableStateNotifications.CheckState = Variables.AppSettings.EnableStateNotifications
+ ? CheckState.Checked
+ : CheckState.Unchecked;
// startup settings
Task.Run(_startup.DetermineStartOnLoginStatus);
// local api
_localApi.NumLocalApiPort.Value = Variables.AppSettings.LocalApiPort;
- _localApi.CbLocalApiActive.CheckState = Variables.AppSettings.LocalApiEnabled ? CheckState.Checked : CheckState.Unchecked;
+ _localApi.CbLocalApiActive.CheckState =
+ Variables.AppSettings.LocalApiEnabled ? CheckState.Checked : CheckState.Unchecked;
// notifications
- _notifications.CbAcceptNotifications.CheckState = Variables.AppSettings.NotificationsEnabled ? CheckState.Checked : CheckState.Unchecked;
- _notifications.CbNotificationsIgnoreImageCertErrors.CheckState = Variables.AppSettings.NotificationsIgnoreImageCertificateErrors ? CheckState.Checked : CheckState.Unchecked;
- _notifications.CbNotificationsOpenActionUri.CheckState = Variables.AppSettings.NotificationsOpenActionUri ? CheckState.Checked : CheckState.Unchecked;
+ _notifications.CbAcceptNotifications.CheckState = Variables.AppSettings.NotificationsEnabled
+ ? CheckState.Checked
+ : CheckState.Unchecked;
+ _notifications.CbNotificationsIgnoreImageCertErrors.CheckState =
+ Variables.AppSettings.NotificationsIgnoreImageCertificateErrors
+ ? CheckState.Checked
+ : CheckState.Unchecked;
+ _notifications.CbNotificationsOpenActionUri.CheckState = Variables.AppSettings.NotificationsOpenActionUri
+ ? CheckState.Checked
+ : CheckState.Unchecked;
// hass settings
_homeAssistantApi.TbHassIp.Text = Variables.AppSettings.HassUri;
_homeAssistantApi.TbHassApiToken.Text = Variables.AppSettings.HassToken;
_homeAssistantApi.TbHassClientCertificate.Text = Variables.AppSettings.HassClientCertificate;
- _homeAssistantApi.CbHassAutoClientCertificate.CheckState = Variables.AppSettings.HassAutoClientCertificate ? CheckState.Checked : CheckState.Unchecked;
- _homeAssistantApi.CbHassAllowUntrustedCertificates.CheckState = Variables.AppSettings.HassAllowUntrustedCertificates ? CheckState.Checked : CheckState.Unchecked;
+ _homeAssistantApi.CbHassAutoClientCertificate.CheckState = Variables.AppSettings.HassAutoClientCertificate
+ ? CheckState.Checked
+ : CheckState.Unchecked;
+ _homeAssistantApi.CbHassAllowUntrustedCertificates.CheckState =
+ Variables.AppSettings.HassAllowUntrustedCertificates ? CheckState.Checked : CheckState.Unchecked;
if (Variables.AppSettings.HassAutoClientCertificate)
{
_homeAssistantApi.TbHassClientCertificate.Text = string.Empty;
@@ -312,10 +406,13 @@ private void LoadSettings()
}
// hotkey
- _hotKey.CbEnableQuickActionsHotkey.CheckState = Variables.AppSettings.QuickActionsHotKeyEnabled ? CheckState.Checked : CheckState.Unchecked;
+ _hotKey.CbEnableQuickActionsHotkey.CheckState = Variables.AppSettings.QuickActionsHotKeyEnabled
+ ? CheckState.Checked
+ : CheckState.Unchecked;
// mqtt
- _mqtt.CbEnableMqtt.CheckState = Variables.AppSettings.MqttEnabled ? CheckState.Checked : CheckState.Unchecked;
+ _mqtt.CbEnableMqtt.CheckState =
+ Variables.AppSettings.MqttEnabled ? CheckState.Checked : CheckState.Unchecked;
_mqtt.TbMqttAddress.Text = Variables.AppSettings.MqttAddress;
_mqtt.NumMqttPort.Value = Variables.AppSettings.MqttPort;
_mqtt.CbMqttTls.CheckState = Variables.AppSettings.MqttUseTls ? CheckState.Checked : CheckState.Unchecked;
@@ -325,14 +422,25 @@ private void LoadSettings()
_mqtt.TbMqttClientId.Text = Variables.AppSettings.MqttClientId;
_mqtt.TbMqttRootCertificate.Text = Variables.AppSettings.MqttRootCertificate;
_mqtt.TbMqttClientCertificate.Text = Variables.AppSettings.MqttClientCertificate;
- _mqtt.CbAllowUntrustedCertificates.CheckState = Variables.AppSettings.MqttAllowUntrustedCertificates ? CheckState.Checked : CheckState.Unchecked;
- _mqtt.CbUseRetainFlag.CheckState = Variables.AppSettings.MqttUseRetainFlag ? CheckState.Checked : CheckState.Unchecked;
- _mqtt.CbIgnoreGracePeriod.CheckState = Variables.AppSettings.MqttIgnoreGracePeriod ? CheckState.Checked : CheckState.Unchecked;
+ _mqtt.CbAllowUntrustedCertificates.CheckState = Variables.AppSettings.MqttAllowUntrustedCertificates
+ ? CheckState.Checked
+ : CheckState.Unchecked;
+ _mqtt.CbUseRetainFlag.CheckState =
+ Variables.AppSettings.MqttUseRetainFlag ? CheckState.Checked : CheckState.Unchecked;
+ _mqtt.CbUseWebSocket.CheckState =
+ Variables.AppSettings.MqttUseWebSocket ? CheckState.Checked : CheckState.Unchecked;
+ _mqtt.CbIgnoreGracePeriod.CheckState = Variables.AppSettings.MqttIgnoreGracePeriod
+ ? CheckState.Checked
+ : CheckState.Unchecked;
// updates
- _updates.CbUpdates.CheckState = Variables.AppSettings.CheckForUpdates ? CheckState.Checked : CheckState.Unchecked;
- _updates.CbBetaUpdates.CheckState = Variables.AppSettings.ShowBetaUpdates ? CheckState.Checked : CheckState.Unchecked;
- _updates.CbExecuteUpdater.CheckState = Variables.AppSettings.EnableExecuteUpdateInstaller ? CheckState.Checked : CheckState.Unchecked;
+ _updates.CbUpdates.CheckState =
+ Variables.AppSettings.CheckForUpdates ? CheckState.Checked : CheckState.Unchecked;
+ _updates.CbBetaUpdates.CheckState =
+ Variables.AppSettings.ShowBetaUpdates ? CheckState.Checked : CheckState.Unchecked;
+ _updates.CbExecuteUpdater.CheckState = Variables.AppSettings.EnableExecuteUpdateInstaller
+ ? CheckState.Checked
+ : CheckState.Unchecked;
// cache
_localStorage.TbImageCacheLocation.Text = Variables.ImageCachePath;
@@ -343,7 +451,9 @@ private void LoadSettings()
_localStorage.NumWebViewRetention.Value = Variables.AppSettings.WebViewCacheRetentionDays;
// logging
- _logging.CbExtendedLogging.CheckState = SettingsManager.GetExtendedLoggingSetting() ? CheckState.Checked : CheckState.Unchecked;
+ _logging.CbExtendedLogging.CheckState = SettingsManager.GetExtendedLoggingSetting()
+ ? CheckState.Checked
+ : CheckState.Unchecked;
// external tools
_externalTools.TbExternalBrowserName.Text = Variables.AppSettings.BrowserName;
@@ -353,19 +463,31 @@ private void LoadSettings()
_externalTools.TbExternalExecutorBinary.Text = Variables.AppSettings.CustomExecutorBinary;
// mediaplayer
- _mediaPlayer.CbEnableMediaPlayer.CheckState = Variables.AppSettings.MediaPlayerEnabled ? CheckState.Checked : CheckState.Unchecked;
+ _mediaPlayer.CbEnableMediaPlayer.CheckState = Variables.AppSettings.MediaPlayerEnabled
+ ? CheckState.Checked
+ : CheckState.Unchecked;
// tray icon
- _trayIcon.CbUseModernIcon.CheckState = Variables.AppSettings.TrayIconUseModern ? CheckState.Checked : CheckState.Unchecked;
- _trayIcon.CbDefaultMenu.CheckState = Variables.AppSettings.TrayIconShowDefaultMenu ? CheckState.Checked : CheckState.Unchecked;
- _trayIcon.CbShowWebView.CheckState = Variables.AppSettings.TrayIconShowWebView ? CheckState.Checked : CheckState.Unchecked;
+ _trayIcon.CbUseModernIcon.CheckState =
+ Variables.AppSettings.TrayIconUseModern ? CheckState.Checked : CheckState.Unchecked;
+ _trayIcon.CbDefaultMenu.CheckState = Variables.AppSettings.TrayIconShowDefaultMenu
+ ? CheckState.Checked
+ : CheckState.Unchecked;
+ _trayIcon.CbShowWebView.CheckState =
+ Variables.AppSettings.TrayIconShowWebView ? CheckState.Checked : CheckState.Unchecked;
_trayIcon.NumWebViewWidth.Value = Variables.AppSettings.TrayIconWebViewWidth;
_trayIcon.NumWebViewHeight.Value = Variables.AppSettings.TrayIconWebViewHeight;
+ _trayIcon.SelectedScreen = Variables.AppSettings.TrayIconWebViewScreen;
_trayIcon.TbWebViewUrl.Text = Variables.AppSettings.TrayIconWebViewUrl;
- _trayIcon.CbWebViewKeepLoaded.CheckState = Variables.AppSettings.TrayIconWebViewBackgroundLoading ? CheckState.Checked : CheckState.Unchecked;
- _trayIcon.CbWebViewShowMenuOnLeftClick.CheckState = Variables.AppSettings.TrayIconWebViewShowMenuOnLeftClick ? CheckState.Checked : CheckState.Unchecked;
+ _trayIcon.CbWebViewKeepLoaded.CheckState = Variables.AppSettings.TrayIconWebViewBackgroundLoading
+ ? CheckState.Checked
+ : CheckState.Unchecked;
+ _trayIcon.CbWebViewShowMenuOnLeftClick.CheckState = Variables.AppSettings.TrayIconWebViewShowMenuOnLeftClick
+ ? CheckState.Checked
+ : CheckState.Unchecked;
- _nfc.CbEnableNfc.CheckState = Variables.AppSettings.NfcScanningEnabled ? CheckState.Checked : CheckState.Unchecked;
+ _nfc.CbEnableNfc.CheckState =
+ Variables.AppSettings.NfcScanningEnabled ? CheckState.Checked : CheckState.Unchecked;
// done
_initializing = false;
@@ -377,10 +499,13 @@ private void LoadSettings()
private async Task StoreSettingsAsync()
{
// general
- var deviceName = string.IsNullOrEmpty(_general.TbDeviceName.Text) ? SharedHelperFunctions.GetSafeDeviceName() : _general.TbDeviceName.Text;
+ var deviceName = string.IsNullOrEmpty(_general.TbDeviceName.Text)
+ ? SharedHelperFunctions.GetSafeDeviceName()
+ : _general.TbDeviceName.Text;
Variables.AppSettings.DeviceName = deviceName;
Variables.AppSettings.SanitizeName = _general.CbEnableDeviceNameSanitation.CheckState == CheckState.Checked;
- Variables.AppSettings.EnableStateNotifications = _general.CbEnableStateNotifications.CheckState == CheckState.Checked;
+ Variables.AppSettings.EnableStateNotifications =
+ _general.CbEnableStateNotifications.CheckState == CheckState.Checked;
var uiLanguage = Variables.SupportedUILanguages.Find(x => x.DisplayName == _general.CbLanguage.Text);
Variables.AppSettings.InterfaceLanguage = uiLanguage?.Name ?? "en";
@@ -392,32 +517,38 @@ private async Task StoreSettingsAsync()
Variables.AppSettings.LocalApiEnabled = _localApi.CbLocalApiActive.CheckState == CheckState.Checked;
// notifications
- Variables.AppSettings.NotificationsEnabled = _notifications.CbAcceptNotifications.CheckState == CheckState.Checked;
- Variables.AppSettings.NotificationsIgnoreImageCertificateErrors = _notifications.CbNotificationsIgnoreImageCertErrors.CheckState == CheckState.Checked;
- Variables.AppSettings.NotificationsOpenActionUri = _notifications.CbNotificationsOpenActionUri.CheckState == CheckState.Checked;
+ Variables.AppSettings.NotificationsEnabled =
+ _notifications.CbAcceptNotifications.CheckState == CheckState.Checked;
+ Variables.AppSettings.NotificationsIgnoreImageCertificateErrors =
+ _notifications.CbNotificationsIgnoreImageCertErrors.CheckState == CheckState.Checked;
+ Variables.AppSettings.NotificationsOpenActionUri =
+ _notifications.CbNotificationsOpenActionUri.CheckState == CheckState.Checked;
// hass settings
Variables.AppSettings.HassUri = _homeAssistantApi.TbHassIp.Text;
Variables.AppSettings.HassToken = _homeAssistantApi.TbHassApiToken.Text;
Variables.AppSettings.HassClientCertificate = _homeAssistantApi.TbHassClientCertificate.Text;
- Variables.AppSettings.HassAutoClientCertificate = _homeAssistantApi.CbHassAutoClientCertificate.CheckState == CheckState.Checked;
- Variables.AppSettings.HassAllowUntrustedCertificates = _homeAssistantApi.CbHassAllowUntrustedCertificates.CheckState == CheckState.Checked;
+ Variables.AppSettings.HassAutoClientCertificate =
+ _homeAssistantApi.CbHassAutoClientCertificate.CheckState == CheckState.Checked;
+ Variables.AppSettings.HassAllowUntrustedCertificates =
+ _homeAssistantApi.CbHassAllowUntrustedCertificates.CheckState == CheckState.Checked;
// hotkey config
- Variables.AppSettings.QuickActionsHotKeyEnabled = _hotKey.CbEnableQuickActionsHotkey.CheckState == CheckState.Checked;
+ Variables.AppSettings.QuickActionsHotKeyEnabled =
+ _hotKey.CbEnableQuickActionsHotkey.CheckState == CheckState.Checked;
if (Variables.AppSettings.QuickActionsHotKeyEnabled)
{
// hotkey enabled, store and activate
- Variables.QuickActionsHotKey = new Hotkey(_hotKey.TbQuickActionsHotkey.Text);
+ Variables.QuickActionsHotKey = _hotKey.TbQuickActionsHotkey.Text;
Variables.AppSettings.QuickActionsHotKey = Variables.QuickActionsHotKey.ToString();
- Variables.HotKeyManager.QuickActionsHotKeyChanged(_previousHotkey);
+ Variables.InternalHotKeyManager.QuickActionsHotKeyChanged(_previousHotkey);
}
else
{
// hotkey disabled, remove and deactivate
Variables.QuickActionsHotKey = null;
Variables.AppSettings.QuickActionsHotKey = string.Empty;
- Variables.HotKeyManager.QuickActionsHotKeyChanged(_previousHotkey, false);
+ Variables.InternalHotKeyManager.QuickActionsHotKeyChanged(_previousHotkey, false);
}
// mqtt
@@ -431,8 +562,10 @@ private async Task StoreSettingsAsync()
Variables.AppSettings.MqttClientId = _mqtt.TbMqttClientId.Text;
Variables.AppSettings.MqttRootCertificate = _mqtt.TbMqttRootCertificate.Text;
Variables.AppSettings.MqttClientCertificate = _mqtt.TbMqttClientCertificate.Text;
- Variables.AppSettings.MqttAllowUntrustedCertificates = _mqtt.CbAllowUntrustedCertificates.CheckState == CheckState.Checked;
+ Variables.AppSettings.MqttAllowUntrustedCertificates =
+ _mqtt.CbAllowUntrustedCertificates.CheckState == CheckState.Checked;
Variables.AppSettings.MqttUseRetainFlag = _mqtt.CbUseRetainFlag.CheckState == CheckState.Checked;
+ Variables.AppSettings.MqttUseWebSocket = _mqtt.CbUseWebSocket.CheckState == CheckState.Checked;
Variables.AppSettings.MqttIgnoreGracePeriod = _mqtt.CbIgnoreGracePeriod.CheckState == CheckState.Checked;
// mqtt -> service
@@ -441,7 +574,8 @@ private async Task StoreSettingsAsync()
// updates
Variables.AppSettings.CheckForUpdates = _updates.CbUpdates.CheckState == CheckState.Checked;
Variables.AppSettings.ShowBetaUpdates = _updates.CbBetaUpdates.CheckState == CheckState.Checked;
- Variables.AppSettings.EnableExecuteUpdateInstaller = _updates.CbExecuteUpdater.CheckState == CheckState.Checked;
+ Variables.AppSettings.EnableExecuteUpdateInstaller =
+ _updates.CbExecuteUpdater.CheckState == CheckState.Checked;
// cache
Variables.AppSettings.ImageCacheRetentionDays = (int)_localStorage.NumImageRetention.Value;
@@ -462,7 +596,8 @@ private async Task StoreSettingsAsync()
AgentSharedBase.SetCustomExecutorBinary(Variables.AppSettings.CustomExecutorBinary);
// mediaplayer
- Variables.AppSettings.MediaPlayerEnabled = _mediaPlayer.CbEnableMediaPlayer.CheckState == CheckState.Checked;
+ Variables.AppSettings.MediaPlayerEnabled =
+ _mediaPlayer.CbEnableMediaPlayer.CheckState == CheckState.Checked;
// tray icon
Variables.AppSettings.TrayIconUseModern = _trayIcon.CbUseModernIcon.CheckState == CheckState.Checked;
@@ -470,13 +605,18 @@ private async Task StoreSettingsAsync()
Variables.AppSettings.TrayIconShowWebView = _trayIcon.CbShowWebView.CheckState == CheckState.Checked;
Variables.AppSettings.TrayIconWebViewWidth = (int)_trayIcon.NumWebViewWidth.Value;
Variables.AppSettings.TrayIconWebViewHeight = (int)_trayIcon.NumWebViewHeight.Value;
+ Variables.AppSettings.TrayIconWebViewScreen = _trayIcon.NumWebViewScreen.SelectedIndex;
Variables.AppSettings.TrayIconWebViewUrl = _trayIcon.TbWebViewUrl.Text;
- Variables.AppSettings.TrayIconWebViewBackgroundLoading = _trayIcon.CbWebViewKeepLoaded.CheckState == CheckState.Checked;
- Variables.AppSettings.TrayIconWebViewShowMenuOnLeftClick = _trayIcon.CbWebViewShowMenuOnLeftClick.CheckState == CheckState.Checked;
+ Variables.AppSettings.TrayIconWebViewBackgroundLoading =
+ _trayIcon.CbWebViewKeepLoaded.CheckState == CheckState.Checked;
+ Variables.AppSettings.TrayIconWebViewShowMenuOnLeftClick =
+ _trayIcon.CbWebViewShowMenuOnLeftClick.CheckState == CheckState.Checked;
// nfc
Variables.AppSettings.NfcScanningEnabled = _nfc.CbEnableNfc.CheckState == CheckState.Checked;
- Variables.AppSettings.NfcSelectedScanner = _nfc.CbNfcScanner.SelectedItem == null ? string.Empty : _nfc.CbNfcScanner.SelectedItem.ToString();
+ Variables.AppSettings.NfcSelectedScanner = _nfc.CbNfcScanner.SelectedItem == null
+ ? string.Empty
+ : _nfc.CbNfcScanner.SelectedItem.ToString();
// save to file
SettingsManager.StoreAppSettings();
@@ -513,7 +653,7 @@ private void Configuration_KeyUp(object sender, KeyEventArgs e)
private void BtnClearHotKey_Click(object sender, EventArgs e)
{
- _hotKey.TbQuickActionsHotkey.Text = _hotkeySelector.EmptyHotkeyText;
+ _hotKey.TbQuickActionsHotkey.Text = string.Empty;
}
private void Configuration_ResizeEnd(object sender, EventArgs e)
@@ -552,4 +692,4 @@ private void CbHassAutoClientCertificate_CheckedChanged(object sender, EventArgs
private void BtnClose_Click(object sender, EventArgs e) => Close();
}
-}
+}
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Forms/Main.cs b/src/HASS.Agent/HASS.Agent/Forms/Main.cs
index 84408a66..5bde6719 100644
--- a/src/HASS.Agent/HASS.Agent/Forms/Main.cs
+++ b/src/HASS.Agent/HASS.Agent/Forms/Main.cs
@@ -24,10 +24,12 @@
using Serilog;
using Syncfusion.Windows.Forms;
using WindowsDesktop;
-using WK.Libraries.HotkeyListenerNS;
using NativeMethods = HASS.Agent.Functions.NativeMethods;
using QuickActionsConfig = HASS.Agent.Forms.QuickActions.QuickActionsConfig;
using Task = System.Threading.Tasks.Task;
+using Microsoft.Win32;
+using NHotkey;
+using NHotkey.WindowsForms;
namespace HASS.Agent.Forms
{
@@ -65,6 +67,11 @@ private async void Main_Load(object sender, EventArgs e)
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
+ if (SharedHelperFunctions.RunningElevated())
+ {
+ Log.Warning("[MAIN] Running with elevated privileges, this might cause issues for example with notifications!");
+ }
+
// catch all key presses
KeyPreview = true;
@@ -82,7 +89,7 @@ private async void Main_Load(object sender, EventArgs e)
SetMqttStatus(ComponentStatus.Loading);
// create a hotkey listener
- Variables.HotKeyListener = new HotkeyListener();
+ Variables.HotKeyListener = HotkeyManager.Current;
// check for dpi scaling
CheckDpiScalingFactor();
@@ -90,7 +97,6 @@ private async void Main_Load(object sender, EventArgs e)
// core components initialization - required for loading the entities
await RadioManager.Initialize();
await InternalDeviceSensorsManager.Initialize();
- InitializeHardwareManager();
InitializeVirtualDesktopManager();
await Task.Run(InitializeAudioManager);
@@ -117,7 +123,10 @@ private async void Main_Load(object sender, EventArgs e)
if (Variables.ShuttingDown)
return;
+ // prepare the tray icon config
+ SystemEvents.DisplaySettingsChanged += (s, a) => RefreshTrayIcon();
ProcessTrayIcon();
+
InitializeHotkeys();
var initTask = Task.Run(async () =>
@@ -166,7 +175,6 @@ await Task.WhenAll(hassApiTask, sensorTask, commandsTask, serviceTask,
private void OnProcessExit(object sender, EventArgs e)
{
AudioManager.Shutdown();
- HardwareManager.Shutdown();
NotificationManager.Exit();
}
@@ -250,13 +258,8 @@ private void CheckDpiScalingFactor()
private void ProcessTrayIcon()
{
- if (Variables.AppSettings.TrayIconUseModern)
- {
- var icon = (Icon)new System.Resources.ResourceManager(typeof(Main)).GetObject("ModernNotifyIcon");
- if (icon != null)
- NotifyIcon.Icon = icon;
- }
-
+ RefreshTrayIcon();
+
// are we set to show the webview and keep it loaded?
if (!Variables.AppSettings.TrayIconShowWebView)
return;
@@ -302,10 +305,10 @@ private static void CurrentDomain_UnhandledException(object sender, UnhandledExc
private void InitializeHotkeys()
{
// prepare listener
- Variables.HotKeyListener.HotkeyPressed += HotkeyListener_HotkeyPressed;
+ Variables.InternalHotKeyManager.HotkeyActivated += HotkeyListener_HotkeyPressed;
// bind quick actions hotkey (if configured)
- Variables.HotKeyManager.InitializeQuickActionsHotKeys();
+ Variables.InternalHotKeyManager.InitializeQuickActionsHotKeys();
}
///
@@ -315,10 +318,10 @@ private void InitializeHotkeys()
///
private void HotkeyListener_HotkeyPressed(object sender, HotkeyEventArgs e)
{
- if (e.Hotkey == Variables.QuickActionsHotKey)
+ if (e.Name == Variables.QuickActionsHotKey)
ShowQuickActions();
else
- HotKeyManager.ProcessQuickActionHotKey(e.Hotkey.ToString());
+ InternalHotKeyManager.ProcessQuickActionHotKey(e.Name);
}
///
@@ -329,14 +332,6 @@ private void InitializeVirtualDesktopManager()
VirtualDesktopManager.Initialize();
}
- ///
- /// Initialized the Hardware Manager
- ///
- private void InitializeHardwareManager()
- {
- HardwareManager.Initialize();
- }
-
///
/// Initialized the Audio Manager
///
@@ -400,6 +395,21 @@ internal void HideTrayIcon()
}));
}
+ internal void RefreshTrayIcon()
+ {
+ var iconResourceName = Variables.AppSettings.TrayIconUseModern ? "ModernNotifyIcon" : "NotifyIcon.Icon";
+ var icon = (Icon)new System.Resources.ResourceManager(typeof(Main)).GetObject(iconResourceName);
+ if (icon != null)
+ {
+ Invoke(new MethodInvoker(delegate
+ {
+ NotifyIcon.Visible = false;
+ NotifyIcon.Icon = icon;
+ NotifyIcon.Visible = true;
+ }));
+ }
+ }
+
///
/// Show a messagebox on the UI thread
///
@@ -833,11 +843,15 @@ private async void CheckForUpdate()
BtnCheckForUpdate.Text = Languages.Main_Checking;
var (isAvailable, version) = await UpdateManager.CheckIsUpdateAvailableAsync();
- if (!isAvailable)
+ if (!isAvailable && version != null)
{
var beta = Variables.Beta ? " [BETA]" : string.Empty;
MessageBoxAdv.Show(this, string.Format(Languages.Main_CheckForUpdate_MessageBox1, Variables.Version, beta), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information);
-
+ return;
+ }
+ else if(!isAvailable)
+ {
+ MessageBoxAdv.Show(this, Languages.Main_CheckForUpdateFailed_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
diff --git a/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActions.cs b/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActions.cs
index 0c54706b..10da740c 100644
--- a/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActions.cs
+++ b/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActions.cs
@@ -108,6 +108,10 @@ private void BuildLayout()
if (rows > 1)
Height += 5 * (rows - 1);
+ var scalingFactor = HelperFunctions.GetScalingFactors();
+ Width = (int)(Width * scalingFactor.dpiScalingFactor);
+ Height = (int)(Height * scalingFactor.dpiScalingFactor);
+
// add the quickactions as controls
var currentColumn = 0;
var currentRow = 0;
diff --git a/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActionsConfig.cs b/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActionsConfig.cs
index 9a8285c4..7c86317c 100644
--- a/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActionsConfig.cs
+++ b/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActionsConfig.cs
@@ -163,7 +163,7 @@ private void BtnStore_Click(object sender, EventArgs e)
StoredQuickActions.Store();
// reload hotkey bindings
- Variables.HotKeyManager.ReloadQuickActionsHotKeys();
+ Variables.InternalHotKeyManager.ReloadQuickActionsHotKeys();
// done
Close();
diff --git a/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActionsMod.cs b/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActionsMod.cs
index dcb776fb..3b4008e0 100644
--- a/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActionsMod.cs
+++ b/src/HASS.Agent/HASS.Agent/Forms/QuickActions/QuickActionsMod.cs
@@ -6,17 +6,18 @@
using HASS.Agent.Shared.Enums;
using HASS.Agent.Shared.Functions;
using Syncfusion.Windows.Forms;
-using WK.Libraries.HotkeyListenerNS;
namespace HASS.Agent.Forms.QuickActions
{
public partial class QuickActionsMod : MetroForm
{
- private readonly HotkeySelector _hotkeySelector = new();
internal readonly QuickAction QuickAction;
private readonly Dictionary _hassDomainEntityTypes = new();
private readonly Dictionary _hassActionEntityTypes = new();
+
+ private Keys _key = Keys.None;
+ private Keys _modifiers = Keys.None;
public QuickActionsMod(QuickAction quickAction)
{
@@ -90,15 +91,17 @@ private async void QuickActionsMod_Load(object sender, EventArgs e)
}
LvDomain.EndUpdate();
+ TbHotkey.ReadOnly = true;
+ TbHotkey.KeyDown += TbQuickActionsHotkey_KeyDown;
+
// load or new quickaction?
if (QuickAction.Id == Guid.Empty)
{
// new quickaction
Text = Languages.QuickActionsMod_Title_New;
QuickAction.Id = Guid.NewGuid();
-
- _hotkeySelector.Enable(TbHotkey);
- TbHotkey.Text = _hotkeySelector.EmptyHotkeyText;
+
+ TbHotkey.Text = string.Empty;
LvDomain.Items[0].Selected = true;
if (CbEntity.Items.Count > 0) CbEntity.SelectedIndex = 0;
@@ -211,12 +214,7 @@ private void LoadQuickAction()
if (!string.IsNullOrWhiteSpace(TbDescription.Text)) TbDescription.SelectionStart = TbDescription.Text.Length;
// load the hotkey
- if (!string.IsNullOrEmpty(QuickAction.HotKey)) _hotkeySelector.Enable(TbHotkey, new Hotkey(QuickAction.HotKey));
- else
- {
- _hotkeySelector.Enable(TbHotkey);
- TbHotkey.Text = _hotkeySelector.EmptyHotkeyText;
- }
+ TbHotkey.Text = !string.IsNullOrEmpty(QuickAction.HotKey) ? QuickAction.HotKey : string.Empty;
}
///
@@ -396,6 +394,22 @@ private void LoadEntityList()
CbEntity.Items.Add(item);
}
break;
+
+ case HassDomain.InputButton:
+ foreach (var item in HassApiManager.InputButtonList)
+ {
+ CbEntity.AutoCompleteCustomSource.Add(item);
+ CbEntity.Items.Add(item);
+ }
+ break;
+
+ case HassDomain.Fan:
+ foreach (var item in HassApiManager.FanList)
+ {
+ CbEntity.AutoCompleteCustomSource.Add(item);
+ CbEntity.Items.Add(item);
+ }
+ break;
}
}
@@ -410,16 +424,13 @@ private void CbEntity_SelectedIndexChanged(object sender, EventArgs e)
private void QuickActionsMod_FormClosing(object sender, FormClosingEventArgs e)
{
- // stop and dispose selector
- _hotkeySelector?.Disable(TbHotkey);
- _hotkeySelector?.Dispose();
+ // clean selector
+ TbHotkey.KeyDown -= TbQuickActionsHotkey_KeyDown;
}
private void TbHotkey_TextChanged(object sender, EventArgs e)
{
- if (string.IsNullOrWhiteSpace(TbHotkey.Text)
- || TbHotkey.Text == _hotkeySelector?.EmptyHotkeyText
- || TbHotkey.Text == _hotkeySelector?.InvalidHotkeyText)
+ if (string.IsNullOrWhiteSpace(TbHotkey.Text))
{
CbEnableHotkey.CheckState = CheckState.Unchecked;
return;
@@ -465,5 +476,53 @@ private void QuickActionsMod_Layout(object sender, LayoutEventArgs e)
// hide the pesky horizontal scrollbar
ListViewTheme.ShowScrollBar(LvDomain.Handle, ListViewTheme.SB_HORZ, false);
}
+
+ private void TbQuickActionsHotkey_KeyDown(object sender, KeyEventArgs e)
+ {
+ e.SuppressKeyPress = true;
+
+ var key = e.KeyCode;
+
+ if (key is Keys.LControlKey or Keys.RControlKey
+ or Keys.LShiftKey or Keys.RShiftKey
+ or Keys.LWin or Keys.RWin
+ or Keys.Alt)
+ {
+ key = Keys.None;
+ }
+
+ if (key == Keys.Escape)
+ {
+ _key = Keys.None;
+ _modifiers = Keys.None;
+ TbHotkey.Text = string.Empty;
+
+ return;
+ }
+
+ _key = key;
+ TbHotkey.Text = FormatHotkey(_key, e.Modifiers);
+ }
+
+ private string FormatHotkey(Keys key, Keys modifiers)
+ {
+ var parts = new List();
+ if ((modifiers & Keys.Shift) != 0)
+ {
+ parts.Add(nameof(Keys.Shift));
+ }
+
+ if ((modifiers & Keys.Control) != 0)
+ {
+ parts.Add(nameof(Keys.Control));
+ }
+
+ if ((modifiers & Keys.Alt) != 0)
+ {
+ parts.Add(nameof(Keys.Alt));
+ }
+
+ return parts.Count > 0 ? string.Join(", ", parts) + " + " + key : key.ToString();
+ }
}
}
diff --git a/src/HASS.Agent/HASS.Agent/Forms/Sensors/SensorsMod.cs b/src/HASS.Agent/HASS.Agent/Forms/Sensors/SensorsMod.cs
index e852dbbf..df3f172a 100644
--- a/src/HASS.Agent/HASS.Agent/Forms/Sensors/SensorsMod.cs
+++ b/src/HASS.Agent/HASS.Agent/Forms/Sensors/SensorsMod.cs
@@ -180,6 +180,7 @@ private void LoadSensor()
switch (_selectedSensorType)
{
case SensorType.NamedWindowSensor:
+ case SensorType.NamedActiveWindowSensor:
TbSetting1.Text = Sensor.WindowName;
break;
@@ -291,6 +292,7 @@ private bool SetType(bool setDefaultValues = true)
// process the interface
switch (sensorCard.SensorType)
{
+ case SensorType.NamedActiveWindowSensor:
case SensorType.NamedWindowSensor:
SetWindowGui();
break;
@@ -702,6 +704,7 @@ private void BtnStore_Click(object sender, EventArgs e)
switch (sensorCard.SensorType)
{
case SensorType.NamedWindowSensor:
+ case SensorType.NamedActiveWindowSensor:
var window = TbSetting1.Text.Trim();
if (string.IsNullOrEmpty(window))
{
diff --git a/src/HASS.Agent/HASS.Agent/Forms/WebView.Designer.cs b/src/HASS.Agent/HASS.Agent/Forms/WebView.Designer.cs
index c15a08b9..e99f42ff 100644
--- a/src/HASS.Agent/HASS.Agent/Forms/WebView.Designer.cs
+++ b/src/HASS.Agent/HASS.Agent/Forms/WebView.Designer.cs
@@ -1,6 +1,6 @@
-extern alias WV2;
-using HASS.Agent.Resources.Localization;
-using WV2::Microsoft.Web.WebView2.WinForms;
+using HASS.Agent.Resources.Localization;
+using Microsoft.Web.WebView2.WinForms;
+
namespace HASS.Agent.Forms
{
diff --git a/src/HASS.Agent/HASS.Agent/Forms/WebView.cs b/src/HASS.Agent/HASS.Agent/Forms/WebView.cs
index 8e0ed48a..96a871e7 100644
--- a/src/HASS.Agent/HASS.Agent/Forms/WebView.cs
+++ b/src/HASS.Agent/HASS.Agent/Forms/WebView.cs
@@ -1,5 +1,4 @@
-extern alias WV2;
-using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.CodeAnalysis;
using Syncfusion.Windows.Forms;
using HASS.Agent.Functions;
using HASS.Agent.Models.Internal;
@@ -8,7 +7,8 @@
using Serilog;
using System.Runtime.InteropServices;
using Windows.Web.UI.Interop;
-using WV2::Microsoft.Web.WebView2.Core;
+using Microsoft.Web.WebView2.Core;
+
namespace HASS.Agent.Forms
{
diff --git a/src/HASS.Agent/HASS.Agent/Functions/HelperFunctions.cs b/src/HASS.Agent/HASS.Agent/Functions/HelperFunctions.cs
index b56eace8..30796038 100644
--- a/src/HASS.Agent/HASS.Agent/Functions/HelperFunctions.cs
+++ b/src/HASS.Agent/HASS.Agent/Functions/HelperFunctions.cs
@@ -1,13 +1,8 @@
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
+using System.Diagnostics;
using System.IO;
-using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
-using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using HASS.Agent.API;
@@ -27,11 +22,15 @@
using HASS.Agent.Shared.Managers;
using Newtonsoft.Json.Serialization;
using System.Windows;
+using System.Security.Policy;
namespace HASS.Agent.Functions
{
- internal static class HelperFunctions
+ internal static partial class HelperFunctions
{
+ [GeneratedRegex("^https?://")]
+ private static partial Regex AbsoluteURLRegex();
+
private static bool _shutdownCalled = false;
///
@@ -173,8 +172,8 @@ internal static async Task ShutdownAsync(TimeSpan waitBeforeClosing)
// stop hotkey
Variables.MainForm?.Invoke(new MethodInvoker(delegate
{
- Variables.HotKeyListener?.RemoveAll();
- Variables.HotKeyListener?.Dispose();
+ Variables.InternalHotKeyManager?.ReloadQuickActionsHotKeys();
+ //Variables.HotKeyListener?.Dispose();
}));
// stop bt listener
@@ -365,18 +364,22 @@ internal static void OpenLocalFolder(string path)
internal static Form GetForm(string formName) => System.Windows.Forms.Application.OpenForms.Cast
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.en.resx b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.en.resx
index 938f6d80..1b3ef33c 100644
--- a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.en.resx
+++ b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.en.resx
@@ -526,7 +526,7 @@ The certificate of the downloaded file will get checked before running,you will
HASS.Agent GitHub page
- There's a lot more to tinker with, so make sure you take a look at the Configuration Wwindow!
+ There's a lot more to tinker with, so make sure you take a look at the Configuration Window!
Thank you for using HASS.Agent, hopefully it'll be useful for you :-)
@@ -1248,6 +1248,7 @@ Your command is provided as an argument 'as is', so you have to supply your own
Simulates a single keypress.
+Making this command a "switch" type will make the button pressed as long as the switch is turned on.
Click on the 'keycode' textbox and press the key you want simulated. The corresponding keycode will be entered for you.
For TAB key please use LCTRL+TAB.
@@ -2058,7 +2059,10 @@ Currently takes the volume of your default device.
Provides the current load of the first GPU as a percentage.
- Provides the current temperature of the first GPU.
+ NOTE: This is a non-functioning sensor.
+
+Due to the security concerns regarding Libre Hardware Monitor (library allowing HASS.Agent to access GPU temperature data) this sensor is left for backward compatibility reasons and will always return 0.
+Please see documentation for alternative options.
Provides a datetime value containing the last moment the user provided input.
@@ -3095,7 +3099,8 @@ Are you sure you want to use this key anyway?
Are you sure you want to use this URI anyway?
- Developing and maintaining this tool (and everything that surrounds it) takes up a lot of time. Like most developers, I run on caffeïne - so if you can spare it, a cup of coffee is always very much appreciated!
+ Currently, we (HASS.Agent Team maintaining the fork) do not accept donations in any form :)
+Please however feel free to donate to the original author of HASS.Agent - Sam! Wherever they currently are, cup of coffee might brighten their day.
Tip: Other donation methods are available on the About Window.
@@ -3436,4 +3441,50 @@ Requires it to be configured in "Configuration -> Tray Icon"
Dismiss
+
+ Failed checking for update!
+
+
+ NamedActiveWindow
+
+
+ Provides an ON/OFF value based on whether the focused window name contains configured string.
+
+
+ Provides #RRGGBB color values for system accent colors.
+Main accent color is the sensor value, additional accent colors are available as attributes.
+
+
+ Use &WebSocket
+
+
+ Use &WebSocket
+
+
+ InputButton
+
+
+ Fan
+
+
+ Puts the machine to sleep using WinForms API.
+
+Note: due to "Modern Sleep" the sleep commands might behave differently depending on the device OEM and OS configuration.
+
+
+ WinformsSleep
+
+
+ Connection OK!
+
+
+ Unable to connect.
+
+
+ MonitorSleepPowerPlan
+
+
+ Puts all monitors in sleep (low power) mode using alternative approach of power plan modification.
+Should provide better experience with new systems with "modern S0ix sleep" and not put the system to sleep.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.es.resx b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.es.resx
index 89aa0d2e..d535ac12 100644
--- a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.es.resx
+++ b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.es.resx
@@ -1248,11 +1248,12 @@ Su comando se proporciona como un argumento 'tal cual', por lo que debe proporci
Simula una sola pulsación de tecla.
+Al configurar este comando como "interruptor", el botón se mantendrá pulsado mientras el interruptor esté activado.
-Haga clic en el cuadro de texto 'keycode' y presione la tecla que desea simular. El código clave correspondiente se ingresará por usted.
-Para la tecla TAB, utilice LCTRL+TAB.
+Haga clic en el cuadro de texto "código de tecla" y pulse la tecla que desee simular. Se introducirá automáticamente el código de tecla correspondiente.
+Para la tecla TAB, utilice Ctrl L+TAB.
-Si necesita más teclas y/o modificadores como CTRL, use el comando MultipleKeys.
+Si necesita más teclas o modificadores como Ctrl, utilice el comando "Múltiples teclas".
Lanza la URL proporcionada, por defecto en su navegador predeterminado.
@@ -2062,7 +2063,10 @@ Actualmente toma el volumen de su dispositivo predeterminado.
Proporciona la carga actual de la primera GPU como porcentaje.
- Proporciona la temperatura actual de la primera GPU.
+ NOTA: Este sensor no funciona.
+
+Debido a problemas de seguridad relacionados con Libre Hardware Monitor (biblioteca que permite a HASS.Agent acceder a los datos de temperatura de la GPU), este sensor se mantiene por compatibilidad con versiones anteriores y siempre devolverá 0.
+Consulte la documentación para ver opciones alternativas.
Proporciona un valor de fecha y hora que contiene la última vez que el usuario realizó una entrada.
@@ -3094,7 +3098,8 @@ Debería contener tres secciones (separadas por dos puntos).
¿Está seguro de que quiere usarlo así?
- Desarrollar y mantener esta herramienta (y todo lo que la rodea) requiere mucho tiempo. Al igual que la mayoría de los desarrolladores, funciono a base de cafeína, así que, si puede dedicarle un poco de tiempo, ¡una taza de café es siempre muy apreciada!
+ Actualmente, nosotros (el equipo de HASS.Agent que mantiene esta versión) no aceptamos donaciones de ningún tipo :)
+Sin embargo, no duden en donar al autor original de HASS.Agent, ¡Sam! Esté donde esté, una taza de café podría alegrarle el día.
Sugerencia: hay otros métodos de donación disponibles en la ventana Acerca de.
@@ -3407,4 +3412,50 @@ Requiere que se configure en "Configuración -> Icono de la bandeja"
Despedir
+
+ Pantalla a utilizar para mostrar WebView
+
+
+ Error al comprobar la actualización.
+
+
+ Ventana activa con nombre
+
+
+ Proporciona un valor de ENCENDIDO/APAGADO según si el nombre de la ventana enfocada contiene una cadena configurada.
+
+
+ Proporciona valores de color #RRGGBB para los colores de acento del sistema.
+El color de acento principal es el valor del sensor; hay colores de acento adicionales disponibles como atributos.
+
+
+ Utilice &WebSocket
+
+
+ Utilice &WebSocket
+
+
+ Admirador
+
+
+ Pone la máquina en suspensión mediante la API de WinForms.
+
+Nota: Debido al modo de suspensión moderno, los comandos de suspensión pueden comportarse de forma diferente según el fabricante del dispositivo y la configuración del sistema operativo.
+
+
+ WinformsSleep
+
+
+ No se puede conectar.
+
+
+ ¡Conexión correcta!
+
+
+ Pone todos los monitores en modo de suspensión (bajo consumo de energía) utilizando un método alternativo de modificación del plan de energía.
+Esto debería proporcionar una mejor experiencia con los nuevos sistemas con "suspensión moderna S0ix" y evitar que el sistema entre en modo de suspensión completa.
+
+
+ Plan de energía para el sueño del monitor
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.fr.resx b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.fr.resx
index 5fa1229c..cc194c4c 100644
--- a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.fr.resx
+++ b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.fr.resx
@@ -1269,14 +1269,6 @@ Votre commande est passée en tant qu'argument 'tel quel', vous devez donc fourn
Mettre Windows en veille prolongée
-
- Simule une seule pression de touche.
-
-Cliquez sur la zone de texte "keycode" et appuyez sur la touche que vous souhaitez simuler. Le code clé correspondant sera saisi pour vous.
-Pour la touche TAB, veuillez utiliser LCTRL+TAB.
-
-Si vous avez besoin de plus de touches et/ou de modificateurs comme CTRL, utilisez la commande MultipleKeys.
-
Ouvre l'URL fournie, par défaut dans votre navigateur par défaut.
@@ -2092,7 +2084,10 @@ Indique le volume de votre appareil par défaut.
Fournit la charge actuelle du premier GPU sous forme de pourcentage.
- Fournit la température actuelle du premier GPU.
+ REMARQUE : Ce capteur est non fonctionnel.
+
+Pour des raisons de sécurité concernant Libre Hardware Monitor (bibliothèque permettant à HASS.Agent d'accéder aux données de température du GPU), ce capteur est conservé pour des raisons de rétrocompatibilité et renvoie toujours 0.
+Veuillez consulter la documentation pour connaître les autres options.
Fournit une valeur datetime qui contient la dernière fois que l'utilisateur a effectué une entrée.
@@ -3127,7 +3122,8 @@ Etes-vous sûr de vouloir l'utiliser comme ça ?
Etes-vous sûr de vouloir l'utiliser ainsi ?
- Développer et maintenir cet outil (et tout ce qui l'entoure) prend beaucoup de temps. Comme la plupart des développeurs, je fonctionne à la caféine - donc si vous pouvez vous le permettre, une tasse de café est toujours très appréciée !
+ Actuellement, nous (l'équipe HASS.Agent qui maintient cette version dérivée) n'acceptons aucune donation, sous quelque forme que ce soit.
+N'hésitez cependant pas à faire un don à l'auteur original de HASS.Agent, Sam ! Où qu'il soit actuellement, une tasse de café pourrait lui faire plaisir.
Astuce : d'autres méthodes de dons sont disponibles dans la fenêtre À propos.
@@ -3440,4 +3436,58 @@ Nécessite sa configuration dans « Configuration -> Icône de la barre d'ét
Rejeter
+
+ Écran à utiliser pour l'affichage du WebView
+
+
+ Échec de la vérification de la mise à jour !
+
+
+ Fenêtre active nommée
+
+
+ Fournit une valeur ON/OFF selon que le nom de la fenêtre focalisée contient ou non une chaîne configurée.
+
+
+ Fournit les valeurs de couleur #RRGGBB pour les couleurs d'accentuation du système. La couleur d'accentuation principale est la valeur du capteur ; des couleurs d'accentuation supplémentaires sont disponibles sous forme d'attributs.
+
+
+ Utiliser &WebSocket
+
+
+ Utiliser &WebSocket
+
+
+ Simule une simple pression de touche.
+Si cette commande est de type « interrupteur », le bouton restera enfoncé tant que l'interrupteur sera activé.
+
+Cliquez sur la zone de texte « Code touche » et appuyez sur la touche à simuler. Le code touche correspondant sera saisi automatiquement.
+Pour la touche TAB, utilisez Ctrl+Clic+Tab.
+
+Si vous avez besoin de touches supplémentaires et/ou de modificateurs comme Ctrl, utilisez la commande TouchesMultiples.
+
+
+ Ventilateur
+
+
+ Met la machine en veille à l'aide de l'API WinForms.
+
+Remarque : en raison de la fonction « Modern Sleep », les commandes de mise en veille peuvent se comporter différemment selon le fabricant de l'appareil et la configuration du système d'exploitation.
+
+
+ WinformsSleep
+
+
+ Connexion impossible.
+
+
+ Connexion OK !
+
+
+ Met tous les moniteurs en mode veille (basse consommation) en utilisant une approche alternative de modification du plan d'alimentation.
+Cela devrait offrir une meilleure expérience avec les nouveaux systèmes dotés du mode veille moderne « S0ix » et éviter de mettre le système en veille complète.
+
+
+ Surveillance du mode veille/alimentation
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.nl.resx b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.nl.resx
index 77b704c4..71bc2a11 100644
--- a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.nl.resx
+++ b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.nl.resx
@@ -1249,11 +1249,12 @@ Je commando wordt onveranderd toegevoegd als argument, dus je moet je eigen haak
Simuleert een enkele toetsaanslag.
+Door van dit commando een "switch"-type te maken, blijft de knop ingedrukt zolang de switch aan staat.
-Klik op het tekstvak 'sleutelcode' en druk op de sleutel die u wilt simuleren. De bijbehorende sleutelcode wordt voor u ingevoerd.
-Gebruik voor de TAB-sleutel LCTRL+TAB.
+Klik op het tekstvak 'keycode' en druk op de toets die u wilt simuleren. De bijbehorende toetscode wordt automatisch ingevoerd.
+Gebruik LCTRL+TAB voor de TAB-toets.
-Als u meer sleutels en/of modifiers zoals CTRL nodig heeft, gebruikt u de opdracht MultipleKeys.
+Als u meer toetsen en/of modifiers zoals CTRL nodig hebt, gebruik dan het commando 'MultipleKeys'.
Fuzzy
@@ -2073,7 +2074,10 @@ Pakt momenteel het volume van je standaardapparaat.
Geeft de huidige belasting van de eerste GPU als een percentage.
- Geeft de huidige temperatuur van de eerste GPU.
+ OPMERKING: Dit is een niet-functionerende sensor.
+
+Vanwege beveiligingsproblemen met Libre Hardware Monitor (bibliotheek die HASS.Agent toegang geeft tot GPU-temperatuurgegevens) wordt deze sensor om redenen van achterwaartse compatibiliteit niet gebruikt en retourneert altijd 0.
+Raadpleeg de documentatie voor alternatieve opties.
Biedt een datum/tijd-waarde die de laatste keer bevat dat de gebruiker iets heeft ingevoerd.
@@ -3116,7 +3120,8 @@ Weet je zeker dat je 'm zo wilt gebruiken?
Weet je zeker dat je 'm zo wilt gebruiken?
- Het ontwikkelen en onderhouden van deze tool (en alles wat erbij komt kijken, zoals support, deze vertaling en de documentatie) neemt een hoop tijd in beslag. Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt missen, wordt een kop koffie altijd erg gewaardeerd!
+ Momenteel accepteren wij (het HASS.Agent-team dat de fork beheert) geen donaties in welke vorm dan ook :)
+Voel je echter vrij om te doneren aan de oorspronkelijke auteur van HASS.Agent - Sam! Waar ze zich ook bevinden, een kopje koffie kan hun dag misschien opvrolijken.
Tip: andere donatie methodes zijn beschikbaar in het Over scherm.
@@ -3428,4 +3433,50 @@ Vereist dat het geconfigureerd is in "Configuratie -> Tray Icon"
Afwijzen
+
+ Scherm dat moet worden gebruikt om WebView weer te geven
+
+
+ Controle op update mislukt!
+
+
+ SchermActiefNaam
+
+
+ Geeft een AAN/UIT-waarde op basis van het al dan niet bevatten van de focusvensternaam van een geconfigureerde tekenreeks.
+
+
+ Biedt #RRGGBB-kleurwaarden voor systeemaccentkleuren.
+De belangrijkste accentkleur is de sensorwaarde. Aanvullende accentkleuren zijn beschikbaar als attributen.
+
+
+ Gebruik &WebSocket
+
+
+ Gebruik &WebSocket
+
+
+ Fan
+
+
+ Zet de machine in slaapstand met behulp van de WinForms API.
+
+Opmerking: vanwege "Modern Sleep" kunnen de slaapopdrachten zich anders gedragen, afhankelijk van de OEM van het apparaat en de configuratie van het besturingssysteem.
+
+
+ WinformsSleep
+
+
+ Kan geen verbinding maken.
+
+
+ Verbinding OK!
+
+
+ Zet alle monitoren in de slaapstand (laag energieverbruik) met behulp van een alternatieve aanpak voor het aanpassen van het energiebeheerschema.
+Zou een betere ervaring moeten bieden met nieuwe systemen met een "moderne S0ix-slaapstand" en het systeem niet in de slaapstand zetten.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.pl.resx b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.pl.resx
index d80f7d7a..4c89d396 100644
--- a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.pl.resx
+++ b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.pl.resx
@@ -1335,9 +1335,10 @@ Twoje polecenie jest dostarczane jako argument „tak jak jest”, więc w razie
Symuluje pojedyncze naciśnięcie klawisza.
+Ustawienie tego polecenia jako „przełącznik” spowoduje, że przycisk będzie wciśnięty tak długo, jak przełącznik będzie włączony.
-Kliknij pole tekstowe „Kod klucza” i naciśnij klawisz, który chcesz zasymulować. Odpowiedni kod zostanie wprowadzony.
-W przypadku klawisza TAB użyj LCTRL+TAB.
+Kliknij pole tekstowe „kod klawisza” i naciśnij klawisz, który chcesz symulować. Odpowiedni kod klawisza zostanie wprowadzony automatycznie.
+W przypadku klawisza TAB użyj kombinacji klawiszy LCTRL+TAB.
Jeśli potrzebujesz więcej klawiszy i/lub modyfikatorów, takich jak CTRL, użyj polecenia MultipleKeys.
Fuzzy
@@ -2166,7 +2167,10 @@ Obecnie zwraca głośność domyślnego urządzenia.
Zwraca obciążenie pierwszego GPU w procentach.
- Zwraca temperaturę pierwszego GPU.
+ UWAGA: Ten czujnik nie działa.
+
+Ze względu na obawy dotyczące bezpieczeństwa Libre Hardware Monitor (biblioteki umożliwiającej HASS.Agent dostęp do danych o temperaturze GPU), ten czujnik został pozostawiony ze względu na kompatybilność wsteczną i zawsze będzie zwracał wartość 0.
+Informacje o alternatywnych opcjach znajdują się w dokumentacji.
Zwraca datę/godzinę, która zawiera czas ostatniej aktywności użytkownika. (klawiatura/myszka)
@@ -3204,7 +3208,8 @@ Czy jesteś pewien, że chcesz użyć tego klucza?
Czy jesteś pewien, że chcesz użyć tego linku URL?
- Tworzenie i utrzymanie aplikacji (i wszystko dookoła, jak wsparcie i dokumentacja) zajmuje sporo czasu. Jak większość deweloperów moim paliwem jest kofeina, więc jeżeli możesz postawić mi kubek kawy będę bardzo wdzięczny!
+ Obecnie my (zespół HASS.Agent, odpowiedzialny za utrzymywanie tej wersji) nie przyjmujemy żadnych darowizn :)
+Prosimy jednak o wsparcie finansowe oryginalnego autora HASS.Agent – Sama! Gdziekolwiek się teraz znajduje, filiżanka kawy z pewnością umili mu dzień.
Wskazówka: Inne sposoby wsparcia dostępne są w zakładce O.
@@ -3517,4 +3522,50 @@ Wymaga konfiguracji w „Configuration -> Tray Icon”
Odrzuć
+
+ Ekran używany do wyświetlania WebView
+
+
+ Sprawdzanie aktualizacji nie powiodło się!
+
+
+ NazwaAktywnegoOkna
+
+
+ Zapewnia wartość WŁ./WYŁ. w zależności od tego, czy nazwa wybranego okna zawiera skonfigurowany ciąg znaków.
+
+
+ Zapewnia wartości kolorów #RRGGBB dla kolorów akcentowych systemu.
+Główny kolor akcentowy to wartość czujnika, dodatkowe kolory akcentowe są dostępne jako atrybuty.
+
+
+ Użyj &WebSocket
+
+
+ Użyj &WebSocket
+
+
+ Wiatrak
+
+
+ Uśpij maszynę za pomocą interfejsu API WinForms.
+
+Uwaga: ze względu na „Modern Sleep” polecenia uśpienia mogą zachowywać się inaczej w zależności od producenta OEM urządzenia i konfiguracji systemu operacyjnego.
+
+
+ WinformsSleep
+
+
+ Nie można nawiązać połączenia.
+
+
+ Połączenie OK!
+
+
+ Przełącza wszystkie monitory w tryb uśpienia (niskiego poboru mocy) za pomocą alternatywnej metody modyfikacji planu zasilania.
+Powinno to zapewnić lepsze działanie w przypadku nowych systemów z „nowoczesnym trybem uśpienia S0ix” i zapobiec przejściu systemu w stan uśpienia.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.pt-br.resx b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.pt-br.resx
index 79a64949..7f6814b9 100644
--- a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.pt-br.resx
+++ b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.pt-br.resx
@@ -237,12 +237,13 @@ Seu comando é fornecido como um argumento 'as is', então você deve fornecer s
Coloca a máquina em hibernação.
- Simula um único pressionamento de tecla.
+ Simula um único toque de tecla.
+Tornar este comando do tipo "interruptor" fará com que o botão seja premido enquanto o interruptor estiver ligado.
-Clique na caixa de texto 'keycode' e pressione a tecla que deseja simular. O código-chave correspondente será inserido para você.
-Para a tecla TAB, use LCTRL+TAB.
+Clique na caixa de texto "código da tecla" e pressione a tecla que pretende simular. O código da tecla correspondente será introduzido.
+Para a tecla TAB, utilize LCTRL+TAB.
-Se precisar de mais teclas e/ou modificadores como CTRL, use o comando MultipleKeys.
+Se necessitar de mais teclas e/ou modificadores como CTRL, utilize o comando MultipleKeys.
Fuzzy
@@ -1732,7 +1733,8 @@ Se você encontrar algum problema, crie um ticket na página do GitHub.
Fuzzy
- Desenvolver e manter essa ferramenta (e tudo o que a envolve, como suporte e documentação) leva muito tempo. Como a maioria dos desenvolvedores, eu amo café - então se você puder me doar um cafezinho serei muito agradecido!
+ Atualmente, nós (a equipa do HASS.Agent que mantém o fork) não aceitamos donativos de qualquer forma :)
+No entanto, sinta-se à vontade para doar ao autor original do HASS.Agent - Sam! Onde quer que ele esteja, uma chávena de café pode alegrar o seu dia.
Dica: outros tipos de doação estão disponíveis na janela Sobre.
@@ -2217,7 +2219,10 @@ Dependendo da sua versão do Windows, isso pode ser encontrado no novo painel de
Fornece a carga atual da GPU como uma porcentagem.
- Fornece a temperatura atual da GPU.
+ NOTA: Este sensor não está a funcionar.
+
+Devido a questões de segurança relacionadas com o Libre Hardware Monitor (biblioteca que permite ao HASS.Agent aceder aos dados de temperatura da GPU), este sensor foi mantido por motivos de compatibilidade com versões anteriores e irá sempre retornar 0.
+Consulte a documentação para obter opções alternativas.
Fornece um valor de data e hora que contém a última vez que o usuário fez uma entrada.
@@ -3453,4 +3458,50 @@ Requer que seja configurado em "Configuration -> Tray Icon"
Dispensar
+
+ Tela a ser usada para exibição do WebView
+
+
+ Falha na verificação da atualização!
+
+
+ JanelaAtiva Nomeada
+
+
+ Fornece um valor ON/OFF com base na presença ou não de uma string configurada no nome da janela em foco.
+
+
+ Fornece valores de cor #RRGGBB para as cores de destaque do sistema.
+A cor de destaque principal é o valor do sensor; cores de destaque adicionais estão disponíveis como atributos.
+
+
+ Utilizar &WebSocket
+
+
+ Utilizar &WebSocket
+
+
+ Fã
+
+
+ Coloca a máquina em modo de espera utilizando a API do WinForms.
+
+Nota: devido ao "Modern Sleep", os comandos de espera podem comportar-se de forma diferente, dependendo do fabricante do dispositivo e da configuração do sistema operativo.
+
+
+ WinformsSleep
+
+
+ Não foi possível ligar.
+
+
+ igação OK!
+
+
+ Coloca todos os monitores em modo de suspensão (baixo consumo de energia) utilizando uma abordagem alternativa de modificação do plano de energia.
+Deve proporcionar uma melhor experiência com novos sistemas com "suspensão S0ix moderna" e não colocar o sistema em modo de suspensão.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.resx b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.resx
index 3722c123..11153161 100644
--- a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.resx
+++ b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.resx
@@ -361,6 +361,7 @@ Your command is provided as an argument 'as is', so you have to supply your own
Simulates a single keypress.
+Making this command a "switch" type will make the button pressed as long as the switch is turned on.
Click on the 'keycode' textbox and press the key you want simulated. The corresponding keycode will be entered for you.
For TAB key please use LCTRL+TAB.
@@ -1168,7 +1169,10 @@ Currently takes the volume of your default device.
Provides the current load of the first GPU as a percentage.
- Provides the current temperature of the first GPU.
+ NOTE: This is a non-functioning sensor.
+
+Due to the security concerns regarding Libre Hardware Monitor (library allowing HASS.Agent to access GPU temperature data) this sensor is left for backward compatibility reasons and will always return 0.
+Please see documentation for alternative options.
Provides a datetime value containing the last moment the user provided input.
@@ -3083,10 +3087,11 @@ Tip: if you're using the HA addon, you can probably use the preset address - jus
Enable &Notifications
- Developing and maintaining this tool (and everything that surrounds it) takes up a lot of time. Like most developers, I run on caffeïne - so if you can spare it, a cup of coffee is always very much appreciated!
+ Currently, we (HASS.Agent Team maintaining the fork) do not accept donations in any form :)
+Please however feel free to donate to the original author of HASS.Agent - Sam! Wherever they currently are, cup of coffee might brighten their day.
- There's a lot more to tinker with, so make sure you take a look at the Configuration Wwindow!
+ There's a lot more to tinker with, so make sure you take a look at the Configuration Window!
Thank you for using HASS.Agent, hopefully it'll be useful for you :-)
@@ -3426,7 +3431,56 @@ Requires it to be configured in "Configuration -> Tray Icon"
Button
+
+ MonitorSleepPowerPlan
+
+
+ Puts all monitors in sleep (low power) mode using alternative approach of power plan modification.
+Should provide better experience with new systems with "modern S0ix sleep" and not put the system to sleep.
+
Dismiss
+
+ Screen to use for WebView to show
+
+
+ Failed checking for update!
+
+
+ NamedActiveWindow
+
+
+ Provides an ON/OFF value based on whether the focused window name contains configured string.
+
+
+ Provides #RRGGBB color values for system accent colors.
+Main accent color is the sensor value, additional accent colors are available as attributes.
+
+
+ Use &WebSocket
+
+
+ Use
+
+
+ InputButton
+
+
+ Fan
+
+
+ Puts the machine to sleep using WinForms API.
+
+Note: due to "Modern Sleep" the sleep commands might behave differently depending on the device OEM and OS configuration.
+
+
+ WinformsSleep
+
+
+ Connection OK!
+
+
+ Unable to connect.
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.ru.resx b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.ru.resx
index cc00f13e..8d089b20 100644
--- a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.ru.resx
+++ b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.ru.resx
@@ -1291,12 +1291,14 @@ HASS.Agent для прослушивания на указанном порту.
Переводит машину в режим гибернации.
- Имитирует одно нажатие клавиши.
+ Имитирует однократное нажатие клавиши.
+Если задать для этой команды тип «переключатель», кнопка будет нажата, пока переключатель включён.
+
+Щёлкните по текстовому полю «код клавиши» и нажмите клавишу, которую хотите имитировать. Соответствующий код клавиши будет введён автоматически.
-Нажмите на текстовое поле «keycode» и нажмите клавишу, которую вы хотите имитировать. Соответствующий ключевой код будет введен для вас.
Для клавиши TAB используйте LCTRL+TAB.
-Если вам нужно больше клавиш и/или модификаторов, таких как CTRL, используйте команду MultipleKeys.
+Если вам нужны дополнительные клавиши и/или модификаторы, например CTRL, используйте команду MultipleKeys.
Fuzzy
@@ -2116,7 +2118,10 @@ Home Assistant version: {0}
Показывает текущую загрузку первого графического процессора в процентах.
- Показывает текущую температуру первого графического процессора.
+ ПРИМЕЧАНИЕ: Это неработающий датчик.
+
+Из-за проблем безопасности, связанных с Libre Hardware Monitor (библиотекой, позволяющей HASS.Agent получать доступ к данным о температуре графического процессора), этот датчик оставлен в целях обратной совместимости и всегда будет возвращать 0.
+Альтернативные варианты см. в документации.
Предоставляет значение даты и времени, содержащее время последнего ввода данных пользователем.
@@ -3162,7 +3167,8 @@ Home Assistant.
Вы уверены, что все равно хотите использовать этот URI?
- Разработка и обслуживание этого инструмента (и всего, что его окружает) отнимает много времени. Как и большинство разработчиков, я работаю на кофеине - так что, если вы можете поделиться им, чашка кофе всегда очень ценится!
+ В настоящее время мы (команда HASS.Agent, поддерживающая форк) не принимаем пожертвования в какой-либо форме :)
+Однако, пожалуйста, не стесняйтесь сделать пожертвование оригинальному автору HASS.Agent — Сэму! Где бы он сейчас ни находился, чашка кофе может скрасить его день.
Совет: Другие способы пожертвования доступны в окне 'О программе'.
@@ -3476,4 +3482,50 @@ Home Assistant.
Увольнять
+
+ Экран, который будет использоваться для отображения WebView
+
+
+ Не удалось проверить обновление!
+
+
+ ИменованноеАктивноеОкно
+
+
+ Предоставляет значение ВКЛ/ВЫКЛ в зависимости от того, содержит ли имя окна в фокусе настроенную строку.
+
+
+ Предоставляет значения цвета #RRGGBB для акцентных цветов системы.
+Основной акцентный цвет — это значение датчика, дополнительные акцентные цвета доступны в качестве атрибутов.
+
+
+ Использовать &WebSocket
+
+
+ Использовать &WebSocket
+
+
+ Вентилятор
+
+
+ Переводит устройство в спящий режим с помощью API WinForms.
+
+Примечание: из-за «Modern Sleep» команды перехода в спящий режим могут работать по-разному в зависимости от производителя устройства и конфигурации ОС.
+
+
+ WinformsSleep
+
+
+ Не удалось подключиться.
+
+
+ Соединение в порядке!
+
+
+ Переводит все мониторы в спящий режим (режим пониженного энергопотребления), используя альтернативный подход к изменению схемы управления питанием.
+Это должно обеспечить лучшую работу на новых системах с «современным спящим режимом S0ix» и предотвратить переход системы в спящий режим.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.sl.resx b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.sl.resx
index 7d39b632..deda2f87 100644
--- a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.sl.resx
+++ b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.sl.resx
@@ -245,11 +245,12 @@ Vaš ukaz je podan kot argument 'tako kot je', zato morate po potrebi navesti sv
Simulira en sam pritisk tipke.
+Če ta ukaz nastavite na »stikalo«, bo gumb pritisnjen, dokler je stikalo vklopljeno.
-Kliknite besedilno polje 'keycode' in pritisnite tipko, ki jo želite simulirati. Vnesena bo ustrezna koda tipke.
+Kliknite na besedilno polje »koda tipke« in pritisnite tipko, ki jo želite simulirati. Ustrezna koda tipke bo vnesena samodejno.
Za tipko TAB uporabite LCTRL+TAB.
-Če potrebujete več tipk in/ali modifikatorjev, kot je CTRL, uporabite ukaz MultipleKeys.
+Če potrebujete več tipk in/ali modifikatorjev, kot je CTRL, uporabite ukaz Več tipk.
Fuzzy
@@ -1791,7 +1792,8 @@ Hvala, ker uporabljate HASS.Agent. Upam, da vam bo koristil :-)
Fuzzy
- Razvoj in vzdrževanje tega dodatka (in vsega, kar spada zraven, kot je podpora, navodila) vzame veliko časa. Kot večina razvijalcev tudi jaz delam na kofein - zato bi bil zelo hvaležen kake skodelice kave, če jo lahko pogrešate!
+ Trenutno (ekipa HASS.Agent, ki vzdržuje forum) ne sprejema donacij v nobeni obliki :)
+Vendar pa lahko brez zadržkov donirate izvirnemu avtorju HASS.Agent - Samu! Kjerkoli že je, mu lahko skodelica kave polepša dan.
Namig: ostale možnosti donacij so na voljo v zavihku "Vizitka".
@@ -2295,7 +2297,10 @@ Glede na verzijo Windows-ov se to lahko nahaja v Nadzorna plošča --> Sistem
Zagotavlja trenutno obremenitev prvega GPU-ja v odstotkih.
- Zagotavlja trenutno temperaturo prvega GPU-ja.
+ OPOMBA: To je nedelujoč senzor.
+
+Zaradi varnostnih pomislekov glede Libre Hardware Monitor (knjižnica, ki omogoča HASS.Agent dostop do podatkov o temperaturi GPU) je ta senzor ostal zaradi združljivosti s prejšnjimi različicami in bo vedno vrnil vrednost 0.
+Za alternativne možnosti glejte dokumentacijo.
Zagotavlja vrednost datuma in časa, ki vsebuje čas zadnjega vnosa uporabnika.
@@ -3556,4 +3561,50 @@ Zahteva, da je konfiguriran v "Konfiguracija -> Ikona pladnja"
Odpusti
+
+ Zaslon, ki se uporabi za prikaz WebView
+
+
+ Neuspešno preverjanje posodobitve!
+
+
+ PoimenovanoAktivnoOkno
+
+
+ Zagotavlja vrednost VKLOP/IZKLOP glede na to, ali ime okna v fokusu vsebuje konfiguriran niz.
+
+
+ Zagotavlja barvne vrednosti #RRGGBB za sistemske poudarjene barve.
+Glavna poudarjena barva je vrednost senzorja, dodatne poudarjene barve so na voljo kot atributi.
+
+
+ Uporabi &WebSocket
+
+
+ Uporabi &WebSocket
+
+
+ Ventilator
+
+
+ Preklopi računalnik v stanje mirovanja z uporabo WinForms API-ja.
+
+Opomba: Zaradi »modernega mirovanja« se lahko ukazi za mirovanje obnašajo drugače, odvisno od proizvajalca originalne opreme naprave in konfiguracije operacijskega sistema.
+
+
+ WinformsSleep
+
+
+ Povezave ni mogoče vzpostaviti.
+
+
+ Povezava v redu!
+
+
+ Preklopi vse monitorje v način mirovanja (nizka poraba energije) z uporabo alternativnega pristopa k spreminjanju načrta porabe energije.
+Omogoča boljšo izkušnjo z novimi sistemi s »sodobnim načinom mirovanja S0ix« in ne preklopi sistema v stanje mirovanja.
+
+
+ MonitorSleepPowerPlan
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.tr.resx b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.tr.resx
index 3f40e569..7edeaab9 100644
--- a/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.tr.resx
+++ b/src/HASS.Agent/HASS.Agent/Resources/Localization/Languages.tr.resx
@@ -1182,12 +1182,13 @@ Ancak bu aracı beğendiyseniz orijinal (LAB02 Araştırması) geliştiricilere
Makineyi hazırda bekletme moduna geçirir.
- Tek bir tuşa basmayı simüle eder.
+ Tek bir tuş basımını simüle eder.
+Bu komutu "anahtar" türü yapmak, anahtar açık olduğu sürece düğmenin basılı kalmasını sağlar.
-'Keycode' metin kutusuna tıklayın ve simüle edilmesini istediğiniz tuşa basın. İlgili anahtar kodu sizin için girilecektir.
-TAB tuşu için lütfen LCTRL+TAB kullanın.
+'Tuş kodu' metin kutusuna tıklayın ve simüle edilmesini istediğiniz tuşa basın. İlgili tuş kodu sizin için girilecektir.
+TAB tuşu için lütfen LCTRL+TAB tuşlarını kullanın.
-Daha fazla tuşa ve/veya CTRL gibi değiştiricilere ihtiyacınız varsa, MultipleKeys komutunu kullanın.
+CTRL gibi daha fazla tuşa ve/veya değiştiriciye ihtiyacınız varsa, MultipleKeys komutunu kullanın.
Varsayılan tarayıcınızda varsayılan olarak sağlanan URL'yi başlatır. 'Gizli' kullanmak için Yapılandırma -> Harici Araçlar'da belirli bir tarayıcı sağlayın. Yalnızca belirli bir URL'ye sahip bir pencere istiyorsanız (tam bir tarayıcı değil), bir 'WebView' komutu kullanın.
@@ -1854,7 +1855,10 @@ Daha fazla tuşa ve/veya CTRL gibi değiştiricilere ihtiyacınız varsa, Multip
Yüzde olarak ilk GPU'nun mevcut yükünü sağlar.
- İlk GPU'nun mevcut sıcaklığını sağlar.
+ NOT: Bu, çalışmayan bir sensördür.
+
+Libre Donanım İzleyicisi (HASS.Agent'ın GPU sıcaklık verilerine erişmesine izin veren kütüphane) ile ilgili güvenlik endişeleri nedeniyle, bu sensör geriye dönük uyumluluk nedeniyle bırakılmıştır ve her zaman 0 döndürecektir.
+Alternatif seçenekler için lütfen belgelere bakın.
Kullanıcının en son ne zaman giriş yaptığını içeren bir tarih saat değeri sağlar.
@@ -2738,7 +2742,8 @@ Daha fazla tuşa ve/veya CTRL gibi değiştiricilere ihtiyacınız varsa, Multip
Sağladığınız URI geçerli görünmüyor, geçerli bir URI aşağıdakilerden biri gibi görünebilir: - http://homeassistant.local:8123 - http://192.168.0.1:8123 Kullanmak istediğinizden emin misiniz? yine de bu URI?
- Bu aracı (ve onu çevreleyen her şeyi) geliştirmek ve sürdürmek çok zaman alır. Çoğu geliştirici gibi, ben de kafein kullanıyorum - bu yüzden eğer onu ayırabilirseniz, bir fincan kahve her zaman çok değerlidir!
+ Şu anda (çatalın bakımını üstlenen HASS.Agent Ekibi) hiçbir şekilde bağış kabul etmiyoruz :)
+Ancak lütfen HASS.Agent'ın orijinal yazarı Sam'e bağış yapmaktan çekinmeyin! Şu anda nerede olurlarsa olsunlar, bir fincan kahve günlerini güzelleştirebilir.
İpucu: Hakkında Penceresinde başka bağış yöntemleri de mevcuttur.
@@ -3023,4 +3028,50 @@ Not: Uydu hizmetinde kullanılırsa kullanıcı alanı uygulamalarını algılam
Azletmek
+
+ WebView'in göstermesi için kullanılacak ekran
+
+
+ Güncelleme kontrolü başarısız oldu!
+
+
+ AdlandırılmışAktifPencere
+
+
+ Odaklanan pencere adının yapılandırılmış dizeyi içerip içermediğine bağlı olarak bir AÇIK/KAPALI değeri sağlar.
+
+
+ Sistem vurgu renkleri için #RRGGBB renk değerleri sağlar.
+Ana vurgu rengi sensör değeridir, ek vurgu renkleri öznitelikler olarak mevcuttur.
+
+
+ &WebSocket'i kullanın
+
+
+ &WebSocket'i kullanın
+
+
+ Fan
+
+
+ WinForms API'sini kullanarak makineyi uyku moduna geçirir.
+
+Not: "Modern Uyku" nedeniyle uyku komutları, cihazın OEM ve işletim sistemi yapılandırmasına bağlı olarak farklı davranabilir.
+
+
+ WinformsSleep
+
+
+ Bağlantı kurulamıyor.
+
+
+ Bağlantı Tamam!
+
+
+ Güç planı değişikliği gibi alternatif bir yaklaşım kullanarak tüm monitörleri uyku moduna (düşük güç) alır.
+"Modern S0ix uyku" özelliğine sahip yeni sistemlerde daha iyi bir deneyim sağlamalı ve sistemi uyku moduna almamalıdır.
+
+
+ MonitörUykuGüçPlanı
+
\ No newline at end of file
diff --git a/src/HASS.Agent/HASS.Agent/Sensors/SensorsManager.cs b/src/HASS.Agent/HASS.Agent/Sensors/SensorsManager.cs
index dd5546d9..1a62e301 100644
--- a/src/HASS.Agent/HASS.Agent/Sensors/SensorsManager.cs
+++ b/src/HASS.Agent/HASS.Agent/Sensors/SensorsManager.cs
@@ -66,11 +66,46 @@ internal static async void Initialize()
/// Unpublishes all single- and multivalue sensors
///
///
- internal static async Task UnpublishAllSensors()
+ internal static async Task UnpublishAllSensors(bool migration = false)
{
- // unpublish the autodisco's
- if (SingleValueSensorsPresent()) foreach (var sensor in Variables.SingleValueSensors) await sensor.UnPublishAutoDiscoveryConfigAsync();
- if (MultiValueSensorsPresent()) foreach (var sensor in Variables.MultiValueSensors) await sensor.UnPublishAutoDiscoveryConfigAsync();
+ if (SingleValueSensorsPresent())
+ {
+ foreach (var sensor in Variables.SingleValueSensors)
+ {
+ await sensor.UnPublishAutoDiscoveryConfigAsync(migration);
+ }
+ }
+ if (MultiValueSensorsPresent())
+ {
+ foreach (var sensor in Variables.MultiValueSensors)
+ {
+ await sensor.UnPublishAutoDiscoveryConfigAsync(migration);
+ }
+ }
+
+ _discoveryPublished = false;
+ }
+
+ ///
+ /// Publishes all single- and multivalue sensors
+ ///
+ ///
+ internal static async Task ForcePublishAllSensors()
+ {
+ if (SingleValueSensorsPresent())
+ {
+ foreach (var sensor in Variables.SingleValueSensors)
+ {
+ await sensor.PublishAutoDiscoveryConfigAsync();
+ }
+ }
+ if (MultiValueSensorsPresent())
+ {
+ foreach (var sensor in Variables.MultiValueSensors)
+ {
+ await sensor.PublishAutoDiscoveryConfigAsync();
+ }
+ }
}
///
@@ -390,6 +425,14 @@ internal static void LoadSensorInfo()
// =================================
+ sensorInfoCard = new SensorInfoCard(SensorType.AccentColorSensor,
+ Languages.SensorsManager_AccentColorSensorDescription,
+ 120, false, true, false);
+
+ SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard);
+
+ // =================================
+
sensorInfoCard = new SensorInfoCard(SensorType.AudioSensors,
Languages.SensorsManager_AudioSensorsDescription,
20, true, true, true);
@@ -486,6 +529,14 @@ internal static void LoadSensorInfo()
// =================================
+ sensorInfoCard = new SensorInfoCard(SensorType.InternalDeviceSensor,
+ Languages.SensorsManager_InternalDeviceSensorDescription,
+ 10, false, true, false);
+
+ SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard);
+
+ // =================================
+
sensorInfoCard = new SensorInfoCard(SensorType.LastActiveSensor,
Languages.SensorsManager_LastActiveSensorDescription,
10, false, true, false);
@@ -566,6 +617,14 @@ internal static void LoadSensorInfo()
// =================================
+ sensorInfoCard = new SensorInfoCard(SensorType.NamedActiveWindowSensor,
+ Languages.SensorsManager_NamedActiveWindowSensorDescription,
+ 30, false, true, false);
+
+ SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard);
+
+ // =================================
+
sensorInfoCard = new SensorInfoCard(SensorType.NetworkSensors,
Languages.SensorsManager_NetworkSensorsDescription,
30, true, true, true);
@@ -606,6 +665,14 @@ internal static void LoadSensorInfo()
// =================================
+ sensorInfoCard = new SensorInfoCard(SensorType.ScreenshotSensor,
+ Languages.SensorsManager_ScreenshotSensorDescription,
+ 10, false, true, false);
+
+ SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard);
+
+ // =================================
+
sensorInfoCard = new SensorInfoCard(SensorType.ServiceStateSensor,
Languages.SensorsManager_ServiceStateSensorDescription,
10, false, true, true);
@@ -677,22 +744,6 @@ internal static void LoadSensorInfo()
SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard);
// =================================
-
- sensorInfoCard = new SensorInfoCard(SensorType.InternalDeviceSensor,
- Languages.SensorsManager_InternalDeviceSensorDescription,
- 10, false, true, false);
-
- SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard);
-
- // =================================
-
- sensorInfoCard = new SensorInfoCard(SensorType.ScreenshotSensor,
- Languages.SensorsManager_ScreenshotSensorDescription,
- 10, false, true, false);
-
- SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard);
-
- // =================================
}
}
}
diff --git a/src/HASS.Agent/HASS.Agent/Service/Protos/hassagentsatellite.proto b/src/HASS.Agent/HASS.Agent/Service/Protos/hassagentsatellite.proto
index a21c9157..f261aa30 100644
--- a/src/HASS.Agent/HASS.Agent/Service/Protos/hassagentsatellite.proto
+++ b/src/HASS.Agent/HASS.Agent/Service/Protos/hassagentsatellite.proto
@@ -120,6 +120,7 @@ message RpcServiceMqttSettings {
string mqttRootCertificate = 9;
string mqttClientCertificate = 10;
string mqttClientId = 11;
+ bool mqttUseWebSocket = 12;
}
message RpcConfiguredServerSensor {
diff --git a/src/HASS.Agent/HASS.Agent/Settings/SettingsManager.cs b/src/HASS.Agent/HASS.Agent/Settings/SettingsManager.cs
index 01c525ac..546f2c31 100644
--- a/src/HASS.Agent/HASS.Agent/Settings/SettingsManager.cs
+++ b/src/HASS.Agent/HASS.Agent/Settings/SettingsManager.cs
@@ -14,7 +14,6 @@
using Newtonsoft.Json;
using Serilog;
using Syncfusion.Windows.Forms;
-using WK.Libraries.HotkeyListenerNS;
namespace HASS.Agent.Settings
{
@@ -139,7 +138,7 @@ private static bool LoadAppSettings()
AgentSharedBase.SetCustomExecutorBinary(Variables.AppSettings.CustomExecutorBinary);
// load the hotkey
- Variables.QuickActionsHotKey = string.IsNullOrEmpty(Variables.AppSettings.QuickActionsHotKey) ? null : HotkeyListener.Convert(Variables.AppSettings.QuickActionsHotKey);
+ Variables.QuickActionsHotKey = string.IsNullOrWhiteSpace(Variables.AppSettings.QuickActionsHotKey) ? string.Empty : Variables.AppSettings.QuickActionsHotKey;
// done
Log.Information("[SETTINGS] Configuration loaded");
diff --git a/src/HASS.Agent/HASS.Agent/Settings/StoredCommands.cs b/src/HASS.Agent/HASS.Agent/Settings/StoredCommands.cs
index 15305e16..1bb2cc7e 100644
--- a/src/HASS.Agent/HASS.Agent/Settings/StoredCommands.cs
+++ b/src/HASS.Agent/HASS.Agent/Settings/StoredCommands.cs
@@ -106,6 +106,9 @@ internal static AbstractCommand ConvertConfiguredToAbstract(ConfiguredCommand co
case CommandType.SleepCommand:
abstractCommand = new SleepCommand(command.EntityName, command.Name, command.EntityType, command.Id.ToString());
break;
+ case CommandType.WinformsSleepCommand:
+ abstractCommand = new WinformsSleepCommand(command.EntityName, command.Name, command.EntityType, command.Id.ToString());
+ break;
case CommandType.LogOffCommand:
abstractCommand = new LogOffCommand(command.EntityName, command.Name, command.EntityType, command.Id.ToString());
break;
@@ -166,6 +169,9 @@ internal static AbstractCommand ConvertConfiguredToAbstract(ConfiguredCommand co
case CommandType.MonitorSleepCommand:
abstractCommand = new MonitorSleepCommand(command.EntityName, command.Name, command.EntityType, command.Id.ToString());
break;
+ case CommandType.MonitorSleepPowerPlanCommand:
+ abstractCommand = new MonitorSleepPowerPlanCommand(command.EntityName, command.Name, command.EntityType, command.Id.ToString());
+ break;
case CommandType.MonitorWakeCommand:
abstractCommand = new MonitorWakeCommand(command.EntityName, command.Name, command.EntityType, command.Id.ToString());
break;
diff --git a/src/HASS.Agent/HASS.Agent/Settings/StoredSensors.cs b/src/HASS.Agent/HASS.Agent/Settings/StoredSensors.cs
index ca701c83..a8db9bef 100644
--- a/src/HASS.Agent/HASS.Agent/Settings/StoredSensors.cs
+++ b/src/HASS.Agent/HASS.Agent/Settings/StoredSensors.cs
@@ -14,7 +14,6 @@
using HASS.Agent.Shared.HomeAssistant.Sensors.WmiSensors.SingleValue;
using HASS.Agent.Shared.Models.Config;
using HASS.Agent.Shared.Models.HomeAssistant;
-using LibreHardwareMonitor.Hardware;
using Newtonsoft.Json;
using Serilog;
using SensorType = HASS.Agent.Shared.Enums.SensorType;
@@ -124,9 +123,15 @@ internal static AbstractSingleValueSensor ConvertConfiguredToAbstractSingleValue
case SensorType.ActiveDesktopSensor:
abstractSensor = new ActiveDesktopSensor(sensor.UpdateInterval, sensor.EntityName, sensor.Name, sensor.Id.ToString(), sensor.AdvancedSettings);
break;
+ case SensorType.AccentColorSensor:
+ abstractSensor = new AccentColorSensor(sensor.UpdateInterval, sensor.EntityName, sensor.Name, sensor.Id.ToString(), sensor.AdvancedSettings);
+ break;
case SensorType.NamedWindowSensor:
abstractSensor = new NamedWindowSensor(sensor.WindowName, sensor.EntityName, sensor.Name, sensor.UpdateInterval, sensor.Id.ToString(), sensor.AdvancedSettings);
break;
+ case SensorType.NamedActiveWindowSensor:
+ abstractSensor = new NamedActiveWindowSensor(sensor.WindowName, sensor.EntityName, sensor.Name, sensor.UpdateInterval, sensor.Id.ToString(), sensor.AdvancedSettings);
+ break;
case SensorType.LastActiveSensor:
abstractSensor = new LastActiveSensor(sensor.ApplyRounding, sensor.Round, sensor.UpdateInterval, sensor.EntityName, sensor.Name, sensor.Id.ToString(), sensor.AdvancedSettings);
break;
@@ -299,6 +304,22 @@ internal static ConfiguredSensor ConvertAbstractSingleValueToConfigured(Abstract
};
}
+ case NamedActiveWindowSensor namedActiveWindowSensor:
+ {
+ _ = Enum.TryParse(namedActiveWindowSensor.GetType().Name, out var type);
+ return new ConfiguredSensor
+ {
+ Id = Guid.Parse(namedActiveWindowSensor.Id),
+ EntityName = namedActiveWindowSensor.EntityName,
+ Name = namedActiveWindowSensor.Name,
+ Type = type,
+ UpdateInterval = namedActiveWindowSensor.UpdateIntervalSeconds,
+ IgnoreAvailability = namedActiveWindowSensor.IgnoreAvailability,
+ WindowName = namedActiveWindowSensor.WindowName,
+ AdvancedSettings = namedActiveWindowSensor.AdvancedSettings
+ };
+ }
+
case PerformanceCounterSensor performanceCounterSensor:
{
_ = Enum.TryParse(performanceCounterSensor.GetType().Name, out var type);
diff --git a/src/HASS.Agent/HASS.Agent/Variables.cs b/src/HASS.Agent/HASS.Agent/Variables.cs
index c8f67547..e38a904d 100644
--- a/src/HASS.Agent/HASS.Agent/Variables.cs
+++ b/src/HASS.Agent/HASS.Agent/Variables.cs
@@ -1,5 +1,4 @@
-extern alias WV2;
-using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Net.Http;
@@ -7,23 +6,19 @@
using Windows.Media.Playback;
using Grapevine;
using HASS.Agent.Forms;
-using HASS.Agent.Functions;
using HASS.Agent.Managers;
using HASS.Agent.Models.Config;
using HASS.Agent.Models.Internal;
using HASS.Agent.MQTT;
using HASS.Agent.Service;
using HASS.Agent.Settings;
-using HASS.Agent.Shared.HomeAssistant;
-using HASS.Agent.Shared.HomeAssistant.Commands;
-using HASS.Agent.Shared.HomeAssistant.Sensors;
using HASS.Agent.Shared.Models.HomeAssistant;
using HASS.Agent.Shared.Mqtt;
-using WV2::Microsoft.Web.WebView2.Core;
using Microsoft.Win32;
using MQTTnet;
-using WK.Libraries.HotkeyListenerNS;
using Serilog.Core;
+using Microsoft.Web.WebView2.Core;
+using NHotkey.WindowsForms;
namespace HASS.Agent
{
@@ -56,9 +51,9 @@ public static class Variables
///
internal static Main MainForm { get; set; }
internal static HttpClient HttpClient { get; set; } = new();
- internal static Hotkey QuickActionsHotKey { get; set; } = new(Keys.Control | Keys.Alt, Keys.Q);
- internal static HotKeyManager HotKeyManager { get; } = new();
- internal static HotkeyListener HotKeyListener { get; set; }
+ internal static string QuickActionsHotKey { get; set; } = "Control, Alt + Q";
+ internal static InternalHotKeyManager InternalHotKeyManager { get; } = new();
+ internal static HotkeyManager HotKeyListener { get; set; }
internal static Random Rnd { get; } = new();
internal static Font DefaultFont { get; } = new("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point);
internal static WebView TrayIconWebView { get; set; } = null;