Tuesday 1 November 2011

The electron has moved to "Flightgear"

Ok so its been a while and I thought I would post my current work on Flight Gear flight simulator.

I have been madly trying to get some better scenery generated around my home area of Newcastle,Australia. So currently I am using topo shape files from Geoscience Australia to produce maps along with OpenStreetMap Australia

This has proven to be very difficult as the scenery generation tools are failing around YSSY. So my next plan is to build using the road data from the shape files. This will unfortunately drop my wonderful dual highway system :(

So if you would like a copy of the Flightgear scenery then try here Aus-SE_Scenery.tar.bz2

Sunday 3 July 2011

Command Line Programming The Arduino

So more on the Buildbot and command line compiles of the arduino.

After using some code and instructions found here I found that I could compile code (only if the library had been compiled first) however I was unable to upload it to my board.

After lots of looking around for a solution I work out that if I write a wrapper for the arduino's avrdude I could get the correct param's for the upload.

Turns out that the Make file was set for 19200 but the chip wants 57600.

So now to test out the latest version of the Arduino.mk file to see if it builds the library correctly.

UPDATE: once setup Arduino-mk-0.5 works apart from upload which needs the baud rate changed to 57600 for the ATMega328

Buildbot on Arduino

Well after much trialling I can now report that I can continuously compile my arduino code with buildbot.

The plan is now to use eclipse as programming tool and compile projects by simply committing back to SVN.

Still have to get the auto program side working, but I am not far off

Sunday 19 June 2011

Oh wonderful buildbot

I have several SVN projects here at home and a few that I follow out on
the big wide web. My problem is tracking updates and then building them.
The solution, buildbot.
Now I can have it do the grunt work of polling update and building. I
then watch all this in one single web site. If there is a problem then
it lets me know.
The biggest problem was how to watch serveral repos and only rebuild the
changed one.

All solved :)
so here is my master.cfg


