iphone MQTT 和 adafruit objc 的应用程序无法正常工作

iphone app for MQTT and adafruit objc not working

我在 ESP8266-01 上构建了一个 MQTT 客户端,它收集传感器数据并将其发布到我在 Adafruit.com 上的帐户仪表板。我还在 ESP8266-12e 上构建了一个,该 ESP8266-12e 订阅了我的 Adafruit 帐户,并在仪表板值之一存在特定条件时打开一个 pin。 我正在尝试使用此处的教程 (https://stablekernel.com/article/esp8266-programming-building-a-iot-weather-station-episode-3/#comments-area) 创建一个 iPhone 应用程序,该应用程序将订阅 Adafruit 仪表板并显示各种值,并在点击按钮时发布一个值。我已经使用 Pods 和 copied/modified 代码安装了框架,但是当我启动应用程序时,它不会更新值,也不会在点击按钮时发布值。
这是我的 iPhone 应用程序代码:

#import "ViewController.h"
#import <MQTTClient/MQTTClient.h>
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *batteryValueLabel;
@property (strong, nonatomic) IBOutlet UILabel *tempValueLabel;
@property (weak, nonatomic) IBOutlet UILabel *levelValueLabel;
@property (weak, nonatomic) IBOutlet UILabel *tripValueLabel;
@property (weak, nonatomic) IBOutlet UILabel *dateValueLabel;
@property(nonatomic, strong, readwrite) NSArray *certificates;
@property(nonatomic, weak) IBOutlet UIButton *Fill;


-(IBAction)Turnon:(id)sender;
@end
NSString *trip = @"0";
int trigger =1;
MQTTSession *session;
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    MQTTCFSocketTransport *transport = [[MQTTCFSocketTransport alloc] init];
    transport.host = @"io.adafruit.com";
    transport.port = 1883;
    transport.certificates = [NSArray arrayWithObjects:@"xxxxxx",@"axxxxxxxxxxxxxxxxxxxx", nil];
    session = [[MQTTSession alloc] init];
    session.transport = transport;
    session.delegate = self;
    [session connectAndWaitTimeout:30];
    [session subscribeToTopic:@"feeds/date" atLevel:1 subscribeHandler:^(NSError *error, NSArray *gQoss){
//These never get called
        if (error) {
            NSLog(@"Subscription failed %@", error.localizedDescription);
        } else {
            NSLog(@"Subscription sucessfull! Granted Qos: %@", gQoss);
        }
    }];
}
- (void)newMessage:(MQTTSession *)session
              data:(NSData *)data
           onTopic:(NSString *)topic
               qos:(MQTTQosLevel)qos
          retained:(BOOL)retained
               mid:(unsigned int)mid {
    NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//These don't get called
    NSLog(@"%@", topic);
    NSLog(@"%@", dataString);
    if ([topic isEqualToString:@"feeds/date"]){
        self.dateValueLabel.text = dataString;}
}
-(IBAction)Turnon:(id)sender;{
    if(trigger ==1){
        trip = @"0";
        trigger = 2;
    }
    else if(trigger==2){
        trip = @"100";
        trigger = 1;
    }
    NSData* data = [trip dataUsingEncoding:NSUTF8StringEncoding];
    [session publishData:data onTopic:@"feeds/trip" retain:NO qos:1 publishHandler:nil];
    NSLog(@"%@", trip);
    NSLog(@"%d",trigger);
}
@end

这是我打开应用程序并尝试订阅时的日志:

