B4J Question [SOLVED][PyBridge] Unknown errors dedicated class

rwblinn

Well-Known Member
Licensed User
Longtime User
Hi,
Iam trying to create B4J class BLEManager to initialize the PyBridge & BLE with Bleak.

The B4J IDE shows error in the log but can not find where these are.

Any help appreciated.

B4X:
Syntax error.
Syntax error.
Syntax error.
'Else' expected.
Unknown member: pylog
Unknown member: pylog
Unknown member: evalglobals
Unknown member: flush
Unknown member: convertlambdaifmatch
Unknown member: detectos
Unknown member: pythonbridgecodeversion
Current declaration does not match previous one.<br />Previous: {Type=Utils,Rank=0, RemoteObject=False}<br />Current: {Type=PyUtils,Rank=0, RemoteObject=True}
Unknown member: connected
Unknown member: createpyobject
Unknown member: createpyobject

In the B4XPages MainPage the initialization is like:
B4X:
    ' Initialize BLEMgr
    BLEMgr.Initialize(Constants.BLE_SERVER_NAME, B4XPages.GetPage("MainPage"))

    ' Start the PyBridge and initialize BLE
    Wait For (BLEMgr.Start) complete (result As Boolean)
    If result Then
        CustomListViewLog_Insert($"[B4XPage_Created]${Utils.LOG_I} PyBridge started, BLE initialized"$)
    Else
        CustomListViewLog_Insert($"[B4XPage_Created]${Utils.LOG_W} Failed to start the PyBridge initialize BLE"$)
    End If


This is the B4J Class BLEManager:

B4X:
Sub Class_Globals
    ' BLE
    Public SERVICE_UUID As String         = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"    ' UART
    Public CHAR_UUID_TX As String         = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"    ' Transmit
    Public CHAR_UUID_RX As String         = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"    ' Receive Flags read,notify,write

    Private mBle As Bleak                    'Bleak Object
    Private mBleDevice As BleakDevice
    Private mBleDeviceName As String
    Private mBleCLient As BleakClient        'Bleak client connected to the ble device
    Public IsConnected As Boolean = False
    
    ' PyBridge
    Private PATH_TO_PYTHON As String = "Python/python/python.exe"
    Public Py As PyBridge
    
    ' MainPage
    Private mMainPage As B4XMainPage
    
    ' Logging
    Public LastMsg As String
End Sub

#Region Initialize
' Initialize
' Initializes the object.
' Parameters
'    devicename String - BLE device name to connect to
' Returns
'    state Boolean - State
Public Sub Initialize(devicename As String, mainpage As B4XMainPage)
    mBleDeviceName = devicename
    mMainPage = mainpage
End Sub

' Start
' Start the PyBridge and then initialize BLE
Public Sub Start As ResumableSub
    ' Start the PyBridge
    Wait For (PyBridgeStart) complete (result As Boolean)
    If result Then
        ' Init BLE using Bleak object and pybridge instance
        mBle.Initialize(Me, "ble", Py)
    End If
    Return result
End Sub
#End Region

#Region PyBridge
Public Sub PyBridgeStart As ResumableSub
    LastMsg = ""
    
    ' PyBridge with event Py, like Py_Connected, Py_Disconnected
    Log($"[BLEManager.PyBridgeStart] Py.Initialize..."$)
    Py.Initialize(Me, "Py")
    Log($"[BLEManager.PyBridgeStart] Done"$)

    ' Set options: path to the python exe
    Dim opt As PyOptions = Py.CreateOptions(PATH_TO_PYTHON)

    ' Start the Python bridge with options set
    Py.Start(opt)

    ' Connect to the pybridge using Py instance
    Wait For Py_Connected (Success As Boolean)
    If Not(Success) Then
        LastMsg = $"[BLEManager.PyBridgeStart]${Utils.LOG_E} Failed to start Python process."$
        LogError(LastMsg)
        Return False
    Else
        LastMsg = $"[BLEManager.PyBridgeStart]${Utils.LOG_I} Python process started."$
        Log(LastMsg)
        Return True
    End If
End Sub

