Cocoamqtt Init,Can Can can似乎连接到MQTT经纪人

发布于 2025-02-09 17:51:18 字数 7800 浏览 0 评论 0 原文

请原谅我有多少新手。我从上周初开始进行Swift ...

我正在尝试制作一个使用BLE和或MQTT通过经纪人与Raspberry Pi交谈的应用程序。 BLE侧是可以的,但是MQTT(对于BLE范围之外)我遇到了麻烦。 这是在几个类的迅速文件中:

import Foundation
import CocoaMQTT

class MQTTManager{

    static let shared = MQTTManager()

    private var mqttClient: CocoaMQTT
   
    init() {
        let clientID = "swift-Trial-13579"
        let host = "IP.Goes.Here"
        let port = UInt16(1883)
        self.mqttClient = CocoaMQTT(clientID: clientID, host: host, port: port)
        self.mqttClient.username = "User"
        self.mqttClient.password = "Pass"
        self.mqttClient.keepAlive = 60
        self.mqttClient.connect()
        sendMessage(topic: "app/init", message: "init called")
        print("MQTT Init Called")
    }

    func sendMessage(topic:String, message:String){
        self.mqttClient.publish(topic, withString: message)
        print("publish MQTT called with message: \(message) and a topic of: \(topic)")
    }

}

class useProperties: ObservableObject{
    @Published var useMQTT = false
    @Published var recallMQTTScene = false
    @Published var MQTTScene = 0
    
    init(){
    }
}

然后,我有3个视图,contentview

import SwiftUI
import CocoaMQTT

struct ContentView: View {
    
        
    @State public var Connection:Bool = false
    @State public var SceneMessqe: String = ""
    let MQTTHandle = MQTTManager()
    
// the main view actually is here
    var body: some View{
       // SceneButton(function: { self.MQTTPub})
        VStack{
            HStack {
                Text("MultiControl POC")
                    .font(.title)
                //.padding()

            }
            Spacer()
            mainSwitch()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(BLEManager())
    }
}

mainswitch

import SwiftUI
import CocoaMQTT

struct mainSwitch: View {
    
    @State public var Connection:Bool = false
    @State private var selection: String? = nil
    @StateObject var bleManager = BLEManager() // gets from environment.
    public var properties = useProperties()
    @State private var selectDeviceShown = false
    @State var isPresenting = false
    public var MQTTHandle = MQTTManager()
    
    var body: some View {
        VStack (spacing: 0){
            NavigationView{
            HStack {
                Spacer()
                NavigationLink(destination: sheetView(), isActive: $isPresenting) { EmptyView() }// added for nav but not working
                Menu("Menu") {
                    Button("BLE Setup", action: {
                        self.isPresenting = true // added to trigger nav not workinh
                        print("Setup button pressed")
                        //selectDeviceShown = true
                    })
                    Button("Reconnect", action: {
                        bleManager.myCentral.connect(bleManager.wrappedControllers[bleManager.currentSceneSwitchControllerUUID]!.wrappedPerh)
                    })
                    Button(action: {
                        MQTTManager.init()
                        Connection.toggle()
                        properties.useMQTT = true
                        print("connect/disconnect pressed useMQTT = \(properties.useMQTT)")
                        }, label: {
                            Text(Connection ? "MQTT Disconnect":"MQTT Connect")
                        })
                    Button("Cancel", action: {
                        print("oops")
                    })
                }
                .foregroundColor(Connection ? .green : .red)
                .padding(38)
                .overlay(
                    RoundedRectangle(cornerRadius: 15)
                        .stroke(lineWidth: 2)
                        .foregroundColor(Connection ? .green : .red)
            )
                Spacer()
                Spacer()
            }
            .fixedSize(horizontal: false, vertical: true)
            .frame(maxHeight: 10)
            .padding()
            }
            HStack{
                Spacer()
                VStack{
                    Spacer()
                    SceneButton(sceneName: "Scene 1", sceneNumber: 1)
                    Spacer()
                    SceneButton(sceneName: "Scene 3" , sceneNumber: 3)
                    Spacer()
                    SceneButton(sceneName: "Scene 5", sceneNumber: 5)
                    Spacer()
                }
                Spacer()
                VStack{
                    Spacer()
                    SceneButton(sceneName: "Scene 2", sceneNumber: 2)
                    Spacer()
                    SceneButton(sceneName: "Scene 4", sceneNumber: 4)
                    Spacer()
                    SceneButton(sceneName: "Off", sceneNumber: 6)
                    Spacer()
                }
                Spacer()
            }
            Spacer()
        }
        .environmentObject(useProperties())
        .environmentObject(BLEManager())
    }
}

struct mainSwitch_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            mainSwitch()
                .environmentObject(BLEManager())
                .environmentObject(useProperties())
        }
    }
}

