Control Smart Home Features with (Satechi®) Bluetooth Button

Sometimes you need another button to control one specific feature in your smart home where no button/control element had been planed. Naturally, digging holes through existing walls in order to lay a new cable is not an option in most cases. I faced this scenario when trying to add another doorbell to my front door. I quickly came up with the idea to use a Bluetooth device to send a signal to some kind of controller – a Raspberry PI in my case – and trigger my KNX-based bell from there.

satechi_bt_home After doing some browsing, I decided to use a Satechi® Bluetooth Button, type Home. It looks quite nice, without any fancy design, and comes with a 3M sticker, so you can put it nearly everywhere. Unfortunately, my existing R-PI (controlling most parts of my KNX installation) was out of range, hence I had to set up a new one for the sole purpose of reacting to the Bluetooth device. The new R-PI then calls a small REST service on my old R-PI, which then triggers the door bell via a signal on the KNX bus.

bluetooth-r-pi-knxHere is a quick list of steps that I took in order to get my new door bell running:

  • Connect R-PI with Bluetooth to my home WIFI network
  • Connect/Pair Bluetooth Button to R-PI using bluetoothctl command (how to)
  • Run a small script to watch for Bluetooth connections using bluetoothctl
  • Upon connection: Call REST service in KNX R-PI

I can confirm the Satechi® Buttons to work flawlessly with the Raspbian OS installed on my PI. Of course, there is a little delay between pushing the button and the bell to ring due to the latency of Bluetooth and WIFI. However, it is quite okay for this scenario. I am pretty sure I will use the same set up for further controls, such as a central off (when leaving the house).

Advertisements

Controlling Home Automation via Telegram Bot

We have been moving to a different house with a KNX-based smarthome installation lately. I have spent quite some time coming up with my own visualisation and automation, mainly using a Python implementation relying on the KNXD (a fork of the well-known EIBD) software for Linux.

When I read about the new Telegram API for Bots, I got excited about the idea of creating a bot for my home automation installation. Using simple commands, I wanted to switch on/off lights, control the temperature, get status messages …

telegram_knxd

Using the Telegram documentation and my PI-based main KNX controller, it was quite easy to come a with a first prototype, which I can use to switch on and off devices. The screenshot is in German, but you can basically see how I use it to switch on my lights and some outlets. More advanced commands will follow soon. Since I have a smart watch (LG Urbane) which I can use to send Telegram messages via voice input, I can even use it as a voice-to-KNX interface without developing a special (watch) app, just relying on existing technology. (Unfortunately, I am cannot start a new chat with my bot for now, but this is a problem of the watch’s OS.)

I am quite happy with this first version and can’t wait to enhance it. Also, I am considering using this “human to machine interface technology” in enterprise/business apps. What do you think?

 

Install KNXD on Raspbian (8)

I am currently in the process of planning the KNX set up for our new home. I have decided to use a Raspberry PI 2 (Model B) with Raspbian OS for the more fancy stuff, such as visualization, logging of measured values, automatic jobs etc. Communication with the KNX bus will be handled by KNXD.

The KNXD git hub page offers a small shell script that can be used — in theory — to install the software on Debian based system (Raspbian is based on Debian). Unfortunately, a few packages are missing in the requirements section (apt-get install).

I have added these packages creating a new version of the KNXD install script specifically for Raspbian OS. My PI runs on Raspbian 8, however, it should work with other releases as well.

#!/bin/bash

# first, install build tools and get the source code
sudo apt-get install git-core build-essential debhelper cdbs autoconf automake libtool libusb-1.0-0-dev libsystemd-daemon-dev dh-systemd
git clone https://github.com/knxd/knxd.git

# knxd requires libpthsem which unfortunately isn't part of Debian
wget https://www.auto.tuwien.ac.at/~mkoegler/pth/pthsem_2.0.8.tar.gz
tar xzf pthsem_2.0.8.tar.gz
cd pthsem-2.0.8
dpkg-buildpackage -b -uc
cd ..
sudo dpkg -i libpthsem*.deb

# now build+install knxd itself
cd knxd
dpkg-buildpackage -b -uc
cd ..
sudo dpkg -i knxd_*.deb knxd-tools_*.deb

Creating PDF documents in OpenUI5 apps

I have been a fan of OpenUI5 (or UI5 in general) ever since my first encounters with it in late 2013. Thus, I have been trying to do some of my work using OpenUI5, and, hence, I have decided to write a few blog posts about UI5 and about how certain things can be achieved. I have mainly been focusing on new apps for our company and myself, since most of our customers have not yet switched to using mobile enabled applications heavily or rather rely on the existing apps from SAP itself. I usually have a PHP-based back-end using JSON as data model provider, since a full SAP stack is an overkill in most cases.

