Monday, 21 December 2015

TrendNet TV-IP562WI IP Connected Wifi Camera

First Impressions

I wanted a camera for inside the garage, so after a bit of research I picked up a TRENDnet TV-IP562WI. The specs are quite impressive for something less than £70:-
  • 2 way audio
  • Night vision up to 5 metres
  • Receive motion & sound detection video via email or FTP
  • Record to MicroSD card or network storage device (samba server)
  • Free mobile apps
  • Wireless N networking
  • Built in mic + external speaker socket
  • Dynamic DNS (support for NO-IP.com or Dyn.com)
  • Max 20 user accounts.
  • Video Codecs/Resolution 
Video resolution is..
  • H.264: 1280 x 720 up to 30 fps 
  • MPEG4: 1280 x 720 up to 30 fps 
  • JPEG: 1280 x 720 up to 5 fps (or 640 x 480 up to 30 fps)


TrendNet TV-IP562WI - Wifi Camera

It looks pretty good, small enough to easily fit in my hand, and it comes with a solid metal stand that doubles as a mounting bracket. Also in the box was a small 5v PSU, a cat5 cable for initial config, a software CD and assorted fittings for the stand.
 
I ran the software from the CD and had the camera up and running in less than 10 minutes. All you need to do is set the admin password and configure your wireless settings, then once it restarts you continue using a web browser. But that's where my problems started.


Mac Problems

Yeah I know, serves me right for owning a mac,.. but I did manage to solve the problems without resorting to a windows box. My newer Mac (running OSX 10.10) wouldn't display the login box, so it kept failing authentication. I tried using Firefox instead and updating Java, but looking online it appears it has problems with El Capitan.

When I switched over to my kid's Mac Mini, which was running 10.9, it worked perfectly. I was then able to continue config, renaming the device and setting it to run on port 82 rather than the standard 80. (This I did so that I could set up port forwarding on my router and see it on the web).

Mounting the Camera

My wifi signal is a bit weak in the garage, but mounting it high up on the wall got around any potential problems. The mount itself has a sturdy metal ring base with 3 mounting holes and a gimbal jointed adapter to a standard 1/4" thread. This gives you pretty much unlimited mounting options, but it's not overly robust.

I used a couple of ½ inch screws to fasten it to one of the wooden rafters, so it's out of reach, and unlikely to be tinkered with.


View from the installed camera using night vision mode

Updating the Firmware

Initially I added the App software to my iPhone and iPad and it worked without a problem. The app is pretty straight forward, search for devices and then enter the login details. Simple as that really,.. but it didn't work on my wife's iPhone. (I suspected I need to update the firmware.)

You update the firmware by downloading the image from TrendNet's (slow) website and use the camera's mini website to apply it. After a few failed attempts in Safari I switched to Firefox, but it still didn't complete properly. Instead of automatically restarting after the file uploaded I had to use the reset to factory defaults before it reported the new firmware number. After that it worked properly on my Mac using El Capitan.

Solving that iPhone Problem

I tried my wife's iPhone again, but it still didn't work. It was an identical phone to mine, running the same version of iOS. It had to be something else.

I compared the network settings of both devices and the only difference was one was using a web proxy. I disabled this and the problem went away.

Thursday, 3 December 2015

Copy & Paste Select Options from a Web Page

Introduction

Something that's always bugged me when I've looked after web based systems is struggling to grab a list of options from drop-down boxes on a web page. Sometimes you just want to be able to select them all, press control+v and paste them into an email.

Until now, the only way I found to get the list of options was to view the web page source, locate the <option> tags from the <select> and then manually hack the code about until you are left with a simple list.

... it's not exactly easy.

I've put up with this method for years for the odd quick request, but today I needed to get lists from 42 select boxes, and I didnt want to spend all day doing it.

There had to be a better way!!!

The Solution

I use Firefox for most of my web development and queries, mainly because of firebug, and I found this great add-on called SelectBoxTools which among other things allows you to copy options into a comma separated list.

Right-click from within your select box, and when the menu appears go down to SelectBoxTools > Copy as comma-separated text.

SelectBoxTools options.

Then when pasted into a text editor you'll get the visible name and it's value as a list. eg:-

 PK_ID,Pk Id
 OS,Os
 AVAILABILITY,Availability
 SUPPORT_DATE,Support Date
 RISK_LEVEL,Risk Level
 RATIONALE,Rationale
 NOTES,Notes


If you want to use the SelectBoxTools > Selection option, you'll need to select one of the picklist options on your web form first or you'll get the error:-

  TypeError:this.focused.options[this.focused.selectedIndex] is undefined

 Simple, effective and fast.