,最后是当前的castect button

import SwiftUI
import CocoaMQTT

struct SceneButton: View {
    
    var sceneName: String
    var sceneNumber: Int
    let properties = useProperties()
    @State private var isDisabled: Bool = true
    @State private var isDuringGesture: Bool = false
    @StateObject private var bleManager = BLEManager()
    let btnClr:Color = Color.orange
    let btnClrOutr:Color = Color.red
    let btnPressedClr:Color = Color.gray
    let MQTTHandle = MQTTManager()
    
    var body: some View {

        if (properties.useMQTT){
            Button(sceneName) {
                bleManager.writeToCharacteristicButtonPress(peripheral: bleManager.currentSceneSwitchControllerUUID, sceneToGoToo: (sceneNumber).description, setButtonPressed: true) // Note the number is the same number as the button.
                bleManager.writeToCharacteristicButtonPress(peripheral: bleManager.currentSceneSwitchControllerUUID, sceneToGoToo: (sceneNumber).description, setButtonPressed: false)
                print("BLE Button" + sceneName)
                print("\(properties.useMQTT)")
            }
            .foregroundColor(.white)
                .frame(minWidth: 100)
                .padding()
                .background(Color(red: 1, green: 0.1, blue: 0.1))
                .cornerRadius(10)
                .padding(10)
                .font(.title2)
                .font(.system(size: 20))
        }else{
            Button(sceneName) {
                print("\(properties.useMQTT)")
                MQTTHandle.sendMessage(topic: "apptest/scene", message: "\(sceneNumber)")
            }
                .frame(minWidth: 100)
                .padding()
                .background(Color(red: 0.40, green: 0.60, blue: 0))
                .cornerRadius(10)
                .padding(10)
        }
    }
}

struct SceneButton_Previews: PreviewProvider {
    static var previews: some View {
        SceneButton(sceneName: "Scene X", sceneNumber: 42) //, publishSceneMQTT: sceneHandle
            .environmentObject(BLEManager())
            .environmentObject(useProperties())
    }
}

,当应用程序加载它调用mqtt init多次,然后不会可靠地连接,有时甚至是10分之一。它连接到发送一条消息,然后我无法发送更多。 理想情况下,只有在我按Mainswitch菜单中的“连接”按钮时,它才会连接。但是,每个按钮(scenetbutton)应该发布一些略有不同的内容。

首先,它是否在开始时一直在调用init的问题?

其次,我做错了什么,这意味着它没有可靠地连接?

第三,(最不重要的)在scene但是(最不重要的)按钮应该更改,无论是使用BLE还是MQTT,此变量,USEMQTT都设置在MainSwitch文件中。但是,button的变化不改变,我做错了什么?

Please excuse how much of a newbie I am. I started on swift at the beginning of last week...

I am trying to make an app that uses BLE and or MQTT to talk to a raspberry pi through a broker. the BLE side is ok but the MQTT (for when out of BLE range) I'm having trouble with.
This is in a swift file of a couple of classes:

import Foundation
import CocoaMQTT

