Friday, March 13, 2015

HOWTO Batch Language Date and Time

Overview

Batch language is super basic but there is one trick BATCH supports for getting the date and time. Looking through many different blogs I was able to assemble this HOWTO.

I use this syntax for a little script that I wrote that to backup/archive various coding directories I have on my workstation. I use Windows Backups but I find I trust a simple BAT file that creates date/time stamped 7z files. I wish Windows had a “time machine” like facility but use what you have vs fuss.
To create a proper date/time stamp you can use the following technique.

Syntax/Technique

If you include something like this in your Windows BAT file, you will get a date and time that can be applied to a filename or similar.
set hr=%time:~0,2%
if "%hr:~0,1%" equ " " set hr=0%hr:~1,1%
set FNAME=ARC_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%hr%%time:~3,2%%time:~6,2%.zip
echo %FNAME%
… you will get a result like this
C:\Users\k.langer>echo %FNAME%
ARC_20150209_115340.zip

Conclusion

You can use this trick when automating backups or similar.
[For More Information http://stackoverflow.com/questions/7727114/batch-command-date-and-time-in-file-name]

HOWTO Setup a PiGlow with PyGlow on a Raspberry Pi B Plus

Overview

There are many articles and blogs out there that show how to use a PiGlow LED GPIO board with a Raspberry Pi but most do not cover everything. Some only describe how to set it up with hardware before the B+ and others get you going but fail on permissions.
My hope is to show all the steps needed to let you run Python code with a PiGlow and the PyGlow.py module.

Security

I am not a security genius, nor do I view this project as security driven. You will need to decide what changes below are reasonable for you. For me, I want the PiGlow to work and be easy to work with. This is the process I used to get there.

What you need

  1. Raspberry Pi B+
  2. Rasparian Wheezy
  3. PiGlow module

kernel setup

For this to work, there will need to be some kernel level changes. This simply tells the kernel to load some required modules.

/boot/config.txt

In order for the i2c module to work, it needs to be enabled. Add or uncomment the following to your config.txt file.
dtparam=i2c1=on

/etc/modules

Ensure that the following two lines are in your modules file.
i2c-dev
i2c-bcm2708

/etc/modprobe.d/raspi-blacklist.conf

Ensure that the following modules are not blacklisted by ensuring these lines are commented out.

# blacklist spi-bcm2708
# blacklist i2c-bcm2708

Reboot

At this point, the kernel will have what it needs to allow you to work with your PiGlow. To activate the new configuration, you need to restart your Raspberry Pi.

Setting up PyGlow Python Module

With the kernel prepped and ready, the next phase is to install the python library needed to interact with your PiGlow. For a Raspberry Pi, I suggest creating a library location where this and other common libraries can be stored for shared use across users and applications. On my RPi, I have them in /opt/lib/python If this path does not exist, create it or something like it. Ensure you can get to it using a normal users and chmod as needed.

Setup a Library area in /etc/bash.bashrc

To ensure all users on the platform see this new library location, it will need to be added to the PYTHONPATH. That can be done either in each users .bashrc file or globally in the /etc/bash.bashrc. Just add the following line.
export PYTHONPATH=/opt/lib/python
For the full approach to work, it will need to be added globally. Within a user’s .bashrc, they can append to this path with other personal lib or module path.

Install PyGlow Module from GIT

To get the lastest PyGlow.py module, run the following commands.
cd /opt/lib/python/
git clone https://github.com/benleb/PyGlow.git

Git should already be installed on your RPi. If not or you don’t like git. You can find a ZIP of the same thing using a few Google searches.
Once completed you should have a PyGlow sub directory within /opt/lib/python/. If you read other documentation, you will be told that you can simply run (or at least attempt to run)
cd PyGlow/examples/
sudo python test.py

But when you do, you get an error that PyGlow cannot be found. This is beause by default, PYTHONPATH is not seen by sudo. This takes us to our last phase of setting this up.

sudo Setup for Python Users

Add PYTHONPATH to /etc/sudoers

To tell sudo that you want to keep PYTHONPATH as an environment variable. Simply edit /etc/sudoers and add (or uncomment) the following line.
Defaults    env_keep += "PYTHONPATH"
Now anything in the global Python path will be available to sudo. I would assume you can have multiple lines for each ENV you want to keep.

PyGlow Error for RPi B+

So, all excited, you re-run the test script

cd $PYTHONPATH
cd PyGlow/examples/
sudo python test.py

Now a new error appears complaining about a revision issue or something like that.

The fix for the PyGlow.py Error


The code for the PyGlow (at the time this was written) was not updated for the B+ (Revision #3) GRUMBLE, but the fix is easy. Edit /opt/lib/python/PyGlow/PyGlow.py and search for the following code….

 # Check what Raspberry Pi version we got
 if rpi.RPI_REVISION == 1:
     i2c_bus = 0
 elif rpi.RPI_REVISION == 2:
     i2c_bus = 1
 else:
     raise PyGlowException(
         self, "Unknown Raspberry Pi hardware revision: %s" %
         (rpi.RPI_REVISION))
 
 
 After the above elif, add the following elif that.  It should be before the else 
 
  elif rpi.RPI_REVISION >= 3:
     i2c_bus = 1


It basically says that any revision after and including 3 should use the #1 bus for ic2. Or at least I suppose.

Testing

Now you re-run, more causiously, the following command.

cd $PYTHONPATH
cd PyGlow/examples/
sudo python test.py

Based on my experience, you should have success. In fact all the example scripts should now work.

Next Steps

There are a lot of groups in linux and it is possible that vs using sudo to run your code you can simply add your user to a group that allows i2c and other modules to work. I’ll have to research that next to see if I can give a user permissions.

This was not much of a goal for me since this device is experimental so sudo is not a worry for me to run. For eample, I like to run the sudo python cpu.py to let the lights show me how much CPU I am using. python-psutil and psutils are needed for that to work so sudo apt-get install python-psutil psutils before running that comand.

Conclusions

With a few steps you now have a working PiGlow with support for PyGlow.py. This same approach should work for other GPIO type components.

Thursday, February 5, 2015

HOWTO Create an SVN Branch from a Tag

Overview

Bugs happen and sometimes you need to create a patch. Best way to do this using SVN is to take an existing tagged version of your code (which you hopefully do before each build) and create a branch off of it.

Approach

For this to happen you need to know which tag to use and what you want to call the branch. In the example below, I am using 20141205_Version_R8–1–0–07 as my tag. Within this location is an SVN copy of what was in trunk at the time the tag was created.

Look at the contents of the tag

To see the contents of the tag, use the following command
> svn list http://svn.homeworld.lan/repos/python/tags/20141205_Version_R8-1-0-07/
You will get a listing similar to what you would see in trunk.

Create the Branch

To create the branch all you will do is tell SVN to copy the contents from the tag into a new (non-existing) target folder. In this case the folder within branches is called 20150205_R8–1–1_Patch. Remember that this folder will be created and filled by SVN automatically so the name of the target folder is all you need to provide.
> svn copy http://svn.homeworld.lan/repos/python/tags/20141205_Version_R8-1-0-07/ \
    http://svn.homeworld.lan/repos/python/branches/20150205_R8-1-1_Patch \
    -m "Creating a branch off of tag 20141205_Version_R8-1-0-07"

Committed revision 630.
Once completed you will see a revision number (630 in this case)

Look at the contents of the new branch

To confirm that the branch worked as you would expect, you can get a listing like you did for the tag.
> svn list http://svn.homeworld.lan/repos/python/branches/20150205_R8-1-1_Patch

Getting to Work

Now that this is done you can checkout the code from the branch into a working directory and get to work solving the worlds problems (certainly not your own).
> mkdir 20150205_R8-1-1_Patch
> cd 20150205_R8-1-1_Patch
> svn checkout http://svn.homeworld.lan/repos/python/branches/20150205_R8-1-1_Patch ./

Conclusion

Using a few commands you can easily create a branch from a tag. If you do not happen to have a tag available, you can branch off a specific revision of your trunk using the revision command line option. But hopefully you will create tags as you go for each build you create or for each release pushed to SQA or any testing group.

HOWTO Create lockfile logic using BATCH language

Overview

The goal of this HOWTO is to show how to manage a lock file in batch language. This is handy for scheduled processes.

Example

@echo off
REM
REM Example of howto use a lockfile in BATCH language
REM

:INIT
CD \BatchJobs
ECHO Current Working Directory
CD

:START
IF EXIST NIGHTLYRUN.LOCK GOTO SKIP_WORK
ECHO Turning on Lock
ECHO ""LOCK"" > NIGHTLYRUN.LOCK
REM Do work here. this is where your program or process goes. 
ECHO Turning off Lock
DEL NIGHTLYRUN.LOCK

GOTO DONE

:SKIP_WORK
ECHO ""This process is already running..""

:DONE

Conclusion

Using this approach you can prevent multiple instances of something running. A possible enhancement is something that can sense a stale lock if there is a crash or something. however this should help for most situations.

HOWTO Python Setup UNICODE Logging

Overview

Python does a very good job handling UNICODE for most modules, however, logging is not one of then. To get around this is easy but a special technique is required.

Common Approach

Normally with logging you pass a file to the logger and then write to it as you need though the logger interface. This approach is fast but does not allow the setting of the file encoding.
import logging
logging.basicConfig(
    level=logging.DEBUG,
    filename=filename,
    filemode="w")

formatter = logging.Formatter('%(asctime)-15s: %(levelname)-7s - %(message)s')
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)

log = logging.getLogger("MAIN")
log.addHandler(ch)
_logger = log

Improved Approach

To get around this and to ensure you control the formatting, a file stream will need to be created first and then that stream can be passed to logger.
import logging
import logging.handlers
log_fh = open("/logs/my_unicode.log", "w", encoding="utf-8")
logging.basicConfig(
    level=logging.DEBUG,
    format=config.FORMAT)

formatter = logging.Formatter('%(asctime)-15s: %(levelname)-7s - %(message)s')
ch = logging.StreamHandler(log_fh)
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)

log = logging.getLogger("MAIN")
log.addHandler(ch)
The log_fh holds the handle to the UTF–8 stream which is passed to the logger StreamHandler. Once set, text will be properly encoded as it is passed to the logger.

Conclusion

Using a slightly altered technique it should be possible to write anything to a python log using the build in logger module. There is no reason to use this technique for all logging even if you do not think UNICODE will be used.