#!/bin/sh
#
# Get temperature from a Dlink DNS-320's microcontroller
#
# Copyright (C) 2012 Jamie Lentin <jm@lentin.co.uk>
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.

[ "$1" = "-v" ] && verbose=1

unset LANG # A UTF-8 LANG will cause bashes read to read multibyte characters
IFS=''	# Stop read treating " " as a field separator

# Set up serial port
stty -F /dev/ttyS1 cs8 -cstopb -crtscts -ixon -ixoff -ignpar cread 19200

(
  # Wait for main thread to be ready before issuing command
  sleep 1
  # D-link did "sleep 0.2s" between each of these, doesn't seem to help
  echo -ne "\xf0\xf0\x10\x04\x02"
  echo -ne "\x00\x00\x00\x00"
  echo -ne "\x00\x00\x00\x00"
  echo -ne "\xf6\xf6\xf6"
) >/dev/ttyS1 &

(
  pos=0
  temp=0
  ch=0 ; p1=0 ; p2=0
  while read  -r -n 1 -t 2 -s raw; do
ch=$(printf "%d" "'$raw")
    [ -n "$verbose" ] && debug="`printf "$debug %x" $ch`"
    
    # If have initial 0xf0 0xf0 0xd0, then know where temperature is
    [ "$pos" = "2" -a "$p2" -eq "240" \
                   -a "$p1" -eq "240" \
                   -a "$ch" -eq "208" ] && packet="std"
    [ "$pos" = "5" -a "$packet" = "std" ] && temp=$ch
    
    # Three equal non-null bytes is the checksum at the end
    [ "$ch" -gt "0" -a "$p2" -eq "$ch" \
                    -a "$p1" -eq "$ch" ] && { checksum="$ch"; break; }
    pos=$(($pos+1))
    p2=$p1
    p1=$ch
  done
  [ -n "$verbose" ] && printf "debug: $debug\n" 1>&2
  if [ "$temp" -gt "0" ]; then
    # Got a temperature
    echo $temp
  elif [ -n "$checksum" ]; then
    # Found a checksum that tells us the temperature
    echo $(($checksum-182)) 
  else
echo "Unknown response: $debug" 1>&2
  fi
) </dev/ttyS1
