Nest Thermostat Away Status changes back to home - ios

Nest thermostat SDK, using iOS sample code from Nest as reference.
Setting the temperature is outlined in the sample code. Setting the away status to away or home (string value saed to firebase is not).
From a previous question Change Away Status on Nest Thermostat (Nest API) im changing the away status:
self.rootFirebase = [[Firebase alloc] initWithUrl:#"https://developer-api.nest.com/"];
Firebase *structuresRef = [self.rootFirebase childByAppendingPath:#"structures"];
Firebase *thisStructureRef = [structuresRef childByAppendingPath: #"structure_id_0"];
Firebase *awayRef = [thisStructureRef childByAppendingPath: #"away"];
// Set Status
[awayRef setValue:#"away"];
This reflects as away in the logs. Getting this to stick is causing a problem.
After being set away the logs a second later show it's back to home again.
The stat seems to be overriding the request from the app, whatever's on the stat has priority
- (void)addSubscriptionToURL:(NSString *)URL withBlock:(SubscriptionBlock)block {
Firebase *newFirebase2 = [self.rootFirebase childByAppendingPath:#"structures"];
[newFirebase2 observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
// Put structures int a dictionary
NSMutableDictionary *dict = snapshot.value;
NSLog(#"\n\n******** STATUS: Away Status = %# **********\n\n", [dict valueForKey:#"away"]);
}];
}
Has anyone successfully set the away status with the nest SDK? Ive tried setting the away status immediately when the app launches in many different sections of the apps model just to try and get the status to stay. Not anything on a google search to assist either, apart from a sample project on github that was not suitible

are you sure you are calling the structures correctly? it supposes to be following:
structures/VqFabWH21nwVyd4RWgJgNb292wa7hG_dUwo2i2SG7j3/away
depends on your actual structure_id, refer here

Related

Mixpanel integrated in iOS SDK is not sending events

​I have an iOS SDK project with lots of modules (in Objective-C).
I want to start tracking events to see how my clients use our SDK but I can't see anything in the insights tab. What am I doing wrong?
 
In the point of entry to the SDK I have added this (just following the docs):
[Mixpanel sharedInstanceWithToken:#"myTOKEN"];
self.mixpanel.serverURL = #"https://api-eu.mixpanel.com";
[self.mixpanel track:#"Video play" properties:#{
#"genre": #"hip-hop",
#"duration in seconds": #42,
}];
I can see with breakpoints that the code it’s executed, however my insights are completely empty.
I also tried adding events with the codeless tracking, and while it looks like it’s working and I can connect to the app, the events aren’t appearing in the insights tab.
 
​
I think you need to assign the shared instance to your local property if that hasn't been done outside of the code you've posted.
[Mixpanel sharedInstanceWithToken:#"myTOKEN"];
self.mixpanel = [Mixpanel sharedInstance]; // assign here
self.mixpanel.serverURL = #"https://api-eu.mixpanel.com";
[self.mixpanel track:#"Video play" properties:#{
#"genre": #"hip-hop",
#"duration in seconds": #42,
}];

Create Pin PDKResponseObject response not consistent with documentation

We are creating a pin in a specific Board by using the method
createPinWithImage🔗onBaord:description:progress:withSuccess:andFailure:
We read in the documentation (here: https://developers.pinterest.com/docs/api/overview/ and here: https://github.com/pinterest/ios-pdk/blob/master/Pod/Classes/PDKClient.h#L417) that this method should return a PDKResponseObject *responseObject with the ID, URL, clickthrough URL and description of the created Pin.
We have been creative enough to try to access the ID of the Pin and its URL using any possible key (#"id", #"identifier", #"url", #"NSUrl") but the values returned are always nil. In fact the PDKResponseObject returns only 2 keys: Board ID and Pin Description.
What should we do to access the ID or, at the very least, the URL of the newly created Pin?
Does anybody have the same issue?
Despite multiple attempts and after having tried to discuss this issue with the Pinterest development Team, this still remains.
Testing a solution becomes also extremely difficult considering the new limitation Pinterest has imposed on not approved apps (which include all apps under development by definition).
For now, I only found a way around by calling a new request to get all pins in a specific board and get the first in the resulting array (which is the last posted):
//Create pin in Pinterest
[[PDKClient sharedInstance]createPinWithImage:image link:urlToShare
onBoard:reference description:message progress:nil
withSuccess:^(PDKResponseObject *responseObjectCreation) {
//Previous block does not return pin id so a new call is required
[[PDKClient sharedInstance]getBoardPins:reference fields:[NSSet
setWithArray:#[#"link"]] withSuccess:^(PDKResponseObject
*responseObject) {
//Get id of last pin
NSArray *pinIDs = [[NSArray arrayWithArray:[responseObject
pins]]valueForKey:#"identifier"];
NSString *postId = [pinIDs objectAtIndex:0];
}];
}];
By the way, the right key for the pin ID is "identifier" and not "id" or "ID" as said in the API documentation. Just found out by trying multiple times and checking the Pinterest Example app in GitHub.
Hope this helps other people who are fighting the same problem.

How do you cancel a Nest ETA using Firebase on iOS?

According to the nest API docs:
"To cancel an eta, send estimated_arrival_window_begin = 0. Check that you're sending an integer (0) in this call, not a string ("0"), or the call will fail."
See https://developers.nest.com/documentation/cloud/eta-reference/
My code is based on the iOS NestDK sample which uses Firebase.
I set things up using the addSubscriptionToURL method as follows: ​
[[FirebaseManager sharedManager] addSubscriptionToURL:[NSString stringWithFormat:#"structures/%#/eta", structureId] withBlock:^(FDataSnapshot *snapshot) {}];
I can then make successful calls to set an eta window for a specific trip.
However, i can't seem to be able to cancel the eta for the same trip. If i just specify the trip_id and estimated_arrival_window_begin properties i get an error message complaining that the estimated_arrival_window_end field is missing.
NSMutableDictionary *values = [[NSMutableDictionary alloc] init];
[values setValue:[_tripId UUIDString] forKey:#"trip_id"];
[values setValue:[NSNumber numberWithInt:0] forKey:#"estimated_arrival_window_begin"];
[[FirebaseManager sharedManager] setValues:values forURL:[NSString stringWithFormat:#"structures/%#/eta", structureId]];
I tried also setting estimated_arrival_window_end to 0 but i then get an error message saying that the estimated_arrival_window_begin is in the past. It seems to be interpreting the 0 value as the beginning of time. Well some time in 1970 anyway!
What am i doing wrong here?!
Thanks!
Are you using a Nest account with virtual devices created with the Nest Home Simulator? There appears to be a bug using virtual devices versus real devices. Please try using a Nest account with real devices.

Non-screenview events with Google Tag Manager on iOS

we're trying to use GTM on iOS to track non-screenview events using the data layer and cannot get this to work. First, here's our call to GTM:
NSLog(#"voted!");
NSLog(#"question: %#, answer: %#",self.question.question,selectedAnswer.answer);
[[ATITracking instance] trackEventWithTagManager:#"didVote" parameters:#{#"questionValue":self.question.question,#"voteValue":selectedAnswer.answer}];
We have 2 data layer variables set in GTM for the questionValue and the voteValue. See:
https://www.dropbox.com/s/jru5a06vs1bfmm3/variables.jpg?dl=0
And here's our trigger with the event set to didVote:
https://www.dropbox.com/s/0ydxml4yemji2f5/trigger.jpg?dl=0
And our event tag uses the trigger from above (cannot post link due to rep limit.)
Has anyone seen a non-screenview event tracked successfully in iOS using GTM? Thanks in advance.
Events are working for me with no problems. This is slightly modified code from the GTM iOS SDK example
-(void) logEvent:(NSString*) event withProperties:(NSDictionary*) properties {
NSMutableDictionary* eventProperties = [NSMutableDictionary dictionaryWithDictionary:#{#"event": #"customEvent",#"eventCategory":#"User action",#"eventName":event}];
if (properties) {
[eventProperties addEntriesFromDictionary:properties];
}
TAGDataLayer* dataLayer = self.tagManager.dataLayer;
[dataLayer push:eventProperties];
}
Based on GTM documentation https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#events event category and event action must not be empty. I didn't see any events in GA until I configured these parameters in my tag and started pushing them from the client.
Hope it helps.
Please see attached screenshot of my tag:

How do I get a server timestamp from Firebase's iOS API?

I have an iOS app that uses Firebase and currently has a few dictionaries with keys that are NSDate objects. The obvious issue with this is that NSDate draws from the device's system time, which is not universal.
With that, what's the best way to get a server timestamp (similar to Firebase.ServerValue.TIMESTAMP for the Web API) using Firebase's iOS API so that I can sort my dictionary keys chronologically?
I'm also aware of the chronological nature of IDs generated by childByAutoID, but I can't figure out the proper way to sort these in code. While they may be returned in chronological order, any time something like allKeys is called on them, the order goes out the window.
Any help with this issue would be greatly appreciated!
Update: In Firebase 3.0 + Swift, you can use
FIRServerValue.timestamp(). In Objective-C this is [FIRServerValue timestamp].
In Swift, you can now use FirebaseServerValue.timestamp() with Firebase 2.0.3+ (before 3.0).
The equivalent for Firebase.ServerValue.TIMESTAMP in iOS is kFirebaseServerValueTimestamp. Right now, this only works for Objective-C and not Swift.
In Swift, you can create your own global timestamp with
let kFirebaseServerValueTimestamp = [".sv":"timestamp"]
and then you'll be able to use kFirebaseServerValueTimestamp in the same way.
But you can only use this as the value or priority of a node. You won't be able to set it as the key name (although, I don't believe you could in the Web API either).
In general, calling allKeys on a dictionary does not guarantee order. But if you're using childByAutoID at a node, you can get back the right order by ordering the NSArray returned by allKeys lexicographically. Something like this would work:
[ref observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
NSDictionary *value = snapshot.value;
NSLog(#"Unsorted allKeys: %#", value.allKeys);
NSArray *sortedAllKeys = [value.allKeys sortedArrayUsingSelector:#selector(compare:)];
NSLog(#"Sorted allKeys: %#", sortedArray);
}];
This is similar to sorting an NSArray alphabetically, but when sorting the auto-generated IDs, you do not want localized or case insensitive sort, so you use compare: instead of localizedCaseInsensitiveCompare:
Caveat: Seems like the timestamp is added AFTER your object is persisted in Firebase. This means that if you have a .Value event listener set up on the location your object is persisted to, it will be triggered TWICE. Once for the initial object being stored in the location, and again for the timestamp being added. Struggled with this issue for days :(
Helpful information for anyone else who can't figure out why their event listeners are triggering twice/multiple times!
As of Firebase 4.0 you can use ServerValue.timestamp()
for example:
let ref = Database.database().reference().child("userExample")
let values = ["fullName": "Joe Bloggs", "timestamp": ServerValue.timestamp()] as [String : Any]
ref.updateChildValues(values) { (err, ref) in
if let err = err {
print("failed to upload user data", err)
return
}
}
You can get Time Stamp using FIRServerValue.timestamp().
But, Because of FIRServerValue.timestamp() listener is called two times. Listener will be called two times.

Resources