Smartified Garage Door

Making the best out of Corona-wise cancelled sports evenings, there was suddenly enough time to smartify my garade door. It already has connectors on the garage door hardware. That way, I could connect a button to the board that is used to open and close the garage. But what was missing is a way to control it remotely. Since the remote went missing it was nearby to integrate the button into my smart home setup: Homematic actuators and a raspberry pie transferring all traffic via MQTT.
As there’s already the possibility to control radio-relays via MQTT, the next move was to replace the connection from the button to board with a circuit integrating the relay HM-LC-Sw1-FM. https://de.elv.com/homematic-unterputzschalter-1fach-hm-lc-sw1-fm-fuer-smart-home-hausautomation-076793
But there was one problem. The relay works with an input and output voltage of 230V. That’s too much to control the board on the garage opener. So I had to integrate another relay that could switch an arbitrary input voltage but works with a rated Control Supply Voltage of 230V. I finally came up with an relay by Entrelec.

Now to the fun part. Connecting all parts together according to the wiring on the left. The Entrelec relay is directly connected to the garage opener board. The control supply is provided by the Homematic relay. The switch input of the Homematic relay is provided by the hardware button and finally some 230V to feed the relay. That’s it.

In order to test it, there’s no faster prototyping than to use Node-Red. It enables visually wiring up a control that either automates a workflow or provides a rudimentary GUI. https://nodered.org In this case, it’s a simple UI consisting of one toggle labeled „Garage“ sending out a message to the MQTT broker to fire up the Homematic relay.
Since that’s quite a boring interface, the next step was to write a control app, fooling around with Combine and SwiftUI. But that’s a story for another time 😉

Swift Dependency Analysis

Almost 3 years ago I started a tool to analyse dependencies of Swift projects. For bigger projects it’s essential to plan dependencies between classes and among modules beforehand. Otherwise a project’s inter-dependencies grow wild and after a while, everything depends on everything.
https://twitter.com/c_gretzki/status/837276844130983936
Why that’s bad you might ask? Because then it’s impossible to replace a class with different functionality, since too many other depend on it. And thus, it gets harder to implement new features, adapt existing features and keep the bug count low. So that’s planning, but what get’s implemented is another story. It’s easy to forget about planned dependencies while implementing and that’s even more true when working in teams of 5, 10 or more people. That’s where tools for visualizing dependencies come into play. Every now and then, one can use these tools to check the actual inter-dependencies of a project and compare them with the planned ones. The existing tools all have one big shortcoming: They ignore ordering structures like modules. All classes are layed out in one space, which gets confusing when visualizing projects with more several hundreds classes:
Demo from https://github.com/PrzemyslawCholewaDev/swift-dependency-visualizer
While this visualisation looks quite amazing it renders quite useless overwhelming when trying to check for unplanned dependencies. What’s more helping is a visualisation that considers modules and Xcode groups. Xcode groups can be used to organise a project’s classes in package-like structures.
Xcode project organising its classes into several nested groups
Like in the sample project above, one can see different features of the app organised in separate groups. There’s a Splash screen organised in the Splash group and an Integration group to accomodate a feature to setup smart kitchen appliances and a Network group to shelter the classes communicating to backends, etc. Inter-dependencies can be planned on these structures too. While it’s easily comprehensible why an Integration group is dependent on the Network group, the Splash group shouldn’t.
Swift dependency analysis tool showing one group, one contained file and its embedded class, enum and protocol definitions.
The above dependency tool shows dependencies between classes, enums and protocols. Furthermore, it depicts the groups and files as rectangles collapsable and expandable. When collapsed, the inter-dependencies of all contained elements to other elements outside this structure are still visible but depicted as dependency of the structuring element.
https://twitter.com/HeyDaveTheDev/status/1244909898464452608
This tool is worked on by David Piper as part of his master thesis. I’m glad to be his advisor and very confident that at the end of his thesis, we’ll see a wonderful tool to supervise the dependencies of Swift projects. What’s even better: As soon as the master thesis is completed, the project will be open-sourced and as a contributor, I’ll gladly keep you updated with more to come feature. So stay tuned ✌️

If your iOS code signing fails today

If your iOS code signing fails today, it may be due to an expired Apple Intermediate Certificate.

What you need for code signing beside your valid developer or distribution certificate is the
Apple Worldwide Developer Relations Certification Authority. It expired yesterday and there’s probably already a new one side by side in your keychain. (If not, download and install the new one here: WWDR Certificate (Expiring 02/07/23)) Alas, the expired one interferes with the chain of trust and as a result you get a

„This certificate has an invalid issuer.“

