Pages

Sunday, October 6, 2019

Managing Social Media Posts

In an effort to troubleshoot and see how far I can go to manage my social media, I delved into a trick I used to do with IFTTT, Blogger, Facebook, Twitter, and LinkedIn.  A while ago, I set up some Applets on IFTTT that fired when I updated this blog page.  What it was supposed to do was auto-publish the new blog post across Facebook, Twitter, and LinkedIn without my having to copy and paste the link on each service separately.  As of March 2019, LinkedIn changed their API and I was oblivious to this, or too busy to research how to correct it.  As I don't blog much (thanks Sharon for pointing THAT one out...), I haven't been bothered by it much.  Today, after being excited enough to post a very extensive blog post, I saw the IFTTT fire, but it only reached Twitter and Facebook.  It was then I found that LinkedIn was broken.  I still have the connection in place though between Twitter and LinkedIn, so anything I post should go to both places, however, I found that now I have to add an extra step.  I have just updated my Applet on IFTTT and this post will test whether adding the hashtag will work to cascade the post across all three again.

Update:  Well, it didn't work.  LinkedIn is being very obstinate about automatic posting.  In addition, they removed the ability to link your account with Blogger (at least for non-Premium accounts), therefore, my workaround is to add my Blog as a publication under my LinkedIn profile and hope people scroll down that far to see it.

Smarthome Connectivity

Since moving into the new house, I've become acutely aware of how Siri, Google, and Alexa are important from the standpoint of a person with vision difficulties.  At first, it was simply a means to engage the time by reading audiobooks and providing the ability to access web searches without the need to be able to see the computer screen.  This has ultimately evolved into a search into enabling such a person to have more control over a world that is becoming ever darker in their eyes.

First a bit of a backstory for those that are not aware.  A very special person in my life is slowly losing his sight, and about two years ago the first signs that he needed help started to appear.  My wife and I got a call that he attempted to drive home after visiting the eye doctor and realized that he was unable to do so safely.  We found him parked on a median in the middle of the road.  Shortly thereafter, he announced that he was no longer capable of driving himself.  This was an extra burden on our already hectic lives, but we did so more than willingly, but a side conversation between the wife and I had to occur.  We needed to discuss the feasibility of continuing to care for him in his home or seek an alternate residential situation for him.

This is one of the hardest conversations to have with the person involved as many children of aging parents will tell you.  We scheduled the conversation and I went to look for potential houses that would be able to fit all of us under the same roof.  This was a very tall order as the wife and I already had plans to find a piece of property that was large enough that our children could also fall back on if they needed to in their young adult years.  We were both wanting several acres of property with trees, but for someone with failing sight, the gradient terrain had to be considered.  I actually found a potential property prior to our conversation and pulled some numbers.

The conversation went far better than we both had thought, and the decision was made to have my father and us source a property together.  I'll skip the next few months of financial conversations, moving, and the like as they aren't relevant nor do they add to the intent of this post.  It is now about a year since the move and my father currently has both Google and Alexa on the table that he sits at every day.  His enjoyment is visible to us as they allow him to interact with the wider world, enjoy sci-fi and fantasy audiobooks (a long-standing hobby of his), and even give us a phone call without needing to manually dial a number on a phone.

One of the pain points of the property though is it came with a private gatehouse that has caused me some grief in setting up with an intercom/gate opener.  There really is only one manufacturer for these devices, because Craftsman and Liftmaster are both owned by Chamberlain.  All of these devices are becoming connected through their technology called "MyQ" and my new gate opener came with this technology.  At the original install, I did not hook it up as I view Internet-connected devices as inherently vulnerable, but my fathers' situation could not be ignored.

The manual intercom system that came with the house was a dinosaur, being some 34 years old, and badly needed replacement.  I sourced and purchased an updated system that added two capabilities to the old one, that of video and RFID entry.  The day I installed that system and made it work was very cool.  Unfortunately, my father had trouble finding the button to open the gate as the touchscreen monitors inside no longer had the tactile feel of a push button.  It was then I realized that no modern closed-circuit system would work for him.

Then came the lightning.  During a heavy thunderstorm, a lightning bolt hit a tree outside the gatehouse and it took out a good bit of technology that I had installed into the house, including the brand new intercom system and gate opener.  I ordered replacement parts, and all but the doorbell on the gate were replaced.  The doorbell from downstairs was relocated to the gatehouse as it was still working so that we could return to functionality, but I was missing the front door and downstairs door doorbells.  Two months have gone by and the part I purchased to replace the failed doorbell has yet to come in from China (Thanks a lot Trump).  I'm now realizing that the tariffs have impacted me in a way I didn't expect. 

Along this journey, I decided to leverage the MyQ technology built into my gate opener and purchased a Liftmaster branded Internet Gateway and set that up.  I can now open my gate from my smartphone, which is good because several manual button openers have become lost.  This solved the problem for most of the family, and we had a temporary solution for my father of taping a paperclip to the interior monitors next to the gate button that he could feel, but I wasn't satisfied with this solution.  I wanted him to be able to open the gate by asking Google or Alexa to do it.

Here's the part of the story that gets technical and was frustrating for me to work out.  The MyQ app can integrate with Google but doesn't have the capability of issuing an open command from Google.  They state this is for security reasons, which is very confusing to me because their app can't be very much more secure.  I suppose, given the layout of most homes, having someone outside yelling "Google, open the door" IS a concern, but in my situation, the gatehouse is a good distance from the house, and that would be futile for someone to attempt. 

