Change Away Status on Nest Thermostat (Nest API) - objective-c

Using the Nest API I am trying to set the nest thermostat's away status
Reading & Setting for temperature is working fine.
I have the read and write permissions correctly configured for both
thermostat temperature control and for setting thermostat away
I can read the status correctly. Does anyone with some experience of this API know how to go about setting this status?
in "FirebaseManager.h"
Firebase *newFirebase2 = [self.rootFirebase childByAppendingPath:#"structures"];
[newFirebase2 observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
// Put structures into a dictionary
NSMutableDictionary *dict = snapshot.value;
NSLog(#"\n\n\n1. Away Status = %#", [dict valueForKey:#"away"]);
NSLog(#"Dict Contents %#", dict); // <--- Reads thermostat status. A string either home or away
dict[#"away"] = #"away"; //<--- Changes status string but not a correct solution, and does not set the stat to away
//Changes status name but this is not parsed back to firebase
NSLog(#"new status = %#", [dict valueForKey:#"away"]);
}];

To update a child value
assume this structure
structures
structure_id_0
away: "home"
setting the away node to a string of away (this code is quite verbose so it's easy to follow)
Firebase *structuresRef = [self.rootFirebase childByAppendingPath:#"structures"];
//build a reference to where we want to write structures/structure_id/
Firebase *thisStructureRef = [structuresRef childByAppendingPath:#"structure_id_0"];
Firebase *awayRef = [thisStructureRef childByAppendingPath:#"away"];
[awayRef setValue:#"away"];
Now, if you want to do this for snapshots that have been retrieved via observing a node with FEventTypeChildAdded, the node name will be whatever is used in place of structure_id_0. The is the key of the key:value pair.
That can be obtained via snapshot.key.
So NSString *key = snapshot.key
Substitute the key variable in for #"structure_id_0" in the path.
Also check out Firebase Writing Data, and then the updateChildValues for another option.

Related

How to get Deep Link Data in iOS objective-c

How do you get the data setup in the dashboard.
I have added a key and a value in "Deep Link Data(Advanced)"
In Branch.io dashboard
Login / Menu: Marketing / Actions / Edit
I have this in objective-c:
Branch *branch = [Branch getTestInstance];
[branch setDebug];
NSDictionary *params = [branch getLatestReferringParams];
I am working in "test" of the dashboard.
Alex with Branch here:
The $ symbol is only used to indicate reserved system control parameters (you can find a list of these parameters here). Since you're setting a custom data key, the key : value pair you're using in the example actually just needs to be myplan : 10.
Your session initialization snippet is also a bit odd. Would you mind sharing where you found it? We might have some documentation somewhere that's out of date...
Branch *branch = [Branch getTestInstance];
[branch setDebug];
[branch initSessionWithLaunchOptions:launchOptions andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) {
if (!error) {
// params are the deep linked params associated with the link that the user clicked -> was re-directed to this app
// params will be empty if no data found
// ... insert custom logic here ...
NSLog(#"params: %#", params.description);
}
}];

get contents of data array from fwrite parameter - to print out data with objective-c

I have some code that reads this:
int SaveTemplateToFile(char* Name, FTR_DATA Template )
{
//NSLog(#"trying to save template to file");
FILE *fp;
fp = fopen( Name, "w+b");
if( fp == NULL ) return FALSE;
int Result = fwrite( Template.pData, 1, Template.dwSize, fp ) == Template.dwSize ? TRUE : FALSE;
fclose(fp);
return Result;
}
I understand that this will write out the data retrieved from Template.pData into a file named whatever is stored in the Name variable.
This is what the .tmpl's contents reads:
Task/Question:
I am simply trying to store this data into a variable so that I can send this data to my webserver database and store it in a blob file for retrieval at a later time. This will also allow me to get rid of the fwrite function which I wont need since im storing everything onto the sebserver instead of storing it locally.
I am currently finding trouble reading this data. I am getting a crash when trying to output this data array, I also present what the datatype structure looks like:
Where DGTVOID is of typedef void DGTVOID.
How can I correctly read the contents of template? I was thinking if I understood what datatype it is, then I would be able to retrieve the data correcty.
Update 1
Thanks to Paulw11 I am able access a very small portion of the data using %s instead of %# which originally lead to a crash. Here is what is being printed now, a few funky upside down question marks:
Is there a way to output the contents of this datastream from Template.pData without having to save the data onto the direction first as a file?
I think the first thing you should do is convert your buffer to an NSData instance -
NSData template = [NSData dataWithBytes:Template.pData length:Template.dwSize];
Once you have that then you can Base64 encode the data for transmission over a web request -
NSString *templateStr = [template base64EncodedStringWithOptions:0];
If you are targeting a version earlier than iOS7 then you can use the deprecated method
NSString *templateStr = [template base64Encoding];

Core Data and unique UIImage per object

I am making a simple app where the user can create severals objects which are saved with CoreData.
My problem is, I want each object to have an image linked to it. The image is brought by the iphone camera or the user personal Camera roll, so the images will have a pretty high weight (> 1MB each I think).
I read that when the weight of images is that high, the good way to handle this is to save the images in the documentsDirectory folder, and save the path to coreData. I achieved this pretty easily.
But how do I find a path name for the image to be linked to an unique object? CoreData does not really handle unique IDs, and two objects can have the same name... I searched around objectID but it's not working really good and I'm not sure it's the good way to handle this.
Do you have any idea? Is there an other simple way I am totally missing? Thank you in advance.
use coredata's objectID as identifier
id uri = [self sanitizeFilename:coreDataObject.objectID.URIRepresentation];
[NSString stringWithFormat:#"%#.png", uri];
helper sanitizeFilename:
- (NSString *)sanitizeFileNameString:(NSString *)fileName {
NSCharacterSet* illegalFileNameCharacters = [NSCharacterSet characterSetWithCharactersInString:#"/\\?%*|\"<>"];
return [[fileName componentsSeparatedByCharactersInSet:illegalFileNameCharacters] componentsJoinedByString:#""];
}
Just create an object_id number property in your CoreData model entity description and each time a new object is created increment this property by one and assign it to the object, then use a naming convention like
[NSString stringWithFormat:#"object_%d_img.png", idNumber];
And save it to NSDoctumentsDirectory.
Then in object's - (void)prepareForDeletion method delete the image.
As for how to increment the id value, create a method that will fetch an object with biggest id value - simply get all objects with sort descriptor by id desc and use it + 1 when creating a new entity.
Thanks to #Daij-Djan. I created version for Swift:
var itemObjectId:String = item.objectID.URIRepresentation().absoluteString!
var fileName = NSString(format:"%#.png", FileHelper.sanitizeFileNameString(itemObjectId)) as String
Helper for sanitize:
struct FileHelper {
static func sanitizeFileNameString(fileName:String) ->String {
let illegalFileNameCharacters:NSCharacterSet = NSCharacterSet(charactersInString: "/\\?%*|\"<>")
let components : [String] = fileName.componentsSeparatedByCharactersInSet(illegalFileNameCharacters)
let joinedString = join("", components)
return joinedString
}
}
I think you'll need to generate the unique id by your self. Since a user can have several objects. so maybe the image id could be named as such
userId-objectId-somesalt
save the value to the object's path

Using Delta in Dropbox API with iOS

I'm using the dropbox api for iOS and have been messing with the loadDelta function. I get the whole "key" that is sent, and I get how the structure is set up (see below this code), but what I don't understand is how to download the file that is sent and how to save it to the iOS device. Does anyone have any insight on how to do this?
-(void)restClient:(DBRestClient *)client loadedDeltaEntries:(NSArray *)entries reset:(BOOL)shouldReset cursor:(NSString *)cursor hasMore:(BOOL)hasMore{
for (DBDeltaEntry *file in entries) {
if(!file.metadata.isDirectory){
NSLog(#"File: %# ", file.metadata.filename );
}else {
NSLog(#"Directory: %# ", file.metadata.filename );
}
}
}
The call sends back an array called entries. Each entry in entries is this:
#interface DBDeltaEntry : NSObject {
NSString *lowercasePath;
DBMetadata *metadata;
}
with the DBMetadata object being:
#interface DBMetadata : NSObject <NSCoding> {
BOOL thumbnailExists;
long long totalBytes;
NSDate* lastModifiedDate;
NSDate *clientMtime; // file's mtime for display purposes only
NSString* path;
BOOL isDirectory;
NSArray* contents;
NSString* hash;
NSString* humanReadableSize;
NSString* root;
NSString* icon;
NSString* rev;
long long revision; // Deprecated; will be removed in version 2. Use rev whenever possible
BOOL isDeleted;
NSString *filename;
}
What I can't figure out is how to recursively set up my offline structure or the best practice for doing so. My assumption is though, using delta, I won't need to keep a database of the files I have saved for update purposes, right?
The /delta call only tells you what has changed. It doesn't itself give you any access to the file contents. If you want to download any particular file that you heard about from /delta, you should use the path it gave you with the /files (GET) call to download the file:
https://www.dropbox.com/developers/reference/api#files-GET
(The iOS SDK makes this available as the loadFile function.)
The /delta call does save you the trouble of having to call /metadata to manually figure out what has changed and keep track of the current state, but note that the Dropbox API best practices ( https://www.dropbox.com/developers/reference/bestpractice ) do say that you shouldn't download anything until the user asks for it.
One scheme is to use a SQLite table with the following columns:
lc_path: The lowercase'd path of the file (primary key for this table)
name: The name of the file
lc_parent_path: The lowercase'd path of the parent folder
other metadata... (last modified, revision, is_dir, etc.)
So when processing an "add" /delta entry, you insert a row into the table (you might have to replace an existing row).
When processing a "delete" entry for the path /a/b/c, you need to delete all children as well, so you can do DELETE ... WHERE lc_path = "/a/b/c" and then DELETE ... WHERE lc_path LIKE "/a/b/c/%".
If you want to query the database for a list of immediate children of the folder "/a/b/c", do SELECT ... WHERE lc_parent_path = "/a/b/c"
You may have noticed that you the path is stored somewhat redundantly (lc_parent_path+name and lc_path). This probably won't be a problem. But if you find that your database is too large and that most of the space is going toward storing the path strings, there are encoding tricks you can do.

Find the number of routes between two places

I need to find out the number of routes from a source to a destination using the Google maps API, and then find, among those, which one is the shortest route.
I am able to get one route by using this code
-(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t {
NSString* saddr = [NSString stringWithFormat:#"%f,%f", f.latitude, f.longitude];
NSString* daddr = [NSString stringWithFormat:#"%f,%f", t.latitude, t.longitude];
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.google.com/maps?output=dragdir&saddr=%#&daddr=%#", saddr, daddr];
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
NSLog(#"api url: %#", apiUrl);
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl];
NSString* encodedPoints = [apiResponse stringByMatching:#"points:\\\"([^\\\"]*)\\\"" capture:1L];
return [self decodePolyLine:[encodedPoints mutableCopy]];
}
but I'm unable to get multiple routes.
I'm new to using the Google Maps API; I followed this tutorial.
How can I do this? Can any one please post some sample code or a tutorial?
alternatives (optional), if set to
true, specifies that the Directions
service may provide more than one
route alternative in the response.
Note that providing route alternatives
may increase the response time from
the server.
From The Google Directions API
You need to add in your query link alternatives=true
For getting the multiple routes you have to use the standard google direction api. Through this api you can get different routes on the bases of traveling mode you select in api ie driving, walking or bicycling( bicycling route availabel in US only) For example : http://maps.googleapis.com/maps/api/directions/xml?origin=srcLatitude,srcLongitude&destination=destLatitude,destLongitude&mode=driving&sensor=false
Here you can give the source and destination latitude and longitude and change the value of mode parameter to driving, walking or bicycling to get multiple route.