Monday, 12 October 2015

Running MAME on a Raspberry Pi


Wocka-wocka....MAME on a Raspberry Pi

Introduction

The other weekend we stopped off for a pub lunch and my boys spotted a coin operated video game table. They'd been given a coin to play after their lunch and the food just couldn't arrive quick enough. But it wasn't that long before they got their first tastes of Pac Man, Galaxian and Centipede.... games of my youth were surprisingly just as amazing to my own kids.

The MAME table we found in the pub.
Right there I hatched an idea to look into running MAME on our Raspberry Pi and maybe even built a gaming table that was something like it. I've seen joystick/control kits on ebay, and read various blogs where impressive cabinets have been built around the diminutive computer, so I figured there'd be plenty of help out there. (I wasn't wrong)


I did some research this weekend; there's a few software projects providing more or less the same thing, with PiPlay (formerly PiMAME) being one of the common choices. I decided to look for something that needed the least amount of effort and I found a project called Raspicade which supports USB controllers or direct wired connections to the GPIO.

Installing Raspicade

Download the card image from the Files page (I chose raspicade-samba-gamepads-keyboard-pikeyd_ready-B-B B-GPIOready-ES-20150513.img.gz), unzip the file and then use DD to write the contents to an empty MicroSD card.

On my Mac the command would be something like..


sudo dd if=raspicade.img of=/dev/disk4

(nb. I shortened the img file name, and ensure you find out what disk number the card is mounted on - use "diskutil list" if you need to find out.)

I did try using diskutility to do this, but it can only handle a single partition. The image has two partitions, one dos and the other linux.

it's a 2.5Gb image, it took a long time!.. but after that it was a case of inserting the flash card into the Pi and booting. After the usual linux boot messages you are asked some questions about sound, input type and which front-end to use. Then you get an amazing looking start-up screen and a simple, easy to interface.

Update - 13/10/15
Before you go much further if you are using a card bigger than 4Gb it's a good idea to resize the linux partition to fill your card. I used gparted to do this. It has a nice easy to use GUI and only takes a few minutes.


My first issue was how do I install ROM files?... even though Samba and ftp should be included, it had failed to correctly set my wireless network up (which isn't surprising). I had to resort to shutting it down and mounting the file on a Linux system (I used my Raspbian install) and copy the ROMs over via USB.


The ROM files are NOT freely available, I guess the content owners (from 30 years ago) haven't released the copyright because there's been a lot of reboot type stuff available on android/ios. So you have no choice but to find a torrent.


I downloaded the MAME 0.37b11 mame4all ROMs and installed them in the following folder..

/home/pi/mame4all-pi/roms/

I also copied the artwork and samples to the following directory:-

/home/pi/mame4all-pi/

Interestingly there's a folder in roms for SCUMMVM too,.. something to look into, as the boys have been known to play Day of The Tentacle from time to time. But I couldn't see an option in the menus in which to load them.

After replacing the card into the Pi we powered on and found all of our old arcade games ready to play. Most seemed to work (the odd one refused to start) but it was apparent that we had no sound. There was no obvious setting (other than the questions on boot-up) so I searched the forums.

Fixing the Sound

Initially I checked to see if the sound was being routed to the 3.5mm jack socket, but nothing there either. There had to be a setting fix because it works fine in Raspbian.

So you can press escape to exit to the console, and the Raspicade forum suggests two things that might fix the sound:-

1) Set the output source on the sound mixer to 2 (HDMI)..
  

sudo amixer cset numid=3 2

2) Then enable HDMI sound..

sudo nano /boot/config.txt

Find and uncomment the line..

#hdmi_drive=2

After I'd saved and then rebooted, the splash screen burst into life with glorious sound, and moments later our selected game responded with glorious 8 bit retro tones.

Big Smiles All Round :o)

Wednesday, 30 September 2015

Background Use of Mobile Network on iPhone

What's with WIFI on the iPhone?

After reviewing my Apache logs to resolve a Davical problem on my wife's phone I discovered something very interesting. I put together a PHP script to enable the caldav messages to be monitored more easily (I based it on my Minecraft log script), and it gave me log messages like this...