' Kills the pybridge process and closes the connection
Public Sub PyBridgeKillProcess
    Py.KillProcess
    LastMsg = $"[BLEManager.PyBridgeKillProcess]${Utils.LOG_I} OK"$
    Log(LastMsg)
End Sub

' Event triggered by pybridge disconnected from pybridge object (Py).
Private Sub Py_Disconnected
    mMainPage.PyBridgeDisconnected
    LastMsg = $"[BLEManager.Py_Disconnected]${Utils.LOG_E} PyBridge disconnected"$
    Log(LastMsg)
End Sub
#End Region

#Region BLE
Public Sub Scan As ResumableSub
    Dim result As Boolean
    ' Do nothing if already connected
    If IsConnected Then
        result = True
        Return result
    End If
    
    ' Not connected > start scanning for devices
    If Not(IsConnected) Then
        ' Scan for devices using service uuid.
        Log($"[BLEManager.Scan]${Utils.LOG_I} scanning devices. serviceuuid=: ${SERVICE_UUID}"$)

        ' The event ble_devicefound is raised.
        Wait For (mBle.Scan(Array As String(SERVICE_UUID))) Complete (Success As Boolean)
        ' Devices found
        If Success Then
            LastMsg = $"[BLEManager.Scan]${Utils.LOG_I} devices found."$
            Log(LastMsg)
            result = True
        Else
            LastMsg = $"[BLEManager.Scan]${Utils.LOG_E} ${Py.PyLastException}"$
            LogError(LastMsg)
            result = False
        End If
    Else
        Wait For(mBleCLient.Disconnect) Complete (Success As Boolean)
        result = Success
    End If
    Return result
End Sub

' Connect to the BLE-Server.
Public Sub Connect As ResumableSub
    'Create a new ble client from the global bledevice
    mBleCLient = mBle.CreateClient(mBleDevice)
    
    'Connect to the bledevice
    Log($"[BLEManager.BLEConnect]${Utils.LOG_I} Connecting. deviceid=${mBleDevice.DeviceId}"$)
    Wait For (mBleCLient.Connect) Complete (Success As Boolean)
    If Success Then
        IsConnected = True
        LastMsg = $"[BLEManager.BLEConnect] connected, deviceid=${mBleDevice.DeviceId}"$
        Sleep(10)
        SetNotify
        Log(LastMsg)
    Else
        IsConnected = False
        LastMsg = $"[BLEManager.BLEConnect]${Utils.LOG_E} ${Utils.ParseErrorMessage(Py.PyLastException)}"$
        LogError(LastMsg)
    End If
    Return IsConnected
End Sub

Public Sub Disconnect As ResumableSub
    Wait For (mBleCLient.Disconnect) Complete (Success As Boolean)
    If Success Then
        IsConnected = False
        LastMsg = $"[BLEManager.Disconnect] Disconnected, deviceid=${mBleDevice.DeviceId}"$
        Sleep(10)
        SetNotify
        Log(LastMsg)
    Else
        IsConnected = True
        LastMsg = $"[BLEManager.Disconnect]${Utils.LOG_E} ${Utils.ParseErrorMessage(Py.PyLastException)}"$
        LogError(LastMsg)
    End If
    Return Success
End Sub

' BLE device found, check for BLE-Server.
' Event triggered by ble.scan (Bleak.b4xlib).
Private Sub BLE_DeviceFound(Device As BleakDevice)
    'Do nothing if not scanning
    If mBle.IsScanning = False Then Return
    'Log($"[ble_DeviceFound] ${Device.DeviceId}, Name=${Device.Name}, Services=${Device.ServiceUUIDS}, ServiceData=${Device.ServiceData}"$)

    'Check if BL Server found
    If Device.name.EqualsIgnoreCase(Constants.BLE_SERVER_NAME) Then
        'Assign the device found to the global bledevice
        mBleDevice = Device
        Log($"[BLEManager.BLE_DeviceFound]${Utils.LOG_I} id=${mBleDevice.DeviceId}, name=${mBleDevice.Name}, services=${mBleDevice.ServiceUUIDS}, servicedata=${mBleDevice.ServiceData}"$)

        'Stop scan
        mBle.StopScan

        'Connect to the BLE-Server using the global bledevice
        Connect
    End If