# -*- python -*-
# ex: set syntax=python:
# This is a sample buildmaster config file. It must be installed as
# 'master.cfg' in your buildmaster's base directory.
# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}
#k = BuildmasterConfig = {}
####### BUILDSLAVES
# The 'slaves' list defines the set of recognized buildslaves. Each element is
# a BuildSlave object, specifying a username and password.  The same username and
# password must be configured on the slave.
from buildbot.buildslave import BuildSlave
c['slaves'] = [BuildSlave("example-slave", "password"),
BuildSlave("embedded-slave", "password")
]
#k['slaves'] = [BuildSlave("example-slave", "pass")]
# 'slavePortnum' defines the TCP port to listen on for connections from slaves.
# This must match the value configured into the buildslaves (with their
# --master option)
c['slavePortnum'] = 9989
#k['slavePortnum'] = 9989
c['debugPassword'] = "pass"
####### CHANGESOURCES
# the 'change_source' setting tells the buildmaster how it should find out
# about source code changes.  Here we point to the buildbot clone of pyflakes.
from buildbot.changes.gitpoller import GitPoller
c['change_source'] = GitPoller(
  'git://github.com/buildbot/pyflakes.git',
branch='master', pollinterval=1200)
from buildbot.changes.svnpoller import SVNPoller
c['change_source'] = SVNPoller(
"svn://localhost/data/svn/CRC_check/CRC_check/trunk/"
, pollinterval=60)
c['change_source'] = SVNPoller(
"svn://localhost/data/svn/hermes-kernel/linux-2.6.39.1/"
, pollinterval=60)
c['change_source'] = [SVNPoller(
"svn://localhost/data/svn/CRC_check/CRC_check/trunk/"
, cachepath="/tmp/crc"
, pollinterval=60
),
SVNPoller(
"svn://localhost/data/svn/hermes-kernel/linux-2.6.39.1/"
, cachepath="/tmp/linux"
, pollinterval=60),
SVNPoller(
"http://domuslink.googlecode.com/svn/trunk/"
, cachepath="/tmp/domus"
, pollinterval=60),
GitPoller(
'git://heyu.org/heyu.git'
, pollinterval=60)
]
####### Filters
from buildbot.changes.filter import ChangeFilter
####### SCHEDULERS
# Configure the Schedulers, which decide how to react to incoming
changes.  In this
# case, just kick off a 'runtests' build
from buildbot.schedulers.filter import ChangeFilter
from buildbot.scheduler import Scheduler
c['schedulers'] = []
c['schedulers'].append(Scheduler(name="crc",
change_filter=ChangeFilter(repository="svn://localhost/data/svn/CRC_check/CRC_check/trunk"),
treeStableTimer=None,
builderNames=["runtests"]))
#c['schedulers'] = []
c['schedulers'].append(Scheduler(name="linux",
change_filter=ChangeFilter(repository="svn://localhost/data/svn/hermes-kernel/linux-2.6.39.1"),
treeStableTimer=None,
builderNames=["linux-2.6.39.1"]))
c['schedulers'].append(Scheduler(name="Domus.Link",
change_filter=ChangeFilter(repository="http://domuslink.googlecode.com/svn/trunk"),
treeStableTimer=None,
builderNames=["Domus.Link"]))
c['schedulers'].append(Scheduler(name="heyu", 
change_filter=ChangeFilter(repository="git://heyu.org/heyu.git"),
treeStableTimer=None,
builderNames=["heyu"]))
####### BUILDERS
# The 'builders' list defines the Builders, which tell Buildbot how to
perform a build:
# what steps, and which slaves can execute them.  Note that any
particular build will
# only take place on one slave.
from buildbot.process.factory import BuildFactory
from buildbot.steps.source import Git
from buildbot.steps.source import SVN
from buildbot.steps.shell import ShellCommand
factory = BuildFactory()
# check out the source
factory.addStep(SVN('svn://localhost/data/svn/CRC_check/CRC_check/trunk/', mode='copy'))
factory.addStep(ShellCommand(command=["cc","procrc.c","-o","procrc"],workdir="build/",usePTY=True))
factory.addStep(ShellCommand(command=["cc","crc.c","crcmodel.c","-o","crc"],workdir="build/",usePTY=True))
f = BuildFactory()
f.addStep(SVN('svn://localhost/data/svn/hermes-kernel/linux-2.6.39.1/',
mode='update'))
f.addStep(ShellCommand(command=["make","defconfig"]))
f.addStep(ShellCommand(command=["make"]))
Domus = BuildFactory()
Domus.addStep(SVN('http://domuslink.googlecode.com/svn/trunk/',
mode='copy'))
heyu = BuildFactory()
heyu.addStep(Git(repourl='git://heyu.org/heyu.git', mode='update'))
heyu.addStep(ShellCommand(command=["./Configure"],workdir="build/",usePTY=True))
heyu.addStep(ShellCommand(command=["make"],workdir="build/",usePTY=True))
heyu.addStep(ShellCommand(command=["/usr/local/bin/heyu","stop"],workdir="build/",usePTY=True))
heyu.addStep(ShellCommand(command=["make","install"],workdir="build/",usePTY=True))
heyu.addStep(ShellCommand(command=["/usr/local/bin/heyu","start"],workdir="build/",usePTY=True))

from buildbot.config import BuilderConfig
c['builders'] = []
c['builders'].append(
BuilderConfig(name="runtests",
slavenames=["example-slave"],
factory=factory))
#k['builders'] = []
c['builders'].append(
BuilderConfig(name="linux-2.6.39.1",
slavenames=["example-slave"],
factory=f))
c['builders'].append(
BuilderConfig(name="Domus.Link",
slavenames=["embedded-slave"],
factory=Domus))