When implementing business apps, creating PDF reports/documents that can be printed, sent via email or stored in an electronic archive often is a required feature. This can be achieved with two different approaches.

  1. It is possible to create the PDF using JavaScript libraries right on the (mobile) device. A common library for generating PDFs in JavaScript is jsPDF. This approach doesn’t require extra communication with the back-end or any back-end at all. On the downside, jsPDF doesn’t seem to be very robust when working with images. Thus, this approach is mainly fitting for small apps with simple output.
  2. The second option is producing the PDF document on the back-end. For PHP-driven services, fpdf is a very good tool for that. Just like jsPDF, fpdf is free software. In my tests, it proved much more reliable when producing complex output using images etc. For this approach, a new script/service has to be called. I found it to be a convenient solution to pass the required data (from the UI5 data model) as a JSON string (JSON.stringify) to the PHP service.

Below, you will find an example for generating PDFs directly on the mobile or desktop device using JavaScript and jsPDF and for creating the documents in the back-end with PDF and fpdf.

jsPDF: Document generation in the (mobile) app

Let us create a small app with input fields and a button for generating a PDF document. The PDF doc will contain the input value to show you, how you can connect your app data to the output process.

Example app

The UI5 coding for our apps looks like this:

<!DOCTYPE html>
<html>
  <head>
	<meta http-equiv='X-UA-Compatible' content='IE=edge' />
	<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
	
	<script id='sap-ui-bootstrap' type='text/javascript' src='https://openui5.hana.ondemand.com/resources/sap-ui-core.js' data-sap-ui-theme='sap_bluecrystal' data-sap-ui-libs='sap.m,sap.ui.commons'></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.1.135/jspdf.min.js"></script>
	<script>      
		var oModel = new sap.ui.model.json.JSONModel({ name: "Name", age: 30 });
		var p = new sap.m.Page( {
          title: "Generate PDF",
          content: [
            new sap.m.Label({ text: "Name:" }),
            new sap.m.Input({ value: "{/name}" } ),
            new sap.m.Label({ text: "Age:" }),
            new sap.m.Input({ value: "{/age}" } ),
            new sap.m.Button({ text: "Generate PDF", press: function(evt) {
              var n = evt.getSource().getModel().getProperty("/name");
              var a = evt.getSource().getModel().getProperty("/age");
              
              var doc = new jsPDF();
              doc.text(20, 20, "This is " + n);
              doc.text(20, 30, "She/he is " + a + " years old.");
              doc.save('sheet.pdf');
            }})
          ]
        } );
      
      var app = new sap.m.App({ pages: [ p ] }).placeAt("content");
      app.setModel(oModel);
	</script>
	
	</head>
	<body class='sapUiBody'>

<div id='content'></div>

	</body>
</html>

As you can see, pushing the button “Generate PDF” will trigger the document output directly in the app. Therefore, a new object of type jsPDF has to be instantiated providing methods for adding content to the PDF document. jsPDF comes with a lot of examples showing you how to create bigger and more complex documents.

You can give the app a try on jsBin.

fpdf: Document generation in the back-end

Let us take the same app from above, but this time the PDF document will be generated in a PHP-based service.

<!DOCTYPE html>
<html>
  <head>
	<meta http-equiv='X-UA-Compatible' content='IE=edge' />
	<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
	
	<script id='sap-ui-bootstrap' type='text/javascript' src='https://openui5.hana.ondemand.com/resources/sap-ui-core.js' data-sap-ui-theme='sap_bluecrystal' data-sap-ui-libs='sap.m,sap.ui.commons'></script>
    
	<script>      
		var oModel = new sap.ui.model.json.JSONModel({ name: "Name", age: 30 });
		var p = new sap.m.Page( {
          title: "Generate PDF",
          content: [
            new sap.m.Label({ text: "Name:" }),
            new sap.m.Input({ value: "{/name}" } ),
            new sap.m.Label({ text: "Age:" }),
            new sap.m.Input({ value: "{/age}" } ),
            new sap.m.Button({ text: "Generate PDF", press: function(evt) {
              var n = evt.getSource().getModel().getProperty("/name");
              var a = evt.getSource().getModel().getProperty("/age");
              
              window.open("http://some.where/?name=" + n + "&age=" + a, "_blank");
            }})
          ]
        } );
      
      var app = new sap.m.App({ pages: [ p ] }).placeAt("content");
      app.setModel(oModel);
	</script>
	
	</head>
	<body class='sapUiBody'>

<div id='content'></div>

	</body>
</html>

Pushing the button “Generate PDF” this time opens a new window/tab with the specified location passing the form data as HTTP GET parameters. Usually, you will pass bigger amounts of data to the output processing and might consider using HTTP POST. So, what does the back-end script look like:

