Skip to content

Commit

Permalink
Update plugin 0.0.8
Browse files Browse the repository at this point in the history
  • Loading branch information
66Bunz committed Apr 30, 2024
1 parent d2632c1 commit e035c38
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 44 deletions.
Binary file modified Bluetooth-Example-Skin/Example.ini
Binary file not shown.
14 changes: 10 additions & 4 deletions Bluetooth-Example-Skin/Example.lua
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,13 @@ function _Populate(PageDevice1, PageDevice2)
local Device1Remembered = Device1[4]
SKIN:Bang("!SetVariable", "Device1Remembered", Device1Remembered)
SKIN:Bang("!WriteKeyValue", "Variables", "Device1Remembered", string.format('%s', Device1Remembered), "Example.ini")
local Device1LastSeen = Device1[5]
local Device1Address = Device1[5]
SKIN:Bang("!SetVariable", "Device1Address", Device1Address)
SKIN:Bang("!WriteKeyValue", "Variables", "Device1Address", string.format('%s', Device1Address), "Example.ini")
local Device1LastSeen = Device1[6]
SKIN:Bang("!SetVariable", "Device1LastSeen", Device1LastSeen)
SKIN:Bang("!WriteKeyValue", "Variables", "Device1LastSeen", string.format('%s', Device1LastSeen), "Example.ini")
local Device1LastUsed = Device1[6]
local Device1LastUsed = Device1[7]
SKIN:Bang("!SetVariable", "Device1LastUsed", Device1LastUsed)
SKIN:Bang("!WriteKeyValue", "Variables", "Device1LastUsed", string.format('%s', Device1LastUsed), "Example.ini")