c['builders'].append(
BuilderConfig(name="heyu",
slavenames=["embedded-slave"],
factory=heyu))
####### STATUS TARGETS
# 'status' is a list of Status Targets. The results of each build will be
# pushed to these targets. buildbot/status/*.py has a variety to choose from,
# including web pages, email senders, and IRC bots.
c['status'] = []
from buildbot.status import html
from buildbot.status.web import auth, authz
authz_cfg=authz.Authz(
# change any of these to True to enable; see the manual for more
# options
gracefulShutdown = False,
forceBuild = True, # use this to test your slave once it is set up
forceAllBuilds = False,
pingBuilder = False,
stopBuild = False,
stopAllBuilds = False,
cancelPendingBuild = False,
)
c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
####### PROJECT IDENTITY
# the 'projectName' string will be used to describe the project that
this
# buildbot is working on. For example, it is used as the title of the
# waterfall HTML page. The 'projectURL' string will be used to provide a
link
# from buildbot HTML pages to your project's home page.
c['projectName'] = "one man and a fe electrons"
c['projectURL'] = "http://"
# the 'buildbotURL' string should point to the location where the
buildbot's
# internal web server (usually the html.WebStatus page) is visible. This
# typically uses the port number set in the Waterfall 'status' entry,
but
# with an externally-visible host name which the buildbot cannot figure
out
# without some help.
c['buildbotURL'] = "http://localhost:8010/"
####### DB URL
# This specifies what database buildbot uses to store change and
scheduler
# state.  You can leave this at its default for all but the largest
# installations.
c['db_url'] = "sqlite:///state.sqlite"

Saturday 26 March 2011

Using Twitter To Stop Hackers

So I think its time to more along with my hacker scripts.
The plan now is to watch the #Breakinlog  feed on twitter and add the IP addresses to the computers deny hosts file (sorry but this is only for Linux)

The plan should be simple, by using my previous script with out ending a message it will pull done the last 10 tweets.
I then just need to process the output and write it back to a file.

Let see what happens over the few days as I go forward

Sunday 27 February 2011

Arduino two way comunication over DC

So the reason that I have gotten an Arduino is so that I can build a sensor/control network primarily targeted at sprinkler systems.
The idea is that I can have the following

PSC05 <=> arduino controller <=> station 1 <=> station 2 <=> ......

At the moment I have the PSC05 and controller work, now onto the fun bit.

My thoughts are to use the zero crossing signal as a master clock for all comms and to transpose the tx/rx signal onto the same line. Then use LC coupling onto the DC supply.
I am hoping that this will allow for easy reuse of the X10 Lib that the controller is using.

Monday 21 February 2011

I hate scammers

So tonight I received a phone call from some who said that my computer was producing spam. They promised that they were not a scammer and ask me to do stuff.
So here's a transcript of the call

Caller: your computer is producing spam and we would like you to help you fix it
Me: huh, ok
Caller: can you go to your computer and turn it on
Me: ok it is
Caller: let me know when you can see the icons
Me: ok i can see them
Called: ok, if you look at your keyboard the bottom left should be CTRL
Me: no, its got CONTROL on it
Caller: ok,next to that should be a windows logo
Me: no its got ALT/OPTION
Caller:[puzzled voice] ok, lets try the desktop. there should be a windows logo on the bottem left
Me: No just a blue box with a K
Caller: ok click on that and it should say windows
Me: no just KDE DESKTOP
Call: [more puzzled noises]
Me: So you just want me to install your key logger then?
Caller: it should say windows
Me: So you just want me to install your key logger then?
Caller: uh, no we dont installer key loggers
Me: I am in IT know the scam
Caller:uh [ beep,beep,beep]

I always love that noise, the beeping of the phone line as they realise that I know what I am on about and the scam isnt going to work.

I thought that the give aways would have worked
1. it's not a windows keyboard but one from a Mac
2. no start button, but one for KDE
3. KDE DESKTOP

Bet I will get another call tomorrow :)

The Twitter feeds

So here is the archive of the twitter feed scripts i spoke of earlier.
http://dl.dropbox.com/u/3028956/twitter-log.tgz

Sunday 20 February 2011

Sharing files

I think I have it now. Sharing files is easy with Dropbox.


Just upload files to my public area and past the link :)

So here is the x10 code for arduino
http://dl.dropbox.com/u/3028956/x10-lib_0.3.tgz

Computer Backups

Got to say that I am impressed with the ease of setup with BackupPC
I just works with Linux/Windows and Mac.
All I need to do now is setup the last computer (Mac) and I'm done :)

Arduino X10 temperature library

Time to release the temperature library I have been working on... ( there has to be a better way )

It turns out that what is required is a response to a status request to send back the temperature using preset dim commands. The results are a rcs type sensor