I started to explore the problem further and discovered that in addition to the integration with Google, MyQ also integrates with IFTTT.  This is interesting because IFTTT is extremely flexible and has lots of integrations with other smart home devices and systems.  As it turns out, IFTTT can integrate with both Alexa and Google as well as Samsung SmartThings.  SmartThings, in case you have been asleep or not aware, has an open API for development and a large contributing community.  In addition, one of those custom-built SmartApps integrates with MyQ.  (see https://github.com/brbeaird/SmartThings_MyQ).

The first time I visited that link, I came away with my head swimming.  I may be good with computers, but this was not an area that I had any experience with.  My experience lies with enterprise-level cloud computing platforms, not the lower end consumer stuff.  I shoved it into the back of my brain until I had a chance to dust it off and take a closer look.  Today was that day. 

I started by logging into all the relevant web portals and having them all side by side, MyQ, Google Assitant, Amazon skills, IFTTT, SmartThings, and several research windows and started digging.  I quickly realized that my phone was also necessary for some of the stuff and even employed the second computer in the process.  In reading through the article above, and doing a bit of other research as well as some intuition jumps myself, I finally arrived at a satisfactory solution, one that I do not believe is fully documented in a single place on the web.

So here goes.  Requirements/Steps:

1. Accounts for MyQ, Google, Amazon, IFTTT, and SmartThings
2. Integrations setup and functional for IFTTT to Google, Alexa, and SmartThings
3. (optional, but highly recommended) The Community Installer for SmartThings (located here: http://thingsthataresmart.wiki/index.php?title=Community_Installer_(Free_Marketplace))
4. The SmartThings_MyQ SmartApp added to SmartThings (located here: https://github.com/brbeaird/SmartThings_MyQ)
5. Creation of a virtual sensor in SmartThings using this guide:  https://community.smartthings.com/t/how-to-smartthings-myq-smartapp-using-myq-sensors-with-ifttt/149601
6.  IFTTT custom Applets for Google and Alexa (either or both, your choice)

Step 1:  If you are reading this, I would assume you can handle that first requirement on your own, so I'll leave that to you.  If you can't handle that, you really don't have any business doing this on your own, go grab the local techie down the street and hope they know better than you do.

Step 2:  Integration of the services can be frustrating from the MyQ side as the phone app seems to have a way to directly integrate with both Google and IFTTT, but in reality, all it does is open the partner app and leave you hanging.  Fortunately, you don't need to integrate MyQ with anything (even though I did and have left them in place).  The long and the short of it is with the direct MyQ integration, all you have the capability to do is check the status of the device and to close it, NOT open it.  What's more, in my case, I was not able to ever have Google recognize that I even had a device through that integration.  I called Chamberlain and they were also unable to help me get it visible, which I found quite odd.

In any case, handle the IFTTT integration from THEIR side with Google, Alexa, and SmartThings.  This integration is simple as of the time of this writing, you simply have to log in to the web portal, click Explore and search for the three services one at a time.  Under the search box will appear the public Connections that others have written and a Services tab.  Choose the services tab, then the service and follow the bouncing ball to log into the other service.  Google and Alexa are just that simple, SmartThings has an extra step once you log in.  It will bring up a window that will have you authorize the connected devices registered to your account.  For now, it should be blank or have devices that you don't want for this project, just skip it and come back later.

Step 3:  The Community Installer guide is well written and you will have no need to go into the Advanced Installation section. 

Step 4:  Once the Community Installer is installed, switch to the phone and download the "Classic" SmartThings app. This app, at the end of the day, isn't actually necessary beyond the addition of the SmartApp except for testing the SmartThings_MyQ SmartApp piece of the puzzle and will leave you with two apps that can then open your garage/gate from your phone without going through Google or Alexa.  The objective in this step is just to get the SmartThings_MyQ SmartApp functional within SmartThings.  Since I didn't find how to actually use this, I'll include a mini-guide here:

     4.1.  Open the Classic SmartThings app, go to Marketplace>My Apps> ST-Community-Installer
     4.2.  Set the IDE Login Account Type to whatever your login is (Samsung or SmartThings) and hit done.
     4.3.  Scroll all the way down and hit Installer Home, then login to the same account type that you identified in step 4.2
     4.4.  Search for and install the MyQ Lite SmartApp.  Under normal circumstances, you can accept the default choices during install
          4.4.1  TAKE NOTE:  You will be doing this step again to update this community app if you run into a problem in the future, so this is one argument for keeping the SmartThings Classic on your phone!!!

Step 5:  Add the Virtual Sensor.  Although the guide was written relatively recently, the SmartThings portal has changed and some steps are out of date.  For the most part, you can figure out the changes, so go ahead with Steps 1 and 2.  Step three of that guide will lead you down the wrong path though, as MyQ has pulled support for the closing function within IFTTT, so don't do that one.  Instead, skip down and do Step 4 and make sure that part works as laid out there.

Now you want to test the actual MyQ Garage Door Opener supplied by the MyQ Lite app added in Step 2 of the guide.  On your "My Home" in the SmartThings Classic app on your phone, you should have at least two devices, one labeled "DO NOT PRESS - something you typed" and one labeled whatever you're naming your devices in MyQ.  Click on the one from MyQ, a dashboard will open giving you the status of Closed and an Open and Close button.  Hit the Open button, then switch apps to the MyQ app*.  Without doing anything, you can watch the gate/garage open from the MyQ app.  If for whatever reason this isn't working, you've done something wrong when adding the virtual sensor or setting up the integration between MyQ and SmartThings.  Go back and check both of these and ensure they are set up correctly.  If the gate/garage opens, CONGRATULATIONS!  you can now move on to Step 6 and you are virtually home free now.

*Because the device in SmartThings is set to a virtualized sensor instead of the actual sensor from your gate/garage, it's not actually reporting real-time information and as long as you haven't set the "DO NOT PRESS - [whatever]" to "ON", it will report "Closed" in SmartThings, therefore, you have to switch apps to get real-time info from your device.

Step 6:  On to IFTTT:  While this is, by far, the simplest in execution, if you got tripped up on the last step, it will be very frustrating.  Step 3 of the last guide shows you to connect IFTTT to MyQ, but MyQ pulled support for the close actions within IFTTT.  Furthermore, due to a strangeness that I ran into as described above, setting the trigger to MyQ resulted in my not finding a door to trigger!  Here's what I did (and tested successfully).  Keep in mind that my ONLY goal was to set up Google and Alexa to OPEN my gate by voice command and I wasn't interested in any other way to connect this string together.  Having said that, the method described below is probably faulty in some way I haven't discovered yet, but it works and I'm happy with the result.

I built two applets, one for Google, and one for Alexa, they are essentially identical except for the phrase needed to trigger the action.  This is not by design, but rather because Alexa requires an extra word in order to functionally work with IFTTT.  Before building these applets though, you have to edit the connection of IFTTT and SmartThings.  From IFTTT (web version) do:

     6.1  Click on your portrait, go to My Services>SmartThings
     6.2  In the upper right, there should be a Settings button (unless they change things, in which case, look around, it's going to be here somewhere as "Settings" or "Edit" or three dots, or a gear icon...you get the idea), click THAT, then "EDIT" in the Account Info section.
     6.3  You will be taken to the SmartThings/IFTTT integration window you saw before way back in Step 2. (I told you we'd be back later :-), but this time, when you choose your Home, you will see devices, and it's asking for permission to action those devices, so put a checkmark in the box next to the device you just tested at the end of Step 5 and click Authorize.

Great, we are almost done here.  The actual setup of the IFTTT applets is extremely straightforward, just go to your portrait, got to Create, and put Alexa/Google in the search bar (THIS side) with "Say a specific phrase" trigger.  Then put SmartThings in the search bar (THAT side) with a "Switch on" action choosing the gate/garage device you just authorized.

I gave the primary phrase the same content for both Google and Alexa, but Alexa has to go through something else on the backside and doesn't allow for multiple phrases nor a customized confirmation response.  Therefore, I have to say "Alexa trigger open front gate" and she tells me that she is contacting IFTTT, but for Google, I can say "Google, open front gate", "Google, Open sesame" or "Google, Let me in" and she comes back with "Ok, I'm opening your front gate"  I like the way Google does this a lot better because it's much more natural...poor Alexa, you lose this round.

Got those built?  Great, as long as IFTTT recognized your gate/garage as setup in SmartThings, and you don't swallow your own tongue talking to your favorite device, your gate/garage door is going to open when you give it the voice command.  Have some fun, I know I did showing it to my wife and father.

NOTE:  Although I'd love to report that the gate/garage will open immediately, alas, there IS a slight delay while those four cloud services talk to each other and then back down to your device.  Give it some time, be patient, it's no worse than the actual MyQ app in response time, so no worries.  Happy trails!

Sunday, November 18, 2018

Another new hobby
















Here are a few pictures from a new project I’ve been working on.  This is the base for a 90 square foot HO scale model train layout.  I’ve been thinking and doing research on this project for most of this year.  It’s refreshing to begin work on the base.  Most importantly, this project is with my father by my side.

Thursday, December 22, 2016

Playing with my Raspberry Pi

It's been a while, and a few updates:  I got a pair of Raspberry Pi 3's on my desk and a Foscam exterior dome camera hanging over my garage now.  One of the Pi's is acting as a server to store the images for me on a custom built attached storage array (I've been busy!).  This post is not about those four projects though....it's about a piece of scripting that I found myself writing today.  See, the camera just dumps the files into a very flat directory structure, resulting in thousands of images and video files per day.  As you can imagine, this can build up to tens or hundreds of thousands if I'm not proactively moving the files into a structured directory tree, which until today, has been a manual process.  I got tired of that, and knew I could write a bash script to do it for me.  It only took me four hours, and here is the result:

#!/bin/bash
### Script to move output files from a Foscam exterior camera into a structured directory tree instead of storing them all in only the two default folders
### Adapted from a script found on the web at http://unix.stackexchange.com/questions/261888/help-creating-script-to-move-files-based-on-date-or-filename
### Modifed with information from http://stackoverflow.com/questions/26881104/extract-date-from-a-file-name-in-unix-using-shell-scripting
### and with information from http://stackoverflow.com/questions/12230762/insert-characters-into-a-string-in-bash
### Written by:
### Christopher M Goodrich, CISSP, ISSEP, ISSMP
### phaldor@comcast.net

### Lets set some variables to the base directories.  These should be changed to the base directories that you are using for the Foscam recording location
### and the top level folder where you want to store the organized files
BASEDIR=[insert folder here]   ### Top level storage location (we are going to make directories under this with this script)
RECDIR=[insert folder here]   ### Location where your Foscam is saving the recorded content

cd ${RECDIR}/record       ### Start with the motion recording files

for file in alarm_*.mkv       ### we are going to loop for .mkv files produced by the motion alarm
do
 ### Foscam uses alarm motion recording file format of alarm_YYYYMMDD-HHMMSS.mkv so
 ### get the year, month, and day out of filename
 rawdate=$(echo ${file} | awk -F'[_-]' '{print $2}')  ### sets variable rawdate to just the 8 digit date from the filename
 date=$(echo ${rawdate} | sed 's/^\(.\{4\}\)\(.\{2\}\)/\1-\2-/') ### sets variable date to the format 'YYYY-MM-DD'
# date=${date}-       ### adds ending '-' (ending hyphen is important)
 year=$(echo ${date} | cut -d"-" -f1)    ### sets varialbe year to the first four digits in variable date
 month=$(echo ${date} | cut -d"-" -f2)    ### sets variable month to the next two digits in variable date
 day=$(echo ${date} | cut -d"-" -f3)    ### sets variable day to the last two digits in variable date

 PARENTDIR=${BASEDIR}/${year}-${month}
 MIDDIR=${PARENTDIR}/${day}     ### create the variable for the parent folder (year and month) and storage folder (day)
 STOREDIR=${MIDDIR}/Motion-record

 if [ -d ${PARENTDIR} ]      ### if the parent directory exists
 then
  if [ -d ${MIDDIR} ]     ### if the storage directory exists
  then
   if [ -d ${STOREDIR} ]    ### if the motion-record subfolder exists
   then
    mv ${file} ${STOREDIR}   ### move the file
   else      ### the sub-folder doesn't exist
    mkdir ${STOREDIR}   ### create it
    mv ${file} ${STOREDIR}   ### move the file
   fi      ### close the if statement
  else       ### the storeage directory doesn't exist
   mkdir -p ${STOREDIR}    ### create the storage directory and the sub-folder that the file will reside in
   mv ${file} ${STOREDIR}    ### then move the file
  fi       ### close the if statement
 else        ### the parent directory doesn't exist
  mkdir -p ${STOREDIR}     ### create the directory tree to store motion recorded media
  mv ${file} ${STOREDIR}     ### then move the file
 fi        ### close the if statement
done         ### close the for loop

for file in schedule_*.mkv      ### we are going to loop for .mkv files produced by the scheduled recording feature
do
 ### Foscam uses scheduled recording file format of schedule_YYYYMMDD-HHMMSS.mkv so
 ### get the year, month, and day out of the filename
 rawdate=$(echo ${file} | awk -F'[_-]' '{print $2}')  ### sets variable rawdate to just the 8 digit date from the filename
 date=$(echo ${rawdate} | sed 's/^\(.\{4\}\)\(.\{2\}\)/\1-\2-/') ### sets variable date to the format 'YYYY-MM-DD'
# date=${date}-       ### adds ending '-' (ending hyphen is important)
# rawdate=$(echo ${file} | grep -Eo '[[:digit:]]{8}')  ### sets variable rawdate to just the 8 digit date from the filename
# date=$(echo ${rawdate:0:4}-${rawdate:4:2}-${rawdate:6:2}-) ### sets variable date to the format 'YYYY-MM-DD-" (ending hyphen is important)
 year=$(echo ${date} | cut -d"-" -f1)    ### sets varialbe year to the first four digits in variable date
 month=$(echo ${date} | cut -d"-" -f2)    ### sets variable month to the next two digits in variable date
 day=$(echo ${date} | cut -d"-" -f3)    ### sets variable day to the last two digits in variable date

 PARENTDIR=${BASEDIR}/${year}-${month}
 MIDDIR=${PARENTDIR}/${day}     ### create the variable for the parent folder (year and month) and storage folder (day)
 STOREDIR=${MIDDIR}/Schedule-record     ### create the variables for the parent folder (year and month) and storage folder (day)

 if [ -d ${PARENTDIR} ]      ### if the parent directory exists
 then
  if [ -d ${MIDDIR} ]     ### if the storage directory exists
  then
   if [ -d ${STOREDIR} ]    ### if the schedule-record subfolder exists
   then
    mv ${file} ${STOREDIR}   ### move the file
   else      ### the sub-folder doesn't exist
    mkdir ${STOREDIR}   ### create it
    mv ${file} ${STOREDIR}   ### move the file
   fi      ### close the if statement
  else       ### the storeage directory doesn't exist
   mkdir -p ${STOREDIR}    ### create the storage directory and the sub-folder that the file will reside in
   mv ${file} ${STOREDIR}    ### then move the file
  fi       ### close the if statement
 else        ### the parent directory doesn't exist
  mkdir -p ${STOREDIR}     ### create the directory tree to store scheduled recorded media
  mv ${file} ${STOREDIR}     ### then move the file
 fi        ### close the if statement
done         ### close the for loop


cd ${RECDIR}/snap       ### switch directory of focus to the snap folder

for file in MDAlarm_*.jpg      ### we are goinig to loop for .jpg files produced by the snapshot feature during motion events
do
 ### Foscam uses a file format of MDAlarm_YYYYMMDD-HHMMSS.jpg for taking snapshots during a motion alarm event so
 ### get the year, month, and day out of the filename
 rawdate=$(echo ${file} | awk -F'[_-]' '{print $2}')  ### sets variable rawdate to just the 8 digit date from the filename
 date=$(echo ${rawdate} | sed 's/^\(.\{4\}\)\(.\{2\}\)/\1-\2-/') ### sets variable date to the format 'YYYY-MM-DD'
# date=${date}-       ### adds ending '-' (ending hyphen is important)
# rawdate=$(echo ${file} | grep -Eo '[[:digit:]]{8}')  ### sets variable rawdate to just the 8 digit date from the filename
# date=$(echo ${rawdate:0:4}-${rawdate:4:2}-${rawdate:6:2}-) ### sets variable date to the format 'YYYY-MM-DD-" (ending hyphen is important)
 year=$(echo ${date} | cut -d"-" -f1)    ### sets varialbe year to the first four digits in variable date
 month=$(echo ${date} | cut -d"-" -f2)    ### sets variable month to the next two digits in variable date
 day=$(echo ${date} | cut -d"-" -f3)    ### sets variable day to the last two digits in variable date

 PARENTDIR=${BASEDIR}/${year}-${month}
 MIDDIR=${PARENTDIR}/${day}     ### create the variable for the parent folder (year and month) and storage folder (day)
 STOREDIR=${MIDDIR}/Motion-snap     ### create the variable for the parent folder (year and month) and storage folder (day)

 if [ -d ${PARENTDIR} ]      ### if the parent directory exists
 then
  if [ -d ${MIDDIR} ]     ### if the storage directory exists
  then
   if [ -d ${STOREDIR} ]    ### if the motion-snap subfolder exists
   then
    mv ${file} ${STOREDIR}   ### move the file
   else      ### the sub-folder doesn't exist
    mkdir ${STOREDIR}   ### create it
    mv ${file} ${STOREDIR}   ### move the file
   fi      ### close the if statement
  else       ### the storeage directory doesn't exist
   mkdir -p ${STOREDIR}    ### create the storage directory and the sub-folder that the file will reside in
   mv ${file} ${STOREDIR}    ### then move the file
  fi       ### close the if statement
 else        ### the parent directory doesn't exist
  mkdir -p ${STOREDIR}     ### create the directory tree to store motion recorded media
  mv ${file} ${STOREDIR}     ### then move the file
 fi        ### close the if statement
done         ### close the for loop


for file in Schedule_*.jpg      ### we are goinig to loop for .jpg files produced by the scheduled snapshot feature
do
 ### Foscam uses a file format of Schedule_YYYYMMDD-HHMMSS.jpg for taking regularly scheduled snapshots so
 ### get the year, month, and day out of the filename
 rawdate=$(echo ${file} | awk -F'[_-]' '{print $2}')  ### sets variable rawdate to just the 8 digit date from the filename
 date=$(echo ${rawdate} | sed 's/^\(.\{4\}\)\(.\{2\}\)/\1-\2-/') ### sets variable date to the format 'YYYY-MM-DD'
# date=${date}-       ### adds ending '-' (ending hyphen is important)
# rawdate=$(echo ${file} | grep -Eo '[[:digit:]]{8}')  ### sets variable rawdate to just the 8 digit date from the filename
# date=$(echo ${rawdate:0:4}-${rawdate:4:2}-${rawdate:6:2}-) ### sets variable date to the format 'YYYY-MM-DD-" (ending hyphen is important)
 year=$(echo ${date} | cut -d"-" -f1)    ### sets varialbe year to the first four digits in variable date
 month=$(echo ${date} | cut -d"-" -f2)    ### sets variable month to the next two digits in variable date
 day=$(echo ${date} | cut -d"-" -f3)    ### sets variable day to the last two digits in variable date

 PARENTDIR=${BASEDIR}/${year}-${month}
 MIDDIR=${PARENTDIR}/${day}     ### create the variable for the parent folder (year and month) and storage folder (day)
 STOREDIR=${MIDDIR}/Schedule-snap     ### create the variable for the parent folder (year and month) and storage folder (day)

 if [ -d ${PARENTDIR} ]      ### if the parent directory exists
 then
  if [ -d ${MIDDIR} ]     ### if the storage directory exists
  then
   if [ -d ${STOREDIR} ]    ### if the schedule-snap subfolder exists
   then
    mv ${file} ${STOREDIR}   ### move the file
   else      ### the sub-folder doesn't exist
    mkdir ${STOREDIR}   ### create it
    mv ${file} ${STOREDIR}   ### move the file
   fi      ### close the if statement
  else       ### the storeage directory doesn't exist
   mkdir -p ${STOREDIR}    ### create the storage directory and the sub-folder that the file will reside in
   mv ${file} ${STOREDIR}    ### then move the file
  fi       ### close the if statement
 else        ### the parent directory doesn't exist
  mkdir -p ${STOREDIR}     ### create the directory tree to store motion recorded media
  mv ${file} ${STOREDIR}     ### then move the file
 fi        ### close the if statement
done         ### close the for loop


Pretty handy little script there, and it processed the 26k files I had lying in the directories with a fair amount of speed!  You will notice that I have some extra lines in there that are commented out.  I tried a couple different methods before I found one that worked, and I failed to remove the extra lines before posting this, I was just that excited!  #HappyDance

Thursday, July 21, 2016

Pokemon Go

Have you caught the fever yet?  Well, if you haven't, perhaps you are under the impression that this is just a fad, that it's childish, or maybe you just don't quite "get" the concept of Augmented Reality (AR) games.  While this post is just about my own experience and why I got into the game, not meant to make an argument for or against it, if this post does convince you to get involved, you have my respect and support.

As a middle-aged man with teenage children, I tried to ignore the original Pokemon movement, but it sure didn't go unnoticed at the time.  Pokemon was big....HUGE, back in the day.  Unless you lived in a cave and didn't talk to anyone for years, you recognized the name, the main Pokemon creature (Pikachu), and the ball icon at the very least.  So when it hit the app store just a couple of weeks ago, I thought to myself "here we go again."  Then the news brought to my attention the staggering numbers, so I checked out what in the world was going on.  This led me to articles about Augmented Reality, city planning, and a few other stories that were only ancillary to the game itself.  Being a bit round around the middle (so to speak), and given that I saw there was a huge benefit to contributing to the data generated by the game, I decided to give it a try.  Another motivator was the teenage children in my household either already playing, or wanting to play the game.  Because I try to monitor the younger one's use of gaming and the internet, it gave me another reason to check it out.

So I downloaded it.  Keep in mind that other than a slight familiarity with the fact that it existed in the past, I had no knowledge of what Pokemon was all about, so I found myself at a disadvantage from the start.  Because I'm an intellectual, I went and did a lot of research on the game mechanics and the general world of Pokemon.  After doing all this, and playing the initial few levels in the game, I brought my younger teenagers aboard, giving me another experience on the back side of the game through the website.  So, here are my thoughts:

The game is dead simple.  At it's heart, you have a classic scavenger hunt where you run around looking for hidden things.  In this case, it's the literal truth as the game is played on the stage of the entire planet.  Think of it this way, Google has been mapping the planet Earth now for quite some time, and in doing so, has created enough public data that a game can be modeled to use it accurately through the use of Global Positioning System (GPS) receivers.  Since most smart phones come with a GPS receiver as well as the ability to download an app, the concept of adding digital data tied to GPS coordinates is not only not new, it's now old hat.  We actually see this every day without thinking of it in navigation apps.  Waze actually was a game first before it became the popular navigator that it is today.  Those that used the original version may remember your car gobbling up candy on the road.  Pokemon Go is the exact same concept, except you don't automatically get the candy once your real life coordinates intersect with it.  Add to that basic concept a simple idea.  What if, once you get within range of the object that you are attempting to get through the coordinates, you could actually see it in the context of the real world?  Well, open up that camera to this app, and your wish is granted.  Welcome to Augmented Reality.  We now have a digital object that is tied to a real world location that you can see through the camera lens.  Not only that, but you can interact with the digital object AND the real world at the same time.

This is, of course, the entire purpose of the game, collecting these objects.  Pokemon Go accomplishes this by setting up a ball throwing game overlaid on the AR experience.  If you throw straight, and take your time, you are more likely to hit your target and capture the Pokemon you are seeing.  I can vouch for what this looks like to an outsider, not much different than what everyone else not playing the game is doing already, keeping their head into their phones, and then raising it to take a picture.  Kudos to the game makers for this, other than the walking around aimlessly, these "trainers" as they are called, look like a normal person out in the world.  It could have been worse, making the game require an unusual movement which would look completely out of place or inappropriate.  Here is where anonymity in reality depart company though.  Whether you catch the Pokemon or not, something compels you to exclaim with joy or despair (as the case may be), making the players of this game extremely easy to spot.  Fortunately for them, they usually have company when they are caught in this situation.  I've experienced this first hand and in realizing that I've probably embarrassed myself, looked around and been met with sympathetic eyes rather than not.  By far the most beneficial aspect here is you are getting exercise that you may not normally be getting.

Ok, great, so collecting Pokemon is the intent here, but to do so comes with the true benefit of the game.  In order to do this, you have to walk....a lot.  The whole game revolves around this simple fact.  There are location based interactive objects other than Pokemon in the game, in the form of rest stops (Pokestops) and community centers (Gyms).  These offer game enhancing items or a place to put your collected Pokemon against other trainer's Pokemon in battle.  The former are static locations where in the real world, you will find other players standing around.  This facilitates interaction with those people, solving another real world problem, that of the increased isolation of the individual.  Because you have a common interest, there is something to talk about, facilitating a social aspect.  While some may say this can bring about a negative encounter, it's far more likely to be a positive one.  One other aspect to these locations is they base themselves on real world points of interest.  Maybe it's a sign, a mural, or a museum piece, but the point is that it exists in the real world.  Why this is important is lost on most people, but not to city planners.  Using the data points generated from this game, they can now plan activities, track visits, and promote locations.

My last point is that I am getting to interact with my children as well.  Sure, not all parents will want to run around their neighborhood playing a game while dealing with kids, but it's nice to relate and build on the relationship with your kids while seeing a few things you may not know about your area and meeting others from your local area.  If this simply isn't for you, you can purchase in game items and not have to walk around to catch the Pokemon, but that will get expensive after a while.  Worried about your data plan?  T-Mobile is now offering an incentive to not count the data from playing the game against your limits.

That about does it for this post, so to all those out there playing, happy hunting!

Wednesday, April 13, 2016

The quest for a better workspace

     Anyone who works from home may relate to this story.  I began working from home last year, and I wasn't really prepared to do so from a workspace perspective.  I started with a writing desk that my wife had rescued some time ago and slowly added surfaces to handle the monitors and personal laptop that I really did need.  The problem with this setup was that the writing desk was never meant to handle computers, especially more than one laptop, so it was very cramped and I couldn't use the CD/DVD drive without moving the laptop towards the front.  Below is a picture of the setup after I moved into a spare bedroom (not the original setup in the master bedroom, which was even more cramped than what this picture displays.

     Moving into the spare bedroom did afford me more surface area, but didn't relieve the basic problem of a surface that I could actually lay out documents or do any other work on, and I still couldn't open the drive bays on the work or the personal laptop.  Perhaps this may need a bit of explanation;  although many people get by with setups like the one I show above, I am very comfortable with a normal office environment, work in the Information Technology field, and for the last 15 years have had at least two monitors for every computer on my desk.  Needless to say, I almost feel physical pain when I don't have that second monitor, thus you see two laptops and two monitors on the setup above.  The size of the second monitor doesn't bug me too much (those are 9 year old Dell 17" ones in the picture) and actually find the larger monitors more of a problem than a benefit.

     Well, it happened one day that I was browsing online and got the thought to look at prices for desk mounted monitor stands.  Don't ask why, because I couldn't tell you what exactly I was thinking at the time since a desk mounted stand wouldn't possibly work with the setup I had, but sometimes I just get a thought into my head and I have to go with it.  As it happens, I found a very reasonably priced hex monitor stand (under $100 is reasonable given it could handle six 24" monitors at once).  True to my nature, I whipped out the card and two minutes later, the stand was bought.  Great, now what?  As I stated before, the desk setup I had wasn't built to secure a desk mounted stand off the back.  It didn't take me very long to come up with the beginnings of an idea though.  The two cabinet units on either side of the writing desk were of the same manufacturer, solidly built, and had the capability to put a surface on top to accommodate the monitor stand.  Next out of the drawer came the tape measure and I found that if I didn't want to sacrifice any leg room between them, the surface would have to be over 7 and a half feet wide.  Try to find a desk that large, I dare you.

     People that don't know me should be informed that once an idea gets into my head, I bull forward solving the problems until I have a complete solution.  Everything else gets set aside, and even if I'm doing something else, my own family catches me with a particular facial expression; head cocked to one side, staring at the ceiling muttering to myself.  Fortunately, I've been around long enough that I've picked up some experience here and there, but it is still a process.  I think I spent the next day going to the salvage yards and consignment markets looking for a suitable surface.  I did find a conference table without legs that may have done the job, but it was too heavy for me to move by myself, was far deeper than I wanted, was oval, and was priced far too high for my thinking.  Craigslist didn't yield any better results, and a quick search online didn't leave me with much hope that I'd find a desk or any reasonable facsimile thereof that fit what was in my mind.

     From the start of the search, I had it in my mind that this may be the case, and I moved to plan B; yup, you guessed it, I'm a guy, that means the local hardware store.  What I wanted was a surface somewhere in the dimensions of 8'x3' that could support the monitor stand off the back edge, which meant at least 3/4" plywood.  Keep in mind, I hadn't stepped foot into the hardware store yet, all of the above was done within the confines of my own skull so far, and I wasn't done, but I wanted to see if they had a piece of wood that may fit.  For anyone familiar with plywood, this could be a tall order, it couldn't be construction grade, it had to be finished and hardwood, meant to be exposed, not rough framing lumber.  As it happens, the local Home Depot had a very nice piece of birchwood with a surface so smooth I couldn't find an imperfection.  What's more, I liked how it looked (I love woodgrain).

     Did I mention that I fancy myself somewhat of an engineer?  Well, I am analytical and have a passing knowledge about weight tolerances, which means I usually OVER-engineer any build (ask my wife about the porch I built for the doublewide when we first got married with the 3/4" carriage bolts through 8"x8" posts).  I wasn't sure 3/4" plywood would be enough, so decided to double the thickness of the desk, which meant two sheets of 4"x8" glued together.  Now I had an idea of the desktop, but I wasn't done yet.  Two pieces in those dimensions meant that I'd be cutting the plywood lengthwise and have a 1'x8' strip left over from each piece.  I'd already be buying the whole sheet, so what was I going to do with the extra wood?  This epiphany wasn't a stretch, I could built shelves on either side of the desk.  After about an hour wandering around the store, I had a very good idea of what I was going to be building, with what materials, and a few extra enhancements to boot.  I walked out empty handed.

     "Wait, empty handed?" you say?  Yup, not only do I have to approve the budget with the wife, but I wanted to be absolutely sure of the design I had in mind, which meant modeling it on a CAD program.  I went home and found a free program that I'd used in the past, but found it didn't have a feature to draw exact measurements (or at least adjust the objects after I had approximated them with the mouse).  The second free program I tried did have what I wanted, and I proceeded to look up the specs on the monitor stand and draw my concept.  Below is the final result.

     This took me about two days to get it to a level of sophistication I was happy with.  I didn't bother drawing the bottom tier of the monitor stand to show the laptop trays I had ordered as they weren't critical for the measurements I was after.  All I wanted out of this drawing was the confirmation that I had enough room between the shelves I had thought of for the monitor stand and mounted equipment.  It looked good, and that Saturday, I pulled the trigger on the purchase.



     As soon as I could, I setup a mock build to ensure I had the store employee cut the wood the right way (the guy that cut the dowels didn't impress me with his measuring skills).

     I didn't waste any time getting to work, I had checked the weather and knew I had about a week before any rain was due, and I had to space the project out to let glue dry as well as allow for the stain/polyurethane finish to set.  I started in on the most detailed piece, the top surface of the desktop, where I had to drill 16 holes for the shelf supports and cut an opening for the sunken power receptacle I was going to put in-between the sheets.  I've spent enough time under desks to know that if I brought power to the surface, and then put the strips on the desktop, life is SO much easier.  Besides, I knew I had plenty of room to play with, so the 6"x6" hole wasn't too large of a sacrifice of desktop space.  Yes, now I had an electrical wiring job as well as a carpentry project on my hands.

     It took an evening and part of the next day to get the holes in the two sheets because I ran out of power on the cordless drill and had to charge the battery, then I took a step back and looked at that sunken receptacle again.  It was meant to go into a wall and had a 1/4" lip on it.  My worry was it would create too much of a gap in-between the plywood and cause the two sheets to not bond properly.  So I dug the Dremel out of the shed and routed the surface of the bottom sheet to sink it enough to allow the two sheets to be perfectly flush.  I managed to save one of the cutouts for a lid to hide the hole on the top surface as well and spent some time with the Dremel getting that piece and the edges of the top hole as smooth as I could so the cords wouldn't catch or fray on sharp edges.

     The next day I glued the two sheets together and added the decorative edge that I picked out (thanks to my Dad for the mitre box!).



     The picture directly above showed my learning curve on drilling holes through hardwood.  A word to the wise, don't drill through all the way from one side to the other, the final surface will chip as shown above.  Instead, drill until the spade bit tip breaks through, then turn the piece over and drill from the other side to finish the hole.  There may still be some chipping, but not nearly as bad as that first hole looks like.  The idea on these holes is the shelf supports, which are 1" diameter dowel cut 12" long and held in place through only one of the two 3/4" plywood sheets.  If necessary, a little glue would make them virtually one piece of wood, but I didn't think that was going to be necessary and I wanted the option to disassemble the desk if I ever had to move it.

     A couple of days into the next work week, the monitor stand arrived, and I was surprised to actually see the size of the thing.  The specs online weren't all inclusive, and I had guessed on certain dimensions.  As it turned out, I had fallen short on a couple of them, so back to the CAD program I went to make sure it was still going to work.  About an hour later, I breathed a sigh of relief, it was still good.  I would have to articulate the arms a bit more, but now I had the right measurements and the monitor stand was truly impressive.
     It was time to paint it with the combo stain/polyurethane I had purchased and let it sit for a few days.  This was the step I didn't have a whole lot of faith in my ability to get it just right.  That, combined with my impatience, led to only a single thick coat on the surface, but it actually looked pretty decent and the brush marks gave the impression of woodgrain, so I lost the actual look of the wood under the stain in favor of a Southwest style finish job.  After a few days, I decided I didn't have a problem with it and grew to like it.

     Originally, I had planned on using the two cabinets for supports, but they weren't going to do the entire job.  I needed to support the back half of the desk, so went out to find a couple of simple bookshelves to use in the back.  I didn't care about color or function, as long as they were 29 1/2" tall (the same height as the two I had already).  Walmart this time, no reason to build some from scratch.  I bought two, but one had an open end, and was missing the hardware kit.  I called the customer support line and they promised to send me the kit out.  I built the one I could and found it was actually a tiny bit taller than the units I had.

     That Friday the forecast called for rain, so I had to bring the finished desktop and all the raw materials inside.  I had wanted to finish the shelves, but settled for setting up the desk and waiting for the weather to clear.  Since I still had not recieved the hardware kit for the second shelf, I used a tripod, which worked out in my favor since the desktop turned out to have a very slight curve and was bowed up in the middle.  When I got it upstairs, I also found that the second shelving unit wasn't necessary, this thing was solid enough for my 200 lbs weight to climb on top and assemble the monitor stand.

     So I've worked at the desk for almost a week now and a break in the weather has allowed me to at least assemble the shelves, but not to apply the stain yet.  Here is the desk as it sits today:

Thursday, July 2, 2015

Freedom of Speech vs. Freedom of Action

Over the last few weeks, my country, the USA, has seen a number of issues rise to the surface of public view and opinion.  While this blog will attepmt to stay neutral on the individual issues, it will not be silent when comparing a vital element found in the mainstream media.  This element is easy to see once it's pointed out, but it's obviously been overlooked by the general public.  I'm talking about a basic misinterpretation of the first amendment.  Yes, I'm talking about freedom of speech and it's key difference with freedom of action.

You see, there is a difference, one that is painfully obvious, yet seems to be largely ignored by certain individuals who try to hide behind the first.  Let's start by stating the intent behind this amendment and follow the trail from there.  When the founders of this country proposed the amendments, one thing was painfully clear to them at the time, that of freedoms, given that they had been under the oppressive thumb of the British crown and were in the midst of a revolt.  I propose that their thoughts were to create a country without the possibility of an oppressive government and, at the same stroke, justify their revolutionary actions to the rest of the world.

After the revolution however, they realized that some of the actions they themselves took could not be condoned outside of the specific situation they found themselves in, and the drafting of the original documents that founded the nation reflect very careful thought along these lines.  Here are two specific examples: 

     1. They gave the right to bear arms, but not to use them against others
     2. They gave us the freedom of speech, but not action

These examples highlight a common element, that of a freedom of expression, but not the execution of the thought.  This is a huge difference when considering the recent events in the media.  We have a right to express ourselves, in other words, a peaceable demonstration.  We do not have the right to rioting and violence.  We have the right to express our thoughts publically and openly, but we do not have the right to act on those thoughts, especially if there is a law against it.  Notice that given the absence of a law, we are still not automatically granted a "right" to act.  In these cases, we are left to our own moral judgement and have a choice to act, not the right.  If we chose to act, there may well be consequences as a result of our actions.