This Site & Me
I'm a technologist, mobile specialist, experienced software developer, author, public speaker & an SAP employee. My thoughts, ideas, rants, comments & most of the code you'll find here are my own. Feel free to use any of this, but be sure to identify the source.
Topics You'll Find Here
This site contains content on a bunch of different topics including Mobile, Mobile Development, IBM Lotus Domino and other topics that strike my fancy. I've written a couple of mobile development books, so mobile and mobile development tend to dominate.
Like What you See?
Like what you see here? Found something useful?
If you benefited from anything I've posted here, please think about buying one of my books or taking advantage of one or more of the ads on the page.
- Category: Microcontrollers & Single Board Computers
I’ve been working on a Particle Photon-powered garage door opener project with my son; I’d found an example project online somewhere (I can’t remember where, otherwise I’d post a link here) and looked pretty interesting. I, of course, modified it and put my own twist on the project. I’ll write about the project once it’s completed. The project’s pretty simple and it’s all ready to assemble (plus the code is all written).
I came up with a few features I wanted for the opener that I couldn’t implement on the Photon, so I decided to do a V2 on the Raspberry Pi. I’ve got the hardware all figured out and I wanted to create a node-based server process running on the Pi to control everything. I love working with the Pi, but I honestly don’t want to write code on it. The editors I’m comfortable with aren’t compatible and the system’s just not fast enough for the dev stuff I want to do. So, for this server project, I started thinking of how I could use my PC to code everything, but also maintain a quick and easy way to publish code to the Pi for execution and testing.
What follows are instructions on how to setup WebStorm to publish code directly to the Pi.
Implementation – Enabling SSH
The first step in the process is to enable SSH on the Pi. It’s fairly easy to do this, simply open the Raspberry Pi Configuration utility (open the Pi menu and select Preferences, then Raspberry Pi Configuration). In the dialog that appears (Figure 1), select the Interfaces tab then enable SSH as shown in the figure. When you click the OK button, the Pi will reboot with SSH enabled.
Figure 1 – Raspberry Pi Configuration Application Interfaces Tab
The next thing you need to do is figure out how your desktop development environment will connect to the Pi. WebStorm needs to know how to reach the Pi; you could enable DNS and use the Pi’s name to connect to it, but that’s more complicated than I wanted for this project. Instead, I decided to connect to the Pi using the device’s IP address. There are several ways to determine the Pi’s IP address. A quick look at the Pi documentation told me I could use the following command to determine the IP address:
So, I opened a terminal window on the Pi and typed in the command and received the results shown in Figure 2. The first time I did this (OK, it was a couple of times) I didn’t get the results I wanted. I’d type in the command, but I’d get back an IP address of 127.0.1.1 which is a local address (only accessible from the PI) and something that wouldn’t work for me. I finally figured out the problem, I used a lower case i and that got me completely different results.
Figure 2 – Using the hostname command to determine the Pi IP address
Another way to get the IP address is to execute the following terminal command:
With this command, you get the results shown in Figure 3.
Figure 3 – Using the ifconfig command to determine the PI IP address
Using either approach, I quickly determined my device’s IP address (192.168.1.92). With that in place, I’m ready to configure WebStorm.
Now that I know how to reach my Pi and the SSH software is installed, it’s time to configure my WebStorm project to publish my code to it. In WebStorm, open the Tools menu, select Deployment then Configuration; you should see a dialog similar to the one shown in Figure 4.
Figure 4 – Configuring a Connection in WebStorm
The first thing you’ll want to do is click the green plus sign in the upper-left corner of the dialog. By clicking on it, you’re instructing WebStorm to create a new connection. When the new connection appears (it will take up the right side of the dialog as shown in the figure), do the following:
- Set the connection type to SFTP as shown in the figure.
- Specify the Pi’s IP address as the SFTP host.
- Leave port alone; port 22 is the default port for SSH and the Raspberry Pi will use it by default.
- For Root Path, you can type in the full path pointing to the Pi user’s home folder if you know what it is. I didn’t know, so I clicked the Autodetect button and it filled it in for me.
- Specify the User name defined on the Pi. The default user name is “pi” and the default password is “raspberry” – if you’ve changed the default user settings on the Pi, make sure you enter the correct values here. Set Auth type to Password as shown in the figure.
- Be sure to check the Save password checkbox if you don’t want to have to type in the password every time you deploy your code to the Pi.
- At this point, you should have everything you need to connect – click the Test SFTP connection button to validate the settings you’ve entered. If the test fails, you’ll have to tweak the settings until everything’s right.
Once you’ve validated the connection, switch over to the Mappings tab shown in Figure 5.
Figure 5 – Mapping the local file system to the remote host
The Local path field should be populated with your current WebStorm project folder. This field specifies the source folder for the deployment.
In the Deployment path on server ‘Pi’ field, enter the home folder path where you want the files deployed. For my configuration, the user’s home folder is located in /home/pi, so with the deployment path shown in the figure, the files will be deployed to /home/pi/dev/pi_garage_door_server.
There will be files/folders in my project’s source folder that I don’t want copied over to the Pi, do I used the Excluded Paths tab to specify the content I wanted excluded as shown in Figure 6.
Figure 6 – Excluding folders published to the Pi
In this case, I wanted to be able to manually install any modules I needed on the Pi, rather than using the ones from my dev environment. I clicked the Add local path button and selected the node_modules folder from my project.
Click the OK button when finished.
Deploying the Project Files
With everything in place, you can deploy the project files to the Pi in two ways:
- Open the WebStorm Tools menu, select Deployment then the Upload to Pi option
- Right-click on the project folder in WebStorm then, in the pop-up menu that appears, select Deployment then the Upload to Pi option
WebStorm will open a File transfer window and show you the status of the file transfer as it progresses.
That’s it, that’s all there is to configuring WebStorm to deploy files to the Raspberry Pi. To test my code, I’ll need to keep a SSH window open, connected to the Pi, to execute the server code. Ultimately, when the code’s stable, I will configure my server to reload itself after every execution, so all I’ll have to do is refresh my browser window twice to load the new code I’ve deployed. More on the server process later. Enjoy!
- Category: Miscellaneous
My publisher recently asked me for some content to use to help promote my latest books, so I spent some time during the holidays writing a couple of articles for their website. I recently received one of the articles back from the editor and I was struck by the absurdity of one of the comments in the file. This post is my response to that absurdity.
When I get a few spare moments, I look through the Cordova/PhoneGap questions on Google Group or Stack Overflow. Whenever I do, I usually find one or two that I can answer without too much work, so I give it a shot. In my most recent article about Cordova, I wrote the following:
“For many years now, I've been trolling the PhoneGap Google Groups and Stack Overflow Cordova sites, trying to answer what questions I can.”
In response to this, the editor wrote the following:
“Can you think of a verb that doesn't resemble troll, since that word is also used to describe the abusive activity of online jerks?”
As I’m describing a scenario where I’m putting a hook in the water and driving around in my boat looking for fish, I was pretty happy with my choice of trolling in this case. That is, after all, the definition (source http://www.merriam-webster.com/dictionary/troll):
- To fish with a hook and line that you pull through the water
- To search for or try to get (something)
- To search through (something)
Sometimes a word is just a word and the classic definition of the word…simply…works. In this case, there’s trolling for fish and, the other, bad, Internet Troll. In this case, I’m pretty sure my context is clear; as you read the sentence, does it feel to you that I’m announcing to the world that I monitor Stack Overflow and Google Groups looking for people to attack verbally? Or, more reasonably, did I intend to mean that I’m, as per the Merriam Webster dictionary definition above, searching through something?
We shouldn’t be afraid to use words simply because of one, unofficial, interpretation of the word. The urban dictionary, for example, completly ignores the actual definition of the word and instead leads with the bad Internet Troll interpretation of the word. I bet that many people don’t actually know the true meaning of troll; the Urban Dictionary’s manipulation of the definition doesn’t help either.
We have to stop looking for things to be offended about; people are way, way too sensitive nowadays and it’s getting a little ridiculous. As George Carlin famously said: “There are bad thoughts, bad intentions, and words.” I’d like to amend that to the following: “There are bad thoughts, bad intentions, actions and words.” Judge me on my actions or the reasonable assessment of my words; not the potential, unreasonable interpretation of a word. Reasonable people will likely assume the least offensive meaning of my use of trolling until I prove otherwise.
- Category: Miscellaneous
A Book Review
I recently received a copy of Simon Monk’s The Maker’s Guide to the Zombie Apocalypse. I’d read several of Simon’s books (Programming the BeagleBone Black and Make: Getting Started with the Photon). I’ve enjoyed his books, and they’ve helped me learn how to work with the Photon and BeagleBone Black.
I travel a lot and when I’m trying to learn something, I prefer to pick up a book and work through the book step by step. Online documentation is OK, especially when you’re trying to find a quick fix to something, but I find that books are better at the overall learning you need when you first start working with a hardware device, developer tool or programming language. There’s something about the structure of a book vs. poking around in product documentation that makes it easier for me to learn from a book.
This book is different – instead of working with a specific hardware device, he’s picked a theme for this one and targeted all of the book’s projects to that theme. In this case, it’s all about some projects you can do that will help you survive the Zombie Apocalypse (ZA). Overall, he’s done a good job in selecting useful projects and connecting them well with the theme. The good news is that even though he’s working with a theme, and having some fun with the whole Zombie aspect of it, he doesn’t overdo it. The ZA attitude and the jokes that accompany it are fun and not overdone. I especially liked the web cam example image that included a Zombie in it – a nice and fun touch.
The good thing about this themed approach is that he’s crafted a series of useful projects then tied them together with a single management console. Each project can be built separately, but when you follow the theme and get them all working together through the console, you get a feel for how more complicated projects can work.
Since he’s focusing on a series of projects and not a specific hardware device, you get to see how to implement projects on different hardware platforms (Most projects are on the Arduino, but the Raspberry Pi shows up as well).
Unfortunately, his parts lists don’t take into account that you might not be adding a particular project to another existing project that already has some parts. I found myself looking at the shopping list and thinking that things were missing only to discover later that he’s expecting this particular project to be added to another. I would have preferred a complete list of parts that were somehow marked to indicate “You may already have this part if you’re adding this to that other project.” It’s not a big deal, but it did cause me some pause as I tried to figure out which parts were needed to complete the whole project.
The thing I liked the most about this book compared to the others I’d read is the length of the book. Since he wasn’t doing a quick hit on a specific hardware device, he spent more time (pages) covering the background material in detail before showing how to make the report. I especially liked the chapter on survival tips for the ZA: Chapter 1 – Apocalypse Basics. In this chapter he covers some basic survival requirements before jumping into the skills you need to make the projects. In the second chapter, he talks about how to generate electricity and provides a lot of good background about electricity and battery life. The value of this for many readers will be when they’re trying to build something with similar (but different parts); the material he provides makes it easy for the reader to figure out how his stuff will work compared to what Monk shows in the book. He did a really good job showing how to make use of the flash in a pile of discarded (empty) disposable cameras.
Of all the microcontroller projects book I’ve read (and I’ve read a bunch), this book had more practical material (background and project) than most others. There are real world applications for each of the projects described herein. Additionally, the none of the projects were that hard, I knew I had the skills for each. I’m looking forward to see what he does next.
- Category: Miscellaneous
For years, I've had this problem in Microsoft Outlook where Outlook will populate only the country field for select contacts. I've never done it purposefully, but somehow either because of some weird sync process or other reason, I had a bunch of contacts with no address, only a country set for them.
Figure 1 – Michael Palin Contact Card (NOT his real contact information)
Anyway, this has been bugging me for some time and I've been too lazy to fix this manually. So, with all the Outlook integration code I've been doing lately, I decided I'd write an app that whacks the Country fields value (there are 4 of them: mailing, home, work and other) from every Outlook contact.
I've posted the Delphi project code to GitHub. The app basically opens a memo field and processes all of the contact records, blanking out the country if it's 'United States of America'. I got the code working then cleaned up my contact list.
Thought about it a bit and realized that I could have done a better job with the code. I made separate blocks of code to check each country field individually, turn out that there isn't (that I could find) a way to retrieve a contact record field value by name, so I don't think there's a better way to do this. Also, whenever the app whacks a country field, it saves the record. I could have easily tracked whether a change was made and save only once, but I didn't.
- Category: Miscellaneous
As I mentioned in my previous post, I'm helping a friend with some Microsoft Outlook integration and came across the need to access the list of meeting and email categories defined within Outlook. Microsoft has done a great job of documenting the object model for Outlook, so it's quick work in Delphi to open an OLE connection to Outlook and get a listing of the Categories. The code's below, but I also posted the complete project to GitHub.
Here's the code:
category, outlook, ns: OLEVariant;
i, numItems: Integer;
// initialize a connection to Outlook
outlook := CreateOLEObject('Outlook.Application');
// get the MAPI namespace
ns := outlook.GetNamespace('MAPI');
numItems := ns.Categories.Count;
output.Lines.add(Format('Found %d items', [numItems]));
if numItems > 0 then
for i := 1 to numItems do
category := ns.Categories.Item[i];
// category.Name is the name of the category
// category.CategoryID is an internal, unique ID for the category
output.Lines.add(Format('%d: %s: (%s)', [i, category.Name,
The output object is a TMemo component on the app's main form, so it is used to list all of the categories when the app initializes. The app doesn't do anything with the categories, this is just an example of how to retrieve them.
- Category: Miscellaneous
Until recently, I've always kept my main set of contacts on my personal mobile device and used Exchange ActiveSync to synchronize it with my mobile device. When I joined Forrester, I decided to keep my work stuff separate from my personal stuff. So, rather than have all of my personal contacts available to me while at work, I let my work account sync my work PIM data to my device through its normal means and used a separate process to sync my person PIM data to my device as well.
Since I carry an Android device, I looked around and found an open source solution called Go Contact Sync Mod (http://googlesyncmod.sourceforge.net/) that works pretty well. I could have the sync run automatically, but for now I'm running it manually. One of the things I noticed when I run it is that it was showing an error indicating that it had found empty calendar entries in Outlook. I didn't know I had empty calendar entries nor did I know you could create empty calendar entries, but apparently my pst file had a bunch of them.
I looked around for a while and didn't find a solution for deleting those empty entries, and I couldn't 'see' them in Outlook, so I decided to write some code to solve the problem. I'd been helping a friend with some Outlook automation, so I had the basis of what I needed to make this work. I'm a big Delphi developer, although I'm pretty upset with Embarcadero right now, so it gave me a chance to dust off my Delphi skills and write some code.
I'm not going to go through everything here, but I've posted the code to GitHub at https://github.com/johnwargo/Kill-Empty-Outlook-Calendar-Entries. Basically you can open the project in Delphi then build and run it, or you can use the pre-built executables I've included in the repository. Enjoy!