private VType decodeValue(final String[] columns, final Timestamp ts) throws Exception {
    Time time = ValueFactory.newTime(ts);
    Alarm alarm = ValueFactory.alarmNone();
    String alarmStr = columns[severity];
    if (alarmStr != null) {
      for (AlarmSeverity s : AlarmSeverity.values()) {
        if (alarmStr.startsWith(s.name())) {
          alarm = ValueFactory.newAlarm(s, alarmStr);
          break;
        }
      }
    }
    Display display = ValueFactory.displayNone();

    // Determine the value type
    // Try double
    if (columns[float_val] != null && !columns[float_val].isEmpty()) {
      Double dbl0 = Double.valueOf(columns[float_val]);
      // Get array elements - if any.
      final double data[] = readBlobArrayElements(dbl0, columns);
      if (data.length == 1) {
        return ValueFactory.newVDouble(data[0], alarm, time, display);
      } else {
        return ValueFactory.newVDoubleArray(new ArrayDouble(data), alarm, time, display);
      }
    }

    // Try integer
    if (columns[num_val] != null && !columns[num_val].isEmpty()) {
      final int num = Integer.valueOf(columns[num_val]);
      return ValueFactory.newVInt(num, alarm, time, display);
    }

    // Default to string
    final String txt = columns[str_val];
    return ValueFactory.newVString(txt, alarm, time);
  }