diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7cfcfbf..9089351 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -23,8 +23,8 @@ android { applicationId = "com.st.demo" minSdk = 26 targetSdk = 34 - versionCode = 4 - versionName = "5.2.4" + versionCode = 7 + versionName = "5.2.5" vectorDrawables { useSupportLibrary = true } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f889b7d..1974967 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,27 +7,27 @@ # [versions] # @pin https://github.com/google/accompanist#compose-versions -accompanist = "0.34.0" -androidGradlePlugin = "8.5.1" +accompanist = "0.36.0" +androidGradlePlugin = "8.5.2" # @pin https://developer.android.com/jetpack/androidx/releases/compose#versions -androidxComposeBom = "2024.06.00" +androidxComposeBom = "2024.09.01" androidxEspresso = "3.6.0-rc01" androidxHiltNavigationCompose = "1.2.0" # https://issuetracker.google.com/issues/336842920 # @pin -androidxLifecycle = "2.8.3" -androidxNavigation = "2.7.7" +androidxLifecycle = "2.8.5" +androidxNavigation = "2.8.0" androidxRoom = "2.6.1" apacheCommons = "3.11.1" appauth = "0.11.1" benManes = "0.51.0" -hilt = "2.51.1" +hilt = "2.52" jwt = "2.0.2" # @pin https://developer.android.com/jetpack/androidx/releases/compose-kotlin -kotlin = "2.0.0" -kotlinxSerializationJson = "1.7.1" +kotlin = "2.0.10" +kotlinxSerializationJson = "1.7.2" # @pin -ksp = "2.0.0-1.0.22" +ksp = "2.0.10-1.0.24" littlerobots = "0.8.4" material2 = "1.12.0" okhttp = "4.12.0" diff --git a/gradlew b/gradlew index 1aa94a4..6afa17a 100755 --- a/gradlew +++ b/gradlew @@ -1,14 +1,18 @@ #!/bin/sh # + # Copyright © 2015-2021 the original authors. # + # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # + # https://www.apache.org/licenses/LICENSE-2.0 # + # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,46 +22,93 @@ ############################################################################## # + # Gradle start up script for POSIX generated by Gradle. # + # Important for running: # -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is + +# (1) +You need +a POSIX +- +compliant shell +to run +this script. +If your +/bin/ +sh is # noncompliant, but you have some other compliant shell such as ksh or # bash, then to run this script, type that shell name before the whole # command line, like: # + # ksh Gradle # + # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». +# * +functions; +# * expansions «$var», «${ +var}», «${ +var:-default}», «${ +var+SET}», +# «${ +var#prefix}», «${ +var%suffix}», and « +$( cmd ) +»; +# * +compound commands +having a +testable exit +status, especially «case»; +# * +various built +- +in commands +including «command», «set», and «ulimit». # + # Important for patching: # -# (2) This script targets any POSIX shell, so it avoids extensions provided + +# (2) +This script +targets any +POSIX shell, so +it avoids +extensions provided # by Bash, Ksh, etc; in particular arrays are avoided. # + # The "traditional" practice of packing multiple parameters into a # space-separated string is a well documented source of bugs and security # problems, so this is (mostly) avoided, by progressively accumulating # options in "$@", and eventually passing that to Java. # + # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; # see the in-line comments for details. # + # There are tweaks for specific operating systems such as AIX, CygWin, # Darwin, MinGW, and NonStop. # -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt + +# (3) +This script +is generated +from the +Groovy +template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # + # You can find Gradle at https://github.com/gradle/gradle/. # ############################################################################## @@ -65,121 +116,185 @@ # Attempt to set APP_HOME # Resolve links: $0 may be a link -app_path=$0 +app_path = $0 # Need this for daisy-chained symlinks. while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] +APP_HOME = ${app_path % "${app_path##*/}"} +# +leaves a +trailing /; empty if +no leading +path +[ -h "$app_path" ] do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac +ls = $(ls - ld +"$app_path" ) +link = ${ls# +*' -> '} +case +$link in +#( +/*) app_path=$link ;; #( +*) app_path=$APP_HOME$link ;; +esac done -# This is normally unused -# shellcheck disable=SC2034 +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS = '"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum +MAX_FD = maximum -warn () { - echo "$*" -} >&2 +warn() { + echo + "$*" +} + +>&2 -die () { +die() { + echo echo - echo "$*" + "$*" echo - exit 1 -} >&2 + exit + 1 +} + +>&2 # OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false +cygwin = false +msys = false +darwin = false +nonstop = false case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; +CYGWIN* ) +cygwin = true;; #( +Darwin* ) +darwin = true;; #( +MSYS* | MINGW* ) +msys = true;; #( +NONSTOP* ) +nonstop = true;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + CLASSPATH = $APP_HOME / gradle / wrapper / gradle - wrapper.jar # Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi +if [ -n "$JAVA_HOME" ]; then +if [ -x "$JAVA_HOME/jre/sh/java" ]; +then +# IBM's JDK on AIX uses strange locations for the executables + JAVACMD = $JAVA_HOME / jre / sh / java else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi +JAVACMD = $JAVA_HOME / bin / java fi +if [ ! -x "$JAVACMD" ]; +then + die +"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac +Please set +the JAVA_HOME +variable in +your environment +to match +the + location +of your +Java installation +." +fi +else +JAVACMD = java +which java +>/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set +the JAVA_HOME +variable in +your environment +to match +the + location +of your +Java installation +." fi +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop"; then +case +$MAX_FD in +#( +max*) +MAX_FD = $(ulimit - H - n) || + warn +"Could not query maximum file descriptor limit" +esac +case +$MAX_FD in +#( +'' | soft) :;; #( +*) +ulimit -n "$MAX_FD" || +warn "Could not set maximum file descriptor limit to $MAX_FD" +esac + fi + # Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name +# * +args from +the command +line +# * +the main + +class name + # * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. +# * - +D...appname +settings +# * --module- +path (only +if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and +GRADLE_OPTS environment +variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath +if "$cygwin" || "$msys"; +then + APP_HOME = $(cygpath-- +path --mixed "$APP_HOME" ) +CLASSPATH = $(cygpath-- +path --mixed "$CLASSPATH" ) + +JAVACMD = $(cygpath-- +unix "$JAVACMD" ) + +# Now convert the arguments - kludge to limit ourselves to /bin/sh +for arg do +if +case +$arg in +#( +-*) false;; # don't mess with options #( +/?*) +t = ${arg# +/} +t = +/${ +t%%/*} # looks like a POSIX filepath [ -e "$t" ] ;; #( *) false ;; esac @@ -198,15 +313,11 @@ if "$cygwin" || "$msys" ; then done fi - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -214,12 +325,6 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 6689b85..107acd3 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,92 +1,89 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/st_blue_sdk/publish.gradle b/st_blue_sdk/publish.gradle index 92601b7..7e92a2a 100644 --- a/st_blue_sdk/publish.gradle +++ b/st_blue_sdk/publish.gradle @@ -10,7 +10,7 @@ apply plugin: 'maven-publish' def LIB_GROUP_ID = 'com.st.blue.sdk' def LIB_ARTIFACT_ID = 'st-blue-sdk' -def LIB_VERSION = '1.2.0' +def LIB_VERSION = '1.2.4' tasks.register('sourceJar', Jar) { from android.sourceSets.main.java.srcDirs diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/BlueManager.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/BlueManager.kt index 44d67c7..df8384d 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/BlueManager.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/BlueManager.kt @@ -117,7 +117,8 @@ interface BlueManager { suspend fun getDtmiModel(nodeId: String, isBeta: Boolean): DtmiModel? - suspend fun setBoardCatalog(fileUri: Uri, contentResolver: ContentResolver): List + suspend fun setBoardCatalog(fileUri: Uri, contentResolver: ContentResolver): Pair,String?> + suspend fun setDtmiModel( nodeId: String, diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/BlueManagerImpl.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/BlueManagerImpl.kt index 1d0d598..87cadb8 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/BlueManagerImpl.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/BlueManagerImpl.kt @@ -486,7 +486,8 @@ class BlueManagerImpl @Inject constructor( override suspend fun setBoardCatalog( fileUri: Uri, contentResolver: ContentResolver - ): List = catalog.setBoardCatalog(fileUri, contentResolver) + ): Pair,String?> = catalog.setBoardCatalog(fileUri, contentResolver) + override suspend fun setDtmiModel( nodeId: String, fileUri: Uri, contentResolver: ContentResolver diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/NodeService.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/NodeService.kt index 1ec54d1..2799f3f 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/NodeService.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/NodeService.kt @@ -141,7 +141,9 @@ class NodeService( if(enabled) { it.numberEnables++ } else { - it.numberEnables-- + if(it.numberEnables>0) { + it.numberEnables-- + } } //For Avoiding to do this operation when it's not necessary if(it.hasEnabledNotifications!=enabled) { diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/BoardCatalogRepo.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/BoardCatalogRepo.kt index 0e51197..9b4eb6c 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/BoardCatalogRepo.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/BoardCatalogRepo.kt @@ -36,7 +36,8 @@ interface BoardCatalogRepo { suspend fun getDtmiModel(deviceId: String, bleFwId: String,isBeta: Boolean): DtmiModel? - suspend fun setBoardCatalog(fileUri: Uri, contentResolver: ContentResolver): List + suspend fun setBoardCatalog(fileUri: Uri, contentResolver: ContentResolver): Pair,String?> + suspend fun setDtmiModel( deviceId: String, diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/BoardCatalogRepoImpl.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/BoardCatalogRepoImpl.kt index 02d782f..58697d5 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/BoardCatalogRepoImpl.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/BoardCatalogRepoImpl.kt @@ -40,7 +40,7 @@ import kotlinx.coroutines.withContext import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray import java.nio.charset.StandardCharsets -import java.util.* +import java.util.Date import javax.inject.Inject import javax.inject.Singleton @@ -65,7 +65,10 @@ class BoardCatalogRepoImpl @Inject constructor( private var catalogRequestOnGoing = false + private var url: String?=null + init { + url = null coroutineScope.launch { //getBoardCatalog() fillCachesFromDB() @@ -153,8 +156,8 @@ class BoardCatalogRepoImpl @Inject constructor( } } - private suspend fun sync(url: String? = null) { - Log.i("DB", "sync()") + private suspend fun sync() { + Log.i("DB", "sync(}") catalogRequestOnGoing = true mutex.withLock { try { @@ -164,11 +167,27 @@ class BoardCatalogRepoImpl @Inject constructor( cacheBoardsDescription.clear() cacheSensorAdapters.clear() cacheBleCharacteristics.clear() - val firmwares = if (url != null) + val firmwares = if (url != null) { api.getFirmwaresFromUrl(url + "catalog.json") + } else api.getFirmwares() + if(url != null) { + //We need to change the fw_url... for pointing to Pre-Production + firmwares.bleListBoardFirmwareV1?.forEach { firmware -> + if(firmware.fota.fwUrl!=null) { + firmware.fota.fwUrl = firmware.fota.fwUrl!!.replace("STMicroelectronics","SW-Platforms") + } + } + + firmwares.bleListBoardFirmwareV2?.forEach { firmware -> + if(firmware.fota.fwUrl!=null) { + firmware.fota.fwUrl = firmware.fota.fwUrl!!.replace("STMicroelectronics","SW-Platforms") + } + } + } + catalogRequestOnGoing = false firmwares.bleListBoardFirmwareV1?.let { cache.addAll(it) @@ -228,7 +247,8 @@ class BoardCatalogRepoImpl @Inject constructor( override suspend fun reset(url: String?) { Log.i("DB", "reset()") - sync(url) + this.url = url + sync() } override suspend fun getBoardCatalog(): List { @@ -419,7 +439,9 @@ class BoardCatalogRepoImpl @Inject constructor( val inStream = contentResolver.openInputStream(fileUri) if (inStream != null) { val text = inStream.bufferedReader(StandardCharsets.ISO_8859_1).readText() - inStream.close() + withContext(Dispatchers.IO) { + inStream.close() + } result = json.decodeFromString(text).mapNotNull { it.toDtmiContent() }.let { val index = @@ -453,15 +475,20 @@ class BoardCatalogRepoImpl @Inject constructor( override suspend fun setBoardCatalog( fileUri: Uri, contentResolver: ContentResolver - ): List { + ): Pair,String?> { // Log.i("DB","setBoardCatalog()") + var outputStringResult: String?=null + try { val inStream = contentResolver.openInputStream(fileUri) if (inStream != null) { val text = inStream.bufferedReader(StandardCharsets.ISO_8859_1).readText() - inStream.close() - val result = json.decodeFromString(text).let { boardCatalog -> + withContext(Dispatchers.IO) { + inStream.close() + } + outputStringResult= "" + json.decodeFromString(text).let { boardCatalog -> cache.clear() boardCatalog.bleListBoardFirmwareV1?.let { listFw -> listFw.forEach { firmware -> @@ -469,6 +496,7 @@ class BoardCatalogRepoImpl @Inject constructor( FirmwareMaturity.CUSTOM } db.add(listFw) + outputStringResult +="Added ${listFw.size} custom board models (V1) " //it.forEach { it2 -> cache.add(it2) } } boardCatalog.bleListBoardFirmwareV2?.let { listFw -> @@ -477,6 +505,7 @@ class BoardCatalogRepoImpl @Inject constructor( firmware.maturity = FirmwareMaturity.CUSTOM } db.add(listFw) + outputStringResult +="Added ${listFw.size} custom board models" //it.forEach { it2 -> cache.add(it2) } } cache.addAll(db.getDeviceFirmwares()) @@ -484,12 +513,16 @@ class BoardCatalogRepoImpl @Inject constructor( //Save the custom added board models pref.edit(commit = true) { putString(CUSTOM_BOARDS_MODEL, text) } } + if(outputStringResult.isNullOrEmpty()) { + outputStringResult += "No custom board models added" + } } } catch (ex: Exception) { + outputStringResult = ex.localizedMessage Log.w(TAG, ex.localizedMessage, ex) } - return cache.toList() + return Pair(cache.toList(),outputStringResult) } companion object { diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/db/BoardCatalogDB.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/db/BoardCatalogDB.kt index 1296244..a83a14c 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/db/BoardCatalogDB.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/db/BoardCatalogDB.kt @@ -27,7 +27,7 @@ import com.st.blue_sdk.board_catalog.models.BoardFirmware import com.st.blue_sdk.board_catalog.models.Sensor @Database( - version = 20, + version = 21, exportSchema = true, entities = [ BoardFirmware::class, diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/BoardDescription.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/BoardDescription.kt index 26098fc..fd5fefc 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/BoardDescription.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/BoardDescription.kt @@ -34,9 +34,12 @@ data class BoardDescription( @ColumnInfo(name = "brd_name") @SerialName(value = "brd_name") val boardName: String, + @ColumnInfo(name = "brd_part") + @SerialName(value = "brd_part") + val boardPart: String, @ColumnInfo(name = "brd_variant") @SerialName(value = "brd_variant") - val boardVariant: String?=null, + val boardVariant: String, @ColumnInfo(name = "friendly_name") @SerialName(value = "friendly_name") val friendlyName: String, diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/FotaDetails.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/FotaDetails.kt index 430e0e9..3273252 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/FotaDetails.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/FotaDetails.kt @@ -20,7 +20,7 @@ data class FotaDetails( @SerialName("max_divisor_constraint") var maxDivisorConstraint: Int? = 0, @SerialName("fw_url") - val fwUrl: String? = null, + var fwUrl: String? = null, @SerialName("bootloader_type") val bootloaderType: BootLoaderType? = BootLoaderType.NONE, @SerialName("mandatory") diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/SensorType.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/SensorType.kt index 20f312e..0cceba8 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/SensorType.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/board_catalog/models/SensorType.kt @@ -5,6 +5,21 @@ import kotlinx.serialization.Serializable @Serializable enum class SensorType(val value: String = "") { + @SerialName("TOF") + TimeOfFlight("tof"), + + @SerialName("ALS") + AmbientLightSensor("als"), + + @SerialName("TMOS") + TmosInfrared("tmos"), + + @SerialName("POW") + PowerMeter("pow"), + + @SerialName("ISPU") + ISPU("ispu"), + @SerialName("ACC") Accelerometer("acc"), @@ -40,6 +55,6 @@ enum class SensorType(val value: String = "") { companion object { fun fromName(name: String) = - values().find { it.value == name.split("_").last() } ?: Unknown + entries.find { it.value == name.split("_").last() } ?: Unknown } } diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/Feature.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/Feature.kt index 347036a..287af4e 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/Feature.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/Feature.kt @@ -38,6 +38,7 @@ import com.st.blue_sdk.features.extended.medical_signal.MedicalSignal16BitFeatur import com.st.blue_sdk.features.extended.medical_signal.MedicalSignal24BitFeature import com.st.blue_sdk.features.extended.motion_algorithm.MotionAlgorithm import com.st.blue_sdk.features.extended.motor_time_param.MotorTimeParameter +import com.st.blue_sdk.features.extended.navigation_control.NavigationControl import com.st.blue_sdk.features.extended.neai_anomaly_detection.NeaiAnomalyDetection import com.st.blue_sdk.features.extended.neai_class_classification.NeaiClassClassification import com.st.blue_sdk.features.extended.neai_extrapolation.NeaiExtrapolation @@ -82,6 +83,7 @@ import com.st.blue_sdk.features.pressure.Pressure import com.st.blue_sdk.features.proximity.Proximity import com.st.blue_sdk.features.proximity_gesture.ProximityGesture import com.st.blue_sdk.features.extended.raw_controlled.RawControlled +import com.st.blue_sdk.features.extended.scene_description.SceneDescription import com.st.blue_sdk.features.remote.humidity.RemoteHumidity import com.st.blue_sdk.features.remote.pressure.RemotePressure import com.st.blue_sdk.features.remote.switch.RemoteSwitch @@ -562,6 +564,8 @@ abstract class Feature( isEnabled = isEnabled, identifier = identifier ) + 0x28 -> NavigationControl(isEnabled = isEnabled, identifier = identifier) + 0x29 -> SceneDescription(isEnabled = isEnabled, identifier = identifier) else -> throw UnsupportedOperationException("$type unknown") diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/audio_classification/AudioClassification.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/audio_classification/AudioClassification.kt index 16e0b15..ca65f85 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/audio_classification/AudioClassification.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/audio_classification/AudioClassification.kt @@ -45,7 +45,7 @@ class AudioClassification( ), algorithm = FeatureField( value = ALGORITHM_NOT_DEFINED, - name = "AudioClassification" + name = "Algorithm" ) ) } else { @@ -56,7 +56,7 @@ class AudioClassification( ), algorithm = FeatureField( value = NumberConversion.byteToUInt8(data, dataOffset + 1), - name = "AudioClassification" + name = "Algorithm" ) ) } diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/fitness_activity/FitnessActivityInfo.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/fitness_activity/FitnessActivityInfo.kt index 8de339e..ae2785a 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/fitness_activity/FitnessActivityInfo.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/fitness_activity/FitnessActivityInfo.kt @@ -37,7 +37,26 @@ enum class FitnessActivityType { BicepCurl, Squat, PushUp, - Error + Error; + + override fun toString(): String = when (this) { + NoActivity -> "None" + BicepCurl -> "Biceps curl" + Squat -> "Squat" + PushUp -> "Push up" + Error -> "Error" + } + + companion object { + @JvmStatic + fun fromString(name: String): FitnessActivityType = when (name) { + "None" -> NoActivity + "Biceps curl" -> BicepCurl + "Squat" -> Squat + "Push up" -> PushUp + else -> Error + } + } } fun getFitnessActivityType(activity: Short) = when ((activity and 0x0F).toInt()) { diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/gesture_navigation/GestureNavigation.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/gesture_navigation/GestureNavigation.kt index 43fbabd..b6df0bd 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/gesture_navigation/GestureNavigation.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/gesture_navigation/GestureNavigation.kt @@ -16,7 +16,7 @@ class GestureNavigation( ) { companion object { - const val NAME = "Navigation" + const val NAME = "Gesture Navigation" const val NUMBER_BYTES = 2 } diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/gesture_navigation/GestureNavigationInfo.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/gesture_navigation/GestureNavigationInfo.kt index 3716712..4f2e75c 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/gesture_navigation/GestureNavigationInfo.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/gesture_navigation/GestureNavigationInfo.kt @@ -39,6 +39,10 @@ enum class GestureNavigationGestureType(val value: Short) { companion object { fun fromShort(value: Short) = entries.first { it.value == value } } + + fun isPressEvent(): Boolean { + return this == SinglePress || this == DoublePress || this == TriplePress || this == LongPress + } } enum class GestureNavigationButton(val value: Short) { @@ -50,6 +54,6 @@ enum class GestureNavigationButton(val value: Short) { Error(5); companion object { - fun fromShort(value: Short) = values().first { it.value == value } + fun fromShort(value: Short) = entries.first { it.value == value } } } \ No newline at end of file diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/motion_algorithm/MotionAlgorithmInfo.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/motion_algorithm/MotionAlgorithmInfo.kt index 813bdc4..a8bbadb 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/motion_algorithm/MotionAlgorithmInfo.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/motion_algorithm/MotionAlgorithmInfo.kt @@ -100,6 +100,22 @@ enum class AlgorithmType { VerticalContext -> 0x03.toByte() Unknown -> 0x00.toByte() } + + @JvmStatic + fun fromString(name: String): AlgorithmType = when (name) { + "Pose Estimation" -> PoseEstimation + "Desktop Type" -> DesktopTypeDetection + "Vertical Context" -> VerticalContext + "None" -> Unknown + else -> Unknown + } + } + + override fun toString(): String = when (this) { + Unknown -> "None" + PoseEstimation -> "Pose Estimation" + DesktopTypeDetection -> "Desktop Type" + VerticalContext -> "Vertical Context" } } diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/navigation_control/NavigationControl.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/navigation_control/NavigationControl.kt new file mode 100644 index 0000000..52b931c --- /dev/null +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/navigation_control/NavigationControl.kt @@ -0,0 +1,42 @@ +package com.st.blue_sdk.features.extended.navigation_control + +import com.st.blue_sdk.features.Feature +import com.st.blue_sdk.features.FeatureCommand +import com.st.blue_sdk.features.FeatureResponse +import com.st.blue_sdk.features.FeatureUpdate + +class NavigationControl( + name: String = NAME, + type: Type = Type.EXTENDED, + isEnabled: Boolean, + identifier: Int +) : Feature( + name = name, + type = type, + isEnabled = isEnabled, + identifier = identifier +) { + companion object { + + const val NAME = "Navigation Control" + const val NUMBER_BYTES = 2 + } + + override fun extractData( + timeStamp: Long, + data: ByteArray, + dataOffset: Int + ): FeatureUpdate { + return FeatureUpdate( + featureName = name, + readByte = data.size, + timeStamp = timeStamp, + rawData = data, + data = NavigationControlInfo(name = "Place holder") + ) + } + + override fun packCommandData(featureBit: Int?, command: FeatureCommand): ByteArray? = null + + override fun parseCommandResponse(data: ByteArray): FeatureResponse? = null +} \ No newline at end of file diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/navigation_control/NavigationControlInfo.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/navigation_control/NavigationControlInfo.kt new file mode 100644 index 0000000..c48d494 --- /dev/null +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/navigation_control/NavigationControlInfo.kt @@ -0,0 +1,14 @@ +package com.st.blue_sdk.features.extended.navigation_control + +import com.st.blue_sdk.logger.Loggable + +data class NavigationControlInfo(val name: String, +): Loggable { + override val logHeader: String = "" + + override val logValue: String = "" + + override fun toString(): String = "To Be Implemented" + + override val logDoubleValues: List = listOf() +} \ No newline at end of file diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/scene_description/SceneDescription.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/scene_description/SceneDescription.kt new file mode 100644 index 0000000..4a0d835 --- /dev/null +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/scene_description/SceneDescription.kt @@ -0,0 +1,42 @@ +package com.st.blue_sdk.features.extended.scene_description + +import com.st.blue_sdk.features.Feature +import com.st.blue_sdk.features.FeatureCommand +import com.st.blue_sdk.features.FeatureResponse +import com.st.blue_sdk.features.FeatureUpdate + +class SceneDescription( + name: String = NAME, + type: Type = Type.EXTENDED, + isEnabled: Boolean, + identifier: Int +) : Feature( + name = name, + type = type, + isEnabled = isEnabled, + identifier = identifier +) { + companion object { + + const val NAME = "Navigation Control" + const val NUMBER_BYTES = 2 + } + + override fun extractData( + timeStamp: Long, + data: ByteArray, + dataOffset: Int + ): FeatureUpdate { + return FeatureUpdate( + featureName = name, + readByte = data.size, + timeStamp = timeStamp, + rawData = data, + data = SceneDescriptionInfo(name = "Place holder") + ) + } + + override fun packCommandData(featureBit: Int?, command: FeatureCommand): ByteArray? = null + + override fun parseCommandResponse(data: ByteArray): FeatureResponse? = null +} \ No newline at end of file diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/scene_description/SceneDescriptionInfo.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/scene_description/SceneDescriptionInfo.kt new file mode 100644 index 0000000..6192595 --- /dev/null +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/features/extended/scene_description/SceneDescriptionInfo.kt @@ -0,0 +1,14 @@ +package com.st.blue_sdk.features.extended.scene_description + +import com.st.blue_sdk.logger.Loggable + +data class SceneDescriptionInfo(val name: String, +): Loggable { + override val logHeader: String = "" + + override val logValue: String = "" + + override fun toString(): String = "To Be Implemented" + + override val logDoubleValues: List = listOf() +} \ No newline at end of file diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/services/calibration/CalibrationServiceImpl.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/services/calibration/CalibrationServiceImpl.kt index ea5ea47..6387af5 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/services/calibration/CalibrationServiceImpl.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/services/calibration/CalibrationServiceImpl.kt @@ -15,9 +15,11 @@ import com.st.blue_sdk.features.GetCalibration import com.st.blue_sdk.features.StartCalibration import com.st.blue_sdk.services.NodeServiceConsumer import kotlinx.coroutines.TimeoutCancellationException -import kotlinx.coroutines.cancel -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onSubscription +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.supervisorScope import kotlinx.coroutines.withTimeout @@ -33,7 +35,7 @@ class CalibrationServiceImpl @Inject constructor( companion object { const val TAG = "CalibrationImpl" const val START_COMMAND = "startMagnCalib" - //const val GET_COMMAND = "getMagnCalibStatus" + const val GET_COMMAND = "getMagnCalibStatus" val STATUS_PARSER: Pattern = Pattern.compile("magnCalibStatus (\\d+)") } @@ -60,6 +62,37 @@ class CalibrationServiceImpl @Inject constructor( val response = service.writeFeatureCommand(GetCalibration(feature = feature)) if (response is CalibrationStatus) { result = response + } else { + val debugService = service.debugService + //The SensorTile.box and SensorTile.box-Pro don't have Configuration BLE Char + debugService.write(GET_COMMAND) + try { + supervisorScope { + launch { + withTimeout(3000L) { + debugService.getDebugMessages() + .filter { it.isError.not() } + .map { it.payload } + .stateIn(this@launch, SharingStarted.Eagerly, initialValue = "") + .onSubscription { + debugService.write(GET_COMMAND) + }.collect { message -> + val matcher = STATUS_PARSER.matcher(message) + if (matcher.matches()) { + val calibStatus = matcher.group(1)?.toByte() + calibStatus?.let { calib -> + result = + CalibrationStatus(feature = feature, status = calib==100.toByte()) + } + } + } + } + } + } + } catch (ex: TimeoutCancellationException) { + Log.d("CalibrationServiceImpl", ex.message, ex) + } + } return result } diff --git a/st_blue_sdk/src/main/java/com/st/blue_sdk/services/debug/DebugServiceImpl.kt b/st_blue_sdk/src/main/java/com/st/blue_sdk/services/debug/DebugServiceImpl.kt index aaeb8ec..088d787 100644 --- a/st_blue_sdk/src/main/java/com/st/blue_sdk/services/debug/DebugServiceImpl.kt +++ b/st_blue_sdk/src/main/java/com/st/blue_sdk/services/debug/DebugServiceImpl.kt @@ -54,6 +54,7 @@ class DebugServiceImpl( } override suspend fun write(message: String): Int { + // Log.i("DebugDebugConsole","write on Debug <$message>") return write(message.toByteArray(CHARSET)) } @@ -81,6 +82,7 @@ class DebugServiceImpl( it.characteristic.uuid == errorDebugCharacteristic?.uuid ) { val isError = it.characteristic.uuid == errorDebugCharacteristic?.uuid + //Log.i("DebugDebugConsole","Get getDebugMessages <${String(it.data, CHARSET)}>") emit(DebugMessage(String(it.data, CHARSET), isError)) } } @@ -89,6 +91,7 @@ class DebugServiceImpl( override suspend fun read(timeout: Long): DebugMessage? { return rwDebugCharacteristic?.let { recipient -> val data = bleHAL.readCharacteristic(recipient, timeout) + //data?.let { payload -> Log.i("Pezz","Read on Debug <${String(payload, CHARSET)}>") } return data?.let { payload -> DebugMessage(String(payload, CHARSET), false) } } }