To get rid of this error, you simply have to delete the expired one
in three easy steps:

  1. Open the Keychain Access utility
  2. In the menu, select View -> Show Expired Certificates
    Screen Shot 2016-02-15 at 10.50.14
  3. Make sure to delete the expired “Apple Worldwide Developer Relations*” certificates from all keychains (probably login and system).
    Screen Shot 2016-02-15 at 10.50.06 copy

Now everything should work like a charm again 😉

Find out iOS SDK version from IPA

Recently I updated xcode on our CI server and additionally provide the option to use older xcode versions per project.
To verify that the option works I wanted to find out the iOS SDK version from the provided ipa.

Here we go:
Assuming the app is named APPNAME and the ipa my-app.ipa.

  1. rename my-app.ipa to my-app.ipa.zip
  2. unzip my-app.ipa.zip (Now we’ve got a folder named Payload)
  3. execute the following bash command:
    otool -l Payload/APPNAME.app/APPNAME | fgrep --after-context=3 LC_VERSION_MIN_IPHONEOS
  4. (Alternative)
    plutil -p Payload/APPNAME.app/Info.plist | grep DTSDKName

The output is something similar to:

cmd LC_VERSION_MIN_IPHONEOS
cmdsize 16
version 7.0
sdk 8.4
--
cmd LC_VERSION_MIN_IPHONEOS
cmdsize 16
version 7.0
sdk 8.4

UIWebView Cross Site Scripting Vulnerability

When integrating UIWebViews you have to pay attention to how the desired webpage is being loaded.
That’s why Apple lately added the following lines to the documentation of UIWebView:

To help you avoid being vulnerable to security attacks, be sure to use this method [-loadHTMLString:baseURL:] to load local HTML files; don’t use loadRequest:.

Loading a website via loadRequest: bears the risk of Cross Site Scripting, since it does not enforce the Same Origin Policy, i.e., access to resources of other websites or within the bundle container of the app is possible.

When installing an app on iOS, the following containers are being generated:

  • Bundle container
  • Data container
  • possibly an iCloud container

Without enforcing the Same Origin Policy a HTML file running inside a UIWebView can access resources within the bundle container of the app.

Example Attack Scenario

Screen Shot 2015-08-04 at 13.22.40
Hacking an app’s imprint webview with the aid of Charles.

Applying a Man-in-the-middle attack I could pass a primed website off as the desired app’s imprint website. An attacker could now prompt for sensitive data and capture it.

Furthermore, the attacker could access sqlite cache files or other sensitive resources inside the bundle container. But since this attack requires guessing the id of the sandbox, which is part of the required URL, this is not very likely to happen.

Solution

A solution is to use the methodsloadData:baseURL:orloadData:MIMEType:textEncodingName:baseURL: to load external websites and specifying the baseURL property to point to the host of the desired website, preventing access to resources on different hosts.

Alternatively you could implement webView:shouldStartLoadWithRequest:navigationType: of the UIWebViewDelegate protocol, inspecting every request’s host address and whitelisting which to allow.

A Signal Light for your Jenkins Build Job

IMG_0340.png-2

Idea

A working master branch in a continuous integration environment is key for fast development. While we hack line after line into the project, we merge back to master branch often even while the feature branch is still in development.

Merging early and often helps to avoid merge conflict hell because otherwise feature branches  move too far apart. But this comes at the risk of breaking the master branch build. If that happens, the developer in charge has to stop his ongoing task and fix stuff immediately.

Until recently we used emails to notify the team of a failing build. But since email is old-fashioned, we hacked a signal light to show us the current build status. Follow the instructions below if you want to build your own Jenkins Traffic Light:

 

Prerequisites

Hardware Requirements

[table caption=“Things you’ll need“ colalign=“left|left|center|left“]
stuff,description,price
arduino, e.g.: uno rev 3. There are cheaper alternatives but some things may work differently, 20€
Ethernet Shield,, 33€
Toy traffic light, e.g. this one http://www.pearl.de/a-NC2046-4480.shtml does not require a separate power supply but the arduino digital pin output power, 4.90€
Soldering iron,I just assume you already got one. If not and you just gain first experiences I recommand one with adjustable heat,
Small screwdriver, You should really have a set of different sizes,
Some sort of case,,
Power supply,e.g. http://www.amazon.de/Aukru-Netzteil-Arduino-Platine-Neufassung/dp/B00PADO5CG/ref=sr_1_1?s=ce-de&ie=UTF8&qid=1432481528&sr=1-1&keywords=arduino+netzteil,8.99€
Cable stripper,A knife will do the trick too,
Bell wire,you get way more than you need for this project,1€
heat shrink tube & lighter, duct tape will work too,1€
drilling machine, knife could work too,
A Jenkins build job, that’s what this idea is all about right?, priceless
[/table]