<?php require('fpdf.php'); $name = $_GET['name']; $age = $_GET['age']; $pdf = new FPDF(); $pdf->AddPage();
$pdf->SetFont('Arial', 'B', 12);
$pdf->Cell(40, 10, 'This is ' . $name . ' aged ' . $age);
$pdf->Output();
?>

The PHP script simply fetches the two parameters (data), creates a new object of type FPDF and uses a few – easy to understand – methods to put some content into the document. Again, fpdf comes with a variety of examples and tutorials to show you how to use it. It takes some time to get used to the positioning of elements etc. But once you have got acquainted to fpdf, it’s quite easy to create large document with different types of content.

In this post, I have shown two different approaches on where to create PDF in (mobile) apps that are based on UI5. Both example were kept as simple as possible ignoring some best practices for UI5. Of course, there are different libraries for PDF output and the same approaches apply for word documents etc. If you know better tools for the job – other than jsPDF and fpdf – feel free to leave a comment. Also, if you’re trying to implement PDF as part of (mobile) apps and require help, please do not hesitate to get in touch.

WebUI components for ITSM

I am currently supporting a SAP Solution Manager ITSM project which requires a lot of modification to the standard ITSM WebUI components. Thus, I have created tiny overview of the most important BSP components in this area. I would like to share this overview here, in case anybody else is looking for one of the specified WebUI elements:

Header comp. Search comp.
Ticket (general) AIC_INCIDENT_H AIC_INCIDENT_S
 RfC AIC_CMCR_H AIC_CMCR_S
 Change AIC_CMCD_H AIC_CMCD_S
 Task BT125H_TASK
 Incident AIC_INCIDENT_H AIC_INCIDENT_S
 Service Request AIC_INCIDENT_H AIC_SRVREQ_S

If I missed an important component, please let me know.

Convert saplogon.ini to SAP Java PlatinGUI connections

I like to use my native Mac OSX system and the Java PlatinGUI for working and developing with SAP whenever I can. Of course, I know that the native Windows GUI is way more advanced (because better taken care of by SAP), but I hate to boot my Windows VM every time I want to do something SAP-related. Since I work for multiple clients having multiple SAP installations (ERP, CRM, Solution Manager, …), I want to have my SAP connections in synch. For my Windows systems – yes, I do have a few of them – I share the saplogon.ini via Dropbox. However, that doesn’t help me having the same connection entries in my Mac Java SAPGUI (PlatinGUI).

Hence, I wrote a tiny (and not very fancy) Python script to convert the saplogon.ini entries to the connection strings used in the Java SAPGUI’s connections file (which on Mac OSX can be found in the user’s Application Library folder). It doesn’t do much and it is not very robust against invalid input, but I would like to share it here, so anybody can use it for their own purposes. If you have an advice on how to improve the script radically or on how to support more input information, please let me know.

#!/usr/bin/env python

import sys, os

try:
    fname = sys.argv[1]
    fh = open(fname, 'r')
except:
    print sys.argv[0], ' &lt;path/saplogon.ini&gt;'
    sys.exit(-1)

data = fh.readlines()
fh.close()

# initialize entry data base (100 records)
entries = []
for i in range(100):
    entry = {'description': '', 'server': '', 'router': '', 'database': ''}
    entries.append(entry)

for line in data:
    data = line.strip()
    if data != '':    # ignore empty lines
        if data.startswith('[') and data.endswith(']'):
            key = data.lower()[1 : len(data) - 1]
        else:
            parts = data.split('=')
            item = parts[0]
            value = parts[1]
            try:
                nr = int(item[4 : ])
                entries[nr][key] = value
            except ValueError:
                pass

# now print connection strings for Java GUI
for e in entries:
    if e['description'] != '':
        comp = '/' if e['router'] != '' else ''
        connStr = e['description'] + ':conn=' + \
            e['router'] + comp + \
            '/H/' + e['server'] + \
            '/S/32' + e['database'] + '&amp;expert=true&amp;wan=true'
        connStr.replace(&quot;/H//H/&quot;, &quot;/H/&quot;)
        print connStr

Citrix Receiver not working with Mac OS X Yosemite

With the update to Mac OS X Yosemite, my Citrix Receiver–which I need for accessing customer systems–suddenly stopped working. I do not know if or why the problem is caused by the update, but it stopped working on both–my iMac and my Macbook Air–at the same point of, meaning with the Mac OSX update. For those Mac and Citrix users having the same problem, I want to provide a quick solution.

The reason for Citrix Receiver not working properly are invalid file permissions in the app specific folder in $HOME/Library. This can easily be fixed, changing the permissions with this simple Terminal command (quick and dirty setting the specific directory to writeable for everyone):

chmod 777 $HOME/Library/Application\ Support/Citrix\ Receiver/Modules