86.152.117.242 - rick [29/Sep/2015:00:16:00 +0100] "PROPFIND /davical/caldav.php/private/ HTTP/1.1" 207 2180 "-" "iOS/8.3 (12F70) dataaccessd/1.0"
86.152.117.242 - rick [29/Sep/2015:00:16:01 +0100] "PROPFIND /davical/caldav.php/pingucal%3A8800/.well-known/carddav HTTP/1.1" 403 670 "-" "iOS/8.3 (12F70) dataaccessd/1.0"
86.152.117.242 - rick [29/Sep/2015:00:16:01 +0100] "PROPFIND /davical/caldav.php/pingucal%3A8080/.well-known/carddav HTTP/1.1" 403 670 "-" "iOS/8.3 (12F70) dataaccessd/1.0" 


My phone was in fact connected to my home Wifi with an IP address of 192.168.1.157, but it was clearly using the Mobile network connection to talk to the Davical service because the log showed my phone was sending requests from 86.152.117.242.

It won't fix!!

I tried lots of different things, resetting network settings, disabling various wifi options, and even turning off mobile networking. But when I viewed the Apache log it was still (as if by magic) logging connections from the mobile network IP address.

I was using iOS8.3 and couldn't find any listed problems with it, so I took the plunge and upgraded to iOS9. Twenty minutes and 1 gigabyte download later I was upgraded, but the problem remained. I gave up and went to bed with Mobile networks clearly OFF.

I viewed the logs the next day - every hour the phone accessed the Davical service from 86.152.117.242

86.152.117.242 - rick [30/Sep/2015:06:32:09 +0100] "PROPFIND /davical/caldav.php/pingucal%3A8008/principals/ HTTP/1.1" 403 664 "-" "iOS/9.0.1 (13A404) dataaccessd/1.0"
86.152.117.242 - rick [30/Sep/2015:06:32:09 +0100] "PROPFIND /davical/caldav.php/pingucal%3A8800/principals/ HTTP/1.1" 403 664 "-" "iOS/9.0.1 (13A404) dataaccessd/1.0"
86.152.117.242 - rick [30/Sep/2015:06:32:09 +0100] "PROPFIND /davical/caldav.php/pingucal%3A8080/principals/ HTTP/1.1" 403 664 "-" "iOS/9.0.1 (13A404) dataaccessd/1.0" 


Now that's surprising!!.. just what does that OFF button do then?


It's all about the Cache

While grabbing log entries for this blog tonight I discovered something quite baffling... it now appears to be using Wifi correctly. My phone continued to connect via 4G from work (using another IP address)
86.152.117.242 - rick [30/Sep/2015:14:13:24 +0100] "PROPFIND /davical/caldav.php/pingucal/ HTTP/1.1" 207 2525 "-" "iOS/8.3 (12F69) dataaccessd/1.0"
213.205.199.17 - rick [30/Sep/2015:14:17:03 +0100] "OPTIONS /davical/caldav.php/paulcal/ HTTP/1.1" 200 613 "-" "iOS/9.0.1 (13A404) dataaccessd/1.0" 


Here half way through the afternoon we can also see an iOS/8.3 device, which is my iPad. It doesn't have a cellular networking radio, so it doesn't make sense that it should have that IP. Clearly there's some sort of caching going on with the Apache logging. My phone is showing as the iOS/9.0.1 device.

Once my iPhone connected to the Wifi it started showing correctly..

192.168.1.157 - rick [30/Sep/2015:19:04:32 +0100] "OPTIONS /davical/caldav.php/lehrlecal/ HTTP/1.1" 200 613 "-" "iOS/9.0.1 (13A404) dataaccessd/1.0"
192.168.1.157 - rick [30/Sep/2015:19:04:32 +0100] "PROPFIND /davical/caldav.php/lehrlecal/ HTTP/1.1" 207 2666 "-" "iOS/9.0.1 (13A404) dataaccessd/1.0"


So I can't trust the IP addresses in the Apache2 log. If you reset the Mobile Data statistics you can confirm for yourself that it isn't actually using Mobile data IF it's turned off. My faith in Apple has almost been restored,.. I'm sorry I ever doubted you!
BUT, with Mobile data turned on, the background process is showing it's being used instead of the Wifi connection. There might be a good reason for this, but as is often the case these days, as a consumer I have little or no control over it without turning the phone off or disabling Mobile data every evening.

Now I'm thinking I need to jailbreak my phone again!

Thursday, 20 August 2015

Weaving a Paper Sombrero

Introduction

I'm leaving my usual topic of computers and technology for a change, and doing something crafty. I've made a fair but of stuff out of cardboard in the past, but today I'll be using paper.

We're hosting a Mexican dinner party soon and I thought it'd be fun to try and make a sombrero. 

Obviously the first thing you do is google it, but the search results returned mostly pictures of cakes, so I set about trying to build my own hat from scratch. After a few false starts I decided to use long paper strips and construct it in the style of a woven palm hat.