/*
  x10.cpp - X10 transmission library for Arduino version 0.3
 
  Original library                              (0.1) by Tom Igoe.
  Timing bug fixes                              (0.2) "   "   "
  #include bug fixes for 0012                   (0.3) "   "   "
  Temperature Sensing                           (0.4) by Jason Cox

  Zero crossing algorithms borrowed from David Mellis' shiftOut command
  for Arduino.
 
  The circuits can be found at

http://www.arduino.cc/en/Tutorial/x10


 */

#include
#include "WProgram.h"
#include "x10.h"
#include "x10constants.h"


/*
 Constructor.

 Sets the pins and sets their I/O modes.

 */
x10::x10(int zeroCrossingPin, int dataPin)
{
  this->zeroCrossingPin = zeroCrossingPin;      // the zero crossing pin
  this->dataPin = dataPin;                                      // the output data pin
 
  // Set I/O modes:
  pinMode(this->zeroCrossingPin, INPUT);
  pinMode(this->dataPin, OUTPUT);
}



/*
        Writes an X10 command out to the X10 modem
*/
void x10::write(byte houseCode, byte numberCode, int numRepeats) {
  byte startCode = B1110;               // every X10 command starts with this

        // repeat as many times as requested:
        for (int i = 0; i < numRepeats; i++) {
                // send the three parts of the command:
                sendBits(startCode, 4, true);
                sendBits(houseCode, 4, false);
                sendBits(numberCode, 5, false);
        }
        // if this isn't a bright or dim command, it should be followed by
        // a delay of 3 power cycles (or 6 zero crossings):
        if ((numberCode != BRIGHT) && (numberCode != DIM)) {
                waitForZeroCross(this->zeroCrossingPin, 6);
        }
}
/*
        Writes a sequence of bits out.  If the sequence is not a start code,
        it repeats the bits, inverting them.
*/

void x10::sendBits(byte cmd, byte numBits, byte isStartCode) {
  byte thisBit;         // copy of command so we can shift bits
 
        // iterate the number of bits to be shifted:
        for(int i=1; i<=numBits; i++) {
                // wait for a zero crossing change:
                waitForZeroCross(this->zeroCrossingPin, 1);
                // shift off the last bit of the command:
                thisBit = !!(cmd & (1 << (numBits - i)));

                // repeat once for each phase:
                for (int phase = 0; phase < 3; phase++) {
                        // set the data Pin:
                        digitalWrite(this->dataPin, thisBit);
                        delayMicroseconds(BIT_LENGTH);
                        // clear the data pin:
                        digitalWrite(this->dataPin, LOW);
                        delayMicroseconds(BIT_DELAY);
                }

                // if this command is a start code, don't
                // send its complement.  Otherwise do:
                if(!isStartCode) {
                        // wait for zero crossing:
                        waitForZeroCross(zeroCrossingPin, 1);
                        for (int phase = 0; phase < 3; phase++) {
                                // set the data pin:
                                digitalWrite(this->dataPin, !thisBit);
                                delayMicroseconds(BIT_LENGTH);
                                // clear the data pin:
                                digitalWrite(dataPin, LOW);
                                delayMicroseconds(BIT_DELAY);
                        }
                }
        }
}


/*
  waits for a the zero crossing pin to cross zero

*/
void x10::waitForZeroCross(int pin, int howManyTimes) {
        unsigned long cycleTime = 0;

        // cache the port and bit of the pin in order to speed up the
        // pulse width measuring loop and achieve finer resolution.  calling
        // digitalRead() instead yields much coarser resolution.
        uint8_t bit = digitalPinToBitMask(pin);
        uint8_t port = digitalPinToPort(pin);

        for (int i = 0; i < howManyTimes; i++) {
                // wait for pin to change:
        if((*portInputRegister(port) & bit))
                while((*portInputRegister(port) & bit))
                        cycleTime++;
        else
                while(!(*portInputRegister(port) & bit))
                        cycleTime++;
                }
}


/*
  version() returns the version of the library:
*/
int x10::version(void)
{
  return 3;
}

