On Mon, 24 Nov 2014, Gareth France wrote:
> Sounds good. The tricky bit is they seem to have encrypted the results 

There doesn't appear to be anything encrypted. 

What's there *is*, is simply short-hand, much aking to how a human
would write down on paper (ticks and crosses) when doing the tests the
old fashioned way.  To echo the other poster, all that's needed is to
work through and find out what test each 1/0 corresponds to.  The
sample size in this 'SSS' file isn't enough, it's only 12 tests, and
10 of those are identical:

  strings -a SSS  | grep 111 | sort | uniq -c
      1 H172008021S121111111
      1 H1C2008021S121111111
     10 I010000022S121111111

The two 'H' entries are the fridge and washing machine. so I'm
guessing this might be a manually-entered category (eg. House-hold
appliance/Class I/Earthed); the rest are resistive heaters of various
descriptions (Hard-wired?).  "2008" could be a year of test---and
"0000" could be unknown.  0/1/2 probably correspond to
unknown/pass/fail in some combination---you'll know what was entered!

The key here, is that yourself, as the owner of the machine has nearly
complete control over the physical inputs to the machine, by choosing
menu items, scanning barcodes, entering asset IDs, which probe is used
and which pins are shorted with what resistance. The two records for
the domestic appliances have slightly longer entries, suggesting
additional tests were performed/selected.

All one needs to do is to work though all the combinations, changing
only one menu item at once, and with ~100 samples matched up with
notes of what was selected on the menu, it should be little trouble to
match them up.

It's not a problem of reverse-engineering (easy in this case as the
file format is really simple).  The problem is having the
domain-specific knowledge of what values the machine is able to
output.  This is where you can help:

  1. Larger sample-sizes of '.sss'
  2. The corresponding notes about what was measured/entered.

Attached is some Python that decodes everything except the Washing
Machine and Fridge.

        -Paul



#!/usr/bin/env python
# Paul Sladen, 2014-11-25, Seaward SSS PAT testing file format debug hardness
# Hereby placed in the public domain in the hopes of improving safety and interoperability

# Examples of the types of PAT-testing fields that are likely to be contained
# http://www.wildingsound.co.uk/images/pat-testing-log-sheet.gif
# http://www.tysoft.co.uk/images/easypat_screenshot20l.jpg
# http://www.simplypats.co.uk/pat_testing_software/specifications.htm

import struct

def main(filename = 'SSS'):
    f = open(filename)
    while True:
        try:
            # Read length, then read record data itself one-by-one
            record = f.read(struct.unpack('>H', f.read(2))[0])
            # Check for the end-of-record-marker
            assert struct.unpack('>L', f.read(4))[0] == 255
            # Bar-code?
            print 'Barcode?: %#04x %#04x %#04x (%3d %3d %3d)' % (struct.unpack('>2x3B', record[0:5]) * 2)
            # Asset ID
            print 'Asset ID: "%s"' % struct.unpack('16s', record[5:21])[0].replace('\x00', '')
            # Date-time (of test)
            datetime = struct.unpack('>4BH', record[21:27])
            print 'Datetime: %04d-%02d-%02d %02d:%02d' % (datetime[4], datetime[3], datetime[2], datetime[0], datetime[1])
            # Remainder of Site/Location/Test results
            # Different classes have slightly different record layouts,
            # which need more examples to full understand.
            # The values c.240-241/250 could be nominal line-voltage?
            rest = '16s16s11s1c20sBB16s'
            labels = struct.unpack(rest, record[27:27+struct.calcsize(rest)])
            print labels

        except struct.error:
            return

if __name__=='__main__':
    main()
-- 
ubuntu-uk@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-uk
https://wiki.ubuntu.com/UKTeam/

Reply via email to