BerryLan Implementation


#1

I’m developing a QT application and want to integrate it with BerryLan, but when i start adding code it gives me a lot of errors, like
-Type BerryLanPage unavailable
-Type StatusView unavailable
-module “BerryLan” is not installed

and also

no matching funtion for call to 'QmlRegistrationType ’
and much more


#2

Did you copy some parts of the berrylan app to your application?

If so, I cannot really tell what’s going wrong from your message. It’s likely something wrong in the project configuration (path etc) but I’d need to see the code to tell for sure.


#3

Can we make a remote session so i can show you exactly what i am doing and the error?

i am just trying to make the same function of berrylan in a tab of an app.


#4

To be honest I’d prefer looking at you code and discuss things here. That would also be beneficial to other people trying to achieve the same.


#5

Sure, well for starter i grab the berrylan code and open it (berrylan.pro) on QT creator and run it and i get a error message saying that:
module “Berrylan” is not installed.

If i get this working whats the correct way to implement it into a tab in a application? for example (Home,Profile, Settings, Connect(Berrylan code)), what do i need to copy into the code, #include or QT +=?


#6

Strange… I just tried…

$ git clone https://github.com/guh/berrylan

Then I open berrylan.pro with QtCreator and it builds and runs fine. I tried using Qt 5.12.1 on Ubuntu 18.08. I can’t really understand how you get this message because the module “Berrylan” is compiled into the binary and registered to QML in main.cpp so it should always find it. Are you sure you didn’t modify anything while trying which might have broken it?

To use the code in your app you’re gonna need to copy the entire wifisetup folder and add those files to your project file. Also, make sure to register all the types as seen in berrylan’s main.cpp.


#7

And i also have a webview error, is it because i am using windows?


#8

The webview error is likely because the webview Qt module isn’t installed in your qt installation.

I believe the reason why you get that message is because that Felgo Live Client breaks it… It would be possible to set up the project in a way the live client could find it, but it is not at this point. Try using a regular launch instead of the Live preview.


#9

now i get this error


#10

i deleted the QtWebView::initialize(); and now it works, thanks! now ill try to implement it into my app and let you know if i had any issues with it

but its weird because i do have the WebView lib


#11

Not i get this error: “LNK1168:cannot open debug/berrylan.exe for writing”

and this is the main.qml code