void x10::x10temp (byte temp_houseCode, byte tmep_Unit, int count, int RPT_SEND){
        detachInterrupt(0);                  // must detach interrupt before sending
          x10::write(temp_houseCode ,tmep_Unit ,RPT_SEND); 
          x10::write(temp_houseCode ,UNIT_13 ,RPT_SEND);
          switch (count) {
            case 0:
              x10::write(M,PRE_SET_DIM,RPT_SEND);
              break;
            case 1:
              x10::write(N,PRE_SET_DIM,RPT_SEND);
              break;
            case 2:
              x10::write(O,PRE_SET_DIM,RPT_SEND);
              break;
            case 3:
              x10::write(P,PRE_SET_DIM,RPT_SEND);
              break;
            case 4:
              x10::write(C,PRE_SET_DIM,RPT_SEND);
              break;
            case 5:
              x10::write(D,PRE_SET_DIM,RPT_SEND);
              break;
            case 6:
              x10::write(A,PRE_SET_DIM,RPT_SEND);
              break;
            case 7:
              x10::write(B,PRE_SET_DIM,RPT_SEND);
              break;
            case 8:
              x10::write(E,PRE_SET_DIM,RPT_SEND);
              break;
            case 9:
              x10::write(F,PRE_SET_DIM,RPT_SEND);
              break;
            case 10:
              x10::write(G,PRE_SET_DIM,RPT_SEND);
              break;
            case 11:
              x10::write(H,PRE_SET_DIM,RPT_SEND);
              break;
            case 12:
              x10::write(K,PRE_SET_DIM,RPT_SEND);
              break;
            case 13:
              x10::write(L,PRE_SET_DIM,RPT_SEND);
              break;
            case 14:
              x10::write(I,PRE_SET_DIM,RPT_SEND);
              break;
            case 15:
              x10::write(J,PRE_SET_DIM,RPT_SEND);
              break;
            case 16:
              x10::write(M,PRE_SET_DIM2,RPT_SEND);
              break;
            case 17:
              x10::write(N,PRE_SET_DIM2,RPT_SEND);
              break;
            case 18:
              x10::write(O,PRE_SET_DIM2,RPT_SEND);
              break;
            case 19:
              x10::write(P,PRE_SET_DIM2,RPT_SEND);
              break;
            case 20:
              x10::write(C,PRE_SET_DIM2,RPT_SEND);
              break;
            case 21:
              x10::write(D,PRE_SET_DIM2,RPT_SEND);
              break;
            case 22:
              x10::write(A,PRE_SET_DIM2,RPT_SEND);
              break;
            case 23:
              x10::write(B,PRE_SET_DIM2,RPT_SEND);
              break;
            case 24:
              x10::write(E,PRE_SET_DIM2,RPT_SEND);
              break;
            case 25:
              x10::write(F,PRE_SET_DIM2,RPT_SEND);
              break;
            case 26:
              x10::write(G,PRE_SET_DIM2,RPT_SEND);
              break;
            case 27:
              x10::write(H,PRE_SET_DIM2,RPT_SEND);
              break;
            case 28:
              x10::write(K,PRE_SET_DIM2,RPT_SEND);
              break;
            case 29:
              x10::write(L,PRE_SET_DIM2,RPT_SEND);
              break;
            case 30:
              x10::write(I,PRE_SET_DIM2,RPT_SEND);
              break;
            case 31:
              x10::write(J,PRE_SET_DIM2,RPT_SEND);
              break;
         
          }
}


and x10.h
/*
 
  Original library              (0.1) by Tom Igoe.
  Timing bug fixes              (0.2) "   "   "
  Temperature                   (0.3) by Jason Cox
        Sends X10 commands.

*/

// ensure this library description is only included once
#ifndef x10_h
#define x10_h

// include types & constants of Wiring core API
#include
#include "WProgram.h"
#include "pins_arduino.h"

// library interface description
class x10 {
  public:
    // constructors:
    x10(int zeroCrossingPin, int dataPin);

    // write command method:
        void write(byte houseCode, byte numberCode, int numRepeats);
    // returns the version number:
    int version(void);
    void x10temp(byte tmep_houseCode, byte temp_Unit , int count, int RPT_SEND);

  private:
        int zeroCrossingPin;    // AC zero crossing pin
        int dataPin;                    // data out pin
        // sends the individual bits of the commands:
    void sendBits(byte cmd, byte numBits, byte isStartCode);
    // checks for AC zero crossing
    void waitForZeroCross(int pin, int howManyTimes);
};

#endif

Lastly the constants file (added preset dim2)


