package it.angelic.soulissclient.fragments;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Looper;
import android.support.v7.widget.SwitchCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TableRow;
import android.widget.TextView;
import java.util.List;
import it.angelic.soulissclient.Constants;
import it.angelic.soulissclient.R;
import it.angelic.soulissclient.SoulissApp;
import it.angelic.soulissclient.SoulissDataService;
import it.angelic.soulissclient.helpers.AlertDialogHelper;
import it.angelic.soulissclient.model.SoulissNode;
import it.angelic.soulissclient.model.SoulissTypical;
import it.angelic.soulissclient.model.db.SoulissDBHelper;
import it.angelic.soulissclient.model.typicals.SoulissTypical32AirCon;
import it.angelic.soulissclient.net.UDPHelper;
import it.angelic.tagviewlib.SimpleTagRelativeLayout;
import static junit.framework.Assert.assertTrue;
public class T32AirConFragment extends AbstractTypicalFragment {
private SoulissDataService mBoundService;
private boolean mIsBound;
Spinner functionSpinner;
Spinner fanSpiner;
// time based
TextView textviewTemperature;
Spinner spinnerInterval;
// position based
TextView textviewPositional;
SwitchCompat togSwirl;
SwitchCompat togIon;
SwitchCompat togEnergySave;
// data based
TextView textviewTriggered;
Button buttPlus;
Button buttMinus;
Button btOff;
Button btOn;
private SoulissTypical collected;
public static T32AirConFragment newInstance(int index, SoulissTypical content) {
T32AirConFragment f = new T32AirConFragment();
// Supply index input as an argument.
Bundle args = new Bundle();
args.putInt("index", index);
// Ci metto il nodo dentro
if (content != null) {
args.putSerializable("TIPICO", content);
}
f.setArguments(args);
return f;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// tema
if (opzioni.isLightThemeSelected())
getActivity().setTheme(R.style.LightThemeSelector);
else
getActivity().setTheme(R.style.DarkThemeSelector);
super.onActivityCreated(savedInstanceState);
if (!opzioni.isDbConfigured()) {
AlertDialogHelper.dbNotInitedDialog(getActivity());
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
if (container == null)
return null;
opzioni = SoulissApp.getOpzioni();
opzioni.reload();
View ret = inflater.inflate(R.layout.main_aircon, container, false);
SoulissDBHelper datasource = new SoulissDBHelper(getActivity());
SoulissDBHelper.open();
Bundle extras = getActivity().getIntent().getExtras();
if (extras != null && extras.get("TIPICO") != null) {
collected = (SoulissTypical) extras.get("TIPICO");
} else if (getArguments() != null) {
collected = (SoulissTypical) getArguments().get("TIPICO");
} else {
Log.e(Constants.TAG, "Error retriving node:");
return ret;
}
assertTrue("TIPICO NULLO", collected instanceof SoulissTypical32AirCon);
SoulissTypical related = (SoulissTypical) getActivity().getIntent().getExtras().get("RELATO");
if (related == null)
related = datasource.getTypical(collected.getNodeId(), (short) (collected.getSlot() + 1));
collected.setPrefs(opzioni);
super.setCollected(collected);
functionSpinner = (Spinner) ret.findViewById(R.id.spinnerFunction);
fanSpiner = (Spinner) ret.findViewById(R.id.spinnerFan);
// time based
textviewTemperature = (TextView) ret.findViewById(R.id.textviewTemp);
textviewPositional = (TextView) ret.findViewById(R.id.textViewInfoPos);
togSwirl = (SwitchCompat) ret.findViewById(R.id.toggleButtonSwing);
togIon = (SwitchCompat) ret.findViewById(R.id.toggleButtonIon);
togEnergySave = (SwitchCompat) ret.findViewById(R.id.toggleButtonEco);
textviewTriggered = (TextView) ret.findViewById(R.id.textViewInfoTrig);
buttPlus = (Button) ret.findViewById(R.id.buttonPlus);
buttMinus = (Button) ret.findViewById(R.id.buttonMinus);
btOff = (Button) ret.findViewById(R.id.buttonTurnOff);
btOn = (Button) ret.findViewById(R.id.buttonTurnOn);
infoTags = (TableRow) ret.findViewById(R.id.tableRowTagInfo);
tagView = (SimpleTagRelativeLayout) ret.findViewById(R.id.tag_group);
refreshTagsInfo();
// upcast
Integer status = Integer.valueOf(collected.getTypicalDTO().getOutput());
Integer status2 = Integer.valueOf(related.getTypicalDTO().getOutput());
Log.d(Constants.TAG, "Power + opts : 0x" + Integer.toHexString(collected.getTypicalDTO().getOutput()));
Log.d(Constants.TAG, "Function + temp: 0x" + Integer.toHexString(status2));
int fun = (status2 & 0XF0);
int temp = (status2 & 0X0F);
int fan = (status & 0X07);
textviewTemperature.setText("" + demapTemperature(temp));
final int[] spinnerArrVal = getResources().getIntArray(R.array.AirConFanValues);
final int[] spinnerFunVal = getResources().getIntArray(R.array.AirConFunctionValues);
for (int i = 0; i < spinnerFunVal.length; i++) {
if (fun == spinnerFunVal[i])
functionSpinner.setSelection(i);
}
/**
* LISTENER SPINNER DESTINATARIO, IN TESTATA
*/
final OnItemSelectedListener lit = new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// /setTypicalSpinner(outputTypicalSpinner, nodiArray[pos]);
issueIrCommand(buildIrCommand(null));
}
public void onNothingSelected(AdapterView<?> parent) {
}
};
final OnItemSelectedListener lib = new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// if (pos > 0) {
// ArrayList<SoulissTypical> re = nodiArray[(int)
// outputNodeSpinner.getSelectedItemId()].getTypicals();
issueIrCommand(buildIrCommand(null));
}
public void onNothingSelected(AdapterView<?> parent) {
}
};
// avoid auto call upon Creation with runnable
functionSpinner.post(new Runnable() {
public void run() {
functionSpinner.setOnItemSelectedListener(lit);
fanSpiner.setOnItemSelectedListener(lib);
}
});
return ret;
}
@Override
public void onStart() {
super.onStart();
OnClickListener plus = new OnClickListener() {
public void onClick(View v) {
int act = Integer.parseInt(textviewTemperature.getText().toString());
if (act < 30)
textviewTemperature.setText("" + (act + 1));
issueIrCommand(buildIrCommand(null));
}
};
buttPlus.setOnClickListener(plus);
OnClickListener min = new OnClickListener() {
public void onClick(View v) {
int act = Integer.parseInt(textviewTemperature.getText().toString());
if (act > 16)
textviewTemperature.setText("" + (act - 1));
issueIrCommand(buildIrCommand(null));
}
};
buttMinus.setOnClickListener(min);
OnClickListener simpleO = new OnClickListener() {
public void onClick(View v) {
issueIrCommand(buildIrCommand(1));
}
};
btOn.setOnClickListener(simpleO);
// Cancel
OnClickListener simplecan = new OnClickListener() {
public void onClick(View v) {
// T32AirConFragment.this.finish();
issueIrCommand(buildIrCommand(0));
return;
}
};
btOff.setOnClickListener(simplecan);
//setActionBarInfo(collected.getNiceName());
//this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public void onResume() {
super.onResume();
SoulissDBHelper.open();
IntentFilter filtere = new IntentFilter();
filtere.addAction("it.angelic.soulissclient.GOT_DATA");
getActivity().registerReceiver(soulissDataReceiver, filtere);
}
@Override
public void onPause() {
super.onPause();
getActivity().unregisterReceiver(soulissDataReceiver);
}
/**
* Collects options from UI and build a Souliss air conditioner command
*
* @param optTurnon
* @return
*/
private long buildIrCommand(Integer optTurnon) {
final int[] spinnerArrVal = getResources().getIntArray(R.array.AirConFanValues);
final int[] spinnerFunVal = getResources().getIntArray(R.array.AirConFunctionValues);
long firstpar = 0;
// Power ON or OFF
if (optTurnon != null) {
if (optTurnon == 1)
firstpar += 0x8000L;
else
firstpar += 0x4000L;
}
long mask = togIon.isChecked() ? 1 : 0;
firstpar += mask << 13;// third output bit = option 1
mask = togEnergySave.isChecked() ? 1 : 0;
firstpar += mask << 12;// fourth output bit = option2
mask = togSwirl.isChecked() ? 1 : 0;
firstpar += mask << 11;// third output bit = air swing
int fan = spinnerArrVal[fanSpiner.getSelectedItemPosition()] << 8;
firstpar += fan;
int fun = spinnerFunVal[functionSpinner.getSelectedItemPosition()] << 4;
firstpar += fun;
int tmp = remapTemperature(Integer.parseInt(textviewTemperature.getText().toString()));
firstpar += tmp;
Log.d(Constants.TAG, "Sending Aircon command:" + "\nFan: " + fan + "\nFunction: " + fun + "\nTemperat: "
+ tmp + "\nHEX: 0x" + Long.toHexString(firstpar));
return firstpar;
}
/**************************************************************************
* Souliss Air Conditioner command Souliss OUTPUT Data is:
*
* 0xABCD A = 4 bit mask (XYZT X= powerON, Y PowerOFF, option1 , option2) B
* = Fan/Swirl (1bit switch + 3bits for four possible fan values) C =
* Function (auto,cool,dry,fan,heat) D = Temperature (from 16 to 30, see .h)
*
* INPUT data 'read' from GUI
**************************************************************************/
private long issueIrCommand(final long finalCommand) {
Thread t = new Thread() {
public void run() {
Looper.prepare();
// comando da due bytes
// alternativa maschere di bit ma non ho voglia
String pars = Long.toHexString(finalCommand);
String par1, par2;
// i primi 4 bit possono essere tutti a 0
if (pars.length() == 3)
pars = "0" + pars;
par1 = Integer.toString(Integer.parseInt(pars.substring(0, 2), 16));
par2 = Integer.toString(Integer.parseInt(pars.substring(2, 4), 16));
UDPHelper.issueSoulissCommand("" + collected.getParentNode().getNodeId(), ""
+ collected.getTypicalDTO().getSlot(), opzioni, par1, par2);
}
};
t.start();
return finalCommand;
}
// Aggiorna il feedback
private BroadcastReceiver soulissDataReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
SoulissNode coll = collected.getParentNode();
Bundle extras = intent.getExtras();
Bundle vers = (Bundle) extras.get("NODES");
Log.d(Constants.TAG, "Detected data arrival: " + vers.size() + " nodes");
int howmany = extras.getInt("quantity");
// SoulissNode[] numversioni = new SoulissNode[(int) howmany];
int temp = howmany - 1;
//TODO sta qua e` roba vetusta. Controllare
while (temp >= 0) {
SoulissNode temrp = (SoulissNode) vers.getSerializable("" + temp);
temp--;
if (coll.getNodeId() == temrp.getNodeId()) {
// rinfresca padre
coll.setHealth(temrp.getHealth());
coll.setRefreshedAt(temrp.getRefreshedAt());
List<SoulissTypical> tips = temrp.getTypicals();
for (SoulissTypical soulissTypical : tips) {
if (soulissTypical.getTypicalDTO().getSlot() == collected.getTypicalDTO().getSlot()) {
collected = soulissTypical;
// collected.getTypicalDTO().setOutput(soulissTypical.getTypicalDTO().getOutput());
// collected.getTypicalDTO().setRefreshedAt(soulissTypical.getTypicalDTO().getRefreshedAt());
Log.i(Constants.TAG, "AirCon data refreshed");
// TODO setta gli spinner
}
}
}
}
}
};
/**
* Bruttino, ma va ben cosi perche funziona
*
* remaps int value to Souliss AirCon protocol
*
* @param CelsiusIn
* @return
*/
static short remapTemperature(int CelsiusIn) {
switch (CelsiusIn) {
case 16:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_16C;
case 17:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_17C;
case 18:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_18C;
case 19:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_19C;
case 20:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_20C;
case 21:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_21C;
case 22:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_22C;
case 23:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_23C;
case 24:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_24C;
case 25:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_25C;
case 26:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_26C;
case 27:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_27C;
case 28:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_28C;
case 29:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_29C;
case 30:
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_30C;
default:
Log.e(Constants.TAG, "error in temp ecode");
return Constants.Typicals.Souliss_T_IrCom_AirCon_temp_24C;
}
}
/**
* Bruttino, ma va ben cosi perche funziona
*
* remaps int value to Souliss AirCon protocol
*
* @param CelsiusIn
* @return
*/
static short demapTemperature(int CelsiusIn) {
switch (CelsiusIn) {
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_16C:
return 16;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_17C:
return 17;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_18C:
return 18;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_19C:
return 19;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_20C:
return 20;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_21C:
return 21;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_22C:
return 22;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_23C:
return 23;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_24C:
return 24;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_25C:
return 25;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_26C:
return 26;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_27C:
return 27;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_28C:
return 28;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_29C:
return 29;
case Constants.Typicals.Souliss_T_IrCom_AirCon_temp_30C:
return 30;
default:
Log.e(Constants.TAG, "Invalid temperature:" + CelsiusIn);
return 24;
}
}
}