Expand All @@ -109,10 +112,13 @@ function _Populate(PageDevice1, PageDevice2)
local Device2Remembered = Device2[4]
SKIN:Bang("!SetVariable", "Device2Remembered", Device2Remembered)
SKIN:Bang("!WriteKeyValue", "Variables", "Device2Remembered", string.format('%s', Device2Remembered), "Example.ini")
local Device2LastSeen = Device2[5]
local Device2Address = Device2[5]
SKIN:Bang("!SetVariable", "Device2Address", Device2Address)
SKIN:Bang("!WriteKeyValue", "Variables", "Device2Address", string.format('%s', Device2Address), "Example.ini")
local Device2LastSeen = Device2[6]
SKIN:Bang("!SetVariable", "Device2LastSeen", Device2LastSeen)
SKIN:Bang("!WriteKeyValue", "Variables", "Device2LastSeen", string.format('%s', Device2LastSeen), "Example.ini")
local Device2LastUsed = Device2[6]
local Device2LastUsed = Device2[7]
SKIN:Bang("!SetVariable", "Device2LastUsed", Device2LastUsed)
SKIN:Bang("!WriteKeyValue", "Variables", "Device2LastUsed", string.format('%s', Device2LastUsed), "Example.ini")
end
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Else, you can download the zip package from the latest [release](https://github.

### Requirements

_TODO_

<!-- TODO: add requirements -->

## Documentation
Expand All @@ -25,7 +27,7 @@ The plugin at every update, is going to scan for Bluetooth devices, and update t
The formatted string is going to be in the following format:

```plaintext
device_name|connected[0,1]|Authenticated[0,1]|Remembered[0,1]|datetime_last_seen|datetime_last_used;
device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|address|datetime_last_seen|datetime_last_used;
```

This is an example of how you can use the plugin in a skin:
Expand All @@ -47,7 +49,7 @@ UpdateDivider=-1
function Refresh()
local DevicesString = SKIN:ReplaceVariables('[&BluetoothMeasure:AvailableDevices()]')
-- DevicesString = Formatted string of all devices
-- ("device_name|connected[0,1]|Authenticated[0,1]|Remembered[0,1]|datetime_last_seen|datetime_last_used;")
-- ("device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|address|datetime_last_seen|datetime_last_used;")

-- Do something with the devices list
-- See example skin for an example
Expand Down
6 changes: 3 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The plugin at every update, is going to scan for Bluetooth devices, and update t
The formatted string is going to be in the following format:

```plaintext
device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|datetime_last_seen|datetime_last_used;
device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|address|datetime_last_seen|datetime_last_used;
```

This is an example of how you can use the plugin in a skin:
Expand All @@ -34,7 +34,7 @@ This is an example of how you can use the plugin in a skin:
[Bluetooth]
Measure=Plugin
Plugin=Bluetooth
UpdateDivider=10 ; Keep a relatively high value, to avoid spamming the plugin with update requests that cannot terminate
UpdateDivider=20 ; Keep a relatively high value, to avoid spamming the plugin with update requests that cannot terminate
DevicesUpdatedAction=[!CommandMeasure LuaScript "Refresh()"]

[LuaScript]
Expand All @@ -47,7 +47,7 @@ UpdateDivider=-1
function Refresh()
local DevicesString = SKIN:ReplaceVariables('[&BluetoothMeasure:AvailableDevices()]')
-- DevicesString = Formatted string of all devices
-- ("device_name|connected[0,1]|Authenticated[0,1]|Remembered[0,1]|datetime_last_seen|datetime_last_used;")
-- ("device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|address|datetime_last_seen|datetime_last_used;")

-- Do something with the devices list
-- See example skin for an example
Expand Down
4 changes: 2 additions & 2 deletions docs/bangs.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Available if the [#type](options.md#type "mention") is set to `1` or `0`.
Disables the Bluetooth adapter.

{% hint style="warning" %}
Available if the [#type](options.md#type "mention") is set to `2` or `0`.
Available if the [#type](options.md#type "mention") is set to `1` or `0`.
{% endhint %}

{% code title="Example Bang" %}
Expand All @@ -37,7 +37,7 @@ Available if the [#type](options.md#type "mention") is set to `2` or `0`.
Enables the Bluetooth adapter.

{% hint style="warning" %}
Available if the [#type](options.md#type "mention") is set to `2` or `0`.
Available if the [#type](options.md#type "mention") is set to `1` or `0`.
{% endhint %}

{% code title="Example Bang" %}
Expand Down
6 changes: 3 additions & 3 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ The file will have this structure:

{% code title="@Resources/output.txt" lineNumbers="true" fullWidth="false" %}
```
device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|datetime_last_seen|datetime_last_used;
device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|datetime_last_seen|datetime_last_used;
device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|address|datetime_last_seen|datetime_last_used;
device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|address|datetime_last_seen|datetime_last_used;
...
```
{% endcode %}
Expand Down Expand Up @@ -117,7 +117,7 @@ The name of the file that contains the [#devicesvariable](options.md#devicesvari
{% code title="Example" lineNumbers="true" %}
```ini
[Variables]
Variable1=device_name|connected[0,1]|Authenticated[0,1]|Remembered[0,1]|datetime_last_seen|datetime_last_used;...
Variable1=device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|address|datetime_last_seen|datetime_last_used;...

[BluetoothMeasure]
Measure=Plugin
Expand Down
2 changes: 1 addition & 1 deletion docs/section-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: Possible section variables that can be used

Returns the list of devices in a string.

`device_name|connected[0,1]|Authenticated[0,1]|Remembered[0,1]|datetime_last_seen|datetime_last_used;`
`device_name|connected[0,1]|authenticated[0,1]|remembered[0,1]|address|datetime_last_seen|datetime_last_used;`

Every device is separated by `;`, and evey item of a device is separated by `|`.

Expand Down
4 changes: 2 additions & 2 deletions src/BluetoothPlugin.rc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//

VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,0,7,0
FILEVERSION 0,0,8,0
PRODUCTVERSION 3,0,2,2161
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
Expand All @@ -26,7 +26,7 @@ BEGIN
BEGIN
VALUE "CompanyName", "bunz"
VALUE "FileDescription", "Bluetooth plugin for Rainmeter"
VALUE "FileVersion", "0.0.7.0"
VALUE "FileVersion", "0.0.8.0"
VALUE "InternalName", "Bluetooth Plugin"
VALUE "LegalCopyright", "© 2024 - Bunz"
VALUE "OriginalFilename", "Bluetooth.dll"
Expand Down
88 changes: 61 additions & 27 deletions src/Plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Devices.Radios.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <set>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>

using namespace std;
Expand All @@ -30,6 +30,9 @@ static wstring availableDevices; // Formatted string of all devices ("device_nam
static wstring devicesBuffer; // Buffer to save devices during list updates to avoid getting back partial lists
static string fileBufferString; // Buffer to save devices during file updates to avoid having an empty file between updates
static wstring bluetoothStatus; // String to hold the status of the Bluetooth adapter
static std::mutex bufferMutex;

std::thread updateThread;

#pragma endregion

Expand All @@ -46,7 +49,7 @@ BOOL WINAPI DllMain(
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
MODULE_INSTANCE = hinstDLL;
//DisableThreadLibraryCalls(hinstDLL); // disable thread library calls, for performance improvement
DisableThreadLibraryCalls(hinstDLL); // disable thread library calls, for performance improvement
default:
break;
}
Expand Down Expand Up @@ -123,52 +126,62 @@ PLUGIN_EXPORT double Update(void* data) {
PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) {
Measure* measure = (Measure*)data;
if (measure->pluginType == 2) {
if (_wcsicmp(args, L"UpdateDevices") == 0) {
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Updating devices");
updateDevices(measure);
}
else {
RmLogF(measure->rm, LOG_ERROR, L"[Bluetooth-Plugin] Invalid bang: %s for selected Plugin Type %s", args, measure->pluginType);
}
}
else if (measure->pluginType == 1) {
if (_wcsicmp(args, L"DisableBluetooth") == 0) {
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Disabling Bluetooth adapter");
disableBluetooth(measure);
}
else if (_wcsicmp(args, L"EnableBluetooth") == 0) {
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Enabling Bluetooth adapter");
enableBluetooth(measure);
}
else if (_wcsicmp(args, L"ToggleBluetooth") == 0) {
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Toggling Bluetooth adapter");
toggleBluetooth(measure);
}
else if (_wcsicmp(args, L"UpdateDevices") == 0) {
updateDevices(measure);
}
else {
RmLogF(measure->rm, LOG_ERROR, L"[Bluetooth-Plugin] Invalid bang: %s for selected plugin Type %s", args, measure->pluginType);
}
}
else if (measure->pluginType == 1) {
if (_wcsicmp(args, L"UpdateBluetoothStatus") == 0) {
else if (_wcsicmp(args, L"UpdateBluetoothStatus") == 0) {
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Updating Bluetooth status");
updateBluetoothStatus(measure);
}
else {
RmLogF(measure->rm, LOG_ERROR, L"[Bluetooth-Plugin] Invalid bang: %s for selected plugin Type %s", args, measure->pluginType);
RmLogF(measure->rm, LOG_ERROR, L"[Bluetooth-Plugin] Invalid bang: %s for selected Plugin Type %s", args, measure->pluginType);
}
}
else if (measure->pluginType == 0) {
if (_wcsicmp(args, L"DisableBluetooth") == 0) {
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Disabling Bluetooth adapter");
disableBluetooth(measure);
}
else if (_wcsicmp(args, L"EnableBluetooth") == 0) {
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Enabling Bluetooth adapter");
enableBluetooth(measure);
}
else if (_wcsicmp(args, L"ToggleBluetooth") == 0) {
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Toggling Bluetooth adapter");
toggleBluetooth(measure);
}
else if (_wcsicmp(args, L"UpdateDevices") == 0) {
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Updating devices");
updateDevices(measure);
}
else if (_wcsicmp(args, L"UpdateBluetoothStatus") == 0) {
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Updating Bluetooth status");
updateBluetoothStatus(measure);
}
else {
RmLogF(measure->rm, LOG_ERROR, L"[Bluetooth-Plugin] Invalid bang: %s", args);
}
}
else {
RmLogF(measure->rm, LOG_ERROR, L"[Bluetooth-Plugin] Invalid PluginType");
RmLogF(measure->rm, LOG_ERROR, L"[Bluetooth-Plugin] Invalid Plugin Type");
}
}

Expand All @@ -178,9 +191,15 @@ PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) {
*/
PLUGIN_EXPORT void Finalize(void* data) {
Measure* measure = (Measure*)data;

RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Unloading");

// Clean up resources
delete measure;
availableDevices.clear();
devicesBuffer.clear();
fileBufferString.clear();
bluetoothStatus.clear();
}

#pragma endregion
Expand All @@ -196,7 +215,6 @@ PLUGIN_EXPORT LPCWSTR AvailableDevices(void* data, const int argc, WCHAR* argv[]
return availableDevices.c_str();
}


/*
* Can be called as a section variable, to get the status of the Bluetooth adapter
*/
Expand Down Expand Up @@ -242,20 +260,27 @@ void updateBluetoothStatus(Measure* measure) {
* - if the device is connected
* - if the device is authenticated
* - if the device is remembered
* - the device address
* - when the device was last seen
* - when the device was last used
*/
void updateDevices(Measure* measure) {
std::thread updateThread([measure]() {
updateThread = std::thread([measure]() {
if (!bufferMutex.try_lock()) {
RmLogF(measure->rm, LOG_ERROR, L"Another thread is already updating the devices");
return;
}

devicesBuffer.clear();
fileBufferString.clear();
set<ULONGLONG> deviceAddresses; // To store unique device addresses
set<wstring> deviceNames; // To store unique device names

HANDLE hRadio;
BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) };
HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio(&btfrp, &hRadio);

if (hFind != NULL) {
if (hFind != nullptr) {
do {
BLUETOOTH_RADIO_INFO radioInfo = { sizeof(BLUETOOTH_RADIO_INFO) };
DWORD dwResult = BluetoothGetRadioInfo(hRadio, &radioInfo);
Expand All @@ -271,21 +296,26 @@ void updateDevices(Measure* measure) {
deviceSearchParams.hRadio = hRadio;

HBLUETOOTH_DEVICE_FIND hDeviceFind = BluetoothFindFirstDevice(&deviceSearchParams, &deviceInfo);
if (hDeviceFind != NULL) {
if (hDeviceFind != nullptr) {
do {
if (deviceInfo.szName && deviceInfo.stLastUsed.wYear != 1601) { // Check to remove ghost devices
if (deviceInfo.szName && deviceInfo.stLastUsed.wYear != 1601 && deviceAddresses.find(deviceInfo.Address.ullLong) == deviceAddresses.end() && deviceNames.find(deviceInfo.szName) == deviceNames.end()) { // Check to remove ghost devices and duplicate addresses
deviceAddresses.insert(deviceInfo.Address.ullLong); // Add the device address to the set
deviceNames.emplace(deviceInfo.szName); // Add the device name to the set

wstring wDeviceName(deviceInfo.szName);
wstring wDeviceConnected = to_wstring((deviceInfo.fConnected ? 1 : 0));
wstring wDeviceAuthenticated = to_wstring((deviceInfo.fAuthenticated ? 1 : 0));
wstring wDeviceRemembered = to_wstring((deviceInfo.fRemembered ? 1 : 0));
wstring wDeviceConnected = to_wstring(deviceInfo.fConnected ? 1 : 0);
wstring wDeviceAuthenticated = to_wstring(deviceInfo.fAuthenticated ? 1 : 0);
wstring wDeviceRemembered = to_wstring(deviceInfo.fRemembered ? 1 : 0);
wstring wDeviceAddress = to_wstring(deviceInfo.Address.ullLong);
wstring wDeviceLastSeen = to_wstring(deviceInfo.stLastSeen.wMonth) + L"/" + to_wstring(deviceInfo.stLastSeen.wDay) + L"/" + to_wstring(deviceInfo.stLastSeen.wYear) + L" " + to_wstring(deviceInfo.stLastSeen.wHour) + L":" + to_wstring(deviceInfo.stLastSeen.wMinute) + L":" + to_wstring(deviceInfo.stLastSeen.wSecond);
wstring wDeviceLastUsed = to_wstring(deviceInfo.stLastUsed.wMonth) + L"/" + to_wstring(deviceInfo.stLastUsed.wDay) + L"/" + to_wstring(deviceInfo.stLastUsed.wYear) + L" " + to_wstring(deviceInfo.stLastUsed.wHour) + L":" + to_wstring(deviceInfo.stLastUsed.wMinute) + L":" + to_wstring(deviceInfo.stLastUsed.wSecond);
wstring wDivider = L"|";

string deviceName(wDeviceName.begin(), wDeviceName.end());
string DeviceConnected = to_string((deviceInfo.fConnected ? 1 : 0));
string DeviceAuthenticated = to_string((deviceInfo.fAuthenticated ? 1 : 0));
string DeviceRemembered = to_string((deviceInfo.fRemembered ? 1 : 0));
string DeviceConnected = to_string(deviceInfo.fConnected ? 1 : 0);
string DeviceAuthenticated = to_string(deviceInfo.fAuthenticated ? 1 : 0);
string DeviceRemembered = to_string(deviceInfo.fRemembered ? 1 : 0);
string DeviceAddress = to_string(deviceInfo.Address.ullLong);
string deviceLastSeen = to_string(deviceInfo.stLastSeen.wMonth) + "/" + to_string(deviceInfo.stLastSeen.wDay) + "/" + to_string(deviceInfo.stLastSeen.wYear) + " " + to_string(deviceInfo.stLastSeen.wHour) + ":" + to_string(deviceInfo.stLastSeen.wMinute) + ":" + to_string(deviceInfo.stLastSeen.wSecond);
string deviceLastUsed = to_string(deviceInfo.stLastUsed.wMonth) + "/" + to_string(deviceInfo.stLastUsed.wDay) + "/" + to_string(deviceInfo.stLastUsed.wYear) + " " + to_string(deviceInfo.stLastUsed.wHour) + ":" + to_string(deviceInfo.stLastUsed.wMinute) + ":" + to_string(deviceInfo.stLastUsed.wSecond);
string divider = "|";
Expand All @@ -297,6 +327,7 @@ void updateDevices(Measure* measure) {
wDeviceConnected + wDivider +
wDeviceAuthenticated + wDivider +
wDeviceRemembered + wDivider +
wDeviceAddress + wDivider +
wDeviceLastSeen + wDivider +
wDeviceLastUsed +
L";"
Expand All @@ -307,6 +338,7 @@ void updateDevices(Measure* measure) {
DeviceConnected + divider +
DeviceAuthenticated + divider +
DeviceRemembered + divider +
DeviceAddress + divider +
deviceLastSeen + divider +
deviceLastUsed +
";\n"
Expand All @@ -320,7 +352,9 @@ void updateDevices(Measure* measure) {
} while (BluetoothFindNextRadio(hFind, &hRadio));
BluetoothFindRadioClose(hFind);
}
availableDevices = devicesBuffer; // Set the availableDevices string to the content of the buffer to avoid partial lists
availableDevices = devicesBuffer; // Set the availableDevices string to the content of the buffer to avoid partial lists

bufferMutex.unlock(); // Unlock the mutex

// Write to file if the "OutputPath" field is populated
if (measure->outputPath != L"") {
Expand Down Expand Up @@ -377,7 +411,7 @@ void enableBluetooth(Measure* measure) {
for (Radio const& radio : radios) {
if (radio.Kind() == RadioKind::Bluetooth) {
radio.SetStateAsync(RadioState::On).get();
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Disabled Bluetooth adapter");
RmLogF(measure->rm, LOG_DEBUG, L"[Bluetooth-Plugin] Enabled Bluetooth adapter");
bluetoothStatus = L"1";
break;
}
Expand Down

0 comments on commit e035c38

Please sign in to comment.