#define HIGH 0x1
#define LOW  0x0
#define BIT_DELAY 2133          // 1778 us between bit repeats in a half-cycle
#define BIT_LENGTH 900          // each bit is slightly less than 1ms long

#define A       B0110
#define B       B1110
#define C       B0010
#define D       B1010
#define E       B0001
#define F       B1001
#define G       B0101
#define H       B1101
#define I       B0111
#define J       B1111
#define K       B0011
#define L       B1011
#define M       B0000
#define N       B1000
#define O       B0100
#define P       B1100

#define UNIT_1  B01100
#define UNIT_2  B11100
#define UNIT_3  B00100
#define UNIT_4  B10100
#define UNIT_5  B00010
#define UNIT_6  B10010
#define UNIT_7  B01010
#define UNIT_8  B11010
#define UNIT_9  B01110
#define UNIT_10 B11110
#define UNIT_11 B00110
#define UNIT_12 B10110
#define UNIT_13 B00000
#define UNIT_14 B10000
#define UNIT_15 B01000
#define UNIT_16 B11000

#define ALL_UNITS_OFF                   B00001
#define ALL_LIGHTS_ON                   B00011
#define ON                              B00101
#define OFF                             B00111
#define DIM                             B01001
#define BRIGHT                          B01011
#define ALL_LIGHTS_OFF                  B01101
#define EXTENDED_CODE                   B01111
#define HAIL_REQUEST                    B10001
#define HAIL_ACKNOWLEDGE                B10011
#define PRE_SET_DIM                     B10101
#define PRE_SET_DIM2                    B10111
#define EXTENDED_DATA                   B11001
#define STATUS_ON                       B11011
#define STATUS_OFF                      B11101
#define STATUS_REQUEST                  B11111

How I log the hacking on my computer

One day I decided that I had had enough of script kiddies and the like trying to hack my computer and so I was thinking how can I shame them....
Having never used twitter before and needing more challenges, I came up with the idea of sending out an automated stream in real time to twitter and so was born https://twitter.com/breakinlog

This has worked out well so far.

I have been asked "how did I do it?" and so here goes.......

I installed rsyslog on to my computer and setup a new rule for auth logging.

The rule is as follows,
auth,authpriv.*                 ^/root/tw3.sh

This executes the wrapper (tw3.sh) on each auth event in the logger sending the data to it.

Next its tw3.sh that does the work sending information to a Perl twitter agent
#!/bin/bash
message="$@"
echo ${message} >> /tw.log
filter1=`echo ${message}|grep -i invalid |grep user`
if [ $? -eq 0 ]
then
        echo " Invalid User" >> /tw.log
        datetime=`echo $filter1 |awk -F"localhost" '{print $1}'`
        field=`echo $filter1 |awk -F"]:" '{print $2}'`
        output=`echo $datetime $field`
        /root/t2.pl "${output}"
        exit
fi

filter1=`echo ${message}|grep  "Did not receive identification string from" `
if [ $? -eq 0 ]
then
        echo "No Identification" >> /tw.log
       datetime=`echo $filter1 |awk -F"localhost" '{print $1}'`
        field=`echo $filter1 |awk -F"]:" '{print $2}'`
        output=`echo $datetime $field`
        /root/t2.pl "${output}"
        exit
fi

filter1=`echo ${message}|grep  "Authentication failure for"`
if [ $? -eq 0 ]
then
        echo "Auth Failed" >> /tw.log
        datetime=`echo $filter1 |awk -F"localhost" '{print $1}'`
        field=`echo $filter1 |awk -F"PAM:" '{print $2}'`
        output=`echo $datetime $field`
        /root/t2.pl "${output}"
        exit
fi

Last on the list is the t2.pl which sends the filtered output to twitter (need to register to get consumer key and secret). The following was found on the net a long time ago and unfortunately it is not mine nor can I remember whose it is .

#!/usr/bin/perl
#
# Net::Twitter::Lite - OAuth desktop app example
#
# From what I can figure out, this code can only perform one operation
# ie, you can get a timeline or update but not both.
# Trying multiple actions results in "503 Bad Gateway" error.

use warnings;
use strict;