2020-12-24 17:00:47.705408-0700 iphoneMQTT[26045:13918734] [MQTTSession] init
2020-12-24 17:00:47.705578-0700 iphoneMQTT[26045:13918734] [MQTTSession] connecting
2020-12-24 17:00:47.705610-0700 iphoneMQTT[26045:13918734] [MQTTCoreDataPersistence] deleteAllFlowsForClientId MQTTClient705518
2020-12-24 17:00:47.725848-0700 iphoneMQTT[26045:13918734] [MQTTPersistence] Persistent store: /var/mobile/Containers/Data/Application/78971181-5902-4962-AED0-F954C3304BB2/Documents/MQTTClient
2020-12-24 17:00:47.727835-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketTransport] open
2020-12-24 17:00:47.729945-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketEncoder] setState 0/0
2020-12-24 17:00:47.780073-0700 iphoneMQTT[26045:13918734] [MQTTSessionSynchron] waiting for connect
2020-12-24 17:00:47.881014-0700 iphoneMQTT[26045:13918734] [MQTTSessionSynchron] waiting for connect
2020-12-24 17:00:47.944259-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketDecoder] NSStreamEventOpenCompleted
2020-12-24 17:00:47.944465-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketEncoder] NSStreamEventOpenCompleted
2020-12-24 17:00:47.944588-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketEncoder] NSStreamEventHasSpaceAvailable
2020-12-24 17:00:47.944705-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketEncoder] setState 0/1
2020-12-24 17:00:47.944833-0700 iphoneMQTT[26045:13918734] [MQTTSession] mqttTransportDidOpen
2020-12-24 17:00:47.944941-0700 iphoneMQTT[26045:13918734] [MQTTSession] sending CONNECT
2020-12-24 17:00:47.945760-0700 iphoneMQTT[26045:13918734] [MQTTMessage] wireFormat(30)={length = 30, bytes = 0x101c0004 4d515454 0402003c 00104d51 ... 6e743730 35353138 }...
2020-12-24 17:00:47.945955-0700 iphoneMQTT[26045:13918734] [MQTTSession] mqttTransport send
2020-12-24 17:00:47.946190-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketEncoder] buffer to write (30)={length = 30, bytes = 0x101c0004 4d515454 0402003c 00104d51 ... 6e743730 35353138 }...
2020-12-24 17:00:47.946604-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketEncoder] NSStreamEventHasSpaceAvailable
2020-12-24 17:00:47.982035-0700 iphoneMQTT[26045:13918734] [MQTTSessionSynchron] waiting for connect
2020-12-24 17:00:48.021667-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketDecoder] NSStreamEventHasBytesAvailable
2020-12-24 17:00:48.022025-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketDecoder] received (4)={length = 4, bytes = 0x20020004}...
2020-12-24 17:00:48.022129-0700 iphoneMQTT[26045:13918734] [MQTTSession] mqttTransport didReceiveMessage
2020-12-24 17:00:48.022290-0700 iphoneMQTT[26045:13918734] [MQTTDecoder] #streams=1
2020-12-24 17:00:48.022538-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketDecoder] NSStreamEventHasBytesAvailable
2020-12-24 17:00:48.022721-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketDecoder] received (0)={length = 0, bytes = 0x}...
2020-12-24 17:00:48.022801-0700 iphoneMQTT[26045:13918734] [MQTTSession] mqttTransport didReceiveMessage
2020-12-24 17:00:48.022891-0700 iphoneMQTT[26045:13918734] [MQTTDecoder] #streams=2
2020-12-24 17:00:48.022970-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketDecoder] NSStreamEventEndEncountered
2020-12-24 17:00:48.023046-0700 iphoneMQTT[26045:13918734] [MQTTSession] mqttTransport mqttTransportDidClose
2020-12-24 17:00:48.023242-0700 iphoneMQTT[26045:13918734] [MQTTSession] closeInternal
2020-12-24 17:00:48.023346-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketTransport] close
2020-12-24 17:00:48.082571-0700 iphoneMQTT[26045:13918734] [MQTTSessionSynchron] end connect
2020-12-24 17:00:48.083128-0700 iphoneMQTT[26045:13918734] [MQTTSession] subscribeToTopics:{
    "feeds/date" = 1;
}]
2020-12-24 17:00:48.083264-0700 iphoneMQTT[26045:13918734] nextMsgId synchronizing
2020-12-24 17:00:48.083342-0700 iphoneMQTT[26045:13918734] nextMsgId synchronized
2020-12-24 17:00:48.083422-0700 iphoneMQTT[26045:13918734] flowforClientId requestingPerform
2020-12-24 17:00:48.083512-0700 iphoneMQTT[26045:13918734] flowforClientId performing
2020-12-24 17:00:48.083802-0700 iphoneMQTT[26045:13918734] flowforClientId performed
2020-12-24 17:00:48.083897-0700 iphoneMQTT[26045:13918734] nextMsgId synchronized done
2020-12-24 17:00:48.084142-0700 iphoneMQTT[26045:13918734] [MQTTMessage] wireFormat(17)={length = 17, bytes = 0x820f0002000a66656564732f6461746502}...
2020-12-24 17:00:48.084231-0700 iphoneMQTT[26045:13918734] [MQTTSession] mqttTransport send
2020-12-24 17:00:48.084360-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketEncoder] buffer to write (17)={length = 17, bytes = 0x820f0002000a66656564732f6461746502}...
2020-12-24 17:00:48.084445-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketEncoder] streamError: (null)
2020-12-24 17:00:48.084520-0700 iphoneMQTT[26045:13918734] [MQTTCFSocketEncoder] setState 1/2

这是我点击发布按钮时的日志:

2020-12-24 17:01:06.419897-0700 iphoneMQTT[26045:13918734] [MQTTSession] publishData:{length = 1, bytes = 0x30}... onTopic:feeds/trip retain:0 qos:1 publishHandler:0x0
2020-12-24 17:01:06.420220-0700 iphoneMQTT[26045:13918734] nextMsgId synchronizing
2020-12-24 17:01:06.420349-0700 iphoneMQTT[26045:13918734] nextMsgId synchronized
2020-12-24 17:01:06.420462-0700 iphoneMQTT[26045:13918734] flowforClientId requestingPerform
2020-12-24 17:01:06.420582-0700 iphoneMQTT[26045:13918734] flowforClientId performing
2020-12-24 17:01:06.421045-0700 iphoneMQTT[26045:13918734] flowforClientId performed
2020-12-24 17:01:06.421166-0700 iphoneMQTT[26045:13918734] nextMsgId synchronized done
2020-12-24 17:01:06.421405-0700 iphoneMQTT[26045:13918734] flowforClientId requestingPerform
2020-12-24 17:01:06.421519-0700 iphoneMQTT[26045:13918734] flowforClientId performing
2020-12-24 17:01:06.421745-0700 iphoneMQTT[26045:13918734] flowforClientId performed
2020-12-24 17:01:06.424204-0700 iphoneMQTT[26045:13918734] [MQTTPersistence] pre-sync: i1 u0 d0
2020-12-24 17:01:06.428943-0700 iphoneMQTT[26045:13918734] [MQTTPersistence] postsync: i0 u0 d0
2020-12-24 17:01:06.429125-0700 iphoneMQTT[26045:13918734] [MQTTPersistence] sizes 0/0
2020-12-24 17:01:06.429326-0700 iphoneMQTT[26045:13918734] [MQTTSession] queueing message 3
2020-12-24 17:01:06.429930-0700 iphoneMQTT[26045:13918734] 0
2020-12-24 17:01:06.430028-0700 iphoneMQTT[26045:13918734] 2

