Share My Creation wear dashboard

ic_launcher.png

This script was written to demonstrate Bluetooth Low Energy connection from a WearOS watch with the AEON
electronic interface or with PC simulation software. It is intended to provide useful information for the development
of various online graphics applications for the AEON product. dashboard

montre.jpg


B4X:
'' This script was written to demonstrate the Bluetooth Low Energy connection with the
'' AEON electronic interface or with PC simulation software. It is intended to provide
'' useful information for the development of various graphics applications in line with
'' the AEON product.
'' Written by André FAËS (Mr Blue Sky)

#Region Shared Files
#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files"
'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True
#End Region

'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=BLEExample.zip

' Class declaration and initialization of global variables
' defines variables used across the class, including UI elements
' like buttons and gauges, and managers for BLE services and execution permissions.
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private manager As BleManager2
    Private rp As RuntimePermissions
 
    Private pnlLayout As Panel
    Private btnDisconnect As B4XView
    Private btnScan As B4XView
    Private lblDeviceStatus As B4XView
    Private currentStateText As String = "UNKNOWN"
    Private currentState As Int
    Private connected As Boolean = False
    Private ConnectedName As String = "AEON"
    Private ConnectedServices As List
    Private pbScan As B4XLoadingIndicator
    Private xSpeedGauge As xGauges
    Private fntTANK, fntOIL, fntTEMP As B4XView
End Sub

' Method provided for initializing additional components or databases if necessary, currently commented
Public Sub Initialize
'    If dBSQL.IsInitialized = False Then
'        InitdbSQL
'    End If
End Sub

' Load the main layout, initialize the dialog, BLE manager, configure gauges,
' start listening for device orientation, and configure policies and colors.
' Each of these methods initializes a specific part of the application,
' such as panel settings, dialogs, handlers, gauges, etc.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("main")
    InitializePanelSettings
    InitializeManager
    ConfigureGauges
    ConfigureFontsAndColors
End Sub

' Configures initial interface panel settings, such as button visibility.
Private Sub InitializePanelSettings
    pnlLayout.SetLayout(0, 0, pnlLayout.Width, pnlLayout.Height)
    pnlLayout.Visible=True
 
    btnScan.Visible = True
    btnDisconnect.Visible = False
End Sub


' Initializes the BLE manager and updates the initial connection state
Private Sub InitializeManager
    manager.Initialize("manager")
    StateChanged
End Sub

' Updates interface elements based on BLE connection status
Public Sub StateChanged
    If connected Then
'        lblDeviceStatus.Text = "Connected: " & ConnectedName
        lblDeviceStatus.Text = ""
        manager.ReadData2(UUID("FFE0"), UUID("FFE1"))
        Sleep(1000)
        btnScan.Visible = False
        btnDisconnect.Visible = True
        manager.SetNotify(UUID("FFE0"), UUID("FFE1"),True)
    Else
        lblDeviceStatus.Text = "Not connected"
        btnScan.Visible = True
        btnDisconnect.Visible = False
    End If
 
    btnDisconnect.Enabled = connected
    btnScan.Enabled = Not(connected)
    pbScan.Hide
    btnScan.Enabled = (currentState = manager.STATE_POWERED_ON) And connected = False
End Sub

' Configures gauges with initial values and visualization settings.
Private Sub ConfigureGauges
    xSpeedGauge.Value = 0
End Sub


Private Sub ConfigureFontsAndColors()
    Dim fonts As List = Array(fntTANK, fntOIL, fntTEMP)
    For Each fnt As B4XView In fonts
        fnt.Font = xui.CreateFont(Typeface.CreateNew(Typeface.LoadFromAssets("fiveaces.ttf"), Typeface.STYLE_NORMAL), fnt.TextSize)
        fnt.TextColor = xui.Color_Gray
        fnt.Color = xui.Color_Transparent
    Next
 
    Dim labelTexts As Map = CreateMap(fntTANK: "E", fntOIL: "F", fntTEMP: "K")
    For Each key As B4XView In labelTexts.Keys
        key.Text = labelTexts.Get(key)
    Next
End Sub

' Handles the click of the scan button, checking the necessary permissions before starting the scan.
Sub btnScan_Click
    Dim Permissions As List
    Dim phone As Phone
    If phone.SdkVersion >= 31 Then
        Permissions = Array("android.permission.BLUETOOTH", rp.PERMISSION_ACCESS_FINE_LOCATION)
    Else
        Permissions = Array(rp.PERMISSION_ACCESS_FINE_LOCATION)
    End If
    For Each per As String In Permissions
        rp.CheckAndRequest(per)
        Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)
        If Result = False Then
            ToastMessageShow("No permission: " & Permission, True)
            Return
        End If
    Next
 
    pbScan.Show
    StartScan
End Sub

Public Sub StartScan
    If manager.State <> manager.STATE_POWERED_ON Then
        Log("Bluetooth is not powered on.")
        Return
    End If

    CheckBluetoothPermissions
    manager.Scan2(Array(UUID("FFE0")), False)
End Sub

Private Sub CheckBluetoothPermissions()
    Dim Permissions As List = Array("android.permission.BLUETOOTH", rp.PERMISSION_ACCESS_FINE_LOCATION)
    For Each Permission As String In Permissions
        rp.CheckAndRequest(Permission)
        Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)
        If Result = False Then
            xui.MsgboxAsync("Permission denied: " & Permission, "Error")
            Return
        End If
    Next