# You need to install all of these from CPAN
# along with dependencies (and having
# Bundle::CPAN installed will help)
# Data::Dumper is just for debugging.
#
# >sudo cpan
# cpan> install Net::Twitter::Lite
#
use Net::Twitter::Lite;
use File::Spec;
use File::HomeDir;
use Storable;
use Data::Dumper;

# You need to register for key and secret at http://dev.twitter.com/
# They are private-ish, don't share.  Anyone using these values
# will show up as using your code.
my %consumer_tokens = (
  consumer_key    => 'consumer_key',
  consumer_secret => 'consumer_secret',
);

# $datafile = oauth_desktop.dat ($0 is program name)
# This will place the dat file in users HOME dir (/home/$user/.net_twitter_example.dat)
# each user needs a .dat file to authenticate.
my (undef, undef, $datafile) = File::Spec->splitpath($0);
my $home = File::HomeDir->my_data;
$datafile = File::Spec->catfile($home,".$datafile.dat");

my $nt = Net::Twitter::Lite->new(%consumer_tokens);
my $access_tokens = eval { retrieve($datafile) } || [];

if ( @$access_tokens ) {
  $nt->access_token($access_tokens->[0]);
  $nt->access_token_secret($access_tokens->[1]);
}
else {
  my $auth_url = $nt->get_authorization_url;
  print " Authorize this application at: $auth_url\nThen, enter the PIN# provided to continue: ";
 
  my $pin = ; # wait for input
  chomp $pin;
 
  # request_access_token stores the tokens in $nt AND returns them
  my @access_tokens = $nt->request_access_token(verifier => $pin);
 
  # save the access tokens
  store \@access_tokens, $datafile;
}

# Authentication done, now process requests
# if nothing was supplied on the command line, get timeline
if (!@ARGV) {
  eval {
    my $statuses = $nt->friends_timeline();
    for my $status ( @$statuses ) {
      #                 dayofweek,month,day,time,  offset, year
      my (undef, $month, $day,undef, undef, $year) = split(' ',"$status->{created_at}");
      print "$month/$day/$year <$status->{user}{screen_name}> $status->{text}\n";
      }
      };
      warn "$@\n" if $@;
      }
      # otherwise, post the string that was supplied
      # this should probably be sanatized at some point
      else {
    my $message = shift(@ARGV);
    eval {
      my $twit = $nt->update($message);
    };
    warn "$@\n" if $@;
      }

     
              
              

Name and shame

My computer sits on the net full time in the DMZ of my network. For years its been setup this way and of course I have a LOT of attempts to hack in.
I eventually thought I would setup a new way of logging these attempts but wanted a more public listing of them. Thats when I came up with my twitter idea.
The plan, collect all these attempts and send them to a feed on twitter in real-time. Once the feed is working correctly, write a daemon to monitor the feed and plug it back into /etc/host.deny......
So my initial work is done and via a few Perl scripts I send it out to  https://twitter.com/breakinlog. It is now very surprising how many hacking attempts are made on my computer, 9602 since the beginning of the year. Also surprising is that I have maintained 10 followers (turn over is about 10/month) for the 6 months of the project so far.
People will follow anything, even auto generated logging.....
So where to now?  Writing the client side scripts to watch the feed :)

Cheap Atmeg328

I wanted to start using Arduino after talking to a co-worker about his experiences with it.
I sourced the processor and resonator from an ebay seller (why can I get it this way for less than Jaycar?).
So once the parts arrived it was onto my plan to make a X10 garden sprinkler control.
First it was onto finding a library for X10 control. After much research I found on at BroHogan.
This covered the basics of send and receive but I also decided that I wanted temperature sensors. The solution came whilst reading one of the manuals for Heyu. This showed the basic algorithm for temperature sensing. I extended the library to include it and also responding to status requests.

And so it begins......

So here I am just past 40, in IT and thought it about time I started to setup a blog.

I have been involved in Linux since it was on 0.95 and before the dawn of the distro. I have been suppling feed back to the wonderful FOSS community and just think its time to get out there on some of my work.

I really should have started this a fews ago when I had the good fortune of helping with port of Rockbox onto the GigaBeat F60. From this project I discovered that I like embedded devices and micro-controllers.
I have also been working on EMC for a home made PCB mill.
So there you have it, time for this adventure to start and take me to who knows where.