class MQTTManager{

    static let shared = MQTTManager()

    private var mqttClient: CocoaMQTT
   
    init() {
        let clientID = "swift-Trial-13579"
        let host = "IP.Goes.Here"
        let port = UInt16(1883)
        self.mqttClient = CocoaMQTT(clientID: clientID, host: host, port: port)
        self.mqttClient.username = "User"
        self.mqttClient.password = "Pass"
        self.mqttClient.keepAlive = 60
        self.mqttClient.connect()
        sendMessage(topic: "app/init", message: "init called")
        print("MQTT Init Called")
    }

    func sendMessage(topic:String, message:String){
        self.mqttClient.publish(topic, withString: message)
        print("publish MQTT called with message: \(message) and a topic of: \(topic)")
    }

}

class useProperties: ObservableObject{
    @Published var useMQTT = false
    @Published var recallMQTTScene = false
    @Published var MQTTScene = 0
    
    init(){
    }
}

I then have 3 views, ContentView

import SwiftUI
import CocoaMQTT

struct ContentView: View {
    
        
    @State public var Connection:Bool = false
    @State public var SceneMessqe: String = ""
    let MQTTHandle = MQTTManager()
    
// the main view actually is here
    var body: some View{
       // SceneButton(function: { self.MQTTPub})
        VStack{
            HStack {
                Text("MultiControl POC")
                    .font(.title)
                //.padding()

            }
            Spacer()
            mainSwitch()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(BLEManager())
    }
}

mainSwitch

import SwiftUI
import CocoaMQTT

struct mainSwitch: View {
    
    @State public var Connection:Bool = false
    @State private var selection: String? = nil
    @StateObject var bleManager = BLEManager() // gets from environment.
    public var properties = useProperties()
    @State private var selectDeviceShown = false
    @State var isPresenting = false
    public var MQTTHandle = MQTTManager()
    
    var body: some View {
        VStack (spacing: 0){
            NavigationView{
            HStack {
                Spacer()
                NavigationLink(destination: sheetView(), isActive: $isPresenting) { EmptyView() }// added for nav but not working
                Menu("Menu") {
                    Button("BLE Setup", action: {
                        self.isPresenting = true // added to trigger nav not workinh
                        print("Setup button pressed")
                        //selectDeviceShown = true
                    })
                    Button("Reconnect", action: {
                        bleManager.myCentral.connect(bleManager.wrappedControllers[bleManager.currentSceneSwitchControllerUUID]!.wrappedPerh)
                    })
                    Button(action: {
                        MQTTManager.init()
                        Connection.toggle()
                        properties.useMQTT = true
                        print("connect/disconnect pressed useMQTT = \(properties.useMQTT)")
                        }, label: {
                            Text(Connection ? "MQTT Disconnect":"MQTT Connect")
                        })
                    Button("Cancel", action: {
                        print("oops")
                    })
                }
                .foregroundColor(Connection ? .green : .red)
                .padding(38)
                .overlay(
                    RoundedRectangle(cornerRadius: 15)
                        .stroke(lineWidth: 2)
                        .foregroundColor(Connection ? .green : .red)
            )
                Spacer()
                Spacer()
            }
            .fixedSize(horizontal: false, vertical: true)
            .frame(maxHeight: 10)
            .padding()
            }
            HStack{
                Spacer()
                VStack{
                    Spacer()
                    SceneButton(sceneName: "Scene 1", sceneNumber: 1)
                    Spacer()
                    SceneButton(sceneName: "Scene 3" , sceneNumber: 3)
                    Spacer()
                    SceneButton(sceneName: "Scene 5", sceneNumber: 5)
                    Spacer()
                }
                Spacer()
                VStack{
                    Spacer()
                    SceneButton(sceneName: "Scene 2", sceneNumber: 2)
                    Spacer()
                    SceneButton(sceneName: "Scene 4", sceneNumber: 4)
                    Spacer()
                    SceneButton(sceneName: "Off", sceneNumber: 6)
                    Spacer()
                }
                Spacer()
            }
            Spacer()
        }
        .environmentObject(useProperties())
        .environmentObject(BLEManager())
    }
}

struct mainSwitch_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            mainSwitch()
                .environmentObject(BLEManager())
                .environmentObject(useProperties())
        }
    }
}

