package devices.PZEM004;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;

import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.keywords.Bit;
import anywheresoftware.b4a.objects.collections.Map;

@BA.ShortName("PZEM004T_MeasurenmentData")
public class PZEM004T_MeasurenmentData {
	public double voltage = 0;
	public double current = 0;
	public double power = 0;
	public double energy = 0;
	public double frequency = 0;
	public double powerfactor = 0;
	public boolean alarm_status = false;
	private boolean isvalid =false;
	
	public PZEM004T_MeasurenmentData() {
		isvalid = false;
	}
	
	public PZEM004T_MeasurenmentData(byte[] bb){
		if (bb!=null) {
			int bblength = bb.length;
			int numbytes = bb[2];
			if (bblength == (numbytes+5)) {
				// 1 slave id, 1 command, 1 number of bytes, 2 crc == 5
				ByteBuffer bx = ByteBuffer.allocate(numbytes);
				bx.put(bb, 3, numbytes);
				bx.rewind();
				bx.order(ByteOrder.BIG_ENDIAN);
				ShortBuffer sx = bx.asShortBuffer();
				int volt = Bit.And(sx.get(), 0xFFFF);
				int cur_L = Bit.And(sx.get(), 0xFFFF);
				int cur_H = Bit.And(sx.get(), 0xFFFF);
				int pow_L = Bit.And(sx.get(), 0xFFFF);
				int pow_H = Bit.And(sx.get(), 0xFFFF);
				int ene_L = Bit.And(sx.get(), 0xFFFF);
				int ene_H = Bit.And(sx.get(), 0xFFFF);
				int freq = Bit.And(sx.get(), 0xFFFF);
				int pf = Bit.And(sx.get(), 0xFFFF);
				int alm = Bit.And(sx.get(), 0xFFFF);
			
				voltage = volt / 10.0;
				current = ((cur_H << 16) | (cur_L)) /1000.0;
				power = ((pow_H << 16) | (pow_L)) / 10.0;
				energy = ((ene_H << 16) | (ene_L));
				frequency = freq / 10.0;
				powerfactor = pf / 100.0;
				alarm_status = (alm == 0 ? false:true);
				
				isvalid = true;
			}
		}
		
	}
	
	/**
	 * Get Voltage in String
	 * @return N/A if not available
	 */
	public String getVoltageString() {
		if (isvalid) {
			return voltage+" V";
		} else return "N/A";
	}
	
	/**
	 * Get Current in String
	 * @return N/A if not available
	 */
	public String getCurrentString() {
		if (isvalid) {
			return current+" A";
		} else return "N/A";
	}
	
	/**
	 * Get Power in String
	 * @return N/A if not available
	 */
	public String getPowerString() {
		if (isvalid) {
			return power+" W";
		} else return "N/A";
	}
	
	/**
	 * Get Energy Consumption in String
	 * @return N/A if not available
	 */
	public String getEnergyString() {
		if (isvalid) {
			return energy+" Wh";
		} else return "N/A";
	}
	
	/**
	 * Get AC Frequency in String
	 * @return N/A if not available
	 */
	public String getFrequencyString() {
		if (isvalid) {
			return frequency+" Hz";
		} else return "N/A";
	}
	
	/**
	 * Get Power Factor in String
	 * @return N/A if not available
	 */
	public String getPowerFactorString() {
		if (isvalid) {
			return String.valueOf(powerfactor);
		} else return "N/A";
	}
	
	/**
	 * Return Summary in String
	 */
	public String toString() {
		StringBuilder str = new StringBuilder();
		str.append("V=").append(voltage).append(" V,");
		str.append("A=").append(current).append(" A,");
		str.append("P=").append(power).append(" W,");
		str.append("E=").append(energy).append(" Wh,");
		str.append("F=").append(frequency).append(" Hz,");
		str.append("pf=").append(powerfactor).append(",");
		str.append("Alarm=").append(alarm_status);
		
		return str.toString();
	}
	
	/**
	 * Check if values is valid
	 * @return true if valid
	 */
	public boolean IsValidMeasurement() {
		return isvalid;
	}
	
	/**
	 * Create values in JSON Map
	 * @return Map value
	 */
	public Map MakeJsonMap() {
		Map result = new Map();
		result.Initialize();
		result.Put("VoltageString", this.getVoltageString());
		result.Put("CurrentString", this.getCurrentString());
		result.Put("PowerString", this.getPowerString());
		result.Put("EnergyString", this.getEnergyString());
		result.Put("FrequencyString", this.getFrequencyString());
		result.Put("PowerFactorString", this.getPowerFactorString());
		return result;
	}
}
