├── .gitignore ├── Android ├── .gitignore ├── .idea │ ├── misc.xml │ ├── modules.xml │ └── runConfigurations.xml ├── appSupervisory │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── br │ │ │ └── com │ │ │ └── brolam │ │ │ └── oha │ │ │ └── supervisory │ │ │ ├── OhaEnergyUseApiV1Test.java │ │ │ └── OhaEnergyUseProviderTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── br │ │ │ │ └── com │ │ │ │ └── brolam │ │ │ │ └── oha │ │ │ │ └── supervisory │ │ │ │ ├── OhaBroadcast.java │ │ │ │ ├── OhaException.java │ │ │ │ ├── apiV1 │ │ │ │ ├── OhaEnergyUseApi.java │ │ │ │ └── models │ │ │ │ │ ├── OhaConnectionStatus.java │ │ │ │ │ ├── OhaEnergyUseLog.java │ │ │ │ │ ├── OhaSequenceLog.java │ │ │ │ │ └── OhaStatusLog.java │ │ │ │ ├── data │ │ │ │ ├── OhaEnergyUseContract.java │ │ │ │ ├── OhaEnergyUseProvider.java │ │ │ │ ├── cursors │ │ │ │ │ ├── IOhaEnergyUseTotalCache.java │ │ │ │ │ ├── OhaEnergyUseBillCursor.java │ │ │ │ │ └── OhaEnergyUseDaysCursor.java │ │ │ │ └── helpers │ │ │ │ │ ├── OhaEnergyUseLogHelper.java │ │ │ │ │ └── OhaSQLHelper.java │ │ │ │ ├── sync │ │ │ │ ├── OhaSyncService.java │ │ │ │ └── tasks │ │ │ │ │ ├── IOhaTask.java │ │ │ │ │ ├── OhaBackupTask.java │ │ │ │ │ └── OhaEnergyUseLogTask.java │ │ │ │ └── ui │ │ │ │ ├── OhaEnergyUseDetailsActivity.java │ │ │ │ ├── OhaMainActivity.java │ │ │ │ ├── OhaSettingsActivity.java │ │ │ │ ├── adapters │ │ │ │ ├── OhaEnergyUseWattsAdapter.java │ │ │ │ ├── OhaEnergyUseWhAdapter.java │ │ │ │ ├── OhaMainAdapter.java │ │ │ │ └── holders │ │ │ │ │ ├── OhaEnergyUseBillHolder.java │ │ │ │ │ ├── OhaEnergyUseDayHolder.java │ │ │ │ │ ├── OhaEnergyUseWattsHolder.java │ │ │ │ │ ├── OhaEnergyUseWhHolder.java │ │ │ │ │ └── OhaMainHolder.java │ │ │ │ ├── fragments │ │ │ │ ├── OhaDatePickerDialogPreference.java │ │ │ │ ├── OhaEnergyUseBillFragment.java │ │ │ │ ├── OhaEnergyUseLogFilterFragment.java │ │ │ │ └── OhaRestoreDatabaseFragment.java │ │ │ │ └── helpers │ │ │ │ ├── AppCompatPreferenceHelper.java │ │ │ │ ├── OhaBackupHelper.java │ │ │ │ ├── OhaEnergyUseSyncHelper.java │ │ │ │ └── OhaHelper.java │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ ├── ic_add_alert_white.png │ │ │ ├── ic_add_white.png │ │ │ ├── ic_alert_black.png │ │ │ ├── ic_backup_black.png │ │ │ ├── ic_backup_setting_black.png │ │ │ ├── ic_bill_black.png │ │ │ ├── ic_chart_black.png │ │ │ ├── ic_delete_black.png │ │ │ ├── ic_edit_black.png │ │ │ ├── ic_energy_black.png │ │ │ ├── ic_filter_white.png │ │ │ ├── ic_restore_black.png │ │ │ └── ic_settings_black.png │ │ │ ├── drawable-mdpi │ │ │ ├── ic_add_alert_white.png │ │ │ ├── ic_add_white.png │ │ │ ├── ic_alert_black.png │ │ │ ├── ic_backup_black.png │ │ │ ├── ic_backup_setting_black.png │ │ │ ├── ic_bill_black.png │ │ │ ├── ic_chart_black.png │ │ │ ├── ic_delete_black.png │ │ │ ├── ic_edit_black.png │ │ │ ├── ic_energy_black.png │ │ │ ├── ic_filter_white.png │ │ │ ├── ic_restore_black.png │ │ │ └── ic_settings_black.png │ │ │ ├── drawable-xhdpi │ │ │ ├── ic_add_alert_white.png │ │ │ ├── ic_add_white.png │ │ │ ├── ic_alert_black.png │ │ │ ├── ic_backup_black.png │ │ │ ├── ic_backup_setting_black.png │ │ │ ├── ic_bill_black.png │ │ │ ├── ic_chart_black.png │ │ │ ├── ic_delete_black.png │ │ │ ├── ic_edit_black.png │ │ │ ├── ic_energy_black.png │ │ │ ├── ic_filter_white.png │ │ │ ├── ic_restore_black.png │ │ │ └── ic_settings_black.png │ │ │ ├── drawable-xxhdpi │ │ │ ├── ic_add_alert_white.png │ │ │ ├── ic_add_white.png │ │ │ ├── ic_alert_black.png │ │ │ ├── ic_backup_black.png │ │ │ ├── ic_backup_setting_black.png │ │ │ ├── ic_bill_black.png │ │ │ ├── ic_chart_black.png │ │ │ ├── ic_delete_black.png │ │ │ ├── ic_edit_black.png │ │ │ ├── ic_energy_black.png │ │ │ ├── ic_filter_white.png │ │ │ ├── ic_restore_black.png │ │ │ └── ic_settings_black.png │ │ │ ├── drawable │ │ │ └── side_nav_bar.xml │ │ │ ├── layout-w480dp │ │ │ ├── fragment_energy_use_bill.xml │ │ │ ├── fragment_energy_use_log_filter.xml │ │ │ ├── holder_energy_use_watts.xml │ │ │ ├── holder_energy_use_wh.xml │ │ │ ├── title_energy_use_wh.xml │ │ │ └── title_energy_use_wh_values.xml │ │ │ ├── layout │ │ │ ├── activity_energy_use_details.xml │ │ │ ├── activity_main.xml │ │ │ ├── app_bar_main.xml │ │ │ ├── content_energy_use_details.xml │ │ │ ├── content_main.xml │ │ │ ├── fragment_date_picker_dialog_preference.xml │ │ │ ├── fragment_energy_use_bill.xml │ │ │ ├── fragment_energy_use_log_filter.xml │ │ │ ├── fragment_restore_database.xml │ │ │ ├── holder_energy_use_bill.xml │ │ │ ├── holder_energy_use_day.xml │ │ │ ├── holder_energy_use_watts.xml │ │ │ ├── holder_energy_use_wh.xml │ │ │ ├── nav_header_main.xml │ │ │ ├── title_energy_use_wh.xml │ │ │ └── title_energy_use_wh_values.xml │ │ │ ├── menu │ │ │ ├── activity_energy_use_details.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_main_drawer.xml │ │ │ ├── fragment_energy_use_bill.xml │ │ │ ├── fragment_energy_use_log_filter.xml │ │ │ ├── fragment_restore_database.xml │ │ │ ├── holder_energy_use_bill.xml │ │ │ └── holder_energy_use_day.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-v21 │ │ │ └── styles.xml │ │ │ ├── values-w480dp │ │ │ └── dimens.xml │ │ │ ├── values-w720dp │ │ │ ├── dimens.xml │ │ │ └── styles.xml │ │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ │ ├── values │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ │ └── xml │ │ │ ├── pref_backup.xml │ │ │ ├── pref_energy_use.xml │ │ │ └── pref_headers.xml │ │ └── test │ │ └── java │ │ └── br │ │ └── com │ │ └── brolam │ │ └── oha │ │ └── supervisory │ │ └── JavaUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── br │ │ │ └── com │ │ │ └── brolam │ │ │ └── library │ │ │ └── LibraryTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── br │ │ │ │ └── com │ │ │ │ └── brolam │ │ │ │ └── library │ │ │ │ ├── helpers │ │ │ │ ├── OhaHelper.java │ │ │ │ └── OhaNetworkHelper.java │ │ │ │ └── ui │ │ │ │ └── fragments │ │ │ │ └── TimeFragment.java │ │ └── res │ │ │ ├── anim │ │ │ └── fab_button.xml │ │ │ ├── layout │ │ │ └── view_time.xml │ │ │ └── values │ │ │ ├── dimens.xml │ │ │ └── strings.xml │ │ └── test │ │ └── java │ │ └── br │ │ └── com │ │ └── brolam │ │ └── library │ │ └── LibraryUnitTest.java └── settings.gradle ├── Documents ├── Fritzing │ └── OhaEnergyUseLog.fzz └── Images │ ├── oha_android_studio.png │ ├── oha_arduino_energy_use_logger.png │ ├── oha_energy_use_logger_00.jpg │ ├── oha_energy_use_logger_01.jpg │ ├── oha_energy_use_logger_02.jpg │ ├── oha_energy_use_logger_03.jpg │ ├── oha_energy_use_logger_04.jpg │ ├── oha_energy_use_logger_05.jpg │ ├── oha_esp8266_energy_use_logger.png │ ├── oha_fritzing.png │ ├── oha_pcb_energy_use_log.png │ ├── oha_pcb_energy_use_logger.pdf │ ├── oha_protoboard_energy_use_log.png │ ├── oha_supervisory_screens_01.png │ ├── oha_supervisory_screens_02.png │ └── oha_supervisory_screens_03.png ├── Firmware ├── EnergyUseLoggerArduino │ └── EnergyUseLoggerArduino.ino ├── EnergyUseLoggerEsp8266 │ ├── .gitignore │ ├── Config_model.h │ └── EnergyUseLoggerEsp8266.ino └── Samples │ └── SD_EDB │ └── SD_EDB.ino ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Android/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/android 2 | 3 | ### Android ### 4 | # Built application files 5 | *.apk 6 | *.ap_ 7 | 8 | # Files for the ART/Dalvik VM 9 | *.dex 10 | 11 | # Java class files 12 | *.class 13 | 14 | # Generated files 15 | bin/ 16 | gen/ 17 | out/ 18 | 19 | # Gradle files 20 | .gradle/ 21 | build/ 22 | 23 | # Local configuration file (sdk path, etc) 24 | local.properties 25 | 26 | # Proguard folder generated by Eclipse 27 | proguard/ 28 | 29 | # Log Files 30 | *.log 31 | 32 | # Android Studio Navigation editor temp files 33 | .navigation/ 34 | 35 | # Android Studio captures folder 36 | captures/ 37 | 38 | # Intellij 39 | *.iml 40 | .idea/workspace.xml 41 | .idea/tasks.xml 42 | .idea/gradle.xml 43 | .idea/libraries 44 | .idea/inspectionProfiles/ 45 | .idea/caches/ 46 | .idea/codeStyles/ 47 | 48 | # Keystore files 49 | *.jks 50 | 51 | # External native build folder generated in Android Studio 2.2 and later 52 | .externalNativeBuild 53 | 54 | # Google Services (e.g. APIs or Firebase) 55 | google-services.json 56 | 57 | #Freeline 58 | freeline.py 59 | freeline/ 60 | freeline_project_description.json 61 | 62 | ### Android Patch ### 63 | gen-external-apklibs 64 | 65 | # End of https://www.gitignore.io/api/android -------------------------------------------------------------------------------- /Android/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | -------------------------------------------------------------------------------- /Android/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Android/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /Android/appSupervisory/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Android/appSupervisory/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion '27.0.3' 6 | defaultConfig { 7 | applicationId "br.com.brolam.oha.supervisory" 8 | minSdkVersion 16 9 | targetSdkVersion 25 10 | versionCode 4 11 | versionName "1.0.3" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | vectorDrawables.useSupportLibrary = true 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | compile fileTree(include: ['*.jar'], dir: 'libs') 25 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 26 | exclude group: 'com.android.support', module: 'support-annotations' 27 | }) 28 | compile project(':library') 29 | compile 'com.android.support:appcompat-v7:25.3.0' 30 | compile 'com.android.support:cardview-v7:25.3.0' 31 | compile 'com.android.support:design:25.3.0' 32 | compile 'com.android.support:support-v4:25.3.0' 33 | compile 'com.android.support:support-vector-drawable:25.3.0' 34 | testCompile 'junit:junit:4.12' 35 | } 36 | -------------------------------------------------------------------------------- /Android/appSupervisory/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/brenomar/android-sdks/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 46 | 47 | 48 | 52 | 53 | 54 | 57 | 58 | 59 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/OhaBroadcast.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory; 2 | 3 | import android.app.AlarmManager; 4 | import android.app.PendingIntent; 5 | import android.content.BroadcastReceiver; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | import android.net.ConnectivityManager; 9 | 10 | import br.com.brolam.oha.supervisory.sync.OhaSyncService; 11 | 12 | /** 13 | * Organizar todas os Broadcast do aplicativo 14 | * @author Breno Marques 15 | * @version 1.00 16 | * @since Release 01 17 | */ 18 | public class OhaBroadcast extends BroadcastReceiver { 19 | //Evento para acionar a sincronização dos logs de utilização de energia. 20 | public static final String START_SYNC_ENERGY_USE = "br.com.brolam.oha.supervisory.broadcast.START_SYNC_ENERGY_USE"; 21 | 22 | @Override 23 | public void onReceive(Context context, Intent intent) { 24 | switch (intent.getAction()) { 25 | case START_SYNC_ENERGY_USE: 26 | OhaSyncService.start(context); 27 | return; 28 | case Intent.ACTION_BOOT_COMPLETED: 29 | OhaSyncService.start(context); 30 | return; 31 | case ConnectivityManager.CONNECTIVITY_ACTION: 32 | OhaSyncService.start(context); 33 | return; 34 | 35 | } 36 | } 37 | 38 | /** 39 | * Registrar o agendamento para acionar o serviço de sincronização dos logs 40 | * de utilização de energia. 41 | * @param context informar um contexto válido. 42 | */ 43 | public static void registerSyncAlarm(Context context) { 44 | //Realizar um verificação se o PendingIntent está ativo a cada 5 segundos. 45 | int INTERVAL_IMPORT = 5000; 46 | Intent intent = new Intent(context, OhaBroadcast.class); 47 | intent.setAction(START_SYNC_ENERGY_USE); 48 | //Utilizar o parâmetro PendingIntent.FLAG_UPDATE_CURRENT para manter somente um 49 | //PendingIntent ativo e evitar o acionamento da sincronização mais de uma vez. 50 | PendingIntent sender = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT); 51 | //Agendar o acionamento. 52 | AlarmManager alarmManager = (AlarmManager) context 53 | .getSystemService(Context.ALARM_SERVICE); 54 | alarmManager.setRepeating( 55 | AlarmManager.ELAPSED_REALTIME_WAKEUP, 56 | INTERVAL_IMPORT, 57 | INTERVAL_IMPORT, 58 | sender); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/OhaException.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory; 2 | /** 3 | * Organizar todas as Exceções do aplicativo 4 | * @author Breno Marques 5 | * @version 1.00 6 | * @since Release 01 7 | */ 8 | public class OhaException extends Exception { 9 | 10 | public OhaException(String message) { 11 | super(message); 12 | } 13 | 14 | /**************************************************************************************** 15 | * EnergyUseLog - Exceções para o tratamento de erros referente a tarefa de processamento 16 | * dos logs utilização de energia. 17 | ****************************************************************************************/ 18 | public static class EnergyUseLogSyncFatalError extends OhaException { 19 | public EnergyUseLogSyncFatalError(String message) { 20 | super(message); 21 | } 22 | } 23 | 24 | public static class EnergyUseLogSdCardFatalError extends OhaException { 25 | public EnergyUseLogSdCardFatalError(String message) { 26 | super(message); 27 | } 28 | } 29 | 30 | public static class EnergyUseLogRead extends Exception { 31 | public EnergyUseLogRead(String message) { 32 | super(message); 33 | } 34 | } 35 | 36 | public static class EnergyUseLogReadSequenceBroken extends Exception { 37 | public EnergyUseLogReadSequenceBroken(Integer previous, int current) { 38 | super(String.format("EnergyUseLog read sequence was broken previous(%s) current(%s)", previous, current)); 39 | } 40 | } 41 | 42 | public static class EnergyUseRequestTimeOut extends Exception { 43 | public EnergyUseRequestTimeOut(String message) { 44 | super(message); 45 | } 46 | } 47 | 48 | public static class BackupAndRestoreOperation extends Exception { 49 | public BackupAndRestoreOperation(String message) { 50 | super(message); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/apiV1/models/OhaConnectionStatus.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.apiV1.models; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | /** 7 | * OhaConnectionStatus - recuperar informações sobre a conexão do módulo WiFi. 8 | * @author Breno Marques 9 | * @version 1.00 10 | * @since Release 01 11 | */ 12 | public class OhaConnectionStatus implements Serializable { 13 | 14 | /***************************************************************************************** 15 | * Constantes dos campos e flags para facilitar a leitura do conteúdo. 16 | ****************************************************************************************/ 17 | private static final byte FIELD_NAME_HOME_WIFI = 0; 18 | private static final byte FIELD_IP_HOME_WIFI= 1; 19 | private static final byte FIELD_NAME_WIFI = 2; 20 | private static final byte FIELD_IP_WIFI = 3; 21 | private static final String FLAG_COLUMNS = ","; 22 | private static final String FLAG_BEGIN = "<"; 23 | private static final String FLAG_END = ">"; 24 | /***************************************************************************************/ 25 | 26 | /** 27 | * Nome da rede WiFi que o módulo WiFi está conectado. 28 | */ 29 | private String nameHomeWiFi; 30 | 31 | /** 32 | * IP na rede WiFi. 33 | */ 34 | private String ipHomeWiFi; 35 | 36 | /** 37 | * Nome do AP WiFi 38 | */ 39 | private String nameWiFi; 40 | 41 | /** 42 | * IP do AP WiFi 43 | */ 44 | private String ipWiFi; 45 | 46 | public OhaConnectionStatus(String nameHomeWiFi, String ipHomeWiFi, String nameWiFi, String ipWiFi) { 47 | this.nameHomeWiFi = nameHomeWiFi; 48 | this.ipHomeWiFi = ipHomeWiFi; 49 | this.nameWiFi = nameWiFi; 50 | this.ipWiFi = ipWiFi; 51 | } 52 | 53 | /** 54 | * Analisar e criar um {@see OhaConnectionStatus } conforme parâmetro abaixo: 55 | * @param strings informar o conteúdo retornar na API. 56 | * @return uma instância de OhaConnectionStatus ou null se o conteúdo for inválido. 57 | */ 58 | public static OhaConnectionStatus parse(List strings) { 59 | 60 | for (String strValue : strings) { 61 | //O conteúdo deve ter os sinalizadores de inicio e final e conter 4 colunas. 62 | if ((strValue.indexOf(FLAG_BEGIN) != -1) && (strValue.indexOf(FLAG_END) != -1)) { 63 | String[] values = strValue.replace(FLAG_BEGIN, "").replace(FLAG_END, "").split(FLAG_COLUMNS); 64 | if (values.length == 4) { 65 | String nameHomeWiFi = values[FIELD_NAME_HOME_WIFI]; 66 | String ipHomeWiFi = values[FIELD_IP_HOME_WIFI]; 67 | String nameWiFi = values[FIELD_NAME_WIFI]; 68 | String ipWiFi = values[FIELD_IP_WIFI]; 69 | return new OhaConnectionStatus(nameHomeWiFi, ipHomeWiFi, nameWiFi, ipWiFi); 70 | } 71 | } 72 | } 73 | return null; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/apiV1/models/OhaSequenceLog.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.apiV1.models; 2 | 3 | import android.text.format.DateUtils; 4 | import java.io.Serializable; 5 | import java.util.List; 6 | 7 | /** 8 | * OhaSequenceLog - recuperar informações sobre o controle de geração de logs, informando a última sequência 9 | * e situação da geração de logs para uma determinada data e hora. 10 | * @author Breno Marques 11 | * @version 1.00 12 | * @since Release 01 13 | */ 14 | public class OhaSequenceLog implements Serializable { 15 | 16 | /***************************************************************************************** 17 | * Constantes dos campos e flags para facilitar a leitura do conteúdo. 18 | ****************************************************************************************/ 19 | private static final byte FIELD_SEQUENCE = 0; 20 | private static final byte FIELD_STATUS = 1; 21 | private static final byte FIELD_DURATION_BOARD_RUNNING = 2; 22 | private static final String FLAG_COLUMNS = ":"; 23 | private static final String FLAG_BEGIN = "<"; 24 | private static final String FLAG_END = ">"; 25 | /***************************************************************************************/ 26 | 27 | /** 28 | * Informar a ultima sequência de registro de log. 29 | */ 30 | private int lastSequence; 31 | 32 | /** 33 | * Informar a duração em milissegundos em que a placa Arduino está em execução desde o último reset. 34 | */ 35 | private long durationBoardRunning; 36 | 37 | /** 38 | * Informar a situação do processo de registros dos logs. 39 | * @see OhaStatusLog STOPPED 40 | * @see OhaStatusLog RUNNING 41 | */ 42 | private OhaStatusLog ohaStatusLog; 43 | 44 | public OhaSequenceLog(int lastSequence, OhaStatusLog ohaStatusLog, long durationBoardRunning){ 45 | this.lastSequence = lastSequence; 46 | this.ohaStatusLog = ohaStatusLog; 47 | this.durationBoardRunning = durationBoardRunning; 48 | } 49 | 50 | public int getLastSequence() { 51 | return lastSequence; 52 | } 53 | 54 | public double getTotalBoardHoursRunning(){ 55 | if ( this.durationBoardRunning > 0){ 56 | return (double)durationBoardRunning / (double) DateUtils.HOUR_IN_MILLIS; 57 | } 58 | return 0.00; 59 | } 60 | 61 | 62 | public OhaStatusLog getOhaStatusLog() { 63 | return ohaStatusLog; 64 | } 65 | 66 | /** 67 | * Analisar e criar um {@see OhaSequenceLog } conforme parâmetro abaixo: 68 | * @param strings informar o conteúdo retornar na API. 69 | * @return uma instância de OhaSequenceLog. 70 | */ 71 | public static OhaSequenceLog parse(List strings) { 72 | OhaStatusLog ohaStatusLog = null; 73 | int lastSequence = -1; //Valor padrão para sequência inválida. 74 | long durationBoardRunning = 0; 75 | 76 | for (String strValue : strings) { 77 | //Uma sequencia válida deve ter os sinalizadores de inicio e fim e 3 colunas/. 78 | if ( (strValue.indexOf(FLAG_BEGIN) != -1) && (strValue.indexOf(FLAG_END) != -1) ){ 79 | String[] values = strValue.replace(FLAG_BEGIN,"").replace(FLAG_END,"").split(FLAG_COLUMNS); 80 | if ( values.length == 3){ 81 | lastSequence = Integer.valueOf(values[FIELD_SEQUENCE]); 82 | ohaStatusLog = OhaStatusLog.getOhaStatusLog(values[FIELD_STATUS]); 83 | durationBoardRunning = Long.valueOf(values[FIELD_DURATION_BOARD_RUNNING]); 84 | break; 85 | } 86 | //Tentar recuepar o primeiro OhaStatusLog válido. 87 | } else if ( ohaStatusLog == null ){ 88 | ohaStatusLog = OhaStatusLog.getOhaStatusLog(strValue); 89 | } 90 | } 91 | if ( (lastSequence == -1) && ( ohaStatusLog == null ) ){ 92 | ohaStatusLog = OhaStatusLog.OHA_REQUEST_END; 93 | } 94 | return new OhaSequenceLog(lastSequence, ohaStatusLog, durationBoardRunning); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/apiV1/models/OhaStatusLog.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.apiV1.models; 2 | 3 | import java.util.List; 4 | 5 | /** Definir todas as possíveis situações(Status) retornadas na API. 6 | * @author Breno Marques 7 | * @version 1.00 8 | * @since Release 01 9 | */ 10 | public enum OhaStatusLog { 11 | /** Sinalizar que não existe logs para a data solicitada. */ 12 | LOG_DATE_NOT_EXISTS, 13 | 14 | /** Sinalizar que a leitura dos logs chegou ao final.*/ 15 | LOG_END_OF_FILE, 16 | 17 | /** Sinalizar que o log foi excluido */ 18 | LOG_DELETED, 19 | 20 | /** Sinalizar que o Cartão de memória do dispositivo OHA está com problema. */ 21 | OHA_STATUS_NOT_SD, 22 | 23 | /** Sinalizar que a data e hora do dispositivo OHA não está atualizada. */ 24 | OHA_STATUS_NOT_DATE, 25 | 26 | /** Sinalizar que os registros de logs não está finalizada para a data e hora informada.*/ 27 | OHA_STATUS_RUNNING, 28 | 29 | /** Sinalizar que os registros de logs está finalizado para a data e hora informada.*/ 30 | OHA_STATUS_FINISHED, 31 | 32 | /** Sinalizar o final da requisição*/ 33 | OHA_REQUEST_END, 34 | 35 | /** Sinalizar que o Arduino não está respondendo ao módulo WIFI ( ESP8266)*/ 36 | OHA_REQUEST_TIMEOUT; 37 | 38 | private static final String FLAG_COLUMNS = "\\|"; 39 | private static final String FLAG_BEGIN = "<"; 40 | private static final String FLAG_END = ">"; 41 | 42 | /** 43 | * Informar a duração de execução em milissegundos da Arduino desde o último reset. 44 | */ 45 | private long durationBoardRunning = -1; 46 | 47 | /** 48 | * Recuperar a duração de execução em milissegundos da Arduino desde o último reset ou 49 | * retornar a -1 se o valor for inválido. 50 | */ 51 | public long getDurationBoardRunning() { 52 | return durationBoardRunning; 53 | } 54 | 55 | /** 56 | * Recuperar um OhaStatusLog conforme texto com o nome do Status 57 | * @param ohaStatusLogContent texto com o conteúdo do OhaStatusLog. 58 | * @return retornar com um OhaStatusLog válido ou nulo. 59 | */ 60 | public static OhaStatusLog getOhaStatusLog(String ohaStatusLogContent){ 61 | for(OhaStatusLog ohaStatusLog : OhaStatusLog.values() ){ 62 | if (ohaStatusLogContent.contains(ohaStatusLog.toString())){ 63 | ohaStatusLog.durationBoardRunning = getDurationBoardRunning(ohaStatusLogContent); 64 | return ohaStatusLog; 65 | } 66 | } 67 | return null; 68 | } 69 | 70 | /** 71 | * Recuperar a duração de execução em milissegundos da placa Arduino desde o último reset. 72 | * @param ohaStatusLogContent informar o conteúdo do OhaStatusLog 73 | * @return duração em milissegundos ou -1 se não for possível recupear a duração. 74 | */ 75 | private static long getDurationBoardRunning(String ohaStatusLogContent) { 76 | try { 77 | if ( (ohaStatusLogContent.indexOf(FLAG_BEGIN) != -1) && (ohaStatusLogContent.indexOf(FLAG_END) != -1) ) { 78 | String[] values = ohaStatusLogContent.replace(FLAG_BEGIN, "").replace(FLAG_END, "").split(FLAG_COLUMNS); 79 | return values.length == 2 ? Long.parseLong(values[1]) : 0; 80 | } 81 | } catch (Exception e){ 82 | e.printStackTrace(); 83 | } 84 | return -1; 85 | } 86 | 87 | /** 88 | * Recuperar um OhaStatusLog no final de uma lista de textos. 89 | * @param strings lista de texto. 90 | * @return retornar com um OhaStatusLog válido ou nulo. 91 | */ 92 | public static OhaStatusLog getOhaStatusLog(List strings) { 93 | //Localizar o OhaStatusLog nos 3 ultimos itens da lista. 94 | int initPossitionStatus = strings.size() - 3 < 0? 0 : strings.size() - 3; 95 | for (int item = initPossitionStatus; item <= strings.size(); item++) { 96 | String ohaStatusLogContent = strings.get(item); 97 | OhaStatusLog ohaStatusLog = getOhaStatusLog(ohaStatusLogContent); 98 | if ((ohaStatusLog != null) || item > 3) return ohaStatusLog; 99 | } 100 | return null; 101 | } 102 | 103 | /** 104 | * Verificar se existe um OhaStatusLog em uma lista. 105 | * @param ohaStatusLog informar um OhaStatusLog válido 106 | * @param strings informar uma lista válida. 107 | * @return verdadeiro se o OhaStatusLog existir nos e últimos itens da lista. 108 | */ 109 | public static boolean exists(OhaStatusLog ohaStatusLog , List strings ){ 110 | //Localicar o OhaStatusLog nos 3 ultimos itens da lista. 111 | for (int item = 1; item <= strings.size(); item++) { 112 | String ohaStatusLogName = strings.get(strings.size() - item); 113 | if (ohaStatusLogName.contains(ohaStatusLog.toString())) 114 | return true; 115 | else if (item > 3) break; 116 | } 117 | return false; 118 | } 119 | } 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/data/cursors/IOhaEnergyUseTotalCache.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.data.cursors; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * Recuperar o total de utilização de energia no cache do {@link br.com.brolam.oha.supervisory.data.OhaEnergyUseProvider} 7 | * @author Breno Marques 8 | * @version 1.00 9 | * @since Release 01 10 | */ 11 | public interface IOhaEnergyUseTotalCache { 12 | HashMap getEnergyUseTotalOnCache(long beginDate, long endDate); 13 | } 14 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/data/cursors/OhaEnergyUseBillCursor.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.data.cursors; 2 | 3 | import android.database.AbstractCursor; 4 | import android.database.Cursor; 5 | import android.database.sqlite.SQLiteDatabase; 6 | 7 | import java.util.HashMap; 8 | 9 | import static br.com.brolam.oha.supervisory.data.OhaEnergyUseContract.*; 10 | 11 | 12 | /** 13 | * Recuperar as contas com o total de utilização de energia no período da conta. 14 | * @author Breno Marques 15 | * @version 1.00 16 | * @since Release 01 17 | */ 18 | public class OhaEnergyUseBillCursor extends AbstractCursor { 19 | 20 | IOhaEnergyUseTotalCache iOhaEnergyUseTotalCache; 21 | 22 | SQLiteDatabase sqLiteDatabase; 23 | Cursor cursorEnergyUseBill; 24 | HashMap energyUseTotal; 25 | 26 | public OhaEnergyUseBillCursor(SQLiteDatabase sqLiteDatabase, Cursor cursorEnergyUseBill, IOhaEnergyUseTotalCache iOhaEnergyUseTotalCache){ 27 | this.sqLiteDatabase = sqLiteDatabase; 28 | this.cursorEnergyUseBill = cursorEnergyUseBill; 29 | this.iOhaEnergyUseTotalCache = iOhaEnergyUseTotalCache; 30 | } 31 | 32 | /** 33 | * Recuperar a conta de energia para a nova posição do cursor. 34 | */ 35 | @Override 36 | public boolean onMove(int oldPosition, int newPosition) { 37 | this.cursorEnergyUseBill.moveToPosition(newPosition); 38 | this.energyUseTotal = this.iOhaEnergyUseTotalCache.getEnergyUseTotalOnCache(this.cursorEnergyUseBill.getLong(EnergyUseBillEntry.INDEX_COLUMN_FROM), this.cursorEnergyUseBill.getLong(EnergyUseBillEntry.INDEX_COLUMN_TO) ); 39 | return super.onMove(oldPosition, newPosition) ; 40 | } 41 | 42 | private boolean isCursorEnergyUseBill(int i) { 43 | return ( i < this.cursorEnergyUseBill.getColumnCount()); 44 | } 45 | 46 | @Override 47 | public int getCount() { 48 | return cursorEnergyUseBill.getCount(); 49 | } 50 | 51 | @Override 52 | public String[] getColumnNames() { 53 | throw new UnsupportedOperationException(); 54 | } 55 | 56 | @Override 57 | public String getString(int i) { 58 | if ( isCursorEnergyUseBill(i) ){ 59 | return this.cursorEnergyUseBill.getString(i); 60 | } 61 | int col = i - (this.cursorEnergyUseBill.getColumnCount()); 62 | return energyUseTotal != null? this.energyUseTotal.get(col): ""; 63 | } 64 | 65 | @Override 66 | public short getShort(int i) { 67 | if ( isCursorEnergyUseBill(i) ){ 68 | return this.cursorEnergyUseBill.getShort(i); 69 | } 70 | int col = i - (this.cursorEnergyUseBill.getColumnCount()); 71 | return energyUseTotal != null? Short.parseShort(this.energyUseTotal.get(col)): 0; 72 | } 73 | 74 | @Override 75 | public int getInt(int i) { 76 | if ( isCursorEnergyUseBill(i) ){ 77 | return this.cursorEnergyUseBill.getInt(i); 78 | } 79 | int col = i - (this.cursorEnergyUseBill.getColumnCount()); 80 | return energyUseTotal != null? Integer.parseInt(this.energyUseTotal.get(col)): 0; 81 | } 82 | 83 | @Override 84 | public long getLong(int i) { 85 | if ( isCursorEnergyUseBill(i) ){ 86 | return this.cursorEnergyUseBill.getLong(i); 87 | } 88 | int col = i - (this.cursorEnergyUseBill.getColumnCount()); 89 | return energyUseTotal != null? Long.parseLong(this.energyUseTotal.get(col)): 0; 90 | } 91 | 92 | @Override 93 | public float getFloat(int i) { 94 | if ( isCursorEnergyUseBill(i) ){ 95 | return this.cursorEnergyUseBill.getFloat(i); 96 | } 97 | int col = i - (this.cursorEnergyUseBill.getColumnCount()); 98 | return energyUseTotal != null? Float.parseFloat(this.energyUseTotal.get(col)): 0; 99 | } 100 | 101 | @Override 102 | public double getDouble(int i) { 103 | if ( isCursorEnergyUseBill(i) ){ 104 | return this.cursorEnergyUseBill.getDouble(i); 105 | } 106 | int col = i - (this.cursorEnergyUseBill.getColumnCount()); 107 | return energyUseTotal != null? Double.parseDouble(this.energyUseTotal.get(col)): 0; 108 | } 109 | 110 | @Override 111 | public boolean isNull(int i) { 112 | if ( isCursorEnergyUseBill(i) ){ 113 | return this.cursorEnergyUseBill.isNull(i); 114 | } 115 | return energyUseTotal == null; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/data/cursors/OhaEnergyUseDaysCursor.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.data.cursors; 2 | 3 | import android.database.AbstractCursor; 4 | import android.database.Cursor; 5 | import android.database.sqlite.SQLiteDatabase; 6 | import java.util.Calendar; 7 | import java.util.Date; 8 | import java.util.HashMap; 9 | 10 | import br.com.brolam.library.helpers.OhaHelper; 11 | import static br.com.brolam.oha.supervisory.data.OhaEnergyUseContract.*; 12 | 13 | 14 | /** 15 | * Recuperar a utilização de energia por dia, {@link EnergyUseLogEntry} 16 | * na ordem decrescente. 17 | * @author Breno Marques 18 | * @version 1.00 19 | * @since Release 01 20 | */ 21 | public class OhaEnergyUseDaysCursor extends AbstractCursor { 22 | 23 | IOhaEnergyUseTotalCache iOhaEnergyUseTotalCache; 24 | 25 | SQLiteDatabase sqLiteDatabase; 26 | Date endDate; 27 | Calendar cursorCurrentDate; 28 | HashMap energyUseTotal; 29 | int count; 30 | 31 | public OhaEnergyUseDaysCursor(SQLiteDatabase sqLiteDatabase, Date endDate, int count, IOhaEnergyUseTotalCache iOhaEnergyUseTotalCache){ 32 | this.iOhaEnergyUseTotalCache = iOhaEnergyUseTotalCache; 33 | this.sqLiteDatabase = sqLiteDatabase; 34 | this.endDate = endDate; 35 | this.count = count; 36 | } 37 | 38 | /** 39 | * Recupear a utilização de energia para a nova posição do cursor na ordem decrescente. 40 | * @param oldPosition 41 | * @param newPosition 42 | * @return 43 | */ 44 | @Override 45 | public boolean onMove(int oldPosition, int newPosition) { 46 | this.cursorCurrentDate = Calendar.getInstance(); 47 | this.cursorCurrentDate.setTime(OhaHelper.getDateBegin(endDate)); 48 | this.cursorCurrentDate.add(Calendar.DATE, newPosition * -1); 49 | long longBeginDate = cursorCurrentDate.getTime().getTime(); 50 | long longEndDate = OhaHelper.getDateEnd(cursorCurrentDate.getTime(), false).getTime(); 51 | this.energyUseTotal = this.iOhaEnergyUseTotalCache.getEnergyUseTotalOnCache(longBeginDate, longEndDate); 52 | return super.onMove(oldPosition, newPosition) ; 53 | } 54 | 55 | @Override 56 | public int getCount() { 57 | return count; 58 | } 59 | 60 | @Override 61 | public String[] getColumnNames() { 62 | throw new UnsupportedOperationException(); 63 | 64 | } 65 | 66 | @Override 67 | public String getString(int i) { 68 | if ( EnergyUseLogEntry.INDEX_COLUMN_CALC_DATE == i ){ 69 | return String.valueOf(cursorCurrentDate.getTime().getTime()); 70 | } 71 | return this.energyUseTotal != null? this.energyUseTotal.get(i): ""; 72 | } 73 | 74 | @Override 75 | public short getShort(int i) { 76 | return !isEmpty(i)? Short.parseShort(getString(i)):0; 77 | } 78 | 79 | @Override 80 | public int getInt(int i) { 81 | return !isEmpty(i)? Integer.parseInt(getString(i)):0; 82 | } 83 | 84 | @Override 85 | public long getLong(int i) { 86 | return !isEmpty(i)? Long.parseLong(getString(i)):0; 87 | } 88 | 89 | @Override 90 | public float getFloat(int i) { 91 | return !isEmpty(i)? Float.parseFloat(getString(i)):0; 92 | } 93 | 94 | @Override 95 | public double getDouble(int i) { 96 | return !isEmpty(i)? Double.parseDouble(getString(i)):0; 97 | } 98 | 99 | @Override 100 | public boolean isNull(int i) { 101 | return this.energyUseTotal != null; 102 | } 103 | 104 | private boolean isEmpty(int i){ 105 | String value = getString(i); 106 | return (value == null) || value.isEmpty(); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/data/helpers/OhaSQLHelper.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.data.helpers; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | import android.os.Environment; 7 | import java.io.File; 8 | import java.io.FileFilter; 9 | import java.io.IOException; 10 | import br.com.brolam.library.helpers.OhaHelper; 11 | import static br.com.brolam.oha.supervisory.data.OhaEnergyUseContract.*; 12 | 13 | /** 14 | * Gerencia um banco de dados local para dados do supervisory. 15 | * @author Breno Marques 16 | * @version 1.00 17 | * @since Release 01 18 | */ 19 | public class OhaSQLHelper extends SQLiteOpenHelper { 20 | 21 | public static final int DATABASE_VERSION = 21; 22 | public static final String DATABASE_NAME = "supervisory.db"; 23 | public static final String BACKUP_DIRECTORY = "Oha/Backups"; 24 | 25 | public OhaSQLHelper(Context context) { 26 | super(context, DATABASE_NAME, null, DATABASE_VERSION); 27 | } 28 | 29 | @Override 30 | public void onCreate(SQLiteDatabase sqLiteDatabase) { 31 | //EnergyUseLogEntry 32 | sqLiteDatabase.execSQL(EnergyUseLogEntry.getSQLCreate()); 33 | //EnergyUseBillEntry 34 | sqLiteDatabase.execSQL(EnergyUseBillEntry.getSQLCreate()); 35 | } 36 | 37 | @Override 38 | public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { 39 | switch (newVersion) {} 40 | } 41 | 42 | /** 43 | * Realizar o backup do banco de dados compactado. 44 | * @param context informar um contexto válido. 45 | * @param backupName somente o nome do backup 46 | * @param iZipFile {@link br.com.brolam.library.helpers.OhaHelper.IZipFile} 47 | * @throws IOException 48 | */ 49 | public static void backup(Context context, String backupName, OhaHelper.IZipFile iZipFile) throws IOException { 50 | File sd = new File(Environment.getExternalStorageDirectory(),BACKUP_DIRECTORY); 51 | sd.mkdirs(); 52 | File data = Environment.getDataDirectory(); 53 | if (sd.canWrite()) { 54 | String dataBasePath = String.format("//data//%s//databases//%s", context.getPackageName(), DATABASE_NAME); 55 | File fileDataBase = new File(data, dataBasePath); 56 | if (fileDataBase.exists() ) { 57 | OhaHelper.zipFile(fileDataBase, String.format("%s/%s.zip", sd.getPath(), backupName), iZipFile); 58 | } 59 | } 60 | } 61 | 62 | /** 63 | * Realizar a restouração do banco de dados. 64 | * @param context informar um constexto válido. 65 | * @param backupNamePath informar o caminho completo do backup. 66 | * @param iZipFile {@link br.com.brolam.library.helpers.OhaHelper.IZipFile} 67 | * @throws IOException 68 | */ 69 | public static void restore(Context context, String backupNamePath, OhaHelper.IZipFile iZipFile) throws IOException { 70 | String dataBasePath = String.format("//data//%s//databases//", context.getPackageName()); 71 | File data = Environment.getDataDirectory(); 72 | File directoryDataBase = new File(data, dataBasePath); 73 | OhaHelper.unZipFile(backupNamePath, DATABASE_NAME, directoryDataBase.getPath(), iZipFile); 74 | } 75 | 76 | /** 77 | * Recuperar uma lista com os backups do banco de dados. 78 | */ 79 | public static File[] getBackups() { 80 | //recuperar somente os arquivos com extenção zip: 81 | FileFilter fileFilter = new FileFilter() { 82 | @Override 83 | public boolean accept(File file) { 84 | return file.getName().toLowerCase().contains("zip"); 85 | } 86 | }; 87 | File backupsPath = new File(Environment.getExternalStorageDirectory(), BACKUP_DIRECTORY); 88 | return backupsPath.listFiles(fileFilter); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/sync/OhaSyncService.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.sync; 2 | 3 | import android.app.IntentService; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.SharedPreferences; 7 | import android.preference.PreferenceManager; 8 | import android.support.annotation.Nullable; 9 | 10 | import br.com.brolam.library.helpers.OhaNetworkHelper; 11 | import br.com.brolam.oha.supervisory.sync.tasks.IOhaTask; 12 | import br.com.brolam.oha.supervisory.sync.tasks.OhaBackupTask; 13 | import br.com.brolam.oha.supervisory.sync.tasks.OhaEnergyUseLogTask; 14 | import br.com.brolam.oha.supervisory.ui.helpers.OhaBackupHelper; 15 | 16 | /** 17 | * Executar em background a tarefa de sincronização {@link OhaEnergyUseLogTask} 18 | * @author Breno Marques 19 | * @version 1.00 20 | * @since Release 01 21 | */ 22 | public class OhaSyncService extends IntentService implements IOhaTask { 23 | private static final String TAG = "OhaSyncService"; 24 | //Variável stática para somente permitir uma instância do objeto OhaEnergyUseLogTask. 25 | private static OhaEnergyUseLogTask ohaEnergyUseLogTask; 26 | private static OhaBackupTask ohaBackupTask; 27 | private SharedPreferences preferences; 28 | 29 | public OhaSyncService() { 30 | super(TAG); 31 | } 32 | 33 | @Override 34 | public int onStartCommand(@Nullable Intent intent, int flags, int startId) { 35 | this.preferences = PreferenceManager.getDefaultSharedPreferences(getContext()); 36 | return super.onStartCommand(intent, flags, startId); 37 | } 38 | 39 | /** 40 | * Inicirar o serviço em background. 41 | */ 42 | public static void start(Context context){ 43 | Intent intent = new Intent(context, OhaSyncService.class); 44 | context.startService(intent); 45 | } 46 | 47 | /** 48 | * Executar as tarefas 49 | */ 50 | @Override 51 | protected void onHandleIntent(@Nullable Intent intent) { 52 | //Priorizar a execução da tarefa de backup e restore. 53 | if (isBackupAndRestoreOperation()) { 54 | if ((ohaBackupTask == null) || (ohaBackupTask.isRunning() == false)) { 55 | this.ohaBackupTask = new OhaBackupTask(this); 56 | this.ohaBackupTask.execute(); 57 | } 58 | } else { 59 | if ((ohaEnergyUseLogTask == null) || (ohaEnergyUseLogTask.isRunning() == false)) { 60 | ohaEnergyUseLogTask = new OhaEnergyUseLogTask(this); 61 | ohaEnergyUseLogTask.execute(); 62 | } 63 | } 64 | } 65 | 66 | @Override 67 | public Context getContext() { 68 | return this; 69 | } 70 | 71 | @Override 72 | public SharedPreferences getPreferences() { 73 | return this.preferences; 74 | } 75 | 76 | @Override 77 | public boolean isBackupAndRestoreOperation() { 78 | OhaBackupHelper ohaBackupHelper = new OhaBackupHelper(this.preferences); 79 | return ohaBackupHelper.isBackupTime() || ohaBackupHelper.isRestoreRequest(); 80 | } 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/sync/tasks/IOhaTask.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.sync.tasks; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | /** 7 | * Definir os recursos para executar uma tarefa. 8 | * @author Breno Marques 9 | * @version 1.00 10 | * @since Release 01 11 | */ 12 | public interface IOhaTask { 13 | Context getContext(); 14 | SharedPreferences getPreferences(); 15 | boolean isBackupAndRestoreOperation(); 16 | } 17 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/sync/tasks/OhaBackupTask.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.sync.tasks; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import java.io.IOException; 7 | import java.util.Date; 8 | 9 | import br.com.brolam.library.helpers.OhaHelper; 10 | import br.com.brolam.oha.supervisory.data.helpers.OhaSQLHelper; 11 | import br.com.brolam.oha.supervisory.ui.helpers.OhaBackupHelper; 12 | 13 | /** 14 | * Realizar o backup ou restore do banco de dados. 15 | * @author Breno Marques 16 | * @version 1.00 17 | * @since Release 01 18 | */ 19 | public class OhaBackupTask implements OhaHelper.IZipFile { 20 | private static String TAG = "OhaBackupTask"; 21 | private boolean flagRunning; 22 | private OhaBackupHelper ohaBackupHelper; 23 | private Context context; 24 | 25 | public OhaBackupTask(IOhaTask iOhaTask) { 26 | this.context = iOhaTask.getContext(); 27 | this.ohaBackupHelper = new OhaBackupHelper(iOhaTask.getPreferences()); 28 | this.flagRunning = false; 29 | } 30 | 31 | private void backup() { 32 | try { 33 | this.flagRunning = true; 34 | String backupName = OhaHelper.formatDate(new Date(),"yyyy_MM_dd_hh_mm_ss"); 35 | Log.i(TAG, String.format("Backup %s started", backupName)); 36 | OhaSQLHelper.backup(context, backupName, this); 37 | this.ohaBackupHelper.setLastDateTime(); 38 | Log.i(TAG, String.format("Backup %s completed", backupName)); 39 | } catch (IOException e) { 40 | //TODO Notify that backup did not run with successfully. 41 | Log.e(TAG, String.format("Backup completed with error: %s", e.toString())); 42 | } finally { 43 | this.flagRunning = false; 44 | } 45 | } 46 | 47 | private void restore() { 48 | try { 49 | String backupRestoreFilePath = ohaBackupHelper.getBackupRestoreFilePath(); 50 | Log.i(TAG, String.format("Restore %s started", backupRestoreFilePath)); 51 | this.flagRunning = true; 52 | OhaSQLHelper.restore(context, backupRestoreFilePath, null); 53 | Log.i(TAG, String.format("Restore %s completed", backupRestoreFilePath)); 54 | } catch (IOException e) { 55 | //TODO Notify that restore did not run with successfully. 56 | Log.e(TAG, String.format("Restore completed with error: %s", e.toString())); 57 | } finally { 58 | this.flagRunning = false; 59 | this.ohaBackupHelper.clearBackupRestoreFilePath(); 60 | this.ohaBackupHelper.setLastDateTime(); 61 | //TODO Notify that app will be finalized. 62 | int id= android.os.Process.myPid(); 63 | android.os.Process.killProcess(id); 64 | } 65 | } 66 | 67 | public boolean isRunning() { 68 | return this.flagRunning; 69 | } 70 | 71 | public void execute() { 72 | if (this.ohaBackupHelper.isRestoreRequest()) { 73 | restore(); 74 | } else if (this.ohaBackupHelper.isBackupTime()) { 75 | backup(); 76 | } 77 | } 78 | 79 | @Override 80 | public void progress(long size, long sizeProcessed) { 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/adapters/OhaEnergyUseWattsAdapter.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.adapters; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import br.com.brolam.oha.supervisory.R; 11 | import br.com.brolam.oha.supervisory.ui.adapters.holders.OhaEnergyUseWattsHolder; 12 | 13 | /** 14 | * Adaptador para exibir as linhas com a utilização de energia em watts. 15 | * @author Breno Marques 16 | * @version 1.00 17 | * @since Release 01 18 | */ 19 | public class OhaEnergyUseWattsAdapter extends RecyclerView.Adapter { 20 | 21 | private Context context; 22 | private Cursor cursor = null; 23 | 24 | public OhaEnergyUseWattsAdapter(Context context) { 25 | this.context = context; 26 | } 27 | 28 | public void swapCursor(Cursor newCursor) { 29 | cursor = newCursor; 30 | notifyDataSetChanged(); 31 | } 32 | 33 | @Override 34 | public OhaEnergyUseWattsHolder onCreateViewHolder(ViewGroup parent, int viewType) { 35 | View view = LayoutInflater.from(this.context).inflate(R.layout.holder_energy_use_watts, parent, false); 36 | return new OhaEnergyUseWattsHolder(view); 37 | } 38 | 39 | @Override 40 | public void onBindViewHolder(OhaEnergyUseWattsHolder holder, int position) { 41 | this.cursor.moveToPosition(position); 42 | holder.bindView(this.cursor); 43 | } 44 | 45 | @Override 46 | public int getItemCount() { 47 | return this.cursor == null? 0 : this.cursor.getCount(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/adapters/OhaEnergyUseWhAdapter.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.adapters; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import java.util.ArrayList; 10 | 11 | import br.com.brolam.oha.supervisory.R; 12 | import br.com.brolam.oha.supervisory.data.helpers.OhaEnergyUseLogHelper; 13 | import br.com.brolam.oha.supervisory.ui.adapters.holders.OhaEnergyUseWhHolder; 14 | 15 | /** 16 | * Adaptador para exibir as linhas com a utilização de energia em watts por hora. 17 | * @author Breno Marques 18 | * @version 1.00 19 | * @since Release 01 20 | */ 21 | public class OhaEnergyUseWhAdapter extends RecyclerView.Adapter { 22 | 23 | private Context context; 24 | private ArrayList energyUseWhs; 25 | private double costKwh; 26 | private OhaEnergyUseWhHolder.IOhaEnergyUseWhHolder iOhaEnergyUseWhHolder; 27 | 28 | public OhaEnergyUseWhAdapter(Context context, double costKwh, OhaEnergyUseWhHolder.IOhaEnergyUseWhHolder iOhaEnergyUseWhHolder) { 29 | this.context = context; 30 | this.costKwh = costKwh; 31 | this.iOhaEnergyUseWhHolder = iOhaEnergyUseWhHolder; 32 | this.energyUseWhs = new ArrayList<>(); 33 | } 34 | 35 | public void swapCursor(ArrayList energyUseWhs) { 36 | this.energyUseWhs = energyUseWhs; 37 | notifyDataSetChanged(); 38 | } 39 | 40 | @Override 41 | public OhaEnergyUseWhHolder onCreateViewHolder(ViewGroup parent, int viewType) { 42 | View view = LayoutInflater.from(this.context).inflate(R.layout.holder_energy_use_wh, parent, false); 43 | return new OhaEnergyUseWhHolder(view); 44 | } 45 | 46 | @Override 47 | public void onBindViewHolder(OhaEnergyUseWhHolder holder, int position) { 48 | holder.bindView(this.energyUseWhs.get(position), this.costKwh, iOhaEnergyUseWhHolder); 49 | } 50 | 51 | @Override 52 | public int getItemCount() { 53 | return energyUseWhs.size(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/adapters/OhaMainAdapter.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.adapters; 2 | 3 | 4 | import android.database.Cursor; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.ViewGroup; 8 | 9 | import br.com.brolam.oha.supervisory.R; 10 | import br.com.brolam.oha.supervisory.ui.adapters.holders.OhaEnergyUseBillHolder; 11 | import br.com.brolam.oha.supervisory.ui.adapters.holders.OhaEnergyUseDayHolder; 12 | import br.com.brolam.oha.supervisory.ui.adapters.holders.OhaMainHolder; 13 | import br.com.brolam.oha.supervisory.ui.adapters.holders.OhaMainHolder.IOhaMainHolder; 14 | 15 | /** 16 | * Adaptador para exibir os cartões na tela principal conforme o NavigationView selecionado. 17 | * @author Breno Marques 18 | * @version 1.00 19 | * @since Release 01 20 | */ 21 | public class OhaMainAdapter extends RecyclerView.Adapter { 22 | 23 | IOhaMainHolder iOhaMainHolder; 24 | private Cursor cursor; 25 | //Informar o id do NavigationView MenuItem selecionado. 26 | private int navId; 27 | 28 | public OhaMainAdapter(IOhaMainHolder iOhaMainHolder) { 29 | this.cursor = null; 30 | this.iOhaMainHolder = iOhaMainHolder; 31 | this.navId = -1; 32 | } 33 | 34 | public void swapCursor(Cursor newCursor, int navId ) { 35 | if (( this.cursor != null) && ( this.cursor != newCursor)){ 36 | this.cursor.close(); 37 | this.cursor = newCursor; 38 | } 39 | this.navId = navId; 40 | cursor = newCursor; 41 | notifyDataSetChanged(); 42 | } 43 | 44 | @Override 45 | public OhaMainHolder onCreateViewHolder(ViewGroup parent, int viewType) { 46 | OhaMainHolder viewHolder = null; 47 | if ( this.navId == R.id.nav_energy_use_day){ 48 | viewHolder = new OhaEnergyUseDayHolder(LayoutInflater.from(this.iOhaMainHolder.getContext()).inflate(R.layout.holder_energy_use_day, parent, false)); 49 | } else if ( this.navId == R.id.nav_energy_use_bill){ 50 | viewHolder = new OhaEnergyUseBillHolder( LayoutInflater.from(this.iOhaMainHolder.getContext()).inflate(R.layout.holder_energy_use_bill, parent, false)); 51 | } 52 | return viewHolder; 53 | } 54 | 55 | @Override 56 | public void onBindViewHolder(OhaMainHolder ohaMainHolder, int position) { 57 | this.cursor.moveToPosition(position); 58 | ohaMainHolder.bindView(cursor, iOhaMainHolder); 59 | } 60 | 61 | @Override 62 | public int getItemCount() { 63 | return this.cursor == null? 0 : this.cursor.getCount(); 64 | } 65 | 66 | @Override 67 | public int getItemViewType(int position) { 68 | return this.navId; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/adapters/holders/OhaEnergyUseBillHolder.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.adapters.holders; 2 | 3 | 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.MenuItem; 8 | import android.view.View; 9 | import android.widget.TextView; 10 | 11 | import br.com.brolam.library.helpers.OhaHelper; 12 | import br.com.brolam.oha.supervisory.R; 13 | import static br.com.brolam.oha.supervisory.data.OhaEnergyUseContract.*; 14 | 15 | 16 | /** 17 | * Suporte para exibir um cartão com a utilização de energia de uma conta. 18 | * @author Breno Marques 19 | * @version 1.00 20 | * @since Release 01 21 | */ 22 | public class OhaEnergyUseBillHolder extends OhaMainHolder { 23 | 24 | TextView textViewTitle; 25 | TextView textViewRead; 26 | TextView textViewDailyCost; 27 | TextView textViewBody; 28 | TextView textViewWattsMax; 29 | Toolbar toolbar; 30 | 31 | public OhaEnergyUseBillHolder(View itemView) { 32 | super(itemView); 33 | this.textViewTitle = (TextView)itemView.findViewById(R.id.textViewTitle); 34 | this.textViewRead = (TextView)itemView.findViewById(R.id.textViewRead); 35 | this.textViewDailyCost = (TextView)itemView.findViewById(R.id.textViewDailyCost); 36 | this.textViewBody = (TextView)itemView.findViewById(R.id.textViewBody); 37 | this.textViewWattsMax = (TextView)itemView.findViewById(R.id.textViewWattsMax); 38 | this.toolbar = (Toolbar)itemView.findViewById(R.id.toolbar); 39 | this.toolbar.inflateMenu(R.menu.holder_energy_use_bill); 40 | } 41 | 42 | @Override 43 | public void bindView(final Cursor cursor, final OhaMainHolder.IOhaMainHolder iOhaMainHolder) { 44 | 45 | long billAmountDays = OhaHelper.getAmountDays(cursor.getLong(EnergyUseBillEntry.INDEX_COLUMN_FROM), cursor.getLong(EnergyUseBillEntry.INDEX_COLUMN_TO)); 46 | double billReadingDays = OhaHelper.convertSecondsToDays(cursor.getDouble(EnergyUseBillEntry.INDEX_COLUMN_CALC_DURATION_SUN)); 47 | 48 | Double totalKWH = OhaHelper.convertWhToKWH(cursor.getDouble(EnergyUseBillEntry.INDEX_COLUMN_CALC_WH_TOTAL_SUN)); 49 | Double dailyCost = totalKWH * cursor.getDouble(EnergyUseBillEntry.INDEX_COLUMN_KWH_COST); 50 | Double avgKWH = totalKWH > 0 ? totalKWH / billReadingDays : 0.00; 51 | Double wattsMax = cursor.getDouble(EnergyUseBillEntry.INDEX_COLUMN_CALC_WATTS_MAX); 52 | this.textViewTitle.setText(getEnergyBillTitle(this.textViewTitle.getContext(), cursor.getLong(EnergyUseBillEntry.INDEX_COLUMN_FROM), cursor.getLong(EnergyUseBillEntry.INDEX_COLUMN_TO))); 53 | String read = textViewRead.getContext().getString(R.string.energy_use_bill_card_read, OhaHelper.formatNumber(billReadingDays, "#0.00"), OhaHelper.formatNumber(billAmountDays, "#0") ); 54 | this.textViewRead.setText(read); 55 | this.textViewDailyCost.setText(OhaHelper.formatMoney(dailyCost, "#,##0.00")); 56 | String body = this.textViewBody.getContext().getString(R.string.energy_use_bill_card_body, OhaHelper.formatNumber(totalKWH, "#0.00"), OhaHelper.formatNumber(avgKWH, "##0.00")); 57 | this.textViewBody.setText(body); 58 | this.textViewWattsMax.setText(OhaHelper.formatNumber(wattsMax, ",##0.00")); 59 | final int id = cursor.getInt(EnergyUseBillEntry.INDEX_COLUMN_ID); 60 | final long fromDate = cursor.getLong(EnergyUseBillEntry.INDEX_COLUMN_FROM); 61 | final long toDate = cursor.getLong(EnergyUseBillEntry.INDEX_COLUMN_TO); 62 | final double kwhCost = cursor.getDouble(EnergyUseBillEntry.INDEX_COLUMN_KWH_COST); 63 | this.itemView.setOnClickListener(new View.OnClickListener() { 64 | @Override 65 | public void onClick(View view) { 66 | 67 | if (iOhaMainHolder != null) { 68 | iOhaMainHolder.onEnergyUseBillSelect(id, fromDate, toDate, kwhCost, R.id.action_details); 69 | } 70 | } 71 | }); 72 | 73 | this.toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { 74 | @Override 75 | public boolean onMenuItemClick(MenuItem item) { 76 | iOhaMainHolder.onEnergyUseBillSelect(id, fromDate, toDate, kwhCost, item.getItemId()); 77 | return true; 78 | } 79 | }); 80 | } 81 | 82 | public static String getEnergyBillTitle(Context context, long fromDate, long toDate) { 83 | return context.getString( 84 | R.string.energy_use_bill_card_title, 85 | OhaHelper.formatDate(fromDate, "yyyy, MMM dd"), 86 | OhaHelper.formatDate(toDate, "MMM dd") 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/adapters/holders/OhaEnergyUseDayHolder.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.adapters.holders; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | import android.support.v7.widget.Toolbar; 6 | import android.text.format.DateUtils; 7 | import android.view.MenuItem; 8 | import android.view.View; 9 | import android.widget.TextView; 10 | 11 | import br.com.brolam.library.helpers.OhaHelper; 12 | import br.com.brolam.oha.supervisory.R; 13 | import br.com.brolam.oha.supervisory.data.OhaEnergyUseContract.EnergyUseLogEntry; 14 | 15 | /** 16 | * Suporte para exibir um cartão com a utilização de energia de um dia. 17 | * @author Breno Marques 18 | * @version 1.00 19 | * @since Release 01 20 | */ 21 | public class OhaEnergyUseDayHolder extends OhaMainHolder { 22 | 23 | TextView textViewDay; 24 | TextView textViewAccuracy; 25 | TextView textViewDailyCost; 26 | TextView textViewBody; 27 | TextView textViewWattsMax; 28 | Toolbar toolbar; 29 | 30 | public OhaEnergyUseDayHolder(View itemView) { 31 | super(itemView); 32 | this.textViewDay = (TextView)itemView.findViewById(R.id.textViewDay); 33 | this.textViewAccuracy = (TextView)itemView.findViewById(R.id.textViewAccuracy); 34 | this.textViewDailyCost = (TextView)itemView.findViewById(R.id.textViewDailyCost); 35 | this.textViewBody = (TextView)itemView.findViewById(R.id.textViewBody); 36 | this.textViewWattsMax = (TextView)itemView.findViewById(R.id.textViewWattsMax); 37 | this.toolbar = (Toolbar)itemView.findViewById(R.id.toolbar); 38 | this.toolbar.inflateMenu(R.menu.holder_energy_use_day); 39 | } 40 | 41 | @Override 42 | public void bindView(final Cursor cursor, final IOhaMainHolder iOhaMainHolder) { 43 | Context context = this.itemView.getContext(); 44 | final long beginDate = cursor.getLong(EnergyUseLogEntry.INDEX_COLUMN_CALC_DATE); 45 | final double kwhCost = cursor.getDouble(EnergyUseLogEntry.INDEX_COLUMN_CALC_KWH_COST); 46 | Double duration = cursor.getDouble(EnergyUseLogEntry.INDEX_COLUMN_CALC_DURATION_SUN); 47 | Double totalKWH = OhaHelper.convertWhToKWH(cursor.getDouble(EnergyUseLogEntry.INDEX_COLUMN_CALC_WH_TOTAL_SUN)); 48 | Double dailyCost = totalKWH * kwhCost; 49 | Double avgKWH = totalKWH > 0 ? totalKWH / OhaHelper.convertMillisToHours(duration * 1000) : 0.00; 50 | Double wattsMax = cursor.getDouble(EnergyUseLogEntry.INDEX_COLUMN_CALC_WATTS_MAX); 51 | String titleDay = OhaHelper.formatDate(beginDate, "EEE, dd MMM yyyy"); 52 | this.textViewDay.setText(OhaHelper.formatCamelCase(titleDay)); 53 | this.textViewAccuracy.setText(OhaHelper.formatAccuracyDay(context, duration, DateUtils.isToday(beginDate))); 54 | String strCost = OhaHelper.formatMoney(dailyCost, "#0.00"); 55 | this.textViewDailyCost.setText(strCost); 56 | String body = context.getString(R.string.energy_use_day_card_body, OhaHelper.formatNumber(totalKWH, "#0.00"), OhaHelper.formatNumber(avgKWH, "#0.00")); 57 | this.textViewBody.setText(body); 58 | this.textViewWattsMax.setText(OhaHelper.formatNumber(wattsMax, ",##0.00")); 59 | this.itemView.setOnClickListener(new View.OnClickListener() { 60 | @Override 61 | public void onClick(View view) { 62 | if (iOhaMainHolder != null) { 63 | iOhaMainHolder.onEnergyUseDaySelect(beginDate, kwhCost, R.id.action_details); 64 | } 65 | } 66 | }); 67 | 68 | this.toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { 69 | @Override 70 | public boolean onMenuItemClick(MenuItem item) { 71 | iOhaMainHolder.onEnergyUseDaySelect(beginDate, kwhCost, item.getItemId() ); 72 | return true; 73 | } 74 | }); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/adapters/holders/OhaEnergyUseWattsHolder.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.adapters.holders; 2 | 3 | 4 | import android.database.Cursor; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.text.format.DateUtils; 7 | import android.view.View; 8 | import android.widget.TextView; 9 | 10 | import br.com.brolam.library.helpers.OhaHelper; 11 | import br.com.brolam.oha.supervisory.R; 12 | import br.com.brolam.oha.supervisory.data.helpers.OhaEnergyUseLogHelper; 13 | 14 | /** 15 | * Suporte para exibir um linha com a utilização de energia em watts. 16 | * @author Breno Marques 17 | * @version 1.00 18 | * @since Release 01 19 | */ 20 | public class OhaEnergyUseWattsHolder extends RecyclerView.ViewHolder { 21 | TextView textViewTime; 22 | TextView textViewDuration; 23 | TextView textViewWatts1; 24 | TextView textViewWatts2; 25 | TextView textViewWatts3; 26 | TextView textViewWattsTotal; 27 | 28 | 29 | 30 | public OhaEnergyUseWattsHolder(View itemView) { 31 | super(itemView); 32 | this.textViewTime = (TextView)itemView.findViewById(R.id.textViewTime); 33 | this.textViewDuration = (TextView)itemView.findViewById(R.id.textViewDuration); 34 | this.textViewWatts1 = (TextView)itemView.findViewById(R.id.textViewWatts1); 35 | this.textViewWatts2 = (TextView)itemView.findViewById(R.id.textViewWatts2); 36 | this.textViewWatts3 = (TextView)itemView.findViewById(R.id.textViewWatts3); 37 | this.textViewWattsTotal = (TextView)itemView.findViewById(R.id.textViewWattsTotal); 38 | } 39 | 40 | public void bindView(final Cursor cursor) { 41 | String time = OhaHelper.formatDate(cursor.getLong(OhaEnergyUseLogHelper.INDEX_LOG_DATE_TIME), "HH:mm:ss"); 42 | this.textViewTime.setText(time); 43 | this.textViewDuration.setText(DateUtils.formatElapsedTime(cursor.getLong(OhaEnergyUseLogHelper.INDEX_DURATION))); 44 | if ( this.textViewWatts1 != null) { 45 | textViewWatts1.setText(OhaHelper.formatNumber(cursor.getDouble(OhaEnergyUseLogHelper.INDEX_WATTS_1), "#,##0.00")); 46 | textViewWatts2.setText(OhaHelper.formatNumber(cursor.getDouble(OhaEnergyUseLogHelper.INDEX_WATTS_2), "#,##0.00")); 47 | textViewWatts3.setText(OhaHelper.formatNumber(cursor.getDouble(OhaEnergyUseLogHelper.INDEX_WATTS_3), "#,##0.00")); 48 | } 49 | this.textViewWattsTotal.setText(OhaHelper.formatNumber(cursor.getDouble(OhaEnergyUseLogHelper.INDEX_WATTS_TOTAL), "#,##0.00")); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/adapters/holders/OhaEnergyUseWhHolder.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.adapters.holders; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.text.format.DateUtils; 5 | import android.view.View; 6 | import android.widget.RadioButton; 7 | import android.widget.TextView; 8 | 9 | import java.util.Date; 10 | 11 | import br.com.brolam.library.helpers.OhaHelper; 12 | import br.com.brolam.oha.supervisory.R; 13 | import br.com.brolam.oha.supervisory.data.helpers.OhaEnergyUseLogHelper; 14 | import br.com.brolam.oha.supervisory.ui.OhaEnergyUseDetailsActivity; 15 | 16 | /** 17 | * Suporte para exibir um linha com a utilização de energia em watts por hora. 18 | * @author Breno Marques 19 | * @version 1.00 20 | * @since Release 01 21 | */ 22 | public class OhaEnergyUseWhHolder extends RecyclerView.ViewHolder { 23 | 24 | public interface IOhaEnergyUseWhHolder{ 25 | void onSelectedEnergyUseWh(long beginDateTime, long endDateTime, double kwhCost); 26 | 27 | } 28 | 29 | 30 | RadioButton radioButtonHour; 31 | TextView textViewHour; 32 | TextView textViewDuration; 33 | TextView textViewWh1; 34 | TextView textViewWh2; 35 | TextView textViewWh3; 36 | TextView textViewKwh; 37 | TextView textViewCost; 38 | 39 | public OhaEnergyUseWhHolder(View itemView) { 40 | super(itemView); 41 | this.radioButtonHour = (RadioButton) itemView.findViewById(R.id.radioButtonHour); 42 | this.textViewHour = (TextView) itemView.findViewById(R.id.textViewHour); 43 | this.textViewDuration = (TextView) itemView.findViewById(R.id.textViewDuration); 44 | this.textViewWh1 = (TextView) itemView.findViewById(R.id.textViewWh1); 45 | this.textViewWh2 = (TextView) itemView.findViewById(R.id.textViewWh2); 46 | this.textViewWh3 = (TextView) itemView.findViewById(R.id.textViewWh3); 47 | this.textViewKwh = (TextView) itemView.findViewById(R.id.textViewKwh); 48 | this.textViewCost = (TextView) itemView.findViewById(R.id.textViewCost); 49 | } 50 | 51 | public void bindView(OhaEnergyUseLogHelper.EnergyUseWh energyUseWh, final double kwhCost, final IOhaEnergyUseWhHolder iOhaEnergyUseWhHolder) { 52 | double totalKwh = OhaHelper.convertWhToKWH(energyUseWh.whTotal); 53 | String hour = OhaHelper.formatDate(energyUseWh.dateTime, "HH"); 54 | this.textViewHour.setText(hour); 55 | this.textViewDuration.setText(DateUtils.formatElapsedTime((long) energyUseWh.duration)); 56 | if (this.textViewWh1 != null) { 57 | this.textViewWh1.setText(OhaHelper.formatNumber(energyUseWh.wh1, "#,##0.00")); 58 | this.textViewWh2.setText(OhaHelper.formatNumber(energyUseWh.wh2, "#,##0.00")); 59 | this.textViewWh3.setText(OhaHelper.formatNumber(energyUseWh.wh3, "#,##0.00")); 60 | } 61 | this.textViewKwh.setText(OhaHelper.formatNumber(totalKwh, "#,##0.00")); 62 | this.textViewCost.setText(OhaHelper.formatNumber(totalKwh * kwhCost, "#,##0.00")); 63 | 64 | 65 | Date date = new Date(energyUseWh.dateTime); 66 | final long beginDateHour = OhaHelper.getBeginHour(date).getTime(); 67 | final long endDateHour = OhaHelper.getEndHour(date, false).getTime(); 68 | 69 | radioButtonHour.setOnClickListener(new View.OnClickListener() { 70 | @Override 71 | public void onClick(View view) { 72 | iOhaEnergyUseWhHolder.onSelectedEnergyUseWh(beginDateHour, endDateHour, kwhCost); 73 | radioButtonHour.setChecked(false); 74 | } 75 | }); 76 | 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/adapters/holders/OhaMainHolder.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.adapters.holders; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.View; 7 | 8 | /** 9 | * Suporte base para os cartões que serão exibidos na tela principal 10 | * @author Breno Marques 11 | * @version 1.00 12 | * @since Release 01 13 | */ 14 | public abstract class OhaMainHolder extends RecyclerView.ViewHolder { 15 | 16 | public OhaMainHolder(View itemView) { 17 | super(itemView); 18 | } 19 | 20 | public interface IOhaMainHolder { 21 | Context getContext(); 22 | void onEnergyUseDaySelect(long beginDate, double kwhCost, int menuItemId); 23 | void onEnergyUseBillSelect(int id, long fromDate, long toDate, double kwhCost, int menuItemId); 24 | } 25 | 26 | public void bindView(final Cursor cursor, final OhaMainHolder.IOhaMainHolder iOhaMainHolder) { 27 | 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/fragments/OhaDatePickerDialogPreference.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.fragments; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.content.res.Resources; 6 | import android.preference.DialogPreference; 7 | import android.support.annotation.NonNull; 8 | import android.util.AttributeSet; 9 | import android.view.View; 10 | import android.widget.DatePicker; 11 | 12 | import java.text.ParseException; 13 | import java.util.Calendar; 14 | import java.util.Date; 15 | 16 | import br.com.brolam.oha.supervisory.R; 17 | import br.com.brolam.oha.supervisory.ui.helpers.OhaHelper; 18 | 19 | /** 20 | * Exibir um calendário na tela de configurações para o usuário selecionar uma data. 21 | * Observação: a data será gravada no formato yyMMdd conforme a chave da preferência. 22 | * @author Breno Marques 23 | * @version 1.00 24 | * @since Release 01 25 | */ 26 | public class OhaDatePickerDialogPreference extends DialogPreference { 27 | DatePicker datePicker; 28 | 29 | public OhaDatePickerDialogPreference(Context context, AttributeSet attrs) { 30 | super(context, attrs); 31 | setDialogLayoutResource(R.layout.fragment_date_picker_dialog_preference); 32 | } 33 | 34 | @Override 35 | protected void onBindDialogView(View view) { 36 | super.onBindDialogView(view); 37 | this.datePicker = (DatePicker) view.findViewById(R.id.datePicker); 38 | //Remover o date_picker_header do datePicker se o mesmo existir 39 | View viewDayDatePicker = datePicker.findViewById(Resources.getSystem().getIdentifier("date_picker_header", "id", "android")); 40 | if (viewDayDatePicker != null) { 41 | viewDayDatePicker.setVisibility(View.GONE); 42 | } 43 | Calendar calendar = Calendar.getInstance(); 44 | try { 45 | //recuperar a preferência no formato yyMMdd e converter para um Calendar: 46 | calendar = OhaHelper.getCalendar(this.getPersistedString(OhaHelper.getStrDate(new Date()))); 47 | } catch (ParseException e) { 48 | e.printStackTrace(); 49 | } 50 | datePicker.init(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), null); 51 | } 52 | 53 | @Override 54 | protected void onDialogClosed(boolean positiveResult) { 55 | super.onDialogClosed(positiveResult); 56 | if ( positiveResult){ 57 | Calendar calendar = Calendar.getInstance(); 58 | calendar.set(Calendar.YEAR, datePicker.getYear()); 59 | calendar.set(Calendar.MONTH, datePicker.getMonth()); 60 | calendar.set(Calendar.DAY_OF_MONTH, datePicker.getDayOfMonth()); 61 | String strDate = OhaHelper.getStrDate(calendar.getTime()); 62 | SharedPreferences.Editor editor = getEditor(); 63 | editor.putString(getKey(), strDate); 64 | editor.commit(); 65 | this.setSummary(strDate); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/fragments/OhaRestoreDatabaseFragment.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.fragments; 2 | 3 | import android.app.Activity; 4 | import android.app.DialogFragment; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.annotation.Nullable; 8 | import android.support.v7.widget.Toolbar; 9 | import android.view.LayoutInflater; 10 | import android.view.MenuItem; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.AdapterView; 14 | import android.widget.ArrayAdapter; 15 | import android.widget.ListView; 16 | 17 | import java.io.File; 18 | 19 | import br.com.brolam.oha.supervisory.R; 20 | import br.com.brolam.oha.supervisory.data.helpers.OhaSQLHelper; 21 | 22 | /** 23 | * Exibir um caixa de dialogo com uma lista de backups do banco de dados para o usuário selecionar e acionar o restore. 24 | * @author Breno Marques 25 | * @version 1.00 26 | * @since Release 01 27 | */ 28 | public class OhaRestoreDatabaseFragment extends DialogFragment implements Toolbar.OnMenuItemClickListener, AdapterView.OnItemClickListener { 29 | public static String TAG = OhaRestoreDatabaseFragment.class.getName(); 30 | 31 | public interface IOhaRestoreDatabaseFragment{ 32 | void onRequestRestoreDatabase(File backup); 33 | } 34 | 35 | ListView listView; 36 | Toolbar toolbar; 37 | //Lista de backups disponível. 38 | File[] backups; 39 | 40 | @Override 41 | public void onCreate(Bundle savedInstanceState) { 42 | super.onCreate(savedInstanceState); 43 | this.backups = OhaSQLHelper.getBackups(); 44 | } 45 | 46 | public static OhaRestoreDatabaseFragment getInstance(Activity activity){ 47 | OhaRestoreDatabaseFragment ohaEnergyUseBillFragment = (OhaRestoreDatabaseFragment) activity.getFragmentManager().findFragmentByTag(TAG); 48 | return (ohaEnergyUseBillFragment == null)? new OhaRestoreDatabaseFragment(): ohaEnergyUseBillFragment; 49 | } 50 | 51 | @Override 52 | public void onViewStateRestored(Bundle savedInstanceState) { 53 | super.onViewStateRestored(savedInstanceState); 54 | //Somente exibir o botão de restore quando um backup for selecionado: 55 | parseActionRestoreDatabase(); 56 | 57 | } 58 | 59 | public static void show(Activity activity) { 60 | OhaRestoreDatabaseFragment ohaEnergyUseBillFragment = getInstance(activity); 61 | Bundle bundle = new Bundle(); 62 | ohaEnergyUseBillFragment.setArguments(bundle); 63 | ohaEnergyUseBillFragment.show(activity.getFragmentManager(), TAG); 64 | } 65 | 66 | @Nullable 67 | @Override 68 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { 69 | View view = inflater.inflate(R.layout.fragment_restore_database, container, false); 70 | this.listView = (ListView) view.findViewById(R.id.listView); 71 | int amountBackups = this.backups != null?this.backups.length:0; 72 | String[] backupsName = new String[amountBackups]; 73 | for(int index = 0; index (this.getActivity(), android.R.layout.simple_list_item_checked, backupsName)); 77 | this.toolbar = (Toolbar) view.findViewById(R.id.toolbar); 78 | this.toolbar.inflateMenu(R.menu.fragment_restore_database); 79 | this.toolbar.setOnMenuItemClickListener(this); 80 | this.listView.setOnItemClickListener(this); 81 | //Somente exibir o botão de restore quando um backup for selecionado: 82 | parseActionRestoreDatabase(); 83 | 84 | return view; 85 | } 86 | 87 | @Override 88 | public boolean onMenuItemClick(MenuItem item) { 89 | switch (item.getItemId()){ 90 | case R.id.action_restore_database: 91 | IOhaRestoreDatabaseFragment iOhaRestoreDatabaseFragment = getActivity() instanceof IOhaRestoreDatabaseFragment? (IOhaRestoreDatabaseFragment) getActivity(): null; 92 | if ( iOhaRestoreDatabaseFragment != null){ 93 | iOhaRestoreDatabaseFragment.onRequestRestoreDatabase(this.backups[this.listView.getCheckedItemPosition()]); 94 | } 95 | this.dismiss(); 96 | return false; 97 | case R.id.action_cancel: 98 | this.dismiss(); 99 | return false; 100 | } 101 | return false; 102 | } 103 | 104 | @Override 105 | public void onItemClick(AdapterView adapterView, View view, int position, long id) { 106 | //Somente exibir o botão de restore quando um backup for selecionado: 107 | parseActionRestoreDatabase(); 108 | } 109 | 110 | /** 111 | * Somente exibir o botão de restore quando um backup for selecionado 112 | */ 113 | private void parseActionRestoreDatabase() { 114 | MenuItem menuItem = this.toolbar.getMenu().findItem(R.id.action_restore_database); 115 | if (menuItem != null) 116 | menuItem.setVisible(this.listView.getCheckedItemPosition() >= 0); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/helpers/OhaBackupHelper.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.helpers; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.preference.PreferenceManager; 6 | 7 | import java.util.Calendar; 8 | import java.util.Date; 9 | 10 | import br.com.brolam.oha.supervisory.R; 11 | import br.com.brolam.oha.supervisory.ui.OhaSettingsActivity; 12 | 13 | /** 14 | * Recuperar as preferências de sincronização dos logs de utilização de energia 15 | * {@link OhaSettingsActivity} 16 | * {@link br.com.brolam.oha.supervisory.sync.tasks.OhaEnergyUseLogTask} 17 | * @author Breno Marques 18 | * @version 1.00 19 | * @since Release 01 20 | */ 21 | public class OhaBackupHelper { 22 | public static final String BACKUP_ACTIVATED = "backup_activated"; 23 | public static final String BACKUP_FREQUENCY = "backup_frequency"; 24 | public static final String BACKUP_LAST_DATE_TIME = "backup_last_date_time"; 25 | public static final String BACKUP_RESTORE_FILE_PATH = "backup_restore_file_path"; 26 | 27 | SharedPreferences preferences; 28 | public OhaBackupHelper(SharedPreferences preferences ) { 29 | this.preferences = preferences; 30 | } 31 | 32 | public OhaBackupHelper(Context context ) { 33 | this.preferences = PreferenceManager.getDefaultSharedPreferences(context); 34 | } 35 | 36 | public boolean isActivated() { 37 | return preferences.getBoolean(BACKUP_ACTIVATED, true); 38 | } 39 | 40 | public String getFrequency() { 41 | return preferences.getString(BACKUP_FREQUENCY, "12"); 42 | } 43 | 44 | public long getLastDateTime() { 45 | Long nextDateTime = preferences.getLong(BACKUP_LAST_DATE_TIME, 0); 46 | if ( nextDateTime == 0 ){ 47 | setLastDateTime(); 48 | return getLastDateTime(); 49 | } 50 | return nextDateTime; 51 | } 52 | 53 | public boolean isBackupTime() { 54 | if (isActivated() == false) return false; 55 | Calendar calendar = Calendar.getInstance(); 56 | calendar.setTime(new Date(getLastDateTime())); 57 | calendar.add(Calendar.HOUR, Integer.parseInt(getFrequency())); 58 | return calendar.getTime().before(new Date()); 59 | } 60 | 61 | public boolean isRestoreRequest(){ 62 | return getBackupRestoreFilePath() != null; 63 | } 64 | 65 | public String getBackupRestoreFilePath() { 66 | return preferences.getString(BACKUP_RESTORE_FILE_PATH, null); 67 | } 68 | 69 | public void setActivated(boolean activated) { 70 | SharedPreferences.Editor editor = preferences.edit(); 71 | editor.putBoolean(BACKUP_ACTIVATED, activated); 72 | editor.commit(); 73 | } 74 | 75 | public void setLastDateTime() { 76 | Date date = new Date(); 77 | SharedPreferences.Editor editor = preferences.edit(); 78 | editor.putLong(BACKUP_LAST_DATE_TIME, date.getTime()); 79 | editor.commit(); 80 | } 81 | 82 | public void setBackupTime(){ 83 | Calendar calendar = Calendar.getInstance(); 84 | calendar.add(Calendar.HOUR, Integer.parseInt(getFrequency()) * -1); 85 | SharedPreferences.Editor editor = preferences.edit(); 86 | editor.putLong(BACKUP_LAST_DATE_TIME, calendar.getTime().getTime()); 87 | editor.commit(); 88 | 89 | } 90 | 91 | public void setBackupRestoreFilePath(String backupRestoreFilePath){ 92 | SharedPreferences.Editor editor = preferences.edit(); 93 | editor.putString(BACKUP_RESTORE_FILE_PATH, backupRestoreFilePath); 94 | editor.commit(); 95 | } 96 | 97 | public void clearBackupRestoreFilePath(){ 98 | setBackupRestoreFilePath(null); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/java/br/com/brolam/oha/supervisory/ui/helpers/OhaHelper.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory.ui.helpers; 2 | 3 | 4 | import android.content.Context; 5 | 6 | import br.com.brolam.oha.supervisory.R; 7 | import br.com.brolam.oha.supervisory.data.OhaEnergyUseContract.EnergyUseLogEntry.FilterWatts; 8 | 9 | 10 | /** 11 | * Disponibilizar funcionalidades para converter e formatar texto, número, data e etc específicas 12 | * para o aplicativo Supervisory 13 | * @author Breno Marques 14 | * @version 1.00 15 | * @since Release 01 16 | */ 17 | public class OhaHelper extends br.com.brolam.library.helpers.OhaHelper { 18 | 19 | /** 20 | * Recuperar a descrição dos campos por Fase 21 | */ 22 | public static String getEnergyUsePhaseDescription(Context context, FilterWatts filterWatts){ 23 | switch (filterWatts){ 24 | case NONE: return context.getString(R.string.energy_Use_Column_filter_none); 25 | case PHASE1: return context.getString(R.string.energy_Use_Column_filter_phase1); 26 | case PHASE2: return context.getString(R.string.energy_Use_Column_filter_phase2); 27 | case PHASE3: return context.getString(R.string.energy_Use_Column_filter_phase3); 28 | case TOTAL: return context.getString(R.string.energy_Use_Column_filter_total); 29 | default: return filterWatts.name(); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_add_alert_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_add_alert_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_add_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_add_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_alert_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_alert_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_backup_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_backup_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_backup_setting_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_backup_setting_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_bill_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_bill_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_chart_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_chart_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_delete_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_delete_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_edit_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_edit_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_energy_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_energy_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_filter_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_filter_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_restore_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_restore_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-hdpi/ic_settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-hdpi/ic_settings_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_add_alert_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_add_alert_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_add_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_add_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_alert_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_alert_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_backup_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_backup_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_backup_setting_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_backup_setting_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_bill_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_bill_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_chart_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_chart_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_delete_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_delete_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_edit_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_edit_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_energy_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_energy_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_filter_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_filter_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_restore_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_restore_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-mdpi/ic_settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-mdpi/ic_settings_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_add_alert_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_add_alert_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_add_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_add_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_alert_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_alert_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_backup_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_backup_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_backup_setting_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_backup_setting_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_bill_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_bill_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_chart_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_chart_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_delete_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_delete_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_edit_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_edit_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_energy_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_energy_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_filter_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_filter_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_restore_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_restore_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xhdpi/ic_settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xhdpi/ic_settings_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_add_alert_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_add_alert_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_add_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_add_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_alert_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_alert_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_backup_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_backup_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_backup_setting_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_backup_setting_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_bill_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_bill_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_chart_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_chart_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_delete_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_delete_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_edit_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_edit_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_energy_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_energy_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_filter_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_filter_white.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_restore_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_restore_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/drawable-xxhdpi/ic_settings_black.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout-w480dp/fragment_energy_use_bill.xml: -------------------------------------------------------------------------------- 1 | 7 | 16 | 17 | 22 | 23 | 28 | 29 | 34 | 35 | 41 | 42 | 43 | 44 | 49 | 50 | 55 | 56 | 62 | 63 | 64 | 65 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 88 | 89 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout-w480dp/fragment_energy_use_log_filter.xml: -------------------------------------------------------------------------------- 1 | 7 | 16 | 17 | 22 | 23 | 30 | 31 | 39 | 40 | 41 | 49 | 50 | 54 | 55 | 59 | 60 | 61 | 67 | 68 | 73 | 74 | 80 | 81 | 82 | 83 | 84 | 89 | 90 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout-w480dp/holder_energy_use_watts.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 20 | 26 | 27 | 33 | 34 | 40 | 41 | 47 | 48 | 54 | 55 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout-w480dp/holder_energy_use_wh.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 18 | 19 | 25 | 26 | 32 | 33 | 39 | 40 | 46 | 47 | 53 | 54 | 60 | 61 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout-w480dp/title_energy_use_wh.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 12 | 17 | 18 | 23 | 24 | 29 | 30 | 35 | 36 | 41 | 42 | 47 | 48 | 53 | 54 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout-w480dp/title_energy_use_wh_values.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 20 | 21 | 28 | 29 | 36 | 37 | 44 | 45 | 51 | 52 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/activity_energy_use_details.xml: -------------------------------------------------------------------------------- 1 | 7 | 14 | 15 | 20 | 21 | 26 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 15 | 16 | 20 | 21 | 29 | 30 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/app_bar_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 14 | 15 | 19 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/content_energy_use_details.xml: -------------------------------------------------------------------------------- 1 | 7 | 16 | 17 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 20 | 21 | 25 | 26 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/fragment_date_picker_dialog_preference.xml: -------------------------------------------------------------------------------- 1 | 7 | 16 | 17 | 24 | 25 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/fragment_energy_use_bill.xml: -------------------------------------------------------------------------------- 1 | 7 | 16 | 17 | 22 | 23 | 28 | 29 | 34 | 35 | 41 | 42 | 43 | 44 | 49 | 50 | 55 | 56 | 62 | 63 | 64 | 65 | 66 | 72 | 73 | 79 | 80 | 81 | 82 | 90 | 91 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/fragment_energy_use_log_filter.xml: -------------------------------------------------------------------------------- 1 | 7 | 16 | 17 | 25 | 26 | 34 | 35 | 42 | 43 | 47 | 48 | 52 | 53 | 54 | 60 | 61 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 80 | 81 | 87 | 88 | 89 | 90 | 91 | 92 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/fragment_restore_database.xml: -------------------------------------------------------------------------------- 1 | 8 | 17 | 18 | 24 | 25 | 30 | 31 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/holder_energy_use_bill.xml: -------------------------------------------------------------------------------- 1 | 7 | 13 | 14 | 21 | 22 | 29 | 30 | 37 | 38 | 45 | 46 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 71 | 72 | 81 | 82 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/holder_energy_use_day.xml: -------------------------------------------------------------------------------- 1 | 7 | 13 | 14 | 21 | 22 | 29 | 30 | 37 | 38 | 45 | 46 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 71 | 72 | 81 | 82 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/holder_energy_use_watts.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 12 | 18 | 19 | 25 | 26 | 32 | 33 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/holder_energy_use_wh.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 12 | 17 | 18 | 24 | 25 | 31 | 32 | 38 | 39 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/nav_header_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 22 | 23 | 29 | 30 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/title_energy_use_wh.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 20 | 26 | 27 | 32 | 33 | 38 | 39 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/layout/title_energy_use_wh_values.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 12 | 13 | 20 | 21 | 28 | 29 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/menu/activity_energy_use_details.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/menu/activity_main.xml: -------------------------------------------------------------------------------- 1 | 6 | 8 | 14 | 15 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/menu/activity_main_drawer.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 13 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 35 | 36 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/menu/fragment_energy_use_bill.xml: -------------------------------------------------------------------------------- 1 | 6 | 8 | 9 | 14 | 15 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/menu/fragment_energy_use_log_filter.xml: -------------------------------------------------------------------------------- 1 | 6 | 8 | 9 | 14 | 15 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/menu/fragment_restore_database.xml: -------------------------------------------------------------------------------- 1 | 6 | 8 | 9 | 14 | 15 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/menu/holder_energy_use_bill.xml: -------------------------------------------------------------------------------- 1 | 6 | 8 | 13 | 14 | 20 | 21 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/menu/holder_energy_use_day.xml: -------------------------------------------------------------------------------- 1 | 6 | 8 | 13 | 14 | 20 | 21 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/appSupervisory/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 14 | 15 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/values-w480dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 95 8 | 97 9 | 10 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/values-w720dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 2 9 | 70 10 | 30 11 | 65 12 | 45 13 | 14 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/values-w720dp/styles.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 15 | 16 | 22 | 23 | 29 | 30 | 36 | 37 | 43 | 44 | 51 | 52 | 59 | 60 | 61 | 64 | 65 | 68 | 69 | 72 | 73 | 76 | 77 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 2 9 | 120dp 10 | 50 11 | 50 12 | 45 13 | 70 14 | 15 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | #F44336 8 | #D32F2F 9 | #FF5722 10 | #B6B6B6 11 | #FFFFFF 12 | #000000 13 | 14 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 16dp 9 | 160dp 10 | 11 | 16dp 12 | 16dp 13 | 16dp 14 | 8dp 15 | 180dp 16 | 16dp 17 | 1 18 | 19 | 20 | 98 21 | 80 22 | 98 23 | 90 24 | 25 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 14 | 15 | 19 | 20 | 30 | 31 | 34 | 35 | 38 | 39 | 42 | 43 | 44 | 45 | 51 | 52 | 58 | 59 | 65 | 66 | 72 | 73 | 79 | 80 | 87 | 88 | 95 | 96 | 97 | 100 | 101 | 104 | 105 | 109 | 110 | 113 | 114 | 117 | 118 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/xml/pref_backup.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 14 | 15 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/xml/pref_energy_use.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 13 | 14 | 22 | 23 | 31 | 32 | 40 | 41 | 49 | 50 | 59 | 60 | 69 | 70 | 79 | 80 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/main/res/xml/pref_headers.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 |
12 | 13 |
17 | 18 | -------------------------------------------------------------------------------- /Android/appSupervisory/src/test/java/br/com/brolam/oha/supervisory/JavaUnitTest.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.oha.supervisory; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class JavaUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /Android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | google() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.2.1' 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | google() 19 | } 20 | } 21 | 22 | task clean(type: Delete) { 23 | delete rootProject.buildDir 24 | } 25 | -------------------------------------------------------------------------------- /Android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /Android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Nov 02 12:44:54 BRST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip 7 | -------------------------------------------------------------------------------- /Android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /Android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /Android/library/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Android/library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | minSdkVersion 16 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:25.3.0' 28 | testCompile 'junit:junit:4.12' 29 | } 30 | -------------------------------------------------------------------------------- /Android/library/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/brenomar/android-sdks/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /Android/library/src/androidTest/java/br/com/brolam/library/LibraryTest.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.library; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class LibraryTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("br.com.brolam.library.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Android/library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Android/library/src/main/java/br/com/brolam/library/helpers/OhaNetworkHelper.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.library.helpers; 2 | 3 | import android.content.Context; 4 | import android.net.ConnectivityManager; 5 | import android.net.Network; 6 | import android.os.Build; 7 | import android.util.Log; 8 | 9 | import java.io.BufferedReader; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.io.InputStreamReader; 13 | import java.net.HttpURLConnection; 14 | import java.net.URL; 15 | import java.net.URLConnection; 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | /** 20 | * Created by brenomar on 28/12/15. 21 | */ 22 | public class OhaNetworkHelper { 23 | private static final String DEBUG_TAG = "OhaNetworkHelper: "; 24 | private static Network ohaNetworkConnected = null; 25 | 26 | /** 27 | * Realizar uma requisição HTTP 28 | * 29 | * @param urlConnection Informar a conexão conforme a rede que o registrador está conectado; 30 | * @param method Informar GET, POST ou outros HTTP methods válidos; 31 | * @return Uma lista de textos. 32 | * @throws IOException 33 | */ 34 | public static List requestHttp(URLConnection urlConnection, String method) throws IOException { 35 | ArrayList strings = new ArrayList<>(); 36 | InputStream inputStream = null; 37 | HttpURLConnection httpURLConnection = null; 38 | try { 39 | httpURLConnection = (HttpURLConnection) urlConnection; 40 | httpURLConnection.setReadTimeout(40000 /* milliseconds */); 41 | httpURLConnection.setConnectTimeout(40000 /* milliseconds */); 42 | httpURLConnection.setRequestMethod(method); 43 | httpURLConnection.setDoInput(true); 44 | Log.d(DEBUG_TAG, String.format("Method / URL : %s / %s ", method, urlConnection.getURL())); 45 | httpURLConnection.connect(); 46 | int responseCode = httpURLConnection.getResponseCode(); 47 | Log.d(DEBUG_TAG, "The response is: " + responseCode); 48 | if ((responseCode >= 200) && ((responseCode < 300))) { 49 | inputStream = httpURLConnection.getInputStream(); 50 | BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 51 | 52 | String line; 53 | while ((line = reader.readLine()) != null) { 54 | strings.add(line); 55 | Log.d(DEBUG_TAG, "Line: " + line); 56 | } 57 | reader.close(); 58 | } else { 59 | strings.add(String.format("HTTP_CODE_ERROR:%s", responseCode)); 60 | } 61 | 62 | } finally { 63 | try { 64 | if (inputStream != null) { 65 | inputStream.close(); 66 | } 67 | 68 | if (httpURLConnection != null) { 69 | httpURLConnection.disconnect(); 70 | } 71 | } catch (Exception e) { 72 | Log.e(DEBUG_TAG, e.getMessage()); 73 | } 74 | } 75 | return strings; 76 | } 77 | 78 | /** 79 | * Realizar uma requisição HTTP na rede que o registrador de energia está conectado. 80 | * Também define a rede das próximas requisições; 81 | * 82 | * @param context Informar um contexto válido; 83 | * @param method Informar GET, POST ou outros HTTP methods válidos; 84 | * @return Uma lista de textos. 85 | * @throws IOException 86 | */ 87 | public static List requestHttp(Context context, String method, String strUrl) throws IOException { 88 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 89 | return requestHttp(new URL(strUrl).openConnection(), method); 90 | } 91 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 92 | final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 93 | if (ohaNetworkConnected != null) { 94 | try { 95 | Log.d(DEBUG_TAG, "requestHttp on ohaNetworkConnected: " + ohaNetworkConnected.toString()); 96 | return requestHttp(ohaNetworkConnected.openConnection(new URL(strUrl)), method); 97 | } catch (Exception e) { 98 | Log.d(DEBUG_TAG, "requestHttp fail on network : " + ohaNetworkConnected.toString()); 99 | ohaNetworkConnected = null; 100 | } 101 | } 102 | for (Network network : connMgr.getAllNetworks()) { 103 | try { 104 | List result = requestHttp(network.openConnection(new URL(strUrl)), method); 105 | ohaNetworkConnected = network; 106 | Log.d(DEBUG_TAG, "Set ohaNetworkConnected : " + ohaNetworkConnected.toString()); 107 | return result; 108 | } catch (Exception e) { 109 | Log.e(DEBUG_TAG, e.getMessage()); 110 | } 111 | } 112 | } 113 | return new ArrayList<>(); 114 | } 115 | 116 | /** 117 | * Analisar e validar um URL. 118 | * 119 | * @param hostName informar o IP ou nome do Host. 120 | * @param webMethod Informar o Nome do WebMethod. 121 | * @param params informar os valores dos paramentos. 122 | * @return texto com a URL. 123 | */ 124 | public static String parseUrl(String hostName, String webMethod, String... params) { 125 | StringBuilder url = new StringBuilder(String.format("http://%s/%s", hostName, webMethod)); 126 | for (String param : params) { 127 | url.append(String.format("%s/", param)); 128 | } 129 | return url.toString(); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /Android/library/src/main/java/br/com/brolam/library/ui/fragments/TimeFragment.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.library.ui.fragments; 2 | 3 | import android.app.Fragment; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ArrayAdapter; 10 | import android.widget.Spinner; 11 | import android.widget.TextView; 12 | import java.util.ArrayList; 13 | 14 | import br.com.brolam.library.R; 15 | 16 | /** 17 | * Fragmento para o usuário selecionar uma hora, minuto e segundos divididos em três listas 18 | * @author Breno Marques 19 | * @version 1.00 20 | * @since Release 01 21 | */ 22 | public class TimeFragment extends Fragment { 23 | TextView textViewTitle; 24 | Spinner spinnerHour; 25 | Spinner spinnerMinute; 26 | Spinner spinnerSecond; 27 | int[] spinnerSavedInstanceState = null; 28 | 29 | @Override 30 | public void onCreate(@Nullable Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | } 33 | 34 | @Override 35 | public void onSaveInstanceState(Bundle outState) { 36 | super.onSaveInstanceState(outState); 37 | this.spinnerSavedInstanceState = new int[]{ 38 | this.spinnerHour.getSelectedItemPosition(), 39 | this.spinnerMinute.getSelectedItemPosition(), 40 | this.spinnerSecond.getSelectedItemPosition(), 41 | }; 42 | outState.putIntArray(String.valueOf(this.getId()), spinnerSavedInstanceState); 43 | } 44 | 45 | @Override 46 | public void onViewStateRestored(Bundle savedInstanceState) { 47 | super.onViewStateRestored(savedInstanceState); 48 | if (savedInstanceState == null) return; 49 | if (savedInstanceState.containsKey(String.valueOf(this.getId()))) { 50 | this.spinnerSavedInstanceState = savedInstanceState.getIntArray(String.valueOf(this.getId())); 51 | } 52 | } 53 | 54 | @Nullable 55 | @Override 56 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { 57 | View view = inflater.inflate(R.layout.view_time, container, false); 58 | this.textViewTitle = (TextView) view.findViewById(R.id.textViewTitle); 59 | this.spinnerHour = (Spinner) view.findViewById(R.id.spinnerHour); 60 | this.spinnerMinute = (Spinner) view.findViewById(R.id.spinnerMinute); 61 | this.spinnerSecond = (Spinner) view.findViewById(R.id.spinnerSecond); 62 | return view; 63 | } 64 | 65 | public void build(String title, int selectHour, int selectMinute, int selectSecond) { 66 | this.textViewTitle.setText(title); 67 | this.buildSpinnerHour(selectHour); 68 | this.buildSpinnerMinuteAndSeconds(selectMinute, selectSecond); 69 | this.spinnerSavedInstanceState = null; 70 | 71 | } 72 | 73 | private void buildSpinnerHour(int selectHour) { 74 | ArrayList hours = new ArrayList<>(); 75 | for (byte hour = 0; hour < 24; hour++) { 76 | hours.add(String.format("%02d", hour)); 77 | } 78 | ArrayAdapter arrayAdapter = new ArrayAdapter(textViewTitle.getContext(), android.R.layout.simple_spinner_item, hours); 79 | this.spinnerHour.setAdapter(arrayAdapter); 80 | if (this.spinnerSavedInstanceState != null) { 81 | this.spinnerHour.setSelection(spinnerSavedInstanceState[0]); 82 | } else { 83 | this.spinnerHour.setSelection(selectHour); 84 | } 85 | } 86 | 87 | private void buildSpinnerMinuteAndSeconds(int selectMinute, int selectSecond) { 88 | ArrayList list = new ArrayList<>(); 89 | for (byte index = 0; index < 60; index++) { 90 | list.add(String.format("%02d", index)); 91 | } 92 | ArrayAdapter arrayAdapter = new ArrayAdapter(textViewTitle.getContext(), android.R.layout.simple_spinner_item, list); 93 | this.spinnerMinute.setAdapter(arrayAdapter); 94 | this.spinnerSecond.setAdapter(arrayAdapter); 95 | if (this.spinnerSavedInstanceState != null) { 96 | this.spinnerMinute.setSelection(spinnerSavedInstanceState[1]); 97 | this.spinnerSecond.setSelection(spinnerSavedInstanceState[2]); 98 | } else { 99 | this.spinnerMinute.setSelection(selectMinute); 100 | this.spinnerSecond.setSelection(selectSecond); 101 | } 102 | } 103 | 104 | public int getHour() { 105 | return this.spinnerHour.getSelectedItemPosition(); 106 | } 107 | 108 | public int getMinute() { 109 | return this.spinnerMinute.getSelectedItemPosition(); 110 | } 111 | 112 | public int getSecond() { 113 | return this.spinnerSecond.getSelectedItemPosition(); 114 | } 115 | 116 | public void setEnabled(boolean hour, boolean minute, boolean second) { 117 | this.spinnerHour.setEnabled(hour); 118 | this.spinnerMinute.setEnabled(minute); 119 | this.spinnerSecond.setEnabled(second); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Android/library/src/main/res/anim/fab_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /Android/library/src/main/res/layout/view_time.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 20 | 24 | 25 | 30 | 31 | 36 | 37 | 42 | 43 | -------------------------------------------------------------------------------- /Android/library/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8dp 4 | 5 | -------------------------------------------------------------------------------- /Android/library/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | library 3 | Accuracy %s%% 4 | 5 | -------------------------------------------------------------------------------- /Android/library/src/test/java/br/com/brolam/library/LibraryUnitTest.java: -------------------------------------------------------------------------------- 1 | package br.com.brolam.library; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class LibraryUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /Android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':appSupervisory', ':library' 2 | -------------------------------------------------------------------------------- /Documents/Fritzing/OhaEnergyUseLog.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Fritzing/OhaEnergyUseLog.fzz -------------------------------------------------------------------------------- /Documents/Images/oha_android_studio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_android_studio.png -------------------------------------------------------------------------------- /Documents/Images/oha_arduino_energy_use_logger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_arduino_energy_use_logger.png -------------------------------------------------------------------------------- /Documents/Images/oha_energy_use_logger_00.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_energy_use_logger_00.jpg -------------------------------------------------------------------------------- /Documents/Images/oha_energy_use_logger_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_energy_use_logger_01.jpg -------------------------------------------------------------------------------- /Documents/Images/oha_energy_use_logger_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_energy_use_logger_02.jpg -------------------------------------------------------------------------------- /Documents/Images/oha_energy_use_logger_03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_energy_use_logger_03.jpg -------------------------------------------------------------------------------- /Documents/Images/oha_energy_use_logger_04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_energy_use_logger_04.jpg -------------------------------------------------------------------------------- /Documents/Images/oha_energy_use_logger_05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_energy_use_logger_05.jpg -------------------------------------------------------------------------------- /Documents/Images/oha_esp8266_energy_use_logger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_esp8266_energy_use_logger.png -------------------------------------------------------------------------------- /Documents/Images/oha_fritzing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_fritzing.png -------------------------------------------------------------------------------- /Documents/Images/oha_pcb_energy_use_log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_pcb_energy_use_log.png -------------------------------------------------------------------------------- /Documents/Images/oha_pcb_energy_use_logger.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_pcb_energy_use_logger.pdf -------------------------------------------------------------------------------- /Documents/Images/oha_protoboard_energy_use_log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_protoboard_energy_use_log.png -------------------------------------------------------------------------------- /Documents/Images/oha_supervisory_screens_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_supervisory_screens_01.png -------------------------------------------------------------------------------- /Documents/Images/oha_supervisory_screens_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_supervisory_screens_02.png -------------------------------------------------------------------------------- /Documents/Images/oha_supervisory_screens_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brolam/OpenHomeAnalysis/d2c707b3eac40ebe5210819b99565efd24ac8d85/Documents/Images/oha_supervisory_screens_03.png -------------------------------------------------------------------------------- /Firmware/EnergyUseLoggerEsp8266/.gitignore: -------------------------------------------------------------------------------- 1 | #O Config_model.h é somente um modelo, sendo assim, as novas configurações serão ignoradas. 2 | Config.h 3 | -------------------------------------------------------------------------------- /Firmware/EnergyUseLoggerEsp8266/Config_model.h: -------------------------------------------------------------------------------- 1 | #include 2 | /* 3 | EnergyUseLoggerEsp8266 Config model - Favor copiar esse arquivo para Config.h e também configurar os parâmetros abaixo antes de instalar esse código no módulo ESP8266. 4 | Esse código e parte do projeto: https://github.com/brolam/OpenHomeAnalysis 5 | @author Breno Marques(https://github.com/brolam) em 12/12/2015. 6 | @version 1.00 7 | */ 8 | const char* ESP8266_NAME = "OHA_EUL_1"; //Informar o nome do ESP8266, se possível, no formato OHA_EUL_[Número] para faciliar a localização na lista de redes WiFi. 9 | const char* ESP8266_PASSWORD = "INFO_ESP8266_PASSWORD"; //Informar a senha do ESP8266. 10 | const char* HOME_WIFI_SSID = "INFO_YOUR_WIFI_NAME"; //Informar o mesmo nome da rede WiFi onde o table ou smartphone está conectado. 11 | const char* HOME_WIFI_PASSWORD = "INFO_YOUR_WIFI_PASSWORD"; //Informar a senha da rede WiFi. 12 | const WiFiMode WIFI_MODE = WIFI_AP; //: set mode to WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF. 13 | -------------------------------------------------------------------------------- /Firmware/Samples/SD_EDB/SD_EDB.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #define SD_PIN 10 // SD Card CS pin 3 | 4 | char* db_name = "edb_02.txt"; 5 | File dbFile; 6 | int readedPosition = 0; 7 | int countRecs = 0; 8 | 9 | void setup() { 10 | // put your setup code here, to run once: 11 | pinMode(SD_PIN, OUTPUT); 12 | digitalWrite(SD_PIN, LOW); 13 | 14 | Serial.begin(9600); 15 | Serial.println(" Extended Database Library + External SD CARD storage demo"); 16 | Serial.println(); 17 | if (!SD.begin(SD_PIN)) { 18 | Serial.println("No SD-card."); 19 | return; 20 | } 21 | } 22 | 23 | void selectNext() { 24 | int count = 0; 25 | //char buffer[40]; 26 | dbFile = SD.open(db_name, FILE_READ); 27 | dbFile.seek(readedPosition); 28 | String line = dbFile.readStringUntil(';'); 29 | while ( line.length() > 1 ) { 30 | Serial.print(readedPosition); Serial.print(" / ") ; Serial.println(line); 31 | readedPosition = dbFile.position(); 32 | count++; 33 | if (count > 50) { 34 | break; 35 | } 36 | line = dbFile.readStringUntil(';'); 37 | } 38 | // close the file: 39 | dbFile.close(); 40 | } 41 | 42 | void deleteAll() { 43 | countRecs = 0; 44 | SD.remove(db_name); 45 | } 46 | 47 | void loop() { 48 | dbFile = SD.open(db_name, FILE_WRITE); 49 | digitalWrite(SD_PIN, HIGH); 50 | countRecs++; 51 | dbFile.print(countRecs); 52 | dbFile.print("<100412|1020|1021|1022|1020|252001>;"); 53 | delay(100); 54 | digitalWrite(SD_PIN, LOW); 55 | Serial.print("Saved Rec: "); Serial.print(countRecs); Serial.print(" File Size: "); Serial.println(dbFile.size()); 56 | dbFile.close(); 57 | if (Serial.available()) { 58 | String command = Serial.readString(); 59 | if ( command.indexOf("list") > -1 ) { 60 | selectNext(); 61 | } else if ( command.indexOf("delete") > -1 ) { 62 | deleteAll(); 63 | } 64 | } 65 | } 66 | --------------------------------------------------------------------------------