and finally sceneButton

import SwiftUI
import CocoaMQTT

struct SceneButton: View {
    
    var sceneName: String
    var sceneNumber: Int
    let properties = useProperties()
    @State private var isDisabled: Bool = true
    @State private var isDuringGesture: Bool = false
    @StateObject private var bleManager = BLEManager()
    let btnClr:Color = Color.orange
    let btnClrOutr:Color = Color.red
    let btnPressedClr:Color = Color.gray
    let MQTTHandle = MQTTManager()
    
    var body: some View {

        if (properties.useMQTT){
            Button(sceneName) {
                bleManager.writeToCharacteristicButtonPress(peripheral: bleManager.currentSceneSwitchControllerUUID, sceneToGoToo: (sceneNumber).description, setButtonPressed: true) // Note the number is the same number as the button.
                bleManager.writeToCharacteristicButtonPress(peripheral: bleManager.currentSceneSwitchControllerUUID, sceneToGoToo: (sceneNumber).description, setButtonPressed: false)
                print("BLE Button" + sceneName)
                print("\(properties.useMQTT)")
            }
            .foregroundColor(.white)
                .frame(minWidth: 100)
                .padding()
                .background(Color(red: 1, green: 0.1, blue: 0.1))
                .cornerRadius(10)
                .padding(10)
                .font(.title2)
                .font(.system(size: 20))
        }else{
            Button(sceneName) {
                print("\(properties.useMQTT)")
                MQTTHandle.sendMessage(topic: "apptest/scene", message: "\(sceneNumber)")
            }
                .frame(minWidth: 100)
                .padding()
                .background(Color(red: 0.40, green: 0.60, blue: 0))
                .cornerRadius(10)
                .padding(10)
        }
    }
}

struct SceneButton_Previews: PreviewProvider {
    static var previews: some View {
        SceneButton(sceneName: "Scene X", sceneNumber: 42) //, publishSceneMQTT: sceneHandle
            .environmentObject(BLEManager())
            .environmentObject(useProperties())
    }
}

Currently when the app loads it calls the MQTT init many times, and then doesn't connect reliably, occasionally, maybe 1 in 10 times it connects to send a single message then I can't send more.
Ideally it would only connect when I press the connect button in the menu in mainSwitch. However each button (SceneButton) should publish something slightly different.

Firstly, is it an issue that it keeps calling init at start?

Secondly, is there something visible that I am doing wrong to mean its not reliably connecting?

thirdly, (least important) in sceneButton the button should change whether using BLE or MQTT, this variable, useMQTT is set in the mainSwitch file. but doesn't change in sceneButton, what have I done wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忆悲凉 2025-02-16 17:51:18

您无处不在(!) mqttmanager 的不同实例,因为通过 init 创建它,您应该在 mqttmanager.shared 中使用它。 /code>,就像

struct ContentView: View {
    
        
    @State public var Connection:Bool = false
    @State public var SceneMessqe: String = ""
//    let MQTTHandle = MQTTManager()       // << not this !!
    let MQTTHandle = MQTTManager.shared    // << this one !!

这样查看您的所有代码并按照上述修复。

You use everywhere (!) different instances of MQTTManager, because create it via init, instead you should use everywhere MQTTManager.shared, like

struct ContentView: View {
    
        
    @State public var Connection:Bool = false
    @State public var SceneMessqe: String = ""
//    let MQTTHandle = MQTTManager()       // << not this !!
    let MQTTHandle = MQTTManager.shared    // << this one !!

so review all your code and fix as above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文