package com.openvehicles.OVMS.entities;
import android.content.Context;
import android.util.Log;
import com.google.gson.Gson;
import com.openvehicles.OVMS.BaseApp;
import com.openvehicles.OVMS.R;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.TimeZone;
/**
* Created by balzer on 07.03.15.
*
* This is the model for LogsFragment.
*
* It's currently designed to meet the storage requirements for the
* SEVCON diagnostic logs as supported by the Twizy firmware,
* but can be used as a container for other vehicles and/or logs.
*
*/
public class LogsData {
private static final transient String TAG = "LogsData";
//
// Storage classes:
//
static public class KeyTime {
public int keyHour;
public int keyMinSec;
public Date timeStamp;
public String fmtKeyTime() {
int days = keyHour / 24;
int hours = keyHour % 24;
int mins = (keyMinSec * 15) / 60;
int secs = (keyMinSec * 15) % 60;
return context.getString(R.string.logs_fmt_keytime,
days, hours, mins, secs);
}
public String fmtTimeStamp() {
return (timeStamp != null)
? DateFormat.getDateTimeInstance().format(timeStamp)
: "-";
}
}
static public class Alert {
public String code;
public String description;
}
static public class Event {
public String code;
public String description;
public KeyTime time;
public String data[];
}
static public class Counter {
public String code;
public String description;
public KeyTime lastTime;
public KeyTime firstTime;
public int count;
}
static public class MinMax {
public Double
batteryVoltageMin,
batteryVoltageMax,
capacitorVoltageMin,
capacitorVoltageMax;
public int
motorCurrentMin,
motorCurrentMax,
motorSpeedMin,
motorSpeedMax,
deviceTempMin,
deviceTempMax;
public String getSensor(int nr) {
switch (nr) {
case 0:
return batteryVoltageMin.toString();
case 1:
return batteryVoltageMax.toString();
case 2:
return capacitorVoltageMin.toString();
case 3:
return capacitorVoltageMax.toString();
case 4:
return "" + motorCurrentMin;
case 5:
return "" + motorCurrentMax;
case 6:
return "" + motorSpeedMin;
case 7:
return "" + motorSpeedMax;
case 8:
return "" + deviceTempMin;
case 9:
return "" + deviceTempMax;
default:
return "";
}
}
}
//
// System environment:
//
private transient static final Context context = BaseApp.getApp();
private transient static final Gson gson = new Gson();
//
// Storage data:
//
public String vehicleId;
public KeyTime keyTime;
public ArrayList<Alert> alerts;
public KeyTime alertsTime;
public ArrayList<Event> faultEvents;
public KeyTime faultEventsTime;
public ArrayList<Event> systemEvents;
public KeyTime systemEventsTime;
public ArrayList<Counter> counters;
public KeyTime countersTime;
public ArrayList<MinMax> minMaxes;
public KeyTime minMaxesTime;
//
// Methods
//
public LogsData() {
vehicleId = "";
keyTime = new KeyTime();
alerts = new ArrayList<Alert>();
alertsTime = new KeyTime();
faultEvents = new ArrayList<Event>();
faultEventsTime = new KeyTime();
systemEvents = new ArrayList<Event>();
systemEventsTime = new KeyTime();
counters = new ArrayList<Counter>();
countersTime = new KeyTime();
minMaxes = new ArrayList<MinMax>();
minMaxesTime = new KeyTime();
}
public static LogsData loadFile(String vehicleId) {
FileInputStream inputStream;
String filename = "logsdata-" + vehicleId + "-default.json";
Log.v(TAG, "loading from file: " + filename);
try {
inputStream = context.openFileInput(filename);
InputStreamReader isr = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
String json = sb.toString();
return gson.fromJson(json, LogsData.class);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public boolean saveFile(String vehicleId) {
FileOutputStream outputStream;
String filename = "logsdata-" + vehicleId + "-default.json";
Log.v(TAG, "saving to file: " + filename);
this.vehicleId = vehicleId;
String json = gson.toJson(this);
try {
outputStream = context.openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(json.getBytes());
outputStream.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public void processCmdResults(CmdSeries cmdSeries) {
int recNr, recCnt;
String recType, timeStamp;
int entryNr;
SimpleDateFormat serverTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
serverTime.setTimeZone(TimeZone.getTimeZone("UTC"));
for (int i=0; i < cmdSeries.size(); i++) {
CmdSeries.Cmd cmd = cmdSeries.get(i);
if (cmd.commandCode != 32)
continue;
for (int resNr=0; resNr < cmd.results.size(); resNr++) {
String result[] = cmd.results.get(resNr);
if (result[2].equals("No historical data available"))
continue;
try {
recNr = Integer.parseInt(result[2]);
recCnt = Integer.parseInt(result[3]);
recType = result[4];
timeStamp = result[5];
entryNr = Integer.parseInt(result[6]);
// [7++] = Payload
Log.v(TAG, "processing recType " + recType + " entryNr " + entryNr);
if (recType.equals("RT-ENG-LogKeyTime")) {
keyTime = new KeyTime();
keyTime.keyHour = Integer.parseInt(result[7]);
keyTime.keyMinSec = Integer.parseInt(result[8]);
try {
keyTime.timeStamp = serverTime.parse(timeStamp);
} catch (Exception e) {
keyTime.timeStamp = new Date();
}
} else if (recType.equals("RT-ENG-LogAlerts")) {
if (entryNr == 0) {
alerts = new ArrayList<Alert>(20);
alertsTime = keyTime;
}
Alert alert = new Alert();
alert.code = result[7];
alert.description = result[8];
alerts.add(alert);
} else if (recType.equals("RT-ENG-LogFaults")) {
if (entryNr == 0) {
faultEvents = new ArrayList<Event>(40);
faultEventsTime = keyTime;
}
Event event = new Event();
event.code = result[7];
event.description = result[8];
event.time = new KeyTime();
event.time.keyHour = Integer.parseInt(result[9]);
event.time.keyMinSec = Integer.parseInt(result[10]);
event.data = new String[3];
event.data[0] = result[11];
event.data[1] = result[12];
event.data[2] = result[13];
faultEvents.add(event);
} else if (recType.equals("RT-ENG-LogSystem")) {
if (entryNr == 0) {
systemEvents = new ArrayList<Event>(20);
systemEventsTime = keyTime;
}
Event event = new Event();
event.code = result[7];
event.description = result[8];
event.time = new KeyTime();
event.time.keyHour = Integer.parseInt(result[9]);
event.time.keyMinSec = Integer.parseInt(result[10]);
event.data = new String[3];
event.data[0] = result[11];
event.data[1] = result[12];
event.data[2] = result[13];
systemEvents.add(event);
} else if (recType.equals("RT-ENG-LogCounts")) {
if (entryNr == 0) {
counters = new ArrayList<Counter>(10);
countersTime = keyTime;
}
Counter counter = new Counter();
counter.code = result[7];
counter.description = result[8];
counter.lastTime = new KeyTime();
counter.lastTime.keyHour = Integer.parseInt(result[9]);
counter.lastTime.keyMinSec = Integer.parseInt(result[10]);
counter.firstTime = new KeyTime();
counter.firstTime.keyHour = Integer.parseInt(result[11]);
counter.firstTime.keyMinSec = Integer.parseInt(result[12]);
counter.count = Integer.parseInt(result[13]);
counters.add(counter);
} else if (recType.equals("RT-ENG-LogMinMax")) {
if (entryNr == 0) {
minMaxes = new ArrayList<MinMax>(2);
minMaxesTime = keyTime;
}
MinMax minMax = new MinMax();
minMax.batteryVoltageMin = Double.parseDouble(result[7]) / 16;
minMax.batteryVoltageMax = Double.parseDouble(result[8]) / 16;
minMax.capacitorVoltageMin = Double.parseDouble(result[9]) / 16;
minMax.capacitorVoltageMax = Double.parseDouble(result[10]) / 16;
minMax.motorCurrentMin = Integer.parseInt(result[11]);
minMax.motorCurrentMax = Integer.parseInt(result[12]);
minMax.motorSpeedMin = Integer.parseInt(result[13]);
minMax.motorSpeedMax = Integer.parseInt(result[14]);
minMax.deviceTempMin = Integer.parseInt(result[15]);
minMax.deviceTempMax = Integer.parseInt(result[16]);
minMaxes.add(minMax);
}
} catch (Exception e) {
// most probably parse error, skip row
e.printStackTrace();
}
}
}
Log.v(TAG, "processCmdResults done");
}
}