From e607c17944cd866da21326ce122e77e7df3c602f Mon Sep 17 00:00:00 2001 From: Phil White <75939018+PWhite-Eng@users.noreply.github.com> Date: Mon, 29 Sep 2025 18:36:27 +0100 Subject: [PATCH] feat: Add uppercase option for unique IDs from byte arrays --- CHANGELOG.md | 4 ++++ src/HADevice.cpp | 9 ++++++++- src/HADevice.h | 13 ++++++++++++- src/utils/HAUtils.cpp | 32 +++++++++++++++++++++++++++----- src/utils/HAUtils.h | 29 ++++++++++++++++++++--------- 5 files changed, 71 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc64985..39909081 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased +**New features:** +* Added an option to generate uppercase unique IDs from byte arrays. + ## 2.1.0 **New features:** diff --git a/src/HADevice.cpp b/src/HADevice.cpp index bdf47760..dcea7dae 100644 --- a/src/HADevice.cpp +++ b/src/HADevice.cpp @@ -48,12 +48,19 @@ HADevice::~HADevice() } bool HADevice::setUniqueId(const byte* uniqueId, const uint16_t length) +{ + // For backward compatibility, default to lowercase. + return setUniqueId(uniqueId, length, false); +} + +bool HADevice::setUniqueId(const byte* uniqueId, const uint16_t length, bool uppercase) { if (_uniqueId) { return false; // unique ID cannot be changed at runtime once it's set } - _uniqueId = HAUtils::byteArrayToStr(uniqueId, length); + // Call the new HAUtils function with the uppercase flag. + _uniqueId = HAUtils::byteArrayToStr(uniqueId, length, uppercase); _ownsUniqueId = true; _serializer->set(AHATOFSTR(HADeviceIdentifiersProperty), _uniqueId); return true; diff --git a/src/HADevice.h b/src/HADevice.h index 09499827..4da29c45 100644 --- a/src/HADevice.h +++ b/src/HADevice.h @@ -88,13 +88,24 @@ class HADevice /** * Sets unique ID of the device based on the given byte array. - * Each byte is converted into a hex string representation, so the final length of the unique ID will be twice as given. + * Each byte is converted into a hex string representation (lowercase by default), so the final length of the unique ID will be twice as given. * * @param uniqueId Bytes array that's going to be converted into the string. * @param length Number of bytes in the array. * @note The unique ID can be set only once (via constructor or using this method). */ bool setUniqueId(const byte* uniqueId, const uint16_t length); + + /** + * Sets unique ID of the device based on the given byte array with case selection. + * Each byte is converted into a hex string representation, so the final length of the unique ID will be twice as given. + * + * @param uniqueId Bytes array that's going to be converted into the string. + * @param length Number of bytes in the array. + * @param uppercase If true, the output will be uppercase; otherwise, it will be lowercase. + * @note The unique ID can be set only once (via constructor or using this method). + */ + bool setUniqueId(const byte* uniqueId, const uint16_t length, bool uppercase); /** * Sets the "manufacturer" property that's going to be displayed in the Home Assistant. diff --git a/src/utils/HAUtils.cpp b/src/utils/HAUtils.cpp index a21eefc1..7c92b105 100644 --- a/src/utils/HAUtils.cpp +++ b/src/utils/HAUtils.cpp @@ -37,12 +37,34 @@ void HAUtils::byteArrayToStr( } char* HAUtils::byteArrayToStr( - const byte* src, - const uint16_t length + const byte* data, + const uint16_t length +) +{ + // For backward compatibility, default to lowercase. + return byteArrayToStr(data, length, false); +} + +char* HAUtils::byteArrayToStr( + const byte* data, + const uint16_t length, + bool uppercase ) { - char* dst = new char[(length * 2) + 1]; // include null terminator - byteArrayToStr(dst, src, length); + const uint16_t strLength = length * 2; + if (strLength == 0) { + return nullptr; + } + + char* str = new char[strLength + 1]; + str[strLength] = '\0'; + + // Choose the format specifier based on the 'uppercase' parameter. + const char* format = uppercase ? "%02X" : "%02x"; + + for (int i = 0; i < length; i++) { + sprintf(&str[i * 2], format, data[i]); + } - return dst; + return str; } diff --git a/src/utils/HAUtils.h b/src/utils/HAUtils.h index 630b204a..869461d6 100644 --- a/src/utils/HAUtils.h +++ b/src/utils/HAUtils.h @@ -36,17 +36,28 @@ class HAUtils ); /** - * Converts the given byte array into hex string. - * This method allocates a new memory. - * - * @param src Bytes array to convert. - * @param length Length of the bytes array. - * @returns Newly allocated string containing the hex representation. + * Converts given byte array into the string of hex values. + * @param data Bytes to convert. + * @param length Number of bytes to convert. + * @return Dynamically allocated string with hex values. You're responsible for deleting it. */ static char* byteArrayToStr( - const byte* src, - const uint16_t length - ); + const byte* data, + const uint16_t length + ); + + /** + * Converts given byte array into the string of hex values with optional uppercase formatting. + * @param data Bytes to convert. + * @param length Number of bytes to convert. + * @param uppercase If true, the output will be uppercase; otherwise, it will be lowercase. + * @return Dynamically allocated string with hex values. You're responsible for deleting it. + */ + static char* byteArrayToStr( + const byte* data, + const uint16_t length, + bool uppercase + ); }; #endif