Making a Start

The boring bit is making a ton of paper strips using wall lining paper. It's relatively stiff paper, course finished and slightly off-white coloured. (Ideal really)

Making paper strips - you'll need lots of these!
  1. Cut off a long strip of lining paper, around 1.5 metres (5ft) long. Fold it along it's length and cut down with a knife to give you two narrower strips.

  2. Repeat this until you end up with strips about 4 cm (1.5 inches) wide, fold these along their length but don't cut them this time. (We're aiming for double thickness 2 cm strips to give the hat better strength.)

  3. Take eight strips and weave them together to give a square starting point, as per the next photo, and fix them with a glue stick. (Glue sticks are quick bonding, not too messy, and can be unpicked if things go wrong.)
Starting weave showing eight strips woven togther.

Weaving the Crown

OK, that was the easy bit, now go and find yourself a tapered pot (I used a flower pot) to use as a former to weave the crown around.
  1. Bend the strips down and start weaving and gluing into a diamond pattern.
Weave down in a diamond formation.
  1. Now it gets a little tricky, add extra strips to fill in the gaps as go, but don't add too many, or your crown will grow too wide. Pull the sides in to each other as you weave.
Add extra strips and weave sides together.
  1. Keep going until your crown is about 20 cm (7-8 inches) high and slightly wider than your head.

Finishing the Crown

Now we'll fix a paper band inside the hat to give it strength and set the width.

  1. Take a strip of paper long enough to go just over twice round your head and glue it together to form a strong oval (head shaped) band.



  1. Once dried, glue this to the inside of the crown with PVA or contact adhesive. (I used the latter because it's fast drying and very strong)

Starting on the Brim

Once dried, turn the hat over and start weaving the brim. Again this can be a little tricky to get started because the strips don't tend to be very evenly spaced. But at least this time you can weave on a flat surface.

Ready to start the brim.
  1. Start with easy diamond shaped weaves again, adding extra strips where missing.
Weaving the brim.
  1. Build it out until you reach your desired width. I went for 18 cm (7 inches) from the base of the crown. (You'll find that even with four layers of paper the brim is very floppy, but don't worry the next stage with fix that.)
Keep adding extra strips as you weave.

Finishing the Brim

Everyone knows that sombreros curve up at the edge, but that's very hard to make. Instead I opted for a simple square edge, and it really transformed the brim from a floppy sheet into a rigid hat.
    Brim edge marked and strips folded up.
  1. Mark the brim's circumference with a pencil, fold up the strips and cut off any excess length. (You may need to unpick some of the weaving if you went too wide.)
  1. Take one of your left over weaving strips, ensure it's long enough to go round the hats circumference, and temporarily join it together to make an edge band. (You'll want to fine tune the length later.)

  2. Weave the strip around the brim's edge using clips until the glue dries. Work your way from the middle of the band to the join.

  3. Glue the join as you finish the last bit of weaving and then repeat from step 12 to add a second band.
Weave edge bands to add rigidity.
  • Your hat should look something like this..
The hat almost finished.
  1. Finally double back the remainder of the strips, trim and glue over the top edge band and you're done.
The completed sombrero.

What Next?

It's a good idea to give the whole thing a coat of diluted PVA glue. (50:50 should do it) This will make the hat a little more durable and prepare it for any pattern you want to add.

I hope you found this useful, and if anyone does have a go at building one, good luck. Oh and please send pix, and I'd love to see the results.

Friday, 7 August 2015

Web Scanning for Devices on your network using Nmap and Perl

Introduction

I wanted a way of keeping tabs on how much the kid's computer was being used during the day while we were out. I can look on the router to see what devices are connected to the network, but this only works while I'm at home.

As I run a web server at my home, I decided to put together a quick webpage that scans for devices and shows the result on a smartphone.




Scanning the Network

After a few web searches I found the best tool to use on my Linux server was nmap, so I installed it and started playing around scanning my network. Results were initially pretty patchy, either the scan took too long (in excess of a minute) or finished quickly but didn't pick everything up.

The results depend on what sort of scan you want to do, it will scan ports and even attempt to detect the device's operating system.

In it's simplest form just enter:-

  nmap 192.168.1.*

Which will scan for range of addresses using a wildcard, or you could just do the following for a smaller range (192.168.1.1 - 192.168.1.20):-

  nmap 192.168.1.1-20

You can perform a fast scan by using the F flag:-

  nmap -F 192.168.1.*

Or include a range of ports (say 80 to 200):-

  nmap -p 80-200 192.168.1.*

