/*
 * peaktech3315.cpp
 * by Bernd Herd (C) 2009 (herdsoft.com)
 *
 * Interprets serial data from a PeakTech 3315 DMM to bring it
 * into a CSV format readable by openoffice 3.x
 *
 * This program expects input data in stdin to work as a filter,
 * for example by:
 *
 * ./hoitek /dev/hidraw1 | ./peaktech3315
 *
 * Format is according to:http://www.mikrocontroller.net/topic/98208
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */



#include <stdio.h>
#if 0
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>
#endif
#include <sys/time.h>
#include <stdlib.h>
#include <string.h>
#include <string>

std::string &
insertComma(std::string &str, int pos)
{
  str.insert(pos+2, ".");
  return str;
}


void static
Interpret_PeakTech_3315(const char *pStr)
{
 std::string val;
  std::string special;
  std::string unit;
  double scale = 1.0;
  double value;

  int i, dp;
  
  unit = "UNKNOWN";
  dp = pStr[5] - '0';
  scale = 1.0;
  if (pStr[6] & 4) // Sign
    {
      val = " -";
    }
  else
    {
      val = "  ";
    }

  val += pStr[1];
  val += pStr[2];
  val += pStr[3];
  val += pStr[4];
  if (!memcmp(pStr+1, "4000", 4) ||
      (pStr[6] & 1)!=0 )
    {
      val = "    0L";
    }

  // Function
  switch (pStr[5])
    {
    case 0x31:
      unit = "D";
      break;

    case 0x3b:
      unit = "V";
      switch (pStr[0]) // Range
        {
        case '0':
          unit = "mV";
          scale = 1e-3;
          val = insertComma(val, 3);
          break;
        case '1':
          val = insertComma(val, 1);
          break;
        case '2':
          val = insertComma(val, 2);
          break;
        case '3':
          val = insertComma(val, 3);
          break;
        }
      break;
    case 0x3d:
      unit = "uA";
      scale = 1e-6;
      switch (pStr[0]) // Range
        {
        case '0':
          val = insertComma(val, 3);
          break;
        }
      break;
    case 0x39:
      unit = "mA";
      scale = 1e-3;
      switch (pStr[0]) // Range
        {
        case '0':
          val = insertComma(val, 2);
          break;
        case '1':
          val = insertComma(val, 3);
          break;
        }
      break;
    case 0x33:
      unit = "kOhm";
      switch (pStr[0]) // Range
        {
        case '0':
          unit = "Ohm";
          val = insertComma(val, 3);
          break;
        case '1':
          scale = 1e3;
          val = insertComma(val, 1);
          break;
        case '2':
          scale = 1e3;
          val = insertComma(val, 2);
          break;
        case '3':
          scale = 1e3;
          val = insertComma(val, 3);
          break;
        case '4':
          unit = "MOhm";
          scale = 1e6;
          val = insertComma(val, 1);
          break;
        case '5':
          unit = "MOhm";
          scale = 1e6;
          val = insertComma(val, 2);
          break;
        }
      break;
    case 0x34:
      unit = (pStr[6] & 8) ? "C" : "F";
      break;
    case 0x3f:
      unit = "A";
      val = insertComma(val, 2);
      break;
    case 0x32:
      switch (pStr[0]) // Range
        {
        case '0':
          unit = "kHz";
          scale = 1e3;
          val = insertComma(val, 1);
          break;
        case '1':
          unit = "kHz";
          scale = 1e3;
          val = insertComma(val, 2);
          break;
        case '2':
          unit = "kHz";
          scale = 1e3;
          val = insertComma(val, 3);
          break;
        case '3':
          unit = "MHz";
          scale = 1e6;
          val = insertComma(val, 1);
          break;
        case '4':
          unit = "MHz";
          scale = 1e6;
          val = insertComma(val, 2);
          break;
        case '5':
          unit = "MHz";
          scale = 1e6;
          val = insertComma(val, 3);
          break;
        }
      break;
    case 0x36:
      switch (pStr[0]) // Range
        {
        case '0':
          unit = "nF";
          scale = 1e-9;
          val = insertComma(val, 1);
          break;
        case '1':
          unit = "nF";
          scale = 1e-9;
          val = insertComma(val, 2);
          break;
        case '3':
          unit = "nF";
          scale = 1e-9;
          val = insertComma(val, 3);
          break;
        case '4':
          unit = "uF";
          scale = 1e-6;
          val = insertComma(val, 1);
          break;
        case '5':
          unit = "uF";
          scale = 1e-6;
          val = insertComma(val, 2);
          break;
        case '6':
          unit = "uF";
          scale = 1e-6;
          val = insertComma(val, 3);
          break;
        case '7':
          unit = "mF";
          scale = 1e-3;
          val = insertComma(val, 1);
          break;
        }
      break;
    }

  if (pStr[8] & 4)
    {
      special += "AC";
    }
  else if (pStr[8] & 8)
    {
      special += "DC";
    }

  setlocale(LC_NUMERIC, "C");
  value = atof(val.c_str()) * scale;

  time_t time_t_now = time(NULL);
  struct tm *tm_now=localtime( &time_t_now );
  char strTime[50];
  strftime(strTime, sizeof(strTime), "%F %T", tm_now);
  //sprintf(t->reading, "%s %s", val.c_str(), t->unit.c_str());
  
  
  setlocale(LC_NUMERIC, "");

  printf("%s\t%s\t%e\t%s\t%s\n", val.c_str(), unit.c_str(), value, strTime, pStr);
}




int
main()
{
  char line[11];
  
  while (fgets(line, sizeof(line), stdin))
    {
      if (strlen(line)>=10)
        {
          Interpret_PeakTech_3315(line);
          fflush(stdout);
        }
    }
	return 0;
}