ApplicationWindow {
    id: app
    visible: true
    width: 320
    height: 480
    title: qsTr("SBI")

    Material.foreground: "#011627"
    Material.background: "#fdfffc"
    Material.accent: "#e71d36"

    property int iconSize: 32
    property int margins: 6
    property int largeFont: 20
    property int smallFont: 12

    BluetoothDiscovery {
        id: discovery
        discoveryEnabled: swipeView.currentIndex <= 1
        onBluetoothEnabledChanged: {
            if (!bluetoothEnabled) {
                swipeView.currentIndex = 0;
            }
        }
    }

    NetworkManagerController {
        id: networkManager
    }

    QtObject {
        id: d
        property var currentAP: null
        readonly property bool accessPointMode: networkManager.manager && networkManager.manager.wirelessDeviceMode == WirelessSetupManager.WirelessDeviceModeAccessPoint
    }

    Connections {
        target: discovery.deviceInfos
        onCountChanged: {
            if (swipeView.currentItem === discoveringView && discovery.deviceInfos.count > 0) {
                swipeView.currentIndex++
            }
        }
    }

    Connections {
        target: networkManager.manager
        onInitializedChanged: {
            print("initialized changed", networkManager.manager.initialized)

            if (networkManager.manager.initialized) {
                swipeView.currentIndex++;
            } else {
                swipeView.currentIndex = 0;
            }
        }

        onConnectedChanged: {
            print("connectedChanged", networkManager.manager.connected)
            if (!networkManager.manager.connected) {
                swipeView.currentIndex = 0;
            }
        }

        onNetworkStatusChanged: {
            print("Network status changed:", networkManager.manager.networkStatus)
            if (swipeView.currentItem === connectingToWiFiView) {
                if (networkManager.manager.networkStatus === WirelessSetupManager.NetworkStatusGlobal) {
                    swipeView.currentIndex++;
                } else {
                    print("UNHANDLED Network status change:", networkManager.manager.networkStatus  )
                }

            }
        }
        onWirelessStatusChanged: {
            print("Wireless status changed:", networkManager.manager.networkStatus)
            if (swipeView.currentItem === connectingToWiFiView) {
                if (networkManager.manager.wirelessStatus === WirelessSetupManager.WirelessStatusActivated) {
                    swipeView.currentIndex++;
                }
                if (networkManager.manager.wirelessStatus === WirelessSetupManager.WirelessStatusFailed) {
                    connectingToWiFiView.running = false
                    connectingToWiFiView.text = qsTr("Sorry, the password is wrong.")
                    connectingToWiFiView.buttonText = qsTr("Try again")
                }
            }
        }
    }

    // app initialization
    Component.onCompleted: {
        // if device has network connection, clear cache at startup
        // you'll probably implement a more intelligent cache cleanup for your app
        // e.g. to only clear the items that aren't required regularly
        if(isOnline) {
            logic.clearCache()
        }

        // fetch todo list data
        logic.fetchTodos()
        logic.fetchDraftTodos()
    }

    // business logic
    Logic {
        id: logic
    }

    // model
    DataModel {
        id: dataModel
        dispatcher: logic // data model handles actions sent by logic

        // global error handling
        onFetchTodosFailed: nativeUtils.displayMessageBox("Unable to load todos", error, 1)
        onFetchTodoDetailsFailed: nativeUtils.displayMessageBox("Unable to load todo "+id, error, 1)
        onStoreTodoFailed: nativeUtils.displayMessageBox("Failed to store "+viewHelper.formatTitle(todo))
    }

    // helper functions for view
    ViewHelper {
        id: viewHelper
    }

    // view
    Navigation {
        id: navigation

        // only enable if user is logged in
        // login page below overlays navigation then
        enabled: dataModel.userLoggedIn

        // first tab
        NavigationItem {
            title: qsTr("Home")
            icon: IconType.home

            NavigationStack {
                splitView: tablet // use side-by-side view on tablets
                initialPage: HomePage { }
            }
        }
        NavigationItem {
            title: qsTr("News") // use qsTr for strings you want to translate
            icon: IconType.newspapero

            NavigationStack {
                initialPage: NewsPage {
                }
            }
        }
        // second tab
        NavigationItem {
            title: qsTr("Profile") // use qsTr for strings you want to translate
            icon: IconType.user

            NavigationStack {
                initialPage: ProfilePage {
                    // handle logout
                    onLogoutClicked: {
                        logic.logout()

                        // jump to main page after logout
                        navigation.currentIndex = 0
                        navigation.currentNavigationItem.navigationStack.popAllExceptFirst()
                    }
                }
            }
        }
        NavigationItem {
            title: qsTr("Products") // use qsTr for strings you want to translate
            icon: IconType.plug

            StackView {
                id: pageStack
                anchors.fill: parent
                initialItem: BerryLanPage {
                    title: {
                        switch (swipeView.currentIndex) {
                        case 0:
                        case 1:
                        case 2:
                            return qsTr("Products")
                        case 3:
                            return qsTr("Network")
                        case 4:
                            return qsTr("Login")
                        case 5:
                            return qsTr("Connecting")
                        case 6:
                            return qsTr("Connected")
                        }
                    }

                    backButtonVisible: swipeView.currentIndex === 4

                    onHelpClicked: pageStack.push(Qt.resolvedUrl("components/HelpPage.qml"))
                    onBackClicked: {
                        d.currentAP = null
                        swipeView.currentIndex--
                    }

                    step: {
                        switch (swipeView.currentIndex) {
                        case 0:
                        case 1:
                            return 0;
                        case 2:
                            return 3;
                        case 3:
                            if (!networkManager.manager) {
                                return 2;
                            }
                            if (networkManager.manager.accessPoints.count == 0) {
                                return 3;
                            }
                            return 4;
                        case 4:
                            return 4;
                        case 5:
                            if (networkManager.manager.wirelessStatus < WirelessSetupManager.WirelessStatusConfig) {
                                return 5;
                            }
        //                    if (networkManager.manager.wirelessStatus < WirelessSetupManager.WirelessStatusIpConfig) {
                                return 6;
        //                    }
        //                    return 7;
                        case 6:
                            return 8;
                        }
                    }

                    content: SwipeView {
                        id: swipeView
                        anchors.fill: parent
                        interactive: false

                        // 0
                        WaitView {
                            id: discoveringView
                            height: swipeView.height
                            width: swipeView.width
                            text: !discovery.bluetoothAvailable
                                  ? qsTr("Bluetooth doesn't seem to be available on this device. SBI requires a working Bluetooth connection.")
                                  : !discovery.bluetoothEnabled
                                    ? qsTr("Bluetooth seems to be disabled. Please enable Bluetooth on your device in order to use the SBI App.")
                                    : qsTr("Searching for your\nProduct")
                        }

                        // 1
                        ListView {
                            id: discoveryListView
                            height: swipeView.height
                            width: swipeView.width
                            model: discovery.deviceInfos
                            clip: true

                            delegate: BerryLanItemDelegate {
                                width: parent.width
                                text: name
                                iconSource: "../images/bluetooth.svg"

                                onClicked: {
                                    networkManager.bluetoothDeviceInfo = discovery.deviceInfos.get(index);
                                    networkManager.connectDevice();
                                    swipeView.currentIndex++;
                                }
                            }
                        }

                        // 2
                        WaitView {
                            id: connectingToPiView
                            height: swipeView.height
                            width: swipeView.width
                            text: qsTr("Connecting to your Product")
                        }

                        // 3
                        ColumnLayout {
                            height: swipeView.height
                            width: swipeView.width

                            ListView {
                                Layout.fillWidth: true
                                Layout.fillHeight: true
                                id: apSelectionListView
                                model: WirelessAccessPointsProxy {
                                    id: accessPointsProxy
                                    accessPoints: networkManager.manager ? networkManager.manager.accessPoints : null
                                }
                                clip: true

                                delegate: BerryLanItemDelegate {
                                    width: parent.width
                                    text: model.ssid
                                    iconSource: model.signalStrength > 66
                                                ? "../images/wifi-100.svg"
                                                : model.signalStrength > 33
                                                  ? "../images/wifi-66.svg"
                                                  : model.signalStrength > 0
                                                    ? "../images/wifi-33.svg"
                                                    : "../images/wifi-0.svg"

                                    onClicked: {
                                        print("Connect to ", model.ssid, " --> ", model.macAddress)
                                        d.currentAP = accessPointsProxy.get(index);

                                        swipeView.currentIndex++;
                                    }
                                }
                            }

                            Button {
                                Layout.alignment: Qt.AlignHCenter
                                visible: networkManager.manager.accessPointModeAvailable
                                text: qsTr("Open Access Point")
                                onClicked: {
                                    swipeView.currentIndex++
                                }
                            }
                        }


                        // 4
                        Item {
                            id: authenticationView
                            width: swipeView.width
                            height: swipeView.height
                            ColumnLayout {
                                anchors.centerIn: parent
                                anchors.verticalCenterOffset: - swipeView.height / 4
                                width: app.iconSize * 8
                                spacing: app.margins
                                Label {
                                    Layout.fillWidth: true
                                    text: qsTr("Name")
                                    visible: !d.currentAP
                                }

                                TextField {
                                    id: ssidTextField
                                    Layout.fillWidth: true
                                    visible: !d.currentAP
                                    maximumLength: 32
                                    onAccepted: {
                                        passwordTextField.focus = true
                                    }
                                }

                                Label {
                                    Layout.fillWidth: true
                                    text: qsTr("Password")
                                }

                                RowLayout {
                                    TextField {
                                        id: passwordTextField
                                        Layout.fillWidth: true
                                        maximumLength: 64
                                        property bool showPassword: false
                                        echoMode: showPassword ? TextInput.Normal : TextInput.Password
                                        onAccepted: {
                                            okButton.clicked()
                                        }
                                    }

                                    ColorIcon {
                                        Layout.preferredHeight: app.iconSize
                                        Layout.preferredWidth: app.iconSize
                                        name: "../images/eye.svg"
                                        color: passwordTextField.showPassword ? "#e71d36" : keyColor
                                        MouseArea {
                                            anchors.fill: parent
                                            onClicked: passwordTextField.showPassword = !passwordTextField.showPassword
                                        }
                                    }
                                }

                                Button {
                                    id: okButton
                                    Layout.fillWidth: true
                                    text: qsTr("OK")
                                    enabled: passwordTextField.displayText.length >= 8
                                    onClicked: {
                                        if (d.currentAP) {
                                            connectingToWiFiView.text = qsTr("Connecting the Product to %1").arg(d.currentAP.ssid);
                                            networkManager.manager.connectWirelessNetwork(d.currentAP.ssid, passwordTextField.text)
                                        } else {
                                            connectingToWiFiView.text = qsTr("Opening access point \"%1\" on the Product").arg(ssidTextField.text);
                                            networkManager.manager.startAccessPoint(ssidTextField.text, passwordTextField.text)
                                        }
                                        connectingToWiFiView.buttonText = "";
                                        connectingToWiFiView.running = true

                                        swipeView.currentIndex++
                                    }
                                }
                            }
                        }

                        // 5
                        WaitView {
                            id: connectingToWiFiView
                            height: swipeView.height
                            width: swipeView.width
                            onButtonClicked: {
                                swipeView.currentIndex--;
                            }
                        }

                        // 6
                        Item {
                            id: resultsView
                            height: swipeView.height
                            width: swipeView.width

                            ColumnLayout {
                                anchors.fill: parent
                                Label {
                                    Layout.fillWidth: true
                                    Layout.margins: app.margins
                                    text: d.accessPointMode
                                          ? qsTr("Access point name: %1").arg(networkManager.manager.currentConnection.ssid)
                                          : networkManager.manager.currentConnection ? qsTr("IP Address: %1").arg(networkManager.manager.currentConnection.hostAddress) : ""
                                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                                    font.pixelSize: app.largeFont
                                    font.bold: true
                                    horizontalAlignment: Text.AlignHCenter
                                }
                                Button {
                                    Layout.alignment: Qt.AlignHCenter
                                    visible: d.accessPointMode
                                    text: qsTr("Close access point")
                                    onClicked: {
                                        networkManager.manager.disconnectWirelessNetwork();
                                    }
                                }

                                Item {
                                    Layout.fillWidth: true
                                    Layout.fillHeight: true
                                    ColumnLayout {
                                        anchors.centerIn: parent
                                        width: parent.width
                                        spacing: app.margins * 4
                                        Label {
                                            text: qsTr("Thanks for using SBI!")
                                            font.pixelSize: app.largeFont
                                            Layout.fillWidth: true
                                            wrapMode: Text.WordWrap
                                            horizontalAlignment: Text.AlignHCenter
                                        }
                                        ColorIcon {
                                            Layout.preferredHeight: app.iconSize
                                            Layout.preferredWidth: app.iconSize
                                            Layout.alignment: Qt.AlignHCenter
                                            name: "../images/github.svg"

                                            MouseArea {
                                                anchors.fill: parent
                                                onClicked: {
                                                    Qt.openUrlExternally("https://github.com/guh/berrylan")
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

        // login page lies on top of previous items and overlays if user is not logged in
        LoginPage {
            visible: opacity > 0
            enabled: visible
            opacity: dataModel.userLoggedIn ? 0 : 1 // hide if user is logged in
    
            Behavior on opacity { NumberAnimation { duration: 250 } } // page fade in/out
        }
    
    
    
    }

#12

It’s been a while since I last worked on Windows, but from the error message you get I suppose the app is running, so Windows cannot overwrite it with the new build.


#13

it was because i didnt closed the window of the build haha,
but now i get this error message
QQmlApplicationEngine failed to load component

qrc:/main.qml:8 "…/berrylan-master/model": no such directory

11:09:13: C:/Users/dbedard.SBINTL/Downloads/berrylan-master/build-berrylan-Desktop_Qt_5_11_2_MSVC2017_64bit4-Debug/debug/berrylan.exe exited with code -1

which is false because i do have the model directory


#14

i am using felgo (v-play) to develop this app, but when i import it, it gives me all this errors, what should i do in this case? is there a work around for this or what sould i do in this case? forget of using felgo and just QT or idk.
thanks for the help!


#15

That looks quite alright. The clang code model doesn’t find find those so they are marked red inside the code view. That’s odd, code completion won’t work in that case, but it is not critical. I think if you actually compile it and start the app it should work.

From the log output I can see that it actually does work. The other issue though is that there doesn’t seem to be a Bluetooth adapter available (or qt fails to find it). You need to resolve that (or start the app on a android device).

The other errors, the typeerrors in line 243 and 352 are also not critical. The networkManager object will become valid once Bluetooth is connected and it will start working.


#16

Sorry i didn’t build it after adding the code, here is the error that i get


#17

This looks like something specific to the Felgo setup… Not sure about that since I never used Felgo so far.