* This is the first attempt at decoding the irda, so is rough around the edges * isn't correct in a few places. But it is a good resting place for the inital * scripts that extracted the test data and got me started on just what I was * looking at. Biggest difference between this and website is... the frames start at different positions, here the checksum is at byte 100, not 110. * So far the conclusions are: * 0. Keying fields(bytes) relative to the model/make Elster A100C, where the E is $1 * 1. Fields $40 to $44 are WattHours. The hex digits just use the numeric digits * to denote the value (check). * 2. Fields $70 and $71 are related to power usage, possibly an instantaineous * measure of power usage. But, $70 spends most of its time at a large value * and $71 spends most time at 0, suggesting they somehow combine to make a 2 byte * floating point number. * 3. $78, $83, $84 and probably earlier fields record meter runtime. The finest * resolution is the hour, stored in $84 (overflowing to $85) and $75. # 4. $100 is a checksum, the sum of all bytes except itself mod 256. Grabbed a hexdump of the irda output using: hexdump -C /dev/ttyS1 having already run minicom to set the parameters as 2400 baud, 7E1. The meter was saying 6824 units used, on 24:04, 5th April, 2009 As it wasnt clear what, if anything the encoded stuff meant, decided to narrow down whats of interest by looking again when the units had changed. Coming back +2 units later, is the output any different? Defo each repeat of above is a repeat. And again, after a small amount of time has passed while checking over the above. With meter now reading 6268 # grabusage.txt used 7 bit codes, but now I know it uses 8 bit which is grabusage2.txt hexdump -C /dev/ttyS1 | awk '/^[0-9]/ {for(i=2;i<=17;i++){k=strtonum(sprintf("0x%s",$i)); v=k; if(v<32 || v>127)v="?"; printf "%d\t%c\n",k,v;} }' | awk -FA"`printf "\t"`" -- 'BEGIN {m=1;} {if( $2==substr("Elster A100C",m,1) )m++; else m==1; if(m>=8){printf "Restart: %d %d\n",fl,s >> "/dev/stderr"; fl=0; s++; printf "\n"; fflush(); m=1;} printf " %02x",$1; fl++; }' >> grabusage2.txt # convert grabusage2.txt into lines showing only the values that have changed # also, only count the line at all if it passes the checksum, which is a sum of whole line but #100, mod 256 tail -n 999999999 -f grabusage2.txt | awk -- 'BEGIN {show[79]=1;} {printf "%d ",NF; sum=0; for(i=1;i<=NF;i++)if(i!=100)sum+=strtonum(sprintf("0x%s",$i)); if(NF==110 && (sum%256)==strtonum(sprintf("0x%s",$100))){ for(i=1;i<=NF;i++){ noshow[i]=show[i]; if((i in was) && was[i]!=$i)show[i]=1; if(show[i]){ if(!noshow[i] )printf " %d->%s->%s",i,was[i],$i; else printf " %d->%s",i,$i; } was[i]=$i; } } printf " 0x%s?=0x%02x\n",$100,sum%256;}' | less # convert key columns. #40->x*Wh, .., #43->100*Wh, #44->Wh #70->poss voltage, #78->poss related to unit used, #83 & 84, counters keyed from #78, or maybe #78 is keyed from this?, #100->checksum, sum of whole line but itself # Suspect the bits have been scattered throughout the bit space, which is why some of it makes no sense. awk -- < grabusage2.txt 'function h2d(a){return strtonum(sprintf("0x%s",a));} { sum=0; for(i=1;i<=NF;i++)if(i!=100)sum+=strtonum(sprintf("0x%s",$i)); if(NF==110 && (sum%256)==strtonum(sprintf("0x%s",$100))){printf "%d\t%d\t%d",NR,$42*10000+$43*100+$44,h2d($70); } printf "\n"; }' > delme.plot echo "plot \"delme.plot\" using 1:3" | gnuplot -persist # average out WattHours counter, seemingly the most high res counter available... # this converts the units into 'units' per second. awk < delme.plot '{if($2!=last)printf "%s\n",$0; last=$2;}' | awk -- '{if(0)printf "Original: %d\t%d\n",$1,$2; dtdp=($2-lp)/($1-lt); if(lt>0)for(t=lt+1;t<=$1;t++){printf "%d\t%0.3f\n",t,dtdp;} lt=$1; lp=$2; }' > delme2.plot # above was a tad noisy, average out of 60 seconds - at least, im thinking the updates # are per second, running for just over day there is just over a days worth of entries. awk -- '{ if(sums>=60){printf "%d\t%0.3f\n",NR,avg/sums; sums=0; avg=0; } sums++; avg+=$2;}' < delme2.plot > delme3.plot echo "plot \"delme3.plot\" using 1:2" | gnuplot -persist # do the batch processing of fresh results and upload to abatis bash bin/irdaconv.sh ; find irda/ -name "*.plot3" | xargs cat > delme.plot ; scp delme.plot abatis.flint:. # extract the unknown rows, #70 and #71, and plot each bit of #70 seperatly, and #71 (which is only ever 4 values) # this hasn't been converted to the new time appended format - have reproduced this in irdaconv.sh and changed to new format. awk -- < grabusage2.txt 'function h2d(a){return strtonum(sprintf("0x%s",a));} { sum=0; for(i=1;i<=NF;i++)if(i!=100)sum+=strtonum(sprintf("0x%s",$i)); if(NF==110 && (sum%256)==strtonum(sprintf("0x%s",$100))){n=strtonum(sprintf("0x%s",$70)); printf "%d\t%d\t %d %d %d %d %d %d %d %d\t%d\t%0.3ff",NR,$42*10000+$43*100+$44,((n/128)%2)+16,((n/64)%2)+14,((n/32)%2)+12,((n/16)%2)+10,((n/8)%2)+8,((n/4)%2)+6,((n/2)%2)+4,((n/1)%2)+2,h2d($71),n*(2^(h2d($71)/32)); } printf "\n"; }' > delme.plot # plot the 8 individual bits echo -e "plot [:] [:] \"delme.plot\" using 1:3 with lines, \"delme.plot\" using 1:4 with lines, \"delme.plot\" using 1:5 with lines, \"delme.plot\" using 1:6 with lines, \"delme.plot\" using 1:7 with lines, \"delme.plot\" using 1:8 with lines, \"delme.plot\" using 1:9 with lines, \"delme.plot\" using 1:9 with lines, \"delme.plot\" using 1:10 with lines, \"delme.plot\" using 1:(\$11/32+20) with lines, \"delme.plot\" using 1:(\$12/32+25) with lines" | gnuplot -persist