End Sub

' Event triggered by ble (Bleak.b4xlib).
Private Sub BLE_DeviceDisconnected(DeviceId As String)
    mMainPage.PyBridgeDisconnected
    LastMsg = $"[BLEManager.BLE_DeviceDisconnected]${Utils.LOG_I} BLE device disconnected"$
    Log(LastMsg)
End Sub

' Handle notification received.
' Event triggered by ble (Bleak.b4xlib).
Private Sub BLE_CharNotify(Notification As BleakNotification)
    Log($"[BLEManager.BLE_CharNotify]${Utils.LOG_I} charuuid=${Notification.CharacteristicUUID}"$)
    mMainPage.HandleBLENotification(Notification.value)
End Sub

'Read data from the ble-server using the read characteristic.
Public Sub Read
    If Not(IsConnected) Then Return

    Wait For (mBleCLient.ReadChar(CHAR_UUID_RX)) Complete (Result As PyWrapper)
    If Not(Result.IsSuccess) Then
        LastMsg = $"[BLEManager.Read]${Utils.LOG_E} ${Utils.ParseErrorMessage(Result.ErrorMessage)}"$
        LogError(LastMsg)
    Else
        'Get the received data as bytearray
        Dim data() As Byte = Result.Value
        'item = BytesToString(data, 0, data.Length, "ascii")
        LastMsg = $"[BLEManager.Read]${Utils.LOG_I} data=${Utils.ByteConv.HexFromBytes(data)}"$
        Log(LastMsg)
    End If
End Sub

'NOT USED
'Private Sub NotificationEvent(n As BleakNotification)
'    Dim item As String
'    item = $"Notification=${BytesToString(n.Value, 0, n.Value.Length, "ASCII")}"$
'    CustomListViewLog.InsertAt(0, CustomListViewLog_CreateItem(item), "")
'End Sub

'Set the ble notify flag using the notify characteristic.
Public Sub SetNotify
    If Not(IsConnected) Then Return

    Wait For (mBleCLient.SetNotify(CHAR_UUID_RX)) Complete (Result As PyWrapper)
    If Not(Result.IsSuccess) Then
        LastMsg = $"[BLEManager.SetNotify]${Utils.LOG_E} ${Utils.ParseErrorMessage(Result.ErrorMessage)}"$
        LogError(LastMsg)
    Else
        LastMsg = $"[BLEManager.SetNotify]${Utils.LOG_I} OK. Waiting for data..."$
        Log(LastMsg)
    End If
End Sub

'Write data to the ble-server using the write characteristic.
Public Sub Write(b() As Byte)
    If Not(IsConnected) Then Return

    Log($"[BLEManager.Write] data=${Convert.ByteConv.HexFromBytes(b)}"$)

    'Write bytes to the characteristic
    Dim rs As Object = mBleCLient.Write(CHAR_UUID_TX, b)
    Wait For (rs) Complete (Result2 As PyWrapper)
    If Not(Result2.IsSuccess) Then
        LastMsg = $"[BLEManager.Write]${Utils.LOG_E} ${Utils.ParseErrorMessage(Result2.ErrorMessage)}"$
        LogError(LastMsg)
    Else
        LastMsg = $"[BLEManager.Write]${Utils.LOG_I} OK, data=${Utils.ByteConv.HexFromBytes(b)}"$
        Log(LastMsg)
    End If
End Sub
#End Region
 

rwblinn

Well-Known Member
Licensed User
Longtime User
Found the issue.

In the project, had a utility code module added named Utils.bas.
After renaming Utils.bas to CommonUtils.bas, the errors disappeared and the program is working OK.

Found out by creating a new B4J Pybridge program and searched for text "pythonbridge".
In the source "pybridge.java", there is a declaration
public b4j.example.pyutils _utils = null;
So thought that there might be naming conflict.

Anyhow, it is working now.
 
Upvote 0
Top