Further requirements

  • A working build infrastructure to execute code on the Arduino.

For hacking on my mac, I prefer a simple text editor with syntax highlighting like Sublime Text and the command line tool INO. But since there are lots of good tutorials on how to setup your build infrastructure, I’ll skip this step. For beginners it’s probably easiest to start with the official IDE.

  • A basic knowledge of Arduino programs.

I don’t want to cover the basics here. There are tons of beginners guides out there that do that in much detail; Why not start with the official getting started guide.

 

Instructions

First aim: Toggle lights timer-based without any networking or consideration of Jenkins build status.

Decomposition

  1. Decompose the traffic light
  2. Dissolve cables from inside the traffic light off of the Platine.
  3. Connect the cables
    • Connect red cable to the plus port of the Arduino.
    • Connect green cable to digital pin 1 of the Arduino.
    • Connect yellow cable to digital pin 2 of the Arduino.
    • Connect white cable to digital pin 3 of the Arduino.
  4. Compile and upload the following script:
int PIN_GREEN_LED = 1;
int PIN_YELLOW_LED = 2;
int PIN_RED_LED = 3;

void setup()
{
pinMode(PIN_RED_LED, OUTPUT);
pinMode(PIN_GREEN_LED, OUTPUT);
pinMode(PIN_YELLOW_LED, OUTPUT);
}

void loop()
{
setSignalRed();
delay(1000);
setSignalGreen();
delay(1000);
setSignalYellow();
delay(1000);
}

void setSignalRed()
{
//HIGH=OFF
digitalWrite(PIN_GREEN_LED, HIGH);
digitalWrite(PIN_RED_LED, LOW);
digitalWrite(PIN_YELLOW_LED, HIGH);
}

void setSignalGreen()
{
digitalWrite(PIN_RED_LED, HIGH);
digitalWrite(PIN_GREEN_LED, LOW);
digitalWrite(PIN_YELLOW_LED, HIGH);
}

void setSignalYellow()
{
digitalWrite(PIN_RED_LED, HIGH);
digitalWrite(PIN_GREEN_LED, HIGH);
digitalWrite(PIN_YELLOW_LED, LOW);
}

 

After upload you should see the lights switching from red to green to yellow and back to red again.
If everything succeeded, congrats! 😀
If not, ping me on twitter or below in the comments section!

Next aim: Find out the right URL for your Jenkins project whose build status you want to observe.

For this we put the Arduino aside for a sec and try out the following URL in our preferred web server:

  • Base Address of your Jenkins Server
    http://YOUR-JENKINS-SERVER-URL
  • Address of project’s last build status
    /job/YOUR-PROJECT-BUILD-JOB-NAME/lastBuild
  • Suffix to tell Jenkins to output JSON and only the interesting part of it.
    /api/json?tree=result

In case it isn’t obvious, you have to replace YOUR-JENKINS-SERVER-URL with the URL pointing to your Jenkins server and YOUR-PROJECT-BUILD-JOB-NAME with the project’s name configured in Jenkins. The remaining parts can stay the same. Put the parts together and try it out on your desktop machine or laptop. If it doesn’t work from there, it won’t work for Arduino neither.
You should see something like this:

{"result":"SUCCESS"}

So make sure this works before you proceed.

The last mile: Packaging all together.