我已尝试使用框架和主要代码来执行操作,但我现在已经足够了解为什么事情无法正常工作了。

这是在 ESP 上使用 Adafruit 的 MQTTClient 框架和代码进行订阅和发布的代码:

#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

/************************* WiFi Access Point *********************************/

#define WLAN_SSID       "xxxxxxxxxxxx
#define WLAN_PASS       "xxxxxxxxxxxxxx"

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                   // 8883 for MQTTS
#define AIO_USERNAME    "xxxxxx"
#define AIO_KEY         "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
#define LED 14
int tripper = 1;


/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/

// Setup a feed called 'photocell' for publishing.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Publish temperature = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/temperature");

// Setup a feed called 'onoff' for subscribing to changes.
Adafruit_MQTT_Subscribe trip2 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/trip");

/*************************** Error Reporting *********************************/

Adafruit_MQTT_Subscribe errors = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/errors");
Adafruit_MQTT_Subscribe throttle = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/throttle");

/*************************** Sketch Code ************************************/

// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();

void setup() {
  Serial.begin(115200);
  delay(1000);
  pinMode(D5,OUTPUT);
digitalWrite(D5,LOW);
  Serial.println(F("Adafruit MQTT demo"));

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.println("IP address: "); Serial.println(WiFi.localIP());

  // Setup MQTT subscription for onoff feed
  mqtt.subscribe(&trip2);

  // Setup MQTT subscriptions for throttle & error messages
  mqtt.subscribe(&throttle);
  mqtt.subscribe(&errors);

}
//could this be where the problem is what format the data is in (I don't think so but....
uint32_t x=80;


void loop() {
  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();
  // this is our 'wait for incoming subscription packets' busy subloop
  // try to spend your time here
  //12e
  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    if (subscription == &trip2) {
      Serial.print(F("Got onoff: "));
      Serial.println((char *)trip2.lastread);
    uint16_t sliderval = atoi((char *)trip2.lastread);
      if((sliderval ==0)&&(tripper == 1)){
        digitalWrite(D5,HIGH);
        delay(2000);
        digitalWrite(D5,LOW);
        tripper = 2;
      }
      else if(sliderval == 50){
      }
      else if((sliderval == 100)&&(tripper == 2)){
        digitalWrite(D5,HIGH);
        delay(2000);
        digitalWrite(D5,LOW);
        tripper = 1;
      }
    } else if(subscription == &errors) {
      Serial.print(F("ERROR: "));
      Serial.println((char *)errors.lastread);
    } else if(subscription == &throttle) {
      Serial.println((char *)throttle.lastread);
    }
  }
  
  // Now we can publish stuff! 01
 Serial.print(F("\nSending temperature val "));
  Serial.print(x);
  Serial.print("...");
  if (! temperature.publish(x)) {
    Serial.println(F("Failed"));
  } else {
    Serial.println(F("OK!"));
  }


//delay(60000);//01
delay(5000);//12e

}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
  Serial.println("MQTT Connected!");
  
}

如果我发布了太多代码,我很抱歉,但我希望每个人都能获得所需的信息。 如果有人做过这样的事情,请帮忙。

所以我通过添加连接了:

session = [[MQTTSession alloc] init];
    session.userName = @"xxxxxxxxx";
    session.password = @"xxxxxxxxxxxxxxxxxxxxxxxxxxx";
    session.transport = transport;
    session.delegate = self;
    [session connectWithConnectHandler:^(NSError *error) {
        if(!error){
    [session subscribeToTopic:@"feeds/temperature" atLevel:1 subscribeHandler:^(NSError *error, NSArray *gQoss){
        if (error) {
            NSLog(@"Subscription failed %@", error.localizedDescription);
        } else {
            NSLog(@"Subscription sucessfull! Granted Qos: %@", gQoss);
        }
    }];
            }
        else {NSLog(@"[connectWithConnectHandler]Error Connect %@", error.localizedDescription);}
    }];

我的代码。

但是我没有收到来自 Adafruit 的错误

MQTT 错误:被拒绝,主题格式无效

有没有其他人遇到过这个问题。 我想我会 post 关于这个问题的另一个问题。我希望应该使用更少的代码。