package Dialog; import android.app.Activity; import android.app.Dialog; import android.content.Intent; import android.content.SharedPreferences; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import org.domogik.domodroid13.R; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import activities.Activity_Main; import database.Cache_management; import database.DomodroidDB; import misc.tracerengine; import rinor.Rest_com; public class Dialog_Synchronize extends Dialog implements OnClickListener { private final Button cancelButton; private final TextView message; private String urlAccess; private SharedPreferences.Editor prefEditor; private static Handler handler = null; private SharedPreferences params; private LoadConfig sync; public Boolean need_refresh = false; private final Activity activity; public Boolean reload = false; private DomodroidDB db = null; private tracerengine Tracer = null; private final String mytag = this.getClass().getName(); private float previous_api_version = 0f; private boolean by_usage; private int progress; private String last_device_update; public Dialog_Synchronize(tracerengine Trac, final Activity activity, SharedPreferences params) { super(activity); this.activity = activity; this.Tracer = Trac; this.params = params; requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.dialog_synchronize); message = (TextView) findViewById(R.id.message); cancelButton = (Button) findViewById(R.id.CancelButton); cancelButton.setOnClickListener(this); last_device_update = params.getString("last_device_update", "1900-01-01 00:00:00"); handler = new Handler() { @Override public void handleMessage(Message msg) { try { String loc_Value = msg.getData().getString("message"); switch (loc_Value) { case "sync_done": sync.cancel(true); dismiss(); return; case "conn_error": message.setText(R.string.sync_rinor_error); return; case "2_area": message.setText(R.string.sync_2_error_area); return; case "2_room": message.setText(R.string.sync_2_error_room); return; case "2_feature": message.setText(R.string.sync_2_error_feature); return; case "2_feature_association": message.setText(R.string.sync_2_error_feature); return; case "2_ui_config": message.setText(R.string.sync_2_error_ui); return; case "3_feature": message.setText(R.string.sync_3_error_feature); return; case "device": message.setText(R.string.sync_4_error_device); return; case "datatype": message.setText(R.string.sync_4_error_datatype); return; } } catch (Exception e) { Tracer.e(mytag, e.toString()); message.setText(R.string.connection_error); } message.setText(R.string.connection_error); } }; } public void onClick(View v) { if (v == cancelButton) need_refresh = false; sync.cancel(true); dismiss(); } public void setParams(SharedPreferences params) { this.params = params; } public void startSync() { sync = new LoadConfig(); sync.execute(); } public class LoadConfig extends AsyncTask<Void, Integer, Void> { private final boolean sync = false; public LoadConfig() { super(); prefEditor = params.edit(); urlAccess = params.getString("rinor_IP", "1.1.1.1") + ":" + params.getString("rinorPort", "40405") + params.getString("rinorPath", "/"); urlAccess = urlAccess.replaceAll("[\r\n]+", ""); //Try to solve #1623 urlAccess = urlAccess.replaceAll(" ", "%20"); //todo try to see if this might help for all case // urlAccess=URLEncoder.encode(urlAccess); String format_urlAccess; //add a '/' at the end of the IP address if (urlAccess.lastIndexOf("/") == urlAccess.length() - 1) format_urlAccess = urlAccess; else format_urlAccess = urlAccess.concat("/"); prefEditor.putString("URL", format_urlAccess); prefEditor.commit(); urlAccess = params.getString("URL", "1.1.1.1"); if (db == null) db = new DomodroidDB(Tracer, activity, params); try { previous_api_version = params.getFloat("API_VERSION", 0); Tracer.d(mytag, "Previous Api version value exist"); } catch (Exception e) { e.printStackTrace(); Tracer.d(mytag, "Can't grab previous value"); } try { by_usage = params.getBoolean("BY_USAGE", false); Tracer.d(mytag, "Previous by usage value exist"); } catch (Exception e) { by_usage = true; e.printStackTrace(); Tracer.d(mytag, "Can't grab previous value of by usage"); } } @Override protected void onPreExecute() { message.setText(activity.getString(R.string.sync_0)); super.onPreExecute(); } @Override protected void onPostExecute(Void result) { if (sync) { Intent reload = new Intent(activity, Activity_Main.class); activity.startActivity(reload); } super.onPostExecute(result); } @Override protected void onProgressUpdate(Integer... values) { message.setText(String.format("%s %d%%", activity.getString(R.string.sync_load), values[0])); super.onProgressUpdate(values); } /* (non-Javadoc) * @see android.os.AsyncTask#doInBackground(Params[]) */ @Override protected Void doInBackground(Void... param_void) { //Requests // if API rinor >0.5 génération auto sinon classic JSONObject json_rinor; String mytag = "Dialog_Synchronize"; try { json_rinor = Rest_com.connect_jsonobject(activity, Tracer, "", 30000); publishProgress(2); } catch (Exception e) { Tracer.e(mytag, "Error connecting to rinor"); json_rinor = null; } if (json_rinor == null || json_rinor.toString().equals("{}")) { //Cannot connect to server... Bundle b = new Bundle(); //Notify error to parent Dialog b.putString("message", "conn_error"); Message msg = new Message(); msg.setData(b); handler.sendMessage(msg); return null; } String Rinor_Api_ver = ""; try { Rinor_Api_ver = json_rinor.getJSONObject("info").getString("REST_API_version"); publishProgress(4); } catch (Exception e) { try { Rinor_Api_ver = json_rinor.getJSONArray("rest").getJSONObject(0).getJSONObject("info").getString("REST_API_version"); } catch (Exception e1) { Tracer.e(mytag, "ERROR getting Rest version"); } } Tracer.i(mytag, "RinorAPI= " + Rinor_Api_ver); Float Rinor_Api_Version = Float.valueOf(Rinor_Api_ver); String domogik_Version = ""; try { domogik_Version = json_rinor.getJSONObject("info").getString("Domogik_version"); publishProgress(6); } catch (Exception e) { try { domogik_Version = json_rinor.getJSONArray("rest").getJSONObject(0).getJSONObject("info").getString("Domogik_version"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } } Tracer.i(mytag, "domogik_Version= " + domogik_Version); JSONObject json_AreaList = null; JSONObject json_RoomList = null; JSONObject json_FeatureList = null; JSONObject device_feature1; JSONArray json_FeatureList1 = null; JSONObject json_Sensors = null; JSONObject json_Commands = null; JSONObject json_FeatureAssociationList = null; JSONObject json_IconList = null; Tracer.i(mytag, "urlAccess = <" + urlAccess + ">"); publishProgress(8); // grab a new method if sync by past that only erase what concern area id 1 if previous api >0.6f // and if syncing with the same api version if ((previous_api_version == Rinor_Api_Version) && (Rinor_Api_Version >= 0.6f)) { // Erase in tables only device/usage list ! // surround with a try catch due to possible error in previous sync try { if (reload) { //Reload is defined by activity_main if user reload from previous settings //Erase all data in this case before reload value from file db.updateDb(); // todo call a method to load saved preferences map_feature to db try { json_AreaList = new JSONObject(params.getString("AREA_LIST", null)); db.insertArea(json_AreaList); Tracer.d(mytag, "inserting area to db"); } catch (Throwable t) { Tracer.e(mytag, "Could not parse malformed area JSON: \"" + params.getString("AREA_LIST", null) + "\""); } try { json_RoomList = new JSONObject(params.getString("ROOM_LIST", null)); db.insertRoom(json_RoomList); Tracer.d(mytag, "inserting room to db"); } catch (Throwable t) { Tracer.e(mytag, "Could not parse malformed room JSON: \"" + params.getString("ROOM_LIST", null) + "\""); } try { json_IconList = new JSONObject(params.getString("ICON_LIST", null)); db.insertIcon(json_IconList); Tracer.d(mytag, "inserting icon to db"); } catch (Throwable t) { Tracer.e(mytag, "Could not parse malformed icon JSON: \"" + params.getString("ICON_LIST", null) + "\""); } try { json_FeatureAssociationList = new JSONObject(params.getString("FEATURE_LIST_association", null)); db.insertFeatureAssociation(json_FeatureAssociationList); Tracer.d(mytag, "inserting FeatureAssociationList to db"); } catch (Throwable t) { Tracer.e(mytag, "Could not parse malformed feature association JSON: \"" + params.getString("FEATURE_LIST_association", null) + "\""); } } db.NewsyncDb(); Tracer.i(mytag, "Doing a sync update only, not erasing all"); publishProgress(10); } catch (Exception e) { Tracer.e(mytag, e.toString()); db.updateDb(); Tracer.i(mytag, "Doing a full sync, erasing all !!!"); } } else { //Erase all tables contents EXCEPT maps coordinates ! db.updateDb(); Tracer.i(mytag, "Doing a full sync, erasing all !!!"); publishProgress(10); } if (Rinor_Api_Version <= 0.5f) { json_AreaList = Rest_com.connect_jsonobject(activity, Tracer, "base/area/list/", 30000); if (json_AreaList == null || json_AreaList.toString().equals("{}")) { //Cannot connect to server... Bundle b = new Bundle(); //Notify error to parent Dialog b.putString("message", "2_base"); Message msg = new Message(); msg.setData(b); handler.sendMessage(msg); return null; } Tracer.d(mytag, "AreaList = <" + json_AreaList.toString() + ">"); publishProgress(20); json_RoomList = Rest_com.connect_jsonobject(activity, Tracer, "base/room/list/", 30000); if (json_RoomList == null || json_RoomList.toString().equals("{}")) { //Cannot connect to server... Bundle b = new Bundle(); //Notify error to parent Dialog b.putString("message", "2_room"); Message msg = new Message(); msg.setData(b); handler.sendMessage(msg); return null; } Tracer.d(mytag, "RoomList = <" + json_RoomList.toString() + ">"); publishProgress(40); json_FeatureList = Rest_com.connect_jsonobject(activity, Tracer, "base/feature/list", 30000); if (json_FeatureList == null || json_FeatureList.toString().equals("{}")) { //Cannot connect to server... Bundle b = new Bundle(); //Notify error to parent Dialog b.putString("message", "2_feature"); Message msg = new Message(); msg.setData(b); handler.sendMessage(msg); return null; } publishProgress(60); json_FeatureAssociationList = Rest_com.connect_jsonobject(activity, Tracer, "base/feature_association/list/", 30000); if (json_FeatureAssociationList == null || json_FeatureAssociationList.toString().equals("{}")) { //Cannot connect to server... Bundle b = new Bundle(); //Notify error to parent Dialog b.putString("message", "2_feature_association"); Message msg = new Message(); msg.setData(b); handler.sendMessage(msg); return null; } publishProgress(80); json_IconList = Rest_com.connect_jsonobject(activity, Tracer, "base/ui_config/list/", 30000); if (json_IconList == null || json_IconList.toString().equals("{}")) { //Cannot connect to server... Bundle b = new Bundle(); //Notify error to parent Dialog b.putString("message", "2_ui_config"); Message msg = new Message(); msg.setData(b); handler.sendMessage(msg); return null; } publishProgress(90); } else if (Rinor_Api_Version <= 0.6f) { // Function special Basilic domogik 0.3 json_FeatureList = Rest_com.connect_jsonobject(activity, Tracer, "base/feature/list", 30000); if (json_FeatureList == null || json_FeatureList.toString().equals("{}")) { // Cannot connect to Rinor server..... Bundle b = new Bundle(); //Notify error to parent Dialog b.putString("message", "3_feature"); Message msg = new Message(); msg.setData(b); handler.sendMessage(msg); return null; } publishProgress(25); //Create JSONObject json_RoomList = new JSONObject(); json_FeatureAssociationList = new JSONObject(); json_AreaList = new JSONObject(); JSONObject map_area = new JSONObject(); JSONObject area = new JSONObject(); //Create JSONArray JSONArray list = new JSONArray(); JSONArray rooms = new JSONArray(); JSONArray ListFeature = new JSONArray(); //Create string String usage; //Create an ArrayList ArrayList<String> list_usage = new ArrayList<>(); try { json_AreaList.put("status", "OK"); json_AreaList.put("code", 0); json_AreaList.put("description", "None"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { map_area.put("description", ""); map_area.put("id", "1"); map_area.put("name", "Usage"); list.put(map_area); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { json_AreaList.put("area", list); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } publishProgress(45); try { json_RoomList.put("status", "OK"); json_RoomList.put("code", 0); json_RoomList.put("description", "None"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { area.put("description", ""); area.put("id", "1"); area.put("name", "Usage"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } int numberofroom = db.requestidlastRoom(); int j = numberofroom + 1; try { json_FeatureAssociationList.put("status", "OK"); json_FeatureAssociationList.put("code", "0"); json_FeatureAssociationList.put("description", ""); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } publishProgress(55); int list_size = 0; if (json_FeatureList != null) try { list_size = json_FeatureList.getJSONArray("feature").length(); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } Tracer.d(mytag, "Features list size = " + list_size); //correct a bug #2020 if device is empty. for (int i = 0; i < list_size; i++) { try { usage = json_FeatureList.getJSONArray("feature").getJSONObject(i) .getJSONObject("device").getString("device_usage_id"); } catch (Exception e) { usage = null; // Cannot parse JSON Array or JSONObject Tracer.e(mytag, "Exception processing Features list (" + i + ")"); Tracer.e(mytag, e.toString()); } Tracer.i(mytag, "Features list processing usage = <" + usage + ">"); // Create a pseudo 'room' for each usage returned by Rinor if (usage != null) { if (!list_usage.contains(usage)) { try { if (json_FeatureList.getJSONArray("feature").length() > 0) { progress = 100 * i / json_FeatureList.getJSONArray("feature").length(); publishProgress(progress); JSONObject room = new JSONObject(); room.put("area_id", "1"); room.put("description", ""); room.put("area", area); room.put("id", j); j++; room.put("name", json_FeatureList.getJSONArray("feature").getJSONObject(i).getJSONObject("device").getString("device_usage_id")); rooms.put(room); list_usage.add(json_FeatureList.getJSONArray("feature").getJSONObject(i).getJSONObject("device").getString("device_usage_id")); } } catch (JSONException e) { Tracer.e(mytag, e.toString()); } } // And its associated widget JSONObject Widget = new JSONObject(); try { Widget.put("place_type", "room"); //#85 here, place_id was false. Widget.put("place_id", numberofroom + list_usage.indexOf( json_FeatureList.getJSONArray("feature").getJSONObject(i).getJSONObject("device").getString("device_usage_id")) + 1); //id_rooms); Widget.put("device_feature_id", json_FeatureList.getJSONArray("feature").getJSONObject(i).getString("id")); Widget.put("id", 50 + i); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } JSONObject device_feature = new JSONObject(); try { device_feature.put("device_feature_model_id", json_FeatureList.getJSONArray("feature").getJSONObject(i).getString("device_feature_model_id")); device_feature.put("id", json_FeatureList.getJSONArray("feature").getJSONObject(i).getString("id")); device_feature.put("device_id", json_FeatureList.getJSONArray("feature").getJSONObject(i).getString("device_id")); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } try { Widget.put("device_feature", device_feature); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } ListFeature.put(Widget); } } // for loop on feature list... //Prepare list of rooms, and list of usable features try { json_RoomList.putOpt("room", rooms); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } try { json_FeatureAssociationList.putOpt("feature_association", ListFeature); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } } else if (Rinor_Api_Version >= 0.7f) { //TODO lot of work on this. // Function special Domogik 0.4 //get value from rest. try { String MQaddress = json_rinor.getJSONObject("mq").getString("ip"); String MQsubport = json_rinor.getJSONObject("mq").getString("sub_port"); String MQpubport = json_rinor.getJSONObject("mq").getString("pub_port"); String MQreq_repport = json_rinor.getJSONObject("mq").getString("req_rep_port"); prefEditor.putString("MQaddress", MQaddress); // #103 if MQadress=localhost if (MQaddress.equals("localhost") || MQaddress.equals("127.0.0.1") || MQaddress.equals("0.0.0.0")) { activity.runOnUiThread(new Runnable() { public void run() { Toast.makeText(activity, R.string.mq_domogik_conf_localhost, Toast.LENGTH_LONG).show(); } }); //MQaddress = ""; //TODO save it as empty or just tell user the MQ will not work? } else if (MQaddress.equals("*")) { activity.runOnUiThread(new Runnable() { public void run() { Toast.makeText(activity, "MQ address in domogik config looks like a demo mode. It will not work correctly with Domodroid", Toast.LENGTH_LONG).show(); } }); //MQaddress = ""; //TODO save it as empty or just tell user the MQ will not work? } prefEditor.putString("MQaddress", MQaddress); prefEditor.putString("MQsubport", MQsubport); prefEditor.putString("MQpubport", MQpubport); prefEditor.putString("MQreq_repport", MQreq_repport); publishProgress(12); } catch (Exception e1) { activity.runOnUiThread(new Runnable() { public void run() { Toast.makeText(activity, R.string.problem_with_mq_information, Toast.LENGTH_LONG).show(); Toast.makeText(activity, R.string.check_server_part_in_option, Toast.LENGTH_LONG).show(); } }); Tracer.e(mytag, "ERROR getting MQ information"); } json_FeatureList1 = Rest_com.connect_jsonarray(activity, Tracer, "device", 30000); if (json_FeatureList1 == null || json_FeatureList1.toString().equals("[]")) { // Cannot connect to Rinor server..... Tracer.e(mytag, "Cannot connect to to grab device list"); activity.runOnUiThread(new Runnable() { public void run() { Toast.makeText(activity, R.string.problem_geting_device_information, Toast.LENGTH_LONG).show(); Toast.makeText(activity, R.string.check_server_part_in_option, Toast.LENGTH_LONG).show(); } }); Bundle b = new Bundle(); //Notify error to parent Dialog b.putString("message", "device"); Message msg = new Message(); msg.setData(b); handler.sendMessage(msg); return null; } publishProgress(14); JSONObject Json_data_type = Rest_com.connect_jsonobject(activity, Tracer, "datatype", 30000); if (Json_data_type == null || (Json_data_type.toString().equals("{}"))) { // Cannot get data_type from Rinor server..... Tracer.e(mytag, "Cannot get data_type from Rinor server....."); activity.runOnUiThread(new Runnable() { public void run() { Toast.makeText(activity, R.string.problem_geting_datatype_information, Toast.LENGTH_LONG).show(); Toast.makeText(activity, R.string.check_server_part_in_option, Toast.LENGTH_LONG).show(); } }); Bundle b = new Bundle(); //Notify error to parent Dialog b.putString("message", "datatype"); Message msg = new Message(); msg.setData(b); handler.sendMessage(msg); return null; } publishProgress(25); Tracer.i(mytag, "connected to a 0.4 or more Domogik Version"); //todo #75 ask user how he want the default Area to be organize //see https://github.com/domogik/domodroid/issues/75 String device_sync_order = params.getString("device_sync_order", "Usage"); Tracer.i(mytag, "Default area ordered by :" + device_sync_order); //Create JSONObject json_RoomList = new JSONObject(); json_IconList = new JSONObject(); json_FeatureAssociationList = new JSONObject(); json_AreaList = new JSONObject(); JSONObject map_area = new JSONObject(); JSONObject area = new JSONObject(); //Create JSONArray JSONArray list = new JSONArray(); JSONArray rooms = new JSONArray(); JSONArray icons = new JSONArray(); JSONArray ListFeature = new JSONArray(); //Create string String usage; //Create an ArrayList ArrayList<String> list_usage = new ArrayList<>(); try { json_AreaList.put("status", "OK"); json_AreaList.put("code", 0); json_AreaList.put("description", "None"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { map_area.put("description", ""); map_area.put("id", "1"); //todo #75 reorder for the moment it his done by name switch (device_sync_order) { case "device_name": map_area.put("name", "Device Name"); break; case "device_type": map_area.put("name", "Device Type"); break; case "plugin": map_area.put("name", "Plugin"); break; default: map_area.put("name", "Usage"); break; } list.put(map_area); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { json_AreaList.put("area", list); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } publishProgress(45); try { json_RoomList.put("status", "OK"); json_RoomList.put("code", 0); json_RoomList.put("description", "None"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { json_IconList.put("status", "OK"); json_IconList.put("code", 0); json_IconList.put("description", "None"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { area.put("description", ""); area.put("id", "1"); area.put("name", "Device"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } int numberofroom = db.requestidlastRoom(); int j = numberofroom + 1; int k = 50; try { json_FeatureAssociationList.put("status", "OK"); json_FeatureAssociationList.put("code", "0"); json_FeatureAssociationList.put("description", ""); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } publishProgress(55); int list_size = 0; if (json_FeatureList1 != null) { list_size = json_FeatureList1.length(); if (Rinor_Api_Version >= 0.8f) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date timestamplast_device_update; Date timestamplast_update = new Date(); boolean newer = false; try { timestamplast_device_update = df.parse(last_device_update); } catch (Exception e) { Tracer.e(mytag, "No saved date or error parsing it"); timestamplast_device_update = new Date(); } try { //test info_changed: for (int i = 0; i < json_FeatureList1.length(); i++) { try { String last_update = json_FeatureList1.getJSONObject(i).getString("info_changed"); timestamplast_update = df.parse(last_update); //compare to latest update if (timestamplast_update.compareTo(timestamplast_device_update) > 0) { newer = true; timestamplast_device_update = timestamplast_update; Tracer.v(mytag, "device info_changed at: " + timestamplast_update.toString()); } } catch (Exception E) { timestamplast_update = new Date(); Tracer.d(mytag, "Exception info_changed:" + E); } } if (newer) { //store last update in prefs for next start prefEditor.putString("last_device_update", df.format(timestamplast_device_update)); prefEditor.commit(); } } catch (Exception e) { Tracer.e(mytag, "Error trying to parse /device and info_changed"); } } } Tracer.i(mytag, "Device list size = " + list_size); for (int i = 0; i < list_size; i++) { progress = 55 + (35 * i / list_size); publishProgress(progress); int list_sensors = 0; //List sensors for this device try { json_Sensors = json_FeatureList1.getJSONObject(i).getJSONObject("sensors"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } if (json_Sensors != null) list_sensors = json_Sensors.length(); try { Tracer.i(mytag, list_sensors + " sensors for device id " + json_FeatureList1.getJSONObject(i).getString("id")); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } JSONArray listsensor = json_Sensors.names(); //Sort list sensors by sensors id List<Integer> sensoridlist = new ArrayList<Integer>(); if (list_sensors > 0) { for (int y = 0; y < list_sensors; y++) try { sensoridlist.add(json_Sensors.getJSONObject(listsensor.getString(y)).getInt("id")); } catch (JSONException e) { Tracer.e(mytag, "sorting error" + e.toString()); } Collections.sort(sensoridlist); } //List all sensors for (int y = 0; y < list_sensors; y++) { try { //todo #75 reorder for the moment it his done by name switch (device_sync_order) { case "device_name": usage = json_FeatureList1.getJSONObject(i).getString("name"); break; case "device_type": usage = json_FeatureList1.getJSONObject(i).getString("device_type_id"); break; case "plugin": usage = json_FeatureList1.getJSONObject(i).getString("client_id"); usage = usage.substring(usage.indexOf("-") + 1, usage.indexOf(".")); usage = usage.substring(0, 1).toUpperCase() + usage.substring(1).toLowerCase(); break; default: usage = json_FeatureList1.getJSONObject(i).getString("name"); break; } } catch (Exception e) { usage = null; // Cannot parse JSON Array or JSONObject Tracer.e(mytag, "Exception processing sensor list (" + y + ")"); } Tracer.i(mytag, "Features list processing usage = " + usage); // Create a pseudo 'room' for each usage returned by Rinor // prepare icon_table for room base on device_type_id in 0.4 if (usage != null) { if (!list_usage.contains(usage)) { if (json_Sensors.length() > 0) { JSONObject room = new JSONObject(); JSONObject icon = new JSONObject(); try { room.put("area_id", "1"); room.put("description", ""); room.put("area", area); room.put("id", j); room.put("name", usage); rooms.put(room); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } try { icon.put("name", "room"); icon.put("value", json_FeatureList1.getJSONObject(i).getString("device_type_id")); icon.put("reference", j); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } icons.put(icon); try { list_usage.add(usage); } catch (Exception e) { Tracer.e(mytag, e.toString()); } j++; } } // And its associated widget JSONObject Widget = new JSONObject(); try { Widget.put("place_type", "room"); //#85 here place_id was false Widget.put("place_id", numberofroom + list_usage.indexOf(usage) + 1); //id_rooms); Widget.put("device_feature_id", json_Sensors.getJSONObject(listsensor.getString(y)).getString("id")); Widget.put("id", k + sensoridlist.indexOf(json_Sensors.getJSONObject(listsensor.getString(y)).getInt("id"))); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } JSONObject device_feature = new JSONObject(); device_feature1 = new JSONObject(); String data_type = null; try { data_type = json_Sensors.getJSONObject(listsensor.getString(y)).getString("data_type"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { device_feature.put("device_feature_model_id", data_type + "." + json_Sensors.getJSONObject(listsensor.getString(y)).getString("reference")); device_feature.put("id", json_Sensors.getJSONObject(listsensor.getString(y)).getString("id")); device_feature.put("device_id", json_FeatureList1.getJSONObject(i).getString("id")); Widget.put("device_feature", device_feature); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } ListFeature.put(Widget); try { json_FeatureAssociationList.put("feature_association", ListFeature); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { device_feature1.put("device_feature_model_id", data_type + "." + json_Sensors.getJSONObject(listsensor.getString(y)).getString("reference")); device_feature1.put("id", json_Sensors.getJSONObject(listsensor.getString(y)).getString("id")); device_feature1.put("device_id", json_FeatureList1.getJSONObject(i).getString("id")); device_feature1.put("device_usage_id", json_Sensors.getJSONObject(listsensor.getString(y)).getString("reference")); device_feature1.put("adress", json_Sensors.getJSONObject(listsensor.getString(y)).getString("name")); device_feature1.put("device_type_id", json_FeatureList1.getJSONObject(i).getString("device_type_id")); device_feature1.put("description", json_FeatureList1.getJSONObject(i).getString("description")); device_feature1.put("name", json_FeatureList1.getJSONObject(i).getString("name")); device_feature1.put("stat_key", json_Sensors.getJSONObject(listsensor.getString(y)).getString("reference")); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } JSONObject parameters = new JSONObject(); String parent_type = null; boolean parent_again = false; String tempdata_type = data_type; try { //get value0 and value1 from labels JSONObject labels = Json_data_type.getJSONObject(tempdata_type).getJSONObject("labels"); for (int length = 0; length < labels.length(); length++) { parameters.put("value" + labels.names().get(length), labels.getString((String) labels.names().get(length))); } Tracer.v(mytag, "dt_type: " + data_type + " as labels: " + labels.toString()); } catch (Exception e) { Tracer.d(mytag, "NO labels for this dt_type: " + data_type); } try { //get values JSONObject values = Json_data_type.getJSONObject(tempdata_type).getJSONObject("values"); parameters.putOpt("values", values.toString()); Tracer.v(mytag, "dt_type: " + data_type + " as values: " + values.toString()); } catch (Exception e) { Tracer.d(mytag, "NO values for this dt_type: " + data_type); } //For 0.4 make a loop until no more parent data_type while (!parent_again) { try { parent_type = Json_data_type.getJSONObject(tempdata_type).getString("parent"); tempdata_type = parent_type; } catch (JSONException e) { parent_type = tempdata_type; parent_again = true; } } parent_type = parent_type.replace("DT_", ""); parent_type = parent_type.toLowerCase(); try { device_feature1.put("value_type", parent_type); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { String unit = Json_data_type.getJSONObject(data_type).getString("unit"); if (!unit.equals(null) && !unit.equals("null")) parameters.put("unit", unit); } catch (JSONException e) { Tracer.d(mytag, "No unit for this one"); } try { device_feature1.put("parameters", parameters); db.insertFeature_0_4(device_feature1); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } } } k = k + list_sensors; //Create feature from commands int list_commands = 0; try { json_Commands = json_FeatureList1.getJSONObject(i).getJSONObject("commands"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } if (json_Commands != null) { Tracer.d(mytag, "Json list_command=" + json_Commands.toString()); list_commands = json_Commands.length(); } try { Tracer.d(mytag, list_commands + " commands for device id " + json_FeatureList1.getJSONObject(i).getString("id")); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } JSONArray listcommand = json_Commands.names(); //Sort list commands by commands id List<Integer> commandidlist = new ArrayList<Integer>(); if (list_commands > 0) { for (int y = 0; y < list_commands; y++) try { commandidlist.add(json_Commands.getJSONObject(listcommand.getString(y)).getInt("id")); } catch (JSONException e) { e.printStackTrace(); } Collections.sort(commandidlist); } //List all commands for (int y = 0; y < list_commands; y++) { try { //todo #75 reorder for the moment it his done by name switch (device_sync_order) { case "device_name": usage = json_FeatureList1.getJSONObject(i).getString("name"); break; case "device_type": usage = json_FeatureList1.getJSONObject(i).getString("device_type_id"); break; case "plugin": usage = json_FeatureList1.getJSONObject(i).getString("client_id"); usage = usage.substring(usage.indexOf("-") + 1, usage.indexOf(".")); usage = usage.substring(0, 1).toUpperCase() + usage.substring(1).toLowerCase(); break; default: usage = json_FeatureList1.getJSONObject(i).getString("name"); break; } } catch (Exception e) { usage = null; // Cannot parse JSON Array or JSONObject Tracer.d(mytag, "Exception processing command list (" + y + ")"); } Tracer.d(mytag, "Features list processing usage = " + usage); // Create a pseudo 'room' for each usage returned by Rinor // Prepare icon_table for room base on device_type_id in 0.4 if (usage != null) { if (!list_usage.contains(usage)) { if (json_Commands.length() > 0) { JSONObject room = new JSONObject(); JSONObject icon = new JSONObject(); try { room.put("area_id", "1"); room.put("description", ""); room.put("area", area); room.put("id", j); room.put("name", usage); rooms.put(room); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } try { icon.put("name", "room"); icon.put("value", json_FeatureList1.getJSONObject(i).getString("device_type_id")); icon.put("reference", j); icons.put(icon); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } try { list_usage.add(usage); } catch (Exception e) { Tracer.e(mytag, e.toString()); } j++; } } // And its associated widget JSONObject Widget = new JSONObject(); //TODO find a way to remove this limit of 50000 sensors //It is used to have not the same id for a sensor and a commands int tempid = 0; try { tempid = json_Commands.getJSONObject(listcommand.getString(y)).getInt("id"); } catch (NumberFormatException | JSONException e1) { Tracer.e(mytag, e1.toString()); } tempid = tempid + 50000; try { Widget.put("place_type", "room"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { //#85 here place_id was false Widget.put("place_id", numberofroom + list_usage.indexOf(usage) + 1); Widget.put("device_feature_id", tempid); Widget.put("id", k + commandidlist.indexOf(json_Commands.getJSONObject(listcommand.getString(y)).getString("id"))); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } String data_type = null; try { data_type = json_Commands.getJSONObject(listcommand.getString(y)).getJSONArray("parameters").getJSONObject(0).getString("data_type"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } JSONObject device_feature = new JSONObject(); device_feature1 = new JSONObject(); try { device_feature.put("device_feature_model_id", json_Commands.getJSONObject(json_Commands.names().getString(y)).getJSONArray("parameters").getJSONObject(0).getString("data_type") + "." + json_Commands.getJSONObject(listcommand.getString(y)).getString("name")); device_feature.put("id", tempid); device_feature.put("device_id", json_FeatureList1.getJSONObject(i).getString("id")); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { Widget.put("device_feature", device_feature); ListFeature.put(Widget); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { json_FeatureAssociationList.put("feature_association", ListFeature); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { device_feature1.put("device_feature_model_id", json_Commands.getJSONObject(json_Commands.names().getString(y)).getJSONArray("parameters").getJSONObject(0).getString("data_type") + "." + json_Commands.getJSONObject(listcommand.getString(y)).getString("name")); device_feature1.put("id", tempid); device_feature1.put("device_id", json_FeatureList1.getJSONObject(i).getString("id")); device_feature1.put("device_usage_id", json_Commands.getJSONObject(listcommand.getString(y)).getString("name")); device_feature1.put("adress", json_Commands.getJSONObject(listcommand.getString(y)).getString("name")); device_feature1.put("device_type_id", json_FeatureList1.getJSONObject(i).getString("device_type_id")); device_feature1.put("description", json_FeatureList1.getJSONObject(i).getString("description")); device_feature1.put("name", json_FeatureList1.getJSONObject(i).getString("name")); device_feature1.put("stat_key", json_Commands.getJSONObject(listcommand.getString(y)).getString("name")); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } JSONObject parameters = new JSONObject(); String parent_type = null; boolean parent_again = false; String tempdata_type = data_type; try { //get value0 and value1 from labels JSONObject labels = Json_data_type.getJSONObject(tempdata_type).getJSONObject("labels"); for (int length = 0; length < labels.length(); length++) { parameters.putOpt("value" + labels.names().get(length), labels.getString((String) labels.names().get(length))); } Tracer.i(mytag, "dt_type: " + data_type + " as labels: " + labels.toString()); } catch (Exception e) { Tracer.d(mytag, "NO labels for this dt_type: " + data_type); } try { //get values JSONObject values = Json_data_type.getJSONObject(tempdata_type).getJSONObject("values"); parameters.putOpt("values", values.toString()); Tracer.v(mytag, "dt_type: " + data_type + " as values: " + values.toString()); } catch (Exception e) { Tracer.d(mytag, "NO values for this dt_type: " + data_type); } //For 0.4 make a loop until no more parent data_type while (!parent_again) { try { parent_type = Json_data_type.getJSONObject(tempdata_type).getString("parent"); tempdata_type = parent_type; } catch (JSONException e) { parent_type = tempdata_type; parent_again = true; } } parent_type = parent_type.replace("DT_", ""); parent_type = parent_type.toLowerCase(); try { device_feature1.putOpt("value_type", parent_type); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } JSONArray list_command = json_Commands.names(); JSONArray command_parameter = new JSONArray(); try { command_parameter = json_Commands.getJSONObject(json_Commands.names().getString(y)).getJSONArray("parameters"); } catch (JSONException e1) { Tracer.e(mytag, e1.toString()); } try { //FOR 0.4 get other params //this is just a try to get a binary switch working.... Tracer.d(mytag, "Json this id=" + json_Commands.getJSONObject(list_command.getString(y)).getString("id")); String command_id = json_Commands.getJSONObject(list_command.getString(y)).getString("id"); parameters.putOpt("command_id", command_id); parameters.putOpt("number_of_command_parameters", command_parameter.length()); for (int nb_parameters = 0; nb_parameters < command_parameter.length(); nb_parameters++) { String command_type = command_parameter.getJSONObject(nb_parameters).getString("key"); if (command_type != null) { Tracer.d(mytag, "Json command_type=" + command_type); parameters.putOpt("command_type" + (nb_parameters + 1), command_type); } String command_data_type = command_parameter.getJSONObject(nb_parameters).getString("data_type"); if (command_data_type != null) { Tracer.d(mytag, "Json command_data_type=" + command_type); parent_again = true; while (!parent_again) { try { parent_type = Json_data_type.getJSONObject(command_data_type).getString("parent"); tempdata_type = parent_type; } catch (JSONException e) { parent_type = command_data_type; parent_again = true; } } parameters.putOpt("command_data_type" + (nb_parameters + 1), parent_type); } } } catch (JSONException e) { Tracer.e(mytag, "error with json commands"); } try { device_feature1.putOpt("parameters", parameters); db.insertFeature_0_4(device_feature1); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } } } k = k + list_commands; // for loop on feature list... //Prepare list of rooms, and list of usable features try { json_RoomList.putOpt("room", rooms); json_IconList.putOpt("ui_config", icons); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } } publishProgress(90); } //TODO #141 when available in rest /*if (Rinor_Api_Version > 0.9f) { try { String External_port = json_rinor.getJSONObject("external").getString("external_ip"); String External_IP = json_rinor.getJSONObject("external").getString("external_port"); prefEditor.putString("rinor_external_IP", External_IP); prefEditor.putString("rinor_external_Port", External_port); } catch (Exception e1) { activity.runOnUiThread(new Runnable() { public void run() { Toast.makeText(activity, "Could not get external IP PORT configuration", Toast.LENGTH_LONG).show(); } }); Tracer.e(mytag, "ERROR getting external IP PORT information"); } }*/ // Common sequence for all versions sync // Insert results into local database // And sharedpref prefEditor.putFloat("API_VERSION", Rinor_Api_Version); prefEditor.putString("DOMOGIK-VERSION", domogik_Version); prefEditor.putBoolean("SYNC", true); publishProgress(91); Tracer.v(mytag, "Updating database tables with new House configuration"); try { db.insertArea(json_AreaList); prefEditor.putString("AREA_LIST", db.request_json_Area().toString()); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } publishProgress(92); try { db.insertRoom(json_RoomList); prefEditor.putString("ROOM_LIST", db.request_json_Room().toString()); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } publishProgress(93); if (Rinor_Api_Version >= 0.7f) { try { db.insertIcon(json_IconList); prefEditor.putString("ICON_LIST", db.request_json_Icon().toString()); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } } publishProgress(94); if (Rinor_Api_Version <= 0.6f) { try { db.insertFeature(json_FeatureList); //No need of db request method as feature only comes from rest // in fact the best way for feature is to rename or change description directly in domogik. prefEditor.putString("FEATURE_LIST", json_FeatureList.toString()); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } } else { //No need of db request method as feature only comes from rest prefEditor.putString("FEATURE_LIST", json_FeatureList1.toString()); } publishProgress(95); try { db.insertFeatureAssociation(json_FeatureAssociationList); prefEditor.putString("FEATURE_LIST_association", db.request_json_Features_association().toString()); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } publishProgress(96); if (Rinor_Api_Version <= 0.5f) { try { db.insertIcon(json_IconList); prefEditor.putString("ICON_LIST", db.request_json_Icon().toString()); } catch (JSONException e) { Tracer.e(mytag, e.toString()); } prefEditor.putBoolean("BY_USAGE", false); } else if (Rinor_Api_Version >= 0.6f) { if (Rinor_Api_Version >= 0.7f) prefEditor.putBoolean("WIDGET_CHOICE", true); prefEditor.putBoolean("BY_USAGE", by_usage); } publishProgress(97); //Clear possible feature association with deleted device db.CleanFeatures_association(); publishProgress(98); //refresh cache address Cache_management.checkcache(Tracer, activity); need_refresh = true; // To notify main activity that screen must be refreshed prefEditor.commit(); /* db.closeDb(); db = null; */ publishProgress(100); Bundle b = new Bundle(); //Notify sync complete to parent Dialog b.putString("message", "sync_done"); Message msg = new Message(); msg.setData(b); handler.sendMessage(msg); return null; } } }