Land-Essender

And we are live! Grad noch vor meiner Abreise geschafft. Projektidee von Gallus, Thomas und Karin. Ich freu mich dann auf mein erstes Experiment wenn ich wieder zurück bin. Viel Erfolg erstmal!

www.land-essender.ch

Screen Shot 2015-06-21 at 16.06.31


Open the Door

This was in my mind since years, and because home-automation is everywhere. I’ve had many ressources to stumble upon. I startet with an infrared to ethernet device to remote controle my stereo and tv with my phone. My most recent project was to remotely open the entrance door to our flat, with great success.

The setup

IMG_3181

An arduino microcontroller hooked up with an ethernet-shield and a self soldered ‘trigger-board’. The arduino and the ethernet-shield is no magic, you can find example code here and here. I simply run a dead-simple non-secure web server on arduino listening for 3 arguments, for each relais on my trigger-board one. One of the relais is connected to my door-buzzer. The arduino is on my local network reachable only via cable. My home server is hooked up to the arduino ethernet interface and on this server I host a publicly available, mobile optimized, secure and beautifully designed, web application – written in plain PHP using RedBeanPHP.

dooropener

You can log in and open the door, wherever you are. One can now use the ‘add to homescreen’ feature on iOS and have a pseudo native door opener.

One more thing…

Since I wanted to play around a little, I created a unique, one-time-usage-link-generator. So I can invite friends over, send them my link and they can open the door exactly once.

// Generating a random string to create a unique URL and allow entrance once 
function generateRandomString($length = 20) {
	$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
	$randomString = '';
	for ($i = 0; $i < $length; $i++) {
		$randomString .= $characters[rand(0, strlen($characters) - 1)];
 	}
	return $randomString;
}

Hickups

Since I live in an old house, the doorbuzzer is not very reliable. So when I trigger the buzzer, my server-arduino-trigger system works like a charm, butte the door doesn’t open always at the first try.


Bash screen

A very useful tool on Linux/Unix systems is ‘screen’. It’s a window manager 😉 read the man pages. I use it to do stuff on my server and being able to disconnect the ssh session while the tasks continue on the server, when I log in later, the tasks are still being executed (unless they are done).

[bash]
ssh flo@example.com
screen -t mytitle
[/bash]
Now, you can do heavy stuff and detach the screen with “ctrl-a-d”. This will release the window but still run the commands. You can log out or do other stuff now and whenever you want reattach the previous screen with [bash] screen -r [/bash]


A try on iOS

New experiences in iOS Application development

Objective – C

To get in touch with iOS development I started watching the Stanford University iOS videos. This language and its framework has a very steep learning curve, so at the beginning I didn’t understand much. With the video tutorials and the material from Apple itself I was able to create a ‘Hello World’ Application and then step by step build the HSRMenu Application. This approach allows it to gain more knowledge by time but has a huge drawback. The software design was not created at the beginning, so a lot of refactoring had to be done.

Xcode

To develop native applications for iPhone you need Xcode, the IDE is provided by Apple. The basic features are self-explanatory and similar to other IDEs. One important feature I decided to use is ‘Storyboard’. With this you can design your application user interface and connect parts to your code. It gives you a feeling of how the app should behave and what it will look like. Also you can get an overview of what should be implemented in code.

The Connection

In iOS 5 an above receiving a JSON over HTTP is built right in. Create a NSURL from a NSString and then create a NSURLRequest. To this request you can assign a delegate (in this case the object itself) which should handle all callbacks from the request.

[objc] - (void)initJsonConnection { NSString *urlString = [[NSString alloc] initWithFormat:@&quot;http://florian.bentele.me/HSRMenu/api.php?day=%d&quot;, currentday]; NSURL* apiurl = [NSURL URLWithString:urlString]; NSURLRequest* request = [NSURLRequest requestWithURL:apiurl]; (void) [[NSURLConnection alloc] initWithRequest:request delegate:self]; }[/objc]

The callback methodes are the following

[objc]- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)jsondata
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
[/objc]

All this methodes are self-explanatory, for further information about this, please see Apples Reference

The Keychain

In Order to save the username and password to access the HSR Badge API, I decided to solve this problem with Apple’s Keychain for iOS. In this way the password is stored encrypted and other applications can not access it. Apple has a reference implementation of the keychain utilities. In the code you only need to store the username and password:

Store items to keychain

[objc]KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@&quot;HSRMenuLogin&quot; accessGroup:nil];
[keychain setObject:pass forKey:CFBridgingRelease(kSecValueData)];
[keychain setObject:user forKey:CFBridgingRelease(kSecAttrAccount)];
[/objc]
(accessGroup is set to nil, so it runs in the iOS simulator)