IMG_2210

  1. Drill a hole through the top of the casing.
  2. Glue the signal light to the top of the casing
    Make sure the cables peek through the hole.
  3. Extend the cables
    Otherwise it will get hard to put everything together.
  4. Use heat shrink tube or duct tape to cover the soldering joints.
  5. Install the network shield
    • Stack the network shield on top of the Arduino.
    • You’ll have to use the digital ports on the network shield now.
    • Make sure to use the same port numbers as before.
  6. Prepare the bottom part of the casing
    As the Arduino will go in there and the casing will get closed, drill holes into the side of the casing for power supply and the network cable.
    Put the Arduino into the casing to check if the holes are at the right position.
  7. Connect the wires
    Connect the wires as before.
    To spare you some scrolling:
    Connect red cable to the plus port of the Arduino.
    Connect green cable to digital pin 1 of the Arduino.
    Connect yellow cable to digital pin 2 of the Arduino.
    Connect white cable to digital pin 3 of the Arduino.
  8. Adapt, compile and upload the following script:
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address for your controller below.
byte mac[] = {  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
char serverName[] = "YOUR-JENKINS-SERVER-URL";

String readString = String(100);
EthernetClient client;

int PIN_RED_LED = 2;
int PIN_GREEN_LED = 1;
int PIN_YELLOW_LED = 3;
int REQUEST_DELAY_IN_MICROSECONDS = 1000 * 10;

void setup() {
   // give the Ethernet shield a second to initialize:
   delay(1000);

   configurePINs();
   setSignalYellow();
   if (!initializeEthernet())
   {
      // Failed to configure ethernet.
      // Prevent entering main loop by never leaving setup procedure
      while(true)
      {
         setAllSignalsOff();
         delay(1000);
         setSignalRed(); 
         delay(1000);
      }
   }
}

bool initializeEthernet()
{
   return (Ethernet.begin(mac) != 0);
}

void configurePINs()
{
   pinMode(PIN_GREEN_LED, OUTPUT);
   pinMode(PIN_RED_LED, OUTPUT);
   pinMode(PIN_YELLOW_LED, OUTPUT);
}

void loop()
{
 // if there are incoming bytes available 
 // from the server, read them and print them:
   String url = "BUILD-JOB-JSON-OUTPUT-RELATIVE-PATH";

   while(connectToURL(url) == false)
   {
      delay(REQUEST_DELAY_IN_MICROSECONDS);
   }

   if (client.available()) {
      char c = client.read();
      readString.concat(c);
      // Serial.print(c);
   }

   // if the server's disconnected, stop the client:
   if (!client.connected()) {
      // connected to server, read in Jenkins's output
      bool isSuccessful = readString.indexOf("SUCCESS") > -1;
      readString.remove(0);
      if (isSuccessful)
      {
         setSignalGreen();
      } else
      {
         setSignalRed();
      }

      client.stop();
      delay(REQUEST_DELAY_IN_MICROSECONDS);
   }
}

bool connectToURL(String url)
{
   if (client.connected())
   {
      return true;
   }

   if (client.connect(serverName, 8080)) {
      // connected to server, make HTTP request
      String request = "GET ";
      request.concat(url);
      request.concat(" HTTP/1.0");
      client.println(request);
      client.println();
      return true;
   } 
   else {
      // no connection to server
      return false;
   }
}

void setSignalYellow()
{
   digitalWrite(PIN_GREEN_LED, HIGH);
   digitalWrite(PIN_YELLOW_LED, LOW);
   digitalWrite(PIN_RED_LED, HIGH);
}

void setSignalRed()
{
   digitalWrite(PIN_GREEN_LED, HIGH);
   digitalWrite(PIN_YELLOW_LED, HIGH);
   digitalWrite(PIN_RED_LED, LOW);
}

void setSignalGreen()
{
   digitalWrite(PIN_RED_LED, HIGH);
   digitalWrite(PIN_YELLOW_LED, HIGH);
   digitalWrite(PIN_GREEN_LED, LOW);
}

void setAllSignalsOff()
{
   digitalWrite(PIN_RED_LED, HIGH);
   digitalWrite(PIN_YELLOW_LED, HIGH);
   digitalWrite(PIN_GREEN_LED, HIGH);   
}

 

From the build status URL you found out in the previous step, replace YOUR-JENKINS-SERVER-URL with the base address and BUILD-JOB-JSON-OUTPUT-RELATIVE-PATH with the remaining part.

Plug in the network cable and test the output. If everything works, you should see the green light for successful builds and the red for unsuccessful ones.
If it does not work, there could be several reasons

  • Arduino does not have a working ethernet connection
  • Jenkins Server not reachable (from same network as Arduino is on)
  • There’s no build job yet
  • Typos in the URLs of the Arduino script

Please check the above.
This script is working fine for me, but there might be other circumstances under which it isn’t.
Have fun with your new Jenkins traffic light 🙂

Key-Value Observing Affected Keys

I like to write handy names for my properties like so:

@property (nonatomic, assign, getter = isLoading) BOOL loading;

As you can see I’ve defined a special name for the getter: isLoading.

There’s only one problem with this:

If another class is observing this class key path loading, it won’t get notified about changes, unless you overwrite your setter like so:

- (void)setLoading:(BOOL)loading
{
    [self willChangeValueForKey:NSStringFromSelector(@selector(isLoading))];
    _loading = loading;
    [self didChangeValueForKey:NSStringFromSelector(@selector(isLoading))];
}

Yesterday I stumbled upon a new way to solve this and a very related problem if different keys are affecting each other.

Registering Dependent Keys

You can implement a class method that follows the naming convention keyPathsForValuesAffecting<Key> to trigger notifications automatically for a (to-one relationship to a) dependent keyPath.

The above snippet could be abandoned using the following implementation:

+ (NSSet *)keyPathsForValuesAffectingIsLoading 
{
    return [NSSet setWithObjects:NSStringFromSelector(@selector(isLoading)), nil];
}

As you can see, the above method returns an instance of NSSet, allowing to specify a bunch of dependent properties that might change dependently.

Here’s the link to the Apple documentation on this topic: Key-Value Observing Programming Guide