Anyway, it does loads of good stuff, and also generated a lot of errors like this..


  RTTVAR has grown to over 2.3 seconds, decreasing to 2.0

I couldn't find much help about this warning message, but it seems to be related to the scan taking longer than expected. Be patient.

Eventually, I settled on the following command which gave a rapid reply and a reasonable degree of accuracy. (The T5 flag sets the timing template so it times-out sooner.)

  nmap -F -T5 192.168.1.*


Building it into a Webpage

My main aim was to show the data in a webpage which could be viewed from anywhere. I chose to use Perl and the CGI library to do this, although I could have used PHP instead. (I'm just more familiar with Perl)

Here's the code I came up with, it also uses the Nmap_Parser library to make handling the nmap data easy.

#!/usr/bin/perl
use strict;
use Nmap::Parser;
use CGI ":all";

my $q = CGI->new();
print $q->header();
print $q->start_html(-title => 'Scan Network',
                     -head  => meta({-name    => 'viewport',
                                     -content => 'width=device-width, initial-scale=1'}));

my %known = ('Unknown-f0-b4-79-19-a8-ff.home'             => "Rick's Laptop",
                         'android-16f4d57ae478ea5.home'   => "Saul's Phone",
                         'Unknown-84-38-35-41-0d-56.home' => "Ruth's Laptop");

print "<h1>Devices on Network</h1>";
print "<FORM><INPUT TYPE='button' onClick='history.go(0)' VALUE='Refresh'></FORM></h1>";

my $np = new Nmap::Parser;
$np->parsescan('/usr/bin/nmap','-F -T5',"192.168.1.*");

for my $host ($np->all_hosts()){
   if ($host->hostname){
       my $hostname = $host->hostname;
       if (exists($known{$hostname})){ $hostname = $known{$hostname}; }     
       print "<p><span style='display:inline-block;width:7em'>".$host->addr."</span>: ".$hostname."</p>";
   }
}
print $q->end_html();

You may also notice I added a way of remapping 'Unknown' devices to something more helpful. It goes without saying that you should add your own devices to the '%known' hash array, if you find them being displayed with unhelpful names.

I also set the meta tag in the html head so that it behaves better on mobile devices.

Performance

In use it takes between 5 and 10 seconds to perform a scan. Sometimes devices aren't detected on the first scan (especially mobile devices), so refresh the page a few times to get a more accurate idea.

It picks up most devices including my Bluray player and Humax PVR, but for some reason it wouldn't detect the Nintendo Wii earlier. (not sure why)

Anyway, hope some of you find it useful.

Monday, 6 July 2015

Hacking a Solar Security Light

Introduction

I've got a few LED lights around my home with infrared motion detectors. They provide soft light at night in the hall, stairs and inside cupboards, and another provides a surprisingly bright light over the back door. So no more fumbling in the dark for light switches or keys on cold dark nights. But the one thing that's been bugging me is the light in the garage.

I replaced the single light fitting with a 6 foot fluorescent tube last year. It does a good job lighting the space, but the kids sometimes leave it on, and the second or so delay is annoying if you're repeatedly going in an out of the side door.

Having been impressed by the light over the back door I decided to get another for inside the garage. Not only will this provide some convenience, but solar = free power.

Problems With the New Light

Solar LED Light
I picked up this 36 LED light from Maplin which provides 150 lumens and has a sensor range of 8 metres. Not bright enough to do any work by, but enough to stop miscellaneous clutter from being a tripping hazard.

It was different from the previous one I'd bought, being a bit cheaper, and the on-line reviews showed that some had problems with water getting in. But as I'd planned to install it inside my garage, I disregarded that as a problem, and purchased the light.

It wasn't until testing that I realised the light wouldn't come on in daylight. (this is determined by measuring the voltage coming from the solar cell). I found I had to cover the solar panel with my hand, or disconnect it to get the light to come on.

This was NOT good!

Hacking the Light

I mused that perhaps the circuit could be altered so that the solar panel only charges the battery and doesn't factor into the sensor circuit. I grabbed my screw driver and started to investigate.

After removing the screws from the main case I found a 3 cell battery pack and a small circuit board.

The light's casing open showing circuit board.

You don't get wiring diagrams these days so I had to trace the circuit and sketch it out on scrap paper.

1. The voltage from the solar cell passes through the blocker diode D1, which then feeds onto the battery connected to the (slightly blurred) white connector.

2. The white return wire from the IR sensor connects to the OUT pad on the circuit board, which feeds the base of larger transistor on the far left. This turns the light on when the sensor is triggered.

3. The smaller transistor Q2 shorts the base to 0v if the voltage through R4 (from solar cell) is high. This stops the light coming on in the day.

Remove R4 from the circuit.

So,.. I grabbed my soldiering iron and desoldered this resistor.

The removed resistor on my finger

Bingo, the light comes on, and this time I didn't have to cover the solar panel.

Tuesday, 24 March 2015

Unicode data extracts using Oracle SQL*Plus in Unix

Introduction

The normal data spooling method using Oracle SQL*Plus will use the locale setting to determine the output file encoding method. Typically we are only interested in data extracts using just ASCII characters, but if you need (for example) to use a unicode character as a data separator, then things tend to go wrong.

Consider the following SQL statement which uses the double dagger unicode character as a separator:-

SELECT 'FIRST_NAME'||unistr('\2021')||'SURNAME' from dual;
 
If we run this in an SQLPlus session we get the following..

FIRST_NAMEĆ¢¡SURNAME 
 
(nb. I'm going to assume that you are using Putty as your terminal client)

 Setting your Locale in Putty

The data returned by the select looks like it's become mangled, but it's not. Your Putty session needs it's Window/Translation setting to be changed to UTF-8 before it can be displayed correctly.

Select UTF-8 translation in Putty


Now if we run this SQL again we get..

FIRST_NAME‡SURNAME

Similarly we can run the following SQL script using SQL*Plus to produce the file output.csv:-

set feedback off
set heading off
set term off
set echo off
spool output.csv SELECT 'FIRST_NAME'||unistr('\2021')||'SURNAME' from dual;
spool off
exit

The contents of output.csv will also display correctly using 'cat', but only because your locale settings in Putty are UTF-8.

NB. You can also copy the file back to your PC and open it using notepad (which handles UTF8 files correctly).

Scheduling with Cron

The spool script works OK when run interactively, but now let's schedule it from the cron. The script will be run using the machine's locale settings (probably ISO8859), and so SQLPlus will replace the unicode characters with question marks to keep it a valid ASCII format.

FIRST_NAME?SURNAME

But we can fix this by adding the following line near the start of our shell script:-

export NLS_LANG=.AL32UTF8

Tuesday, 3 March 2015

Oracle APEX - Soft Validation using Dynamic Actions

Introduction

It's often a good idea to have validation on your forms in APEX, especially when you have business rules that govern how data can be entered. On a recent system enhancement we wanted to add a 'target bonus' flag to a page, but only allow it to be set to 'Yes' if the 'rebate level' was not set to 'None'.

This is simple enough to do..

Create a Page Validation, with a validation type of 'PL/SQL', 'Function Returning Boolean', then enter code as follows:-

BEGIN
  IF :P4_TARGET_BONUS = 'Yes' AND :P4_REBATE_LEVEL = 'None' THEN
     RETURN false;
  ELSE
    RETURN true;
   END IF;
END;

But it turns out that it's not quite what the customer wanted. There may be instances were it's OK to break these rules, so in that case can we just warn the user by showing a pop-up confirmation box instead.

Confirmation boxes are a UI thing which needs to happen before the page is submitted, so this sounds like a job for a dynamic action.


Using Dynamic Actions For Validation

I deleted the page validation (above) and set about using jQuery and a Dynamic Action to perform the same field comparison, but this time at the browser level.

Adding a Confirm action for soft validation.

1. Create a dynamic action against your submit button and set the following details in the When section.

Event: Click
Selection Type: Button
Condition: Javascript expression
Value: ($v('P4_TARGET_BONUS') == 'Yes' && $v('P4_REBATE_LEVEL') == 'None');

2. Next add a True action for when validation fails..
 
Action: Confirm
Fire When Event Result is: True
Text: Target Bonus is not allowed while Rebate Level is 'None', continue?
 

3. Add another True action which will be used if OK is clicked on the confirm action..
 
Action: Submit Page
Fire When Event Result is: True
Request/Button Name: UPDATE
 
4. Finally add a False Action to perform a simple submit if validation passes..

Action: Submit Page
Fire When Event Result is: True
Request/Button Name: UPDATE

That's it!... you can make your own validation tests more complex in the dynamic actions javascript box using the standard comparison and logic operators.

Thursday, 19 February 2015

Nintendo DSi - Resetting Parental Control

The Problem

If you've ever watched kids use computer devices then you'll be aware of their preoccupation with the menus (or screwing around with the settings). I've gotta admit the worst incident of this was when I had to reset the language on an MP3 player from Chinese back to English.

Anyway my son (let's call him Dick to retain his anonymity) has wasted countless hours exploring all of the menu options and settings on his Nintendo DSi. At some stage we think he set the parental lock and then forgot the four digit code.

He'd been complaining for some time about how we need to ring up Nintendo's Technical Support and get a reset key. And we've done our best to ignore the request, keen to show him that there's a real world impact to "buggering about with things in a hap-hazard way".

The net result of this problem: he can't access the web (fine by me), and can't access the Nintendo Shop (again fine). The latter generally forces a firmware update, which in the past has stopped their R4 cartridge from working.

But after replacing his brother Harry's DSi at the weekend, Dick became very upset that the new machine had DSiWare on it that his didn't have. Specifically Flipnote Studio!


Flipnote Studio - Finally a constructive use for the DS


He initially tried to copy the app over using an SD card, but it refused to copy back to his DSi. (Nice try but it's restricted to that console during the download. Copying to an SD card should be viewed as a backup only.)

I think it's a pretty good program, so I waited until they were in bed and then attempted to access the Nintendo Store.


Parentally Locked

My first problem was unlocking internet access. The old four digit code (we'd set when the DSi had belonged to Tom) wouldn't work, so I was then asked to enter the town were I was born. I tapped it in but - no go!,  then tried my wife's - also no! (and various other places we'd lived - all to no avail)

Eventually I was presented with an eight digit enquiry number and advised to contact Customer Support to obtain a master key. I fired off an email, but in the mean time carried on looking for an alternative.

I got a standard reply from Nintendo stating they were busy and would respond soon, and then I found the following page..

http://wii.marcan.st/parental

Obviously it's meant for the Nintendo Wii, but it also works for the DSi.

Enter your enquiry number and click on the button to receive your 5 digit master key.

If it doesn't work check the date is set in-correctly on your DS.

Tuesday, 10 February 2015

Raspberry Pi Diary - Scratch GPIO and 7 Segment Displays

Installing Scratch GPIO

The standard version of scratch can't control the GPIO, so you need to install ScratchGPIO7 before you can play with LED's and switches. I googled the install instructions but here they are if you need them:-

wget http://bit.ly/1wxrqdp -O isgh7.sh

sudo bash isgh7.sh

If you need to add the desktop icons to other users you can specify user name on that last command:-

sudo bash isgh7.sh fred

(nb. make sure you have an internet connection first!)

Use the new desktop icons to start scratch and it will ensure a background python task is running that enables the GPIO control.

There's a simple code example that toggles pin 11 between low and high. We attached an LED to this pin, (using a 470R resistor) and connected the other end to one of the ground pins. (doesn't matter which)

Success - a flashing LED!


Moving on from Basics

The plan was that I'd set my 8 year old a task of driving one of his 7 segment displays using the Raspberry Pi, and maybe get it counting 0 to 9.

It seemed like a suitable jump of of complexity both in software and breadboard wiring. (perhaps it was a jump too far) Here's what happened!


Circuit Debugging

My son disappeared for half an hour and returned with breadboard, 7 segment display, and T-Cobbler carefully connected with jumper wires. He plugged it in to the RPi, loaded up the pin 11 demo program and clicked the green flag icon to run the program. The scratch variable was clearly cycling on and off on the screen, but none of the segments lit. We ended up tearing the circuit down trying to get it to work and along the way discovered a few problems..

1. The T-Cobbler board has 40 pins that need to be inserted into the breadboard. That takes more insertion force than you'd think.

2. The LED display was of the common anode variety. This means that all the anodes are connected together and the segments lit by pulling the individual cathodes down to ground.

(So he had connected the LED segments the wrong way round.)

A quick flick through the Maplin catalog confirmed you can get common cathode versions.

Driving Common Anode Displays

My initial thought was we'd have to use a transistor inverter to drive each segment, but that's a fair bit of extra complexity and not strictly necessary.

A simple inverter circuit is not necessary.

Each GPIO output actively pulls high or low, so if you connect the common anode to 3.3v then any low pins connected to the cathodes will turn the display segment on.

Connecting a common anode display to a Raspberry Pi

The only hitch is the logic is the other way around! (pin low = segment on)

But it's only just occurred to me that we could do this after reading the Raspberry Pi GPIO Documentation and seeing an LED connected this way. (Must try this tonight!!)

Wednesday, 4 February 2015

Raspberry Pi Diary - Breakout Boards

Interfacing 101

One of the main reasons why I bought the Raspberry Pi was to bring together the two worlds of electronics and computing for my two youngest sons. The oldest of the two already has various components and breadboard to play about with, and he's already been experimenting with scratch for a while now.

The great thing about the Raspberry Pi is that it has those GPIO pins just waiting to connected to LEDs, switches, sensors or the wide variety of add-ons that you can buy these days. I thought I'd start by getting a simple breakout board from Maplin.

GPIO Breakout Board
I got one, but lets just say I made a few mistakes!

Mistake #1

It comes in kit form, requiring the ribbon socket and header pins to be soldered together before you can use it. There's a simple diagram that suggests how the ribbon connector should connect to the GPIO pins and which way it should fasten into the breakout board. Seemed simple enough but it wasn't obvious which way up the board should go.

One end of the breakout board
One end was labelled 'GPIO HEADER' (see diagram), so I concluded that it belongs this way up and started soldering the socket. After I'd done about eight I started to get the niggling feeling that it wasn't correct. I stopped and traced the wiring only to find I actually had the board upside down!!!

Now unsoldering a double-sided board is a nightmare, and my desoldering pump just wasn't doing the job. In the end, I levered the socket away from the board leaving the soldered pins still attached. These were then individually removed with a hot soldering iron and a pair of pliers.

Botched breakout board with removed socket pins.
Now I'll have to drill out the remaining solder before I can start again. (This wasn't going well!)

Mistake #2

It wasn't until my son came through to check how I was getting on that I realised my next mistake. I was explaining to him about how the ribbon plug would fit into the GPIO. When I went to demonstrate this I spotted my next mistake. (this one pretty fatal)

This was a 26 pin breakout board for the original Raspberry Pi, but I'd bought the newer RPi B+ model, which has a 40 pin GPIO. The ribbon plug won't fit and if you try to force it you'll end up bending some of the pins. (darn!)

Let's do it Right

All I can say is "Cobblers" - or to be more exact Adafruit's T-Cobbler Plus. As soon as I opened the bag I was immediately impressed by the improved quality and the neat screen printing showing (without doubt) which way the socket should be soldered.

You can bet I still checked it carefully before I started, but within about 10 minutes it was done.

The assembled Adafruit T-Cobbler Plus
My son quickly relieved me of it and started building a circuit to light his 7 segment LED display.

(More about that another day)

Oracle APEX - Advanced Tabular Form Validation

Introduction

In my previous APEX post I took you through a method of adding click-able column help to your tabular forms. I also needed to add validation between my columns, and initially it wasn't clear how I might do this. You can validate against static values, normal item values, or just check for nulls, but nowhere can you validate against a value from another column on the same row.


Tabular Form Requirement

Just to recap from before, I have a table of measures with three columns to hold the weighting, cap and uplift values for each. (shown below)


My Tabular Form
The validation I wanted to add was to ensure that if a Cap value is added then it must be greater than the Weighting value.

One way of performing this type of validation is to use some jQuery code which runs on the browser, but generally its not recommended for security reasons. Instead we'll use a method that replies on the inherent use of collections for tabular tables and write our validation using PL/SQL.

Creating the Validation

1. Run the page containing your tabular form and inspect the input fields from the columns your need to validate to get their id's.

The HTML for the first Weighting field is:-
<input id="f03_0001" type="text" value="0" maxlength="2000" size="2" name="f03"
autocomplete="off">

The HTML for the first Cap field is:-
<input id="f04_0001" type="text" value="0" maxlength="2000" size="2" name="f04"
autocomplete="off">

So the two pieces of information we need here is f03 and f04.

2. Create a page level validation and give it a suitable name. (I'm going to call mine "Check Cap Values Exceed Weighting")

3. Select 'PL/SQL' as the validation type.

4. Then select 'Function Returning Boolean'.

5. Here's the code I entered:-

BEGIN
  FOR i in 1..apex_application.g_f03.count
  LOOP
  IF apex_application.g_f04(i) IS NOT NULL
    THEN IF apex_application.g_f03(i) IS NOT NULL 
      THEN IF TO_NUMBER(apex_application.g_f04(i)) <= TO_NUMBER(apex_application.g_f03(i))
        THEN RETURN false;
      END IF; 
    END IF; 
  END IF; 
  END LOOP;
END;

NB. APEX automatically creates a collection for each column in a tabular form ("apex_application.g_f01", "apex_application.g_f02" etc...) This function loops through the values in columns 3 and 4 comparing the values. 

It's reasonably simple, just don't forget to turn these values into numbers before you do your comparison, or you'll find that 8 is greater than 10 and your validation won't work as you intended!

6. Enter the following for Error Message:-

Cap values must be greater than Weighting, or left empty.

7. Finally set the condition to When Button Pressed 'SUBMIT'.

That's it!