End Sub

' Manage events related to BLE device discovery.
Sub Manager_DeviceFound (Name As String, Id As String, AdvertisingData As Map, RSSI As Double)
    Log("Found: " & Name & ", " & Id & ", RSSI = " & RSSI & ", " & AdvertisingData) 'ignore
'    If Id = "68:E7:4A:EB:EA:BB" Then
    If Name = "AEON" Then
        ConnectedName = Name
        manager.StopScan
        Log("connecting")
        manager.Connect2(Id, False) 'disabling auto connect can make the connection quicker
    End If
End Sub

' Manage events related to Bluetooth state changes.
Sub Manager_StateChanged (State As Int)
    Select State
        Case manager.STATE_POWERED_OFF
            currentStateText = "POWERED OFF"
        Case manager.STATE_POWERED_ON
            currentStateText = "POWERED ON"
        Case manager.STATE_UNSUPPORTED
            currentStateText = "UNSUPPORTED"
    End Select
 
    currentState = State
    StateChanged
End Sub

' Handles the click of the BLE device disconnect button
Sub btnDisconnect_Click
    manager.Disconnect
    Manager_Disconnected
End Sub

Sub btnReadData_Click
    For Each s As String In ConnectedServices
        manager.ReadData(s)
    Next
End Sub

' Processes data received via BLE, decrypting received messages and triggering appropriate processing.
Sub Manager_DataAvailable (ServiceId As String, Characteristics As Map)
    Dim BC As ByteConverter
    For Each id As String In Characteristics.Keys
        Dim b() As Byte = Characteristics.Get(id)
        Dim GetHexString As String = BC.HexFromBytes(b)

        ' Log original hex string
        Log("Trame reçue: " & GetHexString)
     
        ' Split the received string into valid messages
        Dim messages() As String = Regex.Split("0D0A", GetHexString)
        For Each msg As String In messages
            If msg.Length > 0 Then ' Check to ensure non-empty
                Dim validMsg As String = msg & "0D0A" ' Append back the split pattern to each valid message
                'Log("Trame individuelle: " & validMsg)
                If validMsg.EndsWith("0D0A") Then
                    HandleCharacteristic(validMsg)
                Else
'                    Log("Trame individuelle non valide ou incomplète")
                End If
            End If
        Next
    Next
End Sub

' These methods break down and process specific BLE messages received,
' adjusting gauge values and displaying device data like speed, battery status, etc.
Sub HandleCharacteristic(GetHexString As String)
    ' Vérifiez la longueur et l'intégrité de base de GetHexString
    If GetHexString.EndsWith("0D0A") Then
        ' Découpe la trame en fonction des exigences spécifiques de chaque message
        Select Case True
            Case GetHexString.Length = 20 ' Pour la majorité des cas
                ProcessMessage(GetHexString)
             
            Case GetHexString.Length = 24 ' Cas spécifique, comme pour ODO
                If GetHexString.SubString2(8, 12) = "0032" Then
'                    lblODO.Text = "ODO : " & Bit.ParseInt(GetHexString.SubString2(12, 20), 16)
                End If
             
            Case Else
                Log("Unmanaged or incorrect frame length: " & GetHexString)
        End Select
    Else
        Log("Corrupted or incomplete frame: " & GetHexString)
    End If
End Sub

' These methods break down and process specific BLE messages received,
' adjusting gauge values and displaying device data like speed, battery status, etc.
Sub ProcessMessage(GetHexString As String)
    Dim functionCode As String = GetHexString.SubString2(8, 12)
    Dim value As String = GetHexString.SubString2(12, 16)
 
    Select Case functionCode
        Case "0010" 'SPEED
            Dim speedValue As Int = Bit.ParseInt(value, 16)
            xSpeedGauge.Value = speedValue
         
        Case "0117" 'OIL
            If Bit.ParseInt(value, 16) = 1 Then
                fntOIL.TextColor=xui.Color_Red
            Else
                fntOIL.TextColor=xui.Color_Gray
            End If
             
        Case "0118" 'FUEL
            If Bit.ParseInt(value, 16) = 1 Then
                fntTANK.TextColor=xui.Color_ARGB(255,249,180,121)
            Else
                fntTANK.TextColor=xui.Color_Gray
            End If
             
        Case "0120" 'TEMP
            If Bit.ParseInt(value, 16) = 1 Then
                fntTEMP.TextColor=xui.Color_Red
            Else
                fntTEMP.TextColor=xui.Color_Gray
            End If
             
        Case "0122" 'METRIC
            If Bit.ParseInt(value, 16) = 1 Then
                xSpeedGauge.GaugeUnit="mph"
            Else
                xSpeedGauge.GaugeUnit="km/h"
            End If

        Case Else
            ' This case might never be reached due to the above modulo operation
    End Select
End Sub

' Calls the 'StateChanged' method to update the UI to reflect the disconnected state.
Sub Manager_Disconnected
    Log("Disconnected")
    connected = False
    StateChanged
End Sub

' Calls the 'StateChanged' method to update the UI to reflect the connected state.
Sub Manager_Connected (services As List)
    Log("Connected")
    connected = True
    ConnectedServices = services
    Log(services)
    StateChanged
End Sub

'utility to convert short UUIDs to long format on Android
Private Sub UUID(id As String) As String 'ignore
    Return "0000" & id.ToLowerCase & "-0000-1000-8000-00805f9b34fb"
End Sub
 
Last edited:
Top