Read from keychain

[objc]KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@&quot;HSRMenuLogin&quot; accessGroup:nil];
uiuser.text = [keychain objectForKey:CFBridgingRelease(kSecAttrAccount)];
uipass.text = [keychain objectForKey:CFBridgingRelease(kSecValueData)];[/objc]

Pull-to-refresh

When the app starts it tries to load new data automatically. If no internet connection is available an error occures. Whenever the user feels to, one can simply pull to refresh the data, this works throughout the application, in singlemenu view, in menu overview and in badge saldo view.

PTR is using a library so it is compatible in iOS 4 and above, Apples implementation is only available for devices with iOS 6 and above.

The library is public available on Github. In this app it is used as demonstrated in the example code.

[objc]- (void)dropViewDidBeginRefreshing:(ODRefreshControl *)refreshControl
{
[self initJsonConnection];
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[refreshControl endRefreshing];
});
}[/objc]

Star Rating

To give the users the ability to rate a menu, I decided to create a star rating view for each menu and provide the average rating to each menu.

I tried different ways and checked out how others have implemented rating but wasn’t happy at all. Finally I came across DLStarRating. A customizable star rating view which fits my needs.

[objc]DLStarRatingControl *ratingControl = [[DLStarRatingControl alloc] initWithFrame:CGRectMake(85, 50, 220, 70) andStars:5 isFractional:NO];[/objc]

And when the user tabs/creates a new rating for a certain menu, the delegate calls the methode:

[objc]-(void)newRating:(DLStarRatingControl *)control :(float)rating {
// calling the rating services here
}[/objc]

Lessons learned

As noted in the intro, starting an iOS project with no experience in Objective-C is quite challenging. Learning the language and the framework while developing a real world application was possible but also time consuming. The architecture grew with each iteration and had to be adjusted over time. * create project overview and design architecture as soon as possible

One other thing I experienced was, that there are many frameworks out there. If you have a specific need, someone probably already has a solution for this. In my example the rating. I developed two different versions until I came across the DLStarRating library. At this point I had to decide which solution I would use, and the library won. * use frameworks and libraries if possible and meaningful

Another thing I would recommend is read a lot. There are a lot of tutorials and a very good documentation available online. Check out other iOS apps to see how others solved a problem. This gives you new ideas and keeps you open minded. * read a lot: tutorials, books and Apple’s developer library


Convert FLAC to mp3

{Long story}
I love music. In Berlin I bought a pair of Sennheiser. Then I started to realize what a big influence bitrate of hard compressed mp3 had on the quality. The solution to the problem is FLAC (Free Lossless Audio Codec). In short that is the quality you get from a cd. But since my mobile devices and portables can’t handle FLAC I’m now on two lanes:

  • FLAC for office and home usage
  • compressed VBR mp3 for my phone

{Short}
However, if you wish to convert FLAC files to mp3 and do not want to loose the id3 Tags (like me), I found somewhat on the internet and created this little (bash) script:

[code lang=”bash”]

#!/bin/bash
# by K-Soft! 05/24/2012 with parts from
# http://bash.cyberciti.biz/multimedia/linux-unix-bsd-convert-flac-to-mp3/
# convert flac to mp3 and writes id3 tags
# usage: flactomp3 /path/to/my/awesome/music/
# requires FLAC, ID3, LAME
# change quality -V 0-9

IFS=$’\t’

if [ $# -eq 0 ] ; then
echo ‘No arguments provided, usage: flactomp3 /my/awesome/music/’
exit 0
fi
for flacfile in $1*.flac
do
outf=${flacfile%.flac}.mp3
eval "$(
metaflac "$flacfile" –show-tag=ARTIST \
–show-tag=TITLE \
–show-tag=ALBUM \
–show-tag=GENRE \
–show-tag=TRACKNUMBER \
–show-tag=DATE | sed ‘s/=\(.*\)/="\1"/’
)"
flac -c -d "$flacfile" | lame -m j -q 0 –vbr-new -V 0 -s 44.1 – "$outf"
id3 -t "$TITLE" -T "${TRACKNUMBER:-0}" -a "$ARTIST" -A "$ALBUM" -y "$DATE" -g "${GENRE:-12}" "$outf"
done
[/code]