MEDINAKO 04 app

Instalar app de Medinako

Estos son los pasos para Instalar app de Medinako:

Descargar la aplicación: Descargamos e instalamos el apk de MediNako aqui o también podemos descargar el código aquí.

Verificar los requisitos del sistema: Antes de instalar la aplicación de MediNako, es importante verificar que su dispositivo móvil cumple con los requisitos mínimos del sistema, como la versión del sistema operativo y el espacio de almacenamiento disponible.

Instalar app de Medinako en nuestro teléfono.

Descargamos e instalamos el apk de MediNako aqui

image 43
Descargamos y descomprimimos medinako.zip

image 44
Damos click a instalar la app

image 45
Damos click en instalar de todas formas

image 46
Damos click en Abrir

Instalar app MediNako vía Código

image 54
Buscamos MediNako desde VCS

programadornovato/medinako_android (github.com)

image 55
Pegamos esta url https://github.com/programadornovato/medinako_android y damos click en clonar

image 56

Configurar la app MediNako

image 47
Vamos a área de configuración dando click en el area de configuración o aceptamos ir a la configuración

image 48
Damos click en Buscar Wifi

image 49
Seleccionamos el dispositivo Medidor

image 50
Seleccionamos nuestra red WiFi colocamos su contraseña y damos click en guardar

image 52
Regresamos a inicio damos click en tomar medida y esperamos

Instalar app de Medinako
Obtenemos la medida

Código

Configuracion.kt

package com.programadornovato.medinako

class Configuracion {
    var localOremoto: String = "local"
    var ipServidor = "192.168.100.2"
}

ConfiguracionServidor.kt

package com.programadornovato.medinako

import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.widget.TextView
import android.widget.Toast

class ConfiguracionServidor : AppCompatActivity() {
    var txtIpServidor: TextView? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_configuracion_servidor)
        //LLAMAOS LOS DATOS DE SHARED PREFERENCE
        val mGetSharedPreferences = getSharedPreferences("medinako", Context.MODE_PRIVATE)
        //OBTENEMOS LA IP DEL SEL SERVIDOR A DONDE SE ENVIARA EL AUDIO
        val shareIpServidor = mGetSharedPreferences.getString("ipServidor", null)
        txtIpServidor = findViewById(R.id.txtIpServidor)
        //COLOCAMOS LA IP DEL SERVIDOR EN EL EDITTEXT
        txtIpServidor?.text=shareIpServidor
    }
    fun clickGuardarIpServidor(view: View){
        var mSharedPreferences=getSharedPreferences("medinako", Context.MODE_PRIVATE).edit()
        mSharedPreferences.putString("ipServidor",txtIpServidor?.text.toString())
        mSharedPreferences.commit()
        Toast.makeText(this, "Ip guardada exitosamente ", Toast.LENGTH_LONG).show()
    }
    fun clickIrEntrenar(view: View){
        //Abrir la actividad principal
        var intent = Intent(this, Entrenar ::class.java)
        startActivity(intent)
        //Cerrar esta actividad
        finish()
    }
    fun clickIrConfig(view: View){
        //Abrir la actividad principal
        var intent = Intent(this, CrearMedidor::class.java)
        startActivity(intent)
        //Cerrar esta actividad
        finish()
    }
    fun irPrincipal(view: View){
        val intent = Intent(this, Principal::class.java)
        startActivity(intent)
        finish()
    }

}

CrearMedidor.kt

package com.programadornovato.medinako

import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.text.method.HideReturnsTransformationMethod
import android.text.method.PasswordTransformationMethod
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import com.android.volley.Request
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import org.json.JSONException
import java.lang.Thread.sleep


class CrearMedidor : AppCompatActivity() {
    var tlListaRedes: TableLayout? = null
    var imgRedesWifi: VideoView? = null
    var etPasswordWifi: TextView? = null
    var btnGuadarWifi: Button? = null
    var precargador: LinearLayout? = null
    var btnCargarRedes: Button? = null
    var btnBorrarMedidor: Button? = null
    var rlContenedorPass: RelativeLayout? = null
    var btnBuscarRedMedidor: Button? = null
    var btnIrTomarMedidas: Button? = null
    var tvIndicacion: TextView? = null
    var ssidSeleccionado=""
    var cantcargarRedes=0
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.crear_medidor)
        tlListaRedes = findViewById(R.id.tlListaRedes)
        imgRedesWifi = findViewById(R.id.imgRedesWifi)
        imgRedesWifi?.setOnPreparedListener { it.isLooping = true }
        etPasswordWifi = findViewById(R.id.etPasswordWifi)
        btnGuadarWifi = findViewById(R.id.btnGuadarWifi)
        precargador = findViewById(R.id.precargador)
        btnCargarRedes = findViewById(R.id.btnCargarRedes)
        btnBorrarMedidor = findViewById(R.id.btnBorrarMedidor)
        rlContenedorPass = findViewById(R.id.rlContenedorPass)
        btnBuscarRedMedidor = findViewById(R.id.btnBuscarRedMedidor)
        btnIrTomarMedidas = findViewById(R.id.btnIrTomarMedidas)
        tvIndicacion = findViewById(R.id.tvIndicacion)
        cargarRedes()
    }
    fun clickCargarRedes(view: View){
        cargarRedes()
    }
    fun cargarRedes() {
        if(cantcargarRedes==0){
            precargador?.visibility = View.VISIBLE
        }
        tlListaRedes?.removeAllViews()
        val mGetSharedPreferences = getSharedPreferences("medinako", Context.MODE_PRIVATE)
        val ssidShared = mGetSharedPreferences.getString("ssid", null)
        val PasswordWifiShared = mGetSharedPreferences.getString("PasswordWifi", null)
        val ip = mGetSharedPreferences.getString("ip", null)
        etPasswordWifi?.setText(PasswordWifiShared)
        var queue = Volley.newRequestQueue(this)
        var url="http://192.168.4.1/listawifi"
        var jsonObjectRequest = JsonObjectRequest(Request.Method.GET, url, null,
            { responseListaWifi ->
                imgRedesWifi?.visibility = View.INVISIBLE
                btnCargarRedes?.visibility = View.INVISIBLE
                btnBuscarRedMedidor?.visibility = View.INVISIBLE
                rlContenedorPass?.visibility = View.VISIBLE
                btnGuadarWifi?.visibility = View.VISIBLE
                tvIndicacion?.visibility = View.VISIBLE
                btnBorrarMedidor?.visibility = View.VISIBLE
                if(ip!=null){
                    btnIrTomarMedidas?.visibility = View.VISIBLE
                    textoAdvertencia("verde","Medidor conectado correctamente")
                    preguntaIrPrincipal()
                }
                btnBorrarMedidor?.visibility = View.VISIBLE
                try {
                    var jsonArrayListaRedes = responseListaWifi.getJSONArray("data")
                    val cantRedes=jsonArrayListaRedes.length()
                    //Hacemos un ciclo para recorrer todos los elementos de la red y mostrarlos en el TableLayout
                    for (i in 0 until cantRedes-1) {
                        var jsonObject = jsonArrayListaRedes.getJSONObject(i)
                        val registro = LayoutInflater.from(this).inflate(R.layout.table_row_redes, null, false)
                        val colSSID = registro.findViewById<View>(R.id.colSSID) as TextView
                        val ssid = jsonObject.getString("ssid")
                        colSSID.text = ssid
                        tlListaRedes?.addView(registro)
                        if(ssid == ssidShared) {
                            registro.setBackgroundColor(registro.resources.getColor(R.color.teal_700))
                            ssidSeleccionado = ssid
                        }
                    }
                    btnCargarRedes?.visibility = View.INVISIBLE
                    btnBuscarRedMedidor?.visibility = View.INVISIBLE
                    precargador?.visibility = View.INVISIBLE
                    textoAdvertencia("","")
                } catch (e: JSONException) {
                    e.printStackTrace()
                    precargador?.visibility = View.INVISIBLE
                }
            }, { errorListaWifis ->
                imgRedesWifi?.visibility = View.VISIBLE
                val path = "android.resource://" + packageName + "/" + R.raw.video
                imgRedesWifi?.setVideoURI(Uri.parse(path))
                imgRedesWifi?.start()
                btnCargarRedes?.visibility = View.INVISIBLE
                btnBuscarRedMedidor?.visibility = View.VISIBLE
                precargador?.visibility = View.INVISIBLE
                textoAdvertencia("amarillo","Verifique que esté conectado a la red WiFi Medidor")
            }
        )
        queue.add(jsonObjectRequest)
    }
    fun clickBorrarMedidor(view: View){
        precargador?.visibility = View.VISIBLE
        var queue = Volley.newRequestQueue(this)
        var mSharedPreferences=getSharedPreferences("medinako", Context.MODE_PRIVATE).edit()
        mSharedPreferences.remove("ip").apply()
        mSharedPreferences.remove("ssid").apply()
        mSharedPreferences.remove("PasswordWifi").apply()
        mSharedPreferences.remove("mac").apply()
        var url="http://192.168.4.1/EEPROMborrar"
        var stringRequest = StringRequest(Request.Method.GET, url,
            { response ->
                if(response.equals("1")){
                    Toast.makeText(this, "Medidor borrado", Toast.LENGTH_SHORT).show()
                    var queueReset = Volley.newRequestQueue(this)
                    var urlReset = "http://192.168.4.1/ESPrestart"
                    var stringRequestReset = StringRequest(Request.Method.GET, urlReset,
                        { responseReset ->
                            precargador?.visibility = View.INVISIBLE
                            etPasswordWifi?.text=""
                            //Colocamos todos los registros a color blanco
                            resetearColorLista()
                            notificar()
                            btnIrTomarMedidas?.visibility = View.VISIBLE
                        }, { error ->
                            println(error.toString())
                            precargador?.visibility = View.INVISIBLE
                        }
                    )
                    queueReset.add(stringRequestReset)
                }else{
                    Toast.makeText(this, "Error al borrar el medidor", Toast.LENGTH_SHORT).show()
                    precargador?.visibility = View.INVISIBLE
                }
            }, { error ->
                println(error.toString())
                precargador?.visibility = View.INVISIBLE
            }
        )
        queue.add(stringRequest)
    }
    fun irPrincipal(){
        //Abrir la actividad principal
        var intent = Intent(this, Principal::class.java)
        startActivity(intent)
        //Cerrar esta actividad
        finish()
    }
    fun clickIrEntrenar(view: View){
        //Abrir la actividad principal
        var intent = Intent(this, Entrenar::class.java)
        startActivity(intent)
        //Cerrar esta actividad
        finish()
    }
    fun clickReresar(view: View){
        irPrincipal()
    }
    fun clickIrPrincipal(view: View){
        irPrincipal()
    }
    fun clickDetalles(view: View){
        precargador?.visibility = View.VISIBLE
        var queueDetalle = Volley.newRequestQueue(this)
        val mGetSharedPreferences = getSharedPreferences("medinako", Context.MODE_PRIVATE)
        val ip = mGetSharedPreferences.getString("ip", null)
        val mac = mGetSharedPreferences.getString("mac", null)
        var urlDetalles = "http://$ip/detalles"
        var stringRequestDetalles = StringRequest(Request.Method.GET, urlDetalles,
            { responseDetalles ->
                val builder = AlertDialog.Builder(this)
                builder.apply {
                    setTitle("Detalles de su dispositivo")
                    setMessage(responseDetalles.replace("\\n","\n"))
                    setPositiveButton("Ok",
                        DialogInterface.OnClickListener { dialog, id ->
                            precargador?.visibility = View.INVISIBLE
                            textoAdvertencia("", "")
                        }
                    )
                    setIcon(R.drawable.icon_config_azul)
                }
                builder.create().show()
            }, { error ->
                Toast.makeText(this, "No se encontro el dispositivo "+error, Toast.LENGTH_LONG).show()
                textoAdvertencia("rojo", "No se encontro el dispositivo "+error)
                precargador?.visibility = View.INVISIBLE
            })
        queueDetalle.add(stringRequestDetalles)
    }
    fun clickGuadarWifi(view: View){
        val mGetSharedPreferences = getSharedPreferences("medinako", Context.MODE_PRIVATE)
        val ip = mGetSharedPreferences.getString("ip", null)
        //Llamamos a la funcion que guardara la ip que no entrega el dispositivo esp8266
        var mSharedPreferences=getSharedPreferences("medinako", Context.MODE_PRIVATE).edit()
        mSharedPreferences.putString("PasswordWifi",etPasswordWifi?.text.toString())
        mSharedPreferences.putString("ssid",ssidSeleccionado)
        mSharedPreferences.commit()
        if(ssidSeleccionado.isEmpty()){
            Toast.makeText(this, "Seleccione una red WiFi", Toast.LENGTH_SHORT).show()
            return
        }
        if(etPasswordWifi?.text.toString().isEmpty()){
            Toast.makeText(this, "Ingrese una contraseña", Toast.LENGTH_SHORT).show()
            return
        }
        textoAdvertencia("","")
        precargador?.visibility = View.VISIBLE
        //Enviamos ssid y contraseña de la red seleccionada
        var queue = Volley.newRequestQueue(this)
        var url = "http://192.168.4.1/setting?pass="+etPasswordWifi?.text.toString()+"&ssid="+ssidSeleccionado
        var jsonObjectRequest = StringRequest(Request.Method.GET, url,
            { responseSetting ->
            if(responseSetting.equals("(IP unset)")) {
                textoAdvertencia("rojo","Verifique que la contraseña sea correcta e intente de nuevo")
                Toast.makeText(this, "Intente de nuevo", Toast.LENGTH_SHORT).show()
                var queueReset = Volley.newRequestQueue(this)
                var urlReset = "http://192.168.4.1/ESPrestart"
                var stringRequestReset = StringRequest(Request.Method.GET, urlReset,
                    { responseReset ->
                        precargador?.visibility = View.INVISIBLE
                        btnIrTomarMedidas?.visibility = View.VISIBLE
                        return@StringRequest
                    }, { error ->
                        println(error.toString())
                        sleep(3000)
                        btnIrTomarMedidas?.visibility = View.VISIBLE
                        precargador?.visibility = View.INVISIBLE
                    }
                )
                queueReset.add(stringRequestReset)
                precargador?.visibility = View.INVISIBLE
            }
            //Guardamos la ip a la que nos vamos a conectar
            mSharedPreferences.putString("ip",responseSetting.toString())
            mSharedPreferences.commit()
            precargador?.visibility = View.INVISIBLE
            btnBorrarMedidor?.visibility = View.VISIBLE
            var queueMAC = Volley.newRequestQueue(this)
            var urlMAC="http://192.168.4.1/mac"
            var stringRequestMAC = StringRequest(Request.Method.GET, urlMAC,
                { responseMAC ->
                    var mSharedPreferences=getSharedPreferences("medinako", Context.MODE_PRIVATE).edit()
                    mSharedPreferences.putString("mac",responseMAC.toString())
                    mSharedPreferences.commit()
                    var queueReset = Volley.newRequestQueue(this)
                    var urlReset="http://192.168.4.1/ESPrestart"
                    var stringRequestReset = StringRequest(Request.Method.GET, urlReset,
                        { responseReset ->
                            precargador?.visibility = View.INVISIBLE
                            btnIrTomarMedidas?.visibility = View.VISIBLE
                            textoAdvertencia("verde","Medidor conectado correctamente")
                            preguntaIrPrincipal()
                        }, { errorReset ->
                            println(errorReset.toString())
                            sleep(3000)
                            btnIrTomarMedidas?.visibility = View.VISIBLE
                            precargador?.visibility = View.INVISIBLE
                            textoAdvertencia("verde","Medidor conectado correctamente")
                            preguntaIrPrincipal()
                        }
                    )
                    queueReset.add(stringRequestReset)
                }, { errorNoHayMac ->
                    precargador?.visibility = View.INVISIBLE
                    Toast.makeText(this, "No se pudo obtener la MAC", Toast.LENGTH_SHORT).show()
                    textoAdvertencia("rojo","No se pudo obtener la MAC, intente de nuevo")
                }
            )
            queueMAC.add(stringRequestMAC)
           }, { errorSetting ->
               precargador?.visibility = View.INVISIBLE
               textoAdvertencia("rojo","No se pudo conectar a la red, intente de nuevo")
               //Si ya esta guardada la ip mandamos hacia la activity principal
               if(ip!=null) {
                   irPrincipal()
               }
               //Toast.makeText(this, error.toString(), Toast.LENGTH_SHORT).show()
               println(errorSetting.toString())
           }
        )
        queue.add(jsonObjectRequest)
    }
    //Colocamos todos los registros a color blanco
    fun resetearColorLista(){
        //Colocamos todos los registros a color blanco
        for (i in 0 until tlListaRedes!!.childCount) {
            val child = tlListaRedes!!.getChildAt(i)
            if (child is TableRow) {
                val row = child
                for (x in 0 until row.childCount) {
                    val view = row.getChildAt(x)
                    view.setBackgroundColor(resources.getColor(R.color.white))
                }
            }
        }
    }
    //Funcion que se ejecuta cuando se selecciona una red de la lista (en table_row_redes.xml)
    fun clickListaRedes(view: View) {
        //Colocamos todos los registros a color blanco
        resetearColorLista()
        //obtener texto de la caja de texto
        var ssid = view.findViewById<View>(R.id.colSSID) as TextView
        var ssidText=ssid.text
        ssid.setBackgroundColor(resources.getColor(R.color.teal_700))
        //Colocamos en la variable global el ssid seleccionado para despues gurdarlo en el esp8266
        ssidSeleccionado=ssidText.toString()
    }
    fun ShowHidePass(view: View){
        if(etPasswordWifi?.getTransformationMethod()!!.equals(PasswordTransformationMethod.getInstance())){
            etPasswordWifi?.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
        }
        else{
            etPasswordWifi?.setTransformationMethod(PasswordTransformationMethod.getInstance());
        }
    }
    fun clickBuscarRedMedidor(view: View){
        startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
        sleep(1500)
        btnCargarRedes?.visibility = View.VISIBLE
    }
    fun preguntaIrPrincipal(){
        val builder = AlertDialog.Builder(this)
        builder.apply {
            setTitle("Se a cofigurado exitosamente el medidor")
            setMessage("¿Deseas ir a tomar medidas?")
            setPositiveButton("Si",
                DialogInterface.OnClickListener { dialog, id ->
                    irPrincipal()
                }
            )
            setNegativeButton("No",
                DialogInterface.OnClickListener { dialog, id ->
                    // User cancelled the dialog
                }
            )
            setIcon(R.drawable.icon_inicio_azul)
        }
        builder.create().show()
    }
    fun clickSalir(view: MenuItem) {
        finish()
    }
    fun textoAdvertencia(color:String="rojo",texto:String=""){
        tvIndicacion?.text=texto
        if(color=="rojo"){
            tvIndicacion?.setBackgroundColor(Color.RED)
            tvIndicacion?.setTextColor(Color.WHITE)
        }else if(color=="verde"){
            tvIndicacion?.setBackgroundColor(Color.GREEN)
            tvIndicacion?.setTextColor(Color.BLACK)
        }else if(color=="amarillo"){
            tvIndicacion?.setBackgroundColor(Color.YELLOW)
            tvIndicacion?.setTextColor(Color.BLACK)
        } else if(color==""){
            tvIndicacion?.setBackgroundColor(Color.WHITE)
            tvIndicacion?.setTextColor(Color.BLACK)
        }
    }
    fun notificar(){
        val builder = AlertDialog.Builder(this)
        builder.apply {
            setTitle("Medidor eliminado exitosamente")
            setPositiveButton("OK",
                DialogInterface.OnClickListener { dialog, id ->
                })
        }
        builder.create().show()
    }

}

Entrenar.kt

package com.programadornovato.medinako

import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.widget.*
import com.android.volley.DefaultRetryPolicy
import com.android.volley.Request
import com.android.volley.RetryPolicy
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import org.json.JSONException
import java.lang.Thread.sleep

class Entrenar : AppCompatActivity() {
    var lvEstados: ListView? = null
    var tlListaEstados: TableLayout? = null
    var trVacio: TableRow? = null
    var trMedio: TableRow? = null
    var trLleno: TableRow? = null
    var precargador: LinearLayout? = null
    var tvResultado: TextView? = null
    var estado=""
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_entrenar)
        tlListaEstados = findViewById(R.id.tlListaEstados)
        trVacio = findViewById(R.id.trVacio)
        trMedio = findViewById(R.id.trMedio)
        trLleno = findViewById(R.id.trLleno)
        precargador = findViewById(R.id.precargador)
        tvResultado = findViewById(R.id.tvResultado)
        val ip = getSharedPreferences("medinako", Context.MODE_PRIVATE).getString("ip", null)
        if(ip == null){
            preguntaAbrirConfiguracion()
        }
    }
    fun clickLeer(view: View) {
        precargador?.visibility = View.VISIBLE
        textoAdvertencia("amarillo","Tomando medida, espere 20 segundos para poder entrenar")
        var queueEnciende = Volley.newRequestQueue(this)
        val mGetSharedPreferences = getSharedPreferences("medinako", Context.MODE_PRIVATE)
        val ip = mGetSharedPreferences.getString("ip", null)
        val mac = mGetSharedPreferences.getString("mac", null)
        if(estado.isEmpty()){
            textoAdvertencia("rojo","Selecciona un estado")
            Toast.makeText(this, "Selecciona un estado", Toast.LENGTH_SHORT).show()
            precargador?.visibility = View.INVISIBLE
            return
        }
        //Hacemos que el esp82 vibre y mande los datos al servidor
        var url = "http://$ip/entrenar?estado=$estado"
        var stringRequestEncender = StringRequest(
            Request.Method.GET, url,
            { responseEncender ->
                textoAdvertencia("amarillo","Tomando medida, espere 20 segundos para poder entrenar")
                precargador?.visibility = View.INVISIBLE
                if(mac!=null){
                    precargador?.visibility = View.VISIBLE
                    sleep(25000)
                    precargador?.visibility = View.INVISIBLE
                    textoAdvertencia("verde","Se ha leido el estado $estado, lea otros esados para entrenar o proceda a ENTRENAR")
                }else{
                    textoAdvertencia("rojo","No se encontro MAC del dispositivo porfavor reinicie la aplicacion")
                }
            }, { error ->
                textoAdvertencia("rojo","No se ha podido conectar al medidor")
                precargador?.visibility = View.INVISIBLE
                preguntaAbrirConfiguracion()
            })
        queueEnciende.add(stringRequestEncender)
    }
    fun clickEntrenar(view: View) {
        val configuracion = Configuracion()
        precargador?.visibility = View.VISIBLE
        var queueValidaArchivos = Volley.newRequestQueue(this)
        val mGetSharedPreferences = getSharedPreferences("medinako", Context.MODE_PRIVATE)
        val mac = mGetSharedPreferences.getString("mac", null)
        if(mac==null){
            precargador?.visibility = View.INVISIBLE
            preguntaAbrirConfiguracion()
        }
        var urlValidaArchivos = "http://"+configuracion.ipServidor+":5000/listo-entrenar?mac=$mac"
        var JsonObjectValidaArchivos = JsonObjectRequest(
            Request.Method.GET, urlValidaArchivos,null,
            { responseValidaArchivos ->
                try {
                    var jsonArrayEstados = responseValidaArchivos.getJSONArray("data")
                    var jsonObject = jsonArrayEstados.getJSONObject(0)
                    val Vacio = jsonObject.getInt("Vacio")
                    val Medio = jsonObject.getInt("Medio")
                    val Lleno = jsonObject.getInt("Lleno")
                    var mensaje = ""
                    if(Vacio<10){
                        mensaje = mensaje + "Vacio, "
                    }
                    if(Medio<10){
                        mensaje = mensaje +"Medio, "
                    }
                    if(Lleno<10){
                        mensaje = mensaje +"Lleno, "
                    }
                    if(mensaje.isEmpty()){

                        var queueEntrenar = Volley.newRequestQueue(this)
                        val retryPolicy: RetryPolicy = DefaultRetryPolicy(10000,3,3F)
                        //Nos conectamos al servidor python para que entrene el modelo
                        var urlEntrenar = "http://"+configuracion.ipServidor+":5000/entrenar?mac=$mac"
                        var stringEntrenar = StringRequest(
                            Request.Method.GET, urlEntrenar,
                            { responseEntrenar ->
                                if(responseEntrenar=="1" || responseEntrenar=="1.0" ){
                                    textoAdvertencia("verde","Entrenamiento finalizado EXITOSAMENTE")
                                    precargador?.visibility = View.INVISIBLE
                                }else{
                                    textoAdvertencia("rojo","No se ha podido entrenar el modelo (intentelo de nuevo)")
                                    precargador?.visibility = View.INVISIBLE
                                }
                            }, { error ->
                                textoAdvertencia("rojo","No hay conexión a internet")
                                precargador?.visibility = View.INVISIBLE
                            })
                        stringEntrenar.retryPolicy = retryPolicy
                        queueEntrenar.add(stringEntrenar)


                    }else{
                        //Remover la ultima coma
                        mensaje = mensaje.substring(0, mensaje.length-2)
                        textoAdvertencia("rojo","Falta entrenar $mensaje")
                        precargador?.visibility = View.INVISIBLE
                    }
                } catch (e: JSONException) {
                    e.printStackTrace()
                    precargador?.visibility = View.INVISIBLE
                }


            }, { error ->
                textoAdvertencia("rojo","No se pudo entrenar (Falta subir archivos) "+error.toString())
                precargador?.visibility = View.INVISIBLE
            })
        queueValidaArchivos.add(JsonObjectValidaArchivos)
    }
    fun clickRegistro(view: View){
        trVacio?.setBackgroundColor(resources.getColor(R.color.white))
        trMedio?.setBackgroundColor(resources.getColor(R.color.white))
        trLleno?.setBackgroundColor(resources.getColor(R.color.white))
        view.setBackgroundColor(resources.getColor(R.color.teal_700))
        if (view.id == R.id.trVacio) {
            estado = "Vacio"
        } else if (view.id == R.id.trMedio) {
            estado = "Medio"
        } else if (view.id == R.id.trLleno) {
            estado = "Lleno"
        }
    }
    //Abrir la actividad de entrenar
    fun abrirConfigurarMedidor(menu: MenuItem){
        val intent = Intent(this, CrearMedidor::class.java)
        startActivity(intent)
        finish()
    }
    fun abrirPrincipal(menu:MenuItem){
        val intent = Intent(this, Principal::class.java)
        startActivity(intent)
        finish()
    }
    fun Salir(menu:MenuItem){
        finish()
    }
    fun preguntaAbrirConfiguracion(){
        val builder = AlertDialog.Builder(this)
        builder.apply {
            setTitle("No se encontró el medidor")
            setMessage("Revise que el dispositivo este funcionando.\n¿Desea abrir la cofiguración?")
            setPositiveButton("Si",
                DialogInterface.OnClickListener { dialog, id ->
                    abrirCrearMedidor("menu")
                })
            setNegativeButton("No",
                DialogInterface.OnClickListener { dialog, id ->
                })
        }
        builder.create().show()
    }
    fun abrirCrearMedidor(desde:String=""){
        val intent = Intent(this, CrearMedidor::class.java)
        if(desde=="menu") {
            intent.putExtra("desde", "menu");
        }
        startActivity(intent)
        finish()
    }
    fun clickIrConfig(view: View){
        //Abrir la actividad principal
        var intent = Intent(this, CrearMedidor::class.java)
        startActivity(intent)
        //Cerrar esta actividad
        finish()
    }
    fun clickIrEntrenar(view: View){
        //Abrir la actividad principal
        var intent = Intent(this, Entrenar ::class.java)
        startActivity(intent)
        //Cerrar esta actividad
        finish()
    }
    fun irPrincipal(view: View){
        //Abrir la actividad principal
        var intent = Intent(this, Principal::class.java)
        startActivity(intent)
        //Cerrar esta actividad
        finish()
    }
    fun clickDetalles(view: View){
        precargador?.visibility = View.VISIBLE
        var queueDetalle = Volley.newRequestQueue(this)
        val mGetSharedPreferences = getSharedPreferences("medinako", Context.MODE_PRIVATE)
        val ip = mGetSharedPreferences.getString("ip", null)
        val mac = mGetSharedPreferences.getString("mac", null)
        var urlDetalles = "http://$ip/detalles"
        var stringRequestDetalles = StringRequest(Request.Method.GET, urlDetalles,
            { responseDetalles ->
                val builder = AlertDialog.Builder(this)
                builder.apply {
                    setTitle("Detalles de su dispositivo")
                    setMessage(responseDetalles.replace("\\n","\n"))
                    setPositiveButton("Ok",
                        DialogInterface.OnClickListener { dialog, id ->
                            precargador?.visibility = View.INVISIBLE
                            textoAdvertencia("", "")
                        }
                    )
                    setIcon(R.drawable.icon_config_azul)
                }
                builder.create().show()
            }, { error ->
                Toast.makeText(this, "No se encontro el dispositivo "+error, Toast.LENGTH_LONG).show()
                textoAdvertencia("rojo", "No se encontro el dispositivo "+error)
                precargador?.visibility = View.INVISIBLE
            })
        queueDetalle.add(stringRequestDetalles)
    }
    fun textoAdvertencia(color:String="rojo",texto:String=""){
        tvResultado?.text=texto
        if(color=="rojo"){
            tvResultado?.setBackgroundColor(Color.RED)
            tvResultado?.setTextColor(Color.WHITE)
        }else if(color=="verde"){
            tvResultado?.setBackgroundColor(Color.GREEN)
            tvResultado?.setTextColor(Color.BLACK)
        }else if(color=="amarillo"){
            tvResultado?.setBackgroundColor(Color.YELLOW)
            tvResultado?.setTextColor(Color.BLACK)
        } else if(color==""){
            tvResultado?.setBackgroundColor(Color.WHITE)
            tvResultado?.setTextColor(Color.BLACK)
        }
    }

}

Principal.kt

package com.programadornovato.medinako

import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import com.android.volley.Request
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import org.json.JSONException
import java.lang.Thread.sleep
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*


class Principal : AppCompatActivity() {
    var tlListaResultados: TableLayout?=null
    var precargador: LinearLayout? = null
    var tvRes: TextView? = null
    lateinit var etDia: TextView
    lateinit var calDia: CalendarView
    var fecha = ""
    var yaPreguntoCambiarWifi=false
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_principal)
        tlListaResultados=findViewById(R.id.tlListaResultados)
        precargador = findViewById(R.id.precargador)
        tvRes = findViewById(R.id.tvRes)
        etDia = findViewById(R.id.etDia)
        calDia = findViewById(R.id.calDia)
        calDia.visibility = View.GONE
        val configuracion=Configuracion()
        //LLAMAOS LOS DATOS DE SHARED PREFERENCE
        val mGetSharedPreferences = getSharedPreferences("medinako", Context.MODE_PRIVATE)
        //OBTENEMOS LA IP DEL SEL SERVIDOR A DONDE SE ENVIARA EL AUDIO
        val shareIpServidor = mGetSharedPreferences.getString("ipServidor", "")
        if( shareIpServidor?.length!! > 0 ){
            configuracion.ipServidor= shareIpServidor.toString()
        }

        //Si estamos conectados al wifi medidor preguntamos si queremos conectarnos a una red wifi especifica
        validaSiRedMedidorEstaConectado()
        //Si estamos conectados al wifi internet
        validaSiRedInternetEstaConectado()
        //Colocar en el textview (etDia) la fecha actual
        colocarLaFechaHoy()
        val ip = getSharedPreferences("medinako", Context.MODE_PRIVATE).getString("ip", null)
        //Si no hau IP preguntar si se quiere ir al crear un medidor
        if(ip == null){
            preguntaAbrirConfiguracionMedidor()
        }
        //Si la ip no es nula validamos que exista conexion a internet
        else{
            //Leemos la mac del medidor para guardar su medicion
            var queue = Volley.newRequestQueue(this)
            var url = "http://"+configuracion.ipServidor+":5000/lista-mediciones"
            var stringObjectRequest = StringRequest(Request.Method.GET, url,
                { responseHayInternet ->
                    //Si hay conexion a internet cargamos las tablas
                    cargaTabla()
                },
                { errorHayInternet ->
                    //Si no hay conexion a internet preguntamos si podemos abrir wifi
                    if(yaPreguntoCambiarWifi==false) {
                        yaPreguntoCambiarWifi = true
                        preguntaAbrirConfiguracionWifi()
                    }
                })
            queue.add(stringObjectRequest)
        }
        //Click en el calendario colocamos la fecha en el textview
        calDia.setOnDateChangeListener(
            CalendarView.OnDateChangeListener { view, year, month, dayOfMonth ->
                val mes=String.format("%02d", month+1)
                val dia=String.format("%02d", dayOfMonth)
                fecha = "$year-$mes-$dia"
                etDia.text = "Resultados del dia "+fecha
                cargaTabla()
                calDia?.visibility = View.GONE
            }
        )
    }
    //Validamos si estamos conectados al wifi medidor y si es asi lo reseteamos y preguntamos si se quiere cambiar wifi
    fun validaSiRedMedidorEstaConectado(){
        var queue = Volley.newRequestQueue(this)
        var url = "http://192.168.4.1/ESPrestart"
        var stringObjectRequest = StringRequest(
            Request.Method.GET, url,
            { responseResetMedidor ->
                if(yaPreguntoCambiarWifi==false) {
                    yaPreguntoCambiarWifi=true
                    preguntaAbrirConfiguracionWifi()
                }
            },
            { errorResetMedidor ->
            })
        queue.add(stringObjectRequest)
    }
    fun validaSiRedInternetEstaConectado(){
        var configuracion=Configuracion()
        var queue = Volley.newRequestQueue(this)
        var url="http://"+configuracion.ipServidor+":5000/lista-mediciones"
        var stringObjectRequest = StringRequest(
            Request.Method.GET, url,
            { response ->

            },
            { error ->
                if(yaPreguntoCambiarWifi==false) {
                    yaPreguntoCambiarWifi = true
                    preguntaAbrirConfiguracionWifi()
                }
            })
        queue.add(stringObjectRequest)
    }
    fun colocarLaFechaHoy(){
        val ahora = System.currentTimeMillis()
        val hoy = Date(ahora)
        val df: DateFormat = SimpleDateFormat("yyyy-MM-dd")
        fecha = df.format(hoy)
        etDia.text = "Resultados del dia "+fecha
    }
    fun clickRecargar(view: View){
        val mac = getSharedPreferences("medinako", Context.MODE_PRIVATE).getString("mac", null)
        if(mac!=null){
            cargaTabla()
        }else{
            Toast.makeText(this, "No fue posible ontener la MAC", Toast.LENGTH_LONG).show()
            textoAdvertencia("rojo", "No fue posible ontener la MAC")
        }
    }
    fun cargaTabla(){
        textoAdvertencia("", "")
        val configuracion=Configuracion()
        precargador?.visibility = View.VISIBLE
        tlListaResultados?.removeAllViews()
        val mac= getSharedPreferences("medinako", Context.MODE_PRIVATE).getString("mac", null)
        if(mac==null){
            precargador?.visibility = View.INVISIBLE
            preguntaAbrirConfiguracionMedidor()
            return
        }
        var queueListaMediciones=Volley.newRequestQueue(this)
        //var url="http://"+configuracion.ipServidor+"/medinako/listaMediciones.php?idDispositivo=$mac&fecha=$fecha"
        var url="http://"+configuracion.ipServidor+":5000/lista-mediciones?mac=$mac&fecha=$fecha"
        var jsonObjectRequest=JsonObjectRequest(Request.Method.GET,url,null,
            { responseMediciones ->
                precargador?.visibility = View.INVISIBLE
                try {
                    var jsonArray=responseMediciones.getJSONArray("data")
                    for(i in 0 until jsonArray.length() ){
                        var jsonObject=jsonArray.getJSONObject(i)
                        val registro= LayoutInflater.from(this).inflate(R.layout.table_row_np,null,false)
                        val colEstado=registro.findViewById<View>(R.id.colEstado) as TextView
                        val colFechaCreacion=registro.findViewById<View>(R.id.colSSID) as TextView
                        colFechaCreacion.text=jsonObject.getString("fechaCreacion")
                        colEstado.text=jsonObject.getString("estado")
                        //Cambiar el color de la fila dependiendo del estado
                        if(jsonObject.getString("estado")=="Vacio"){
                            colEstado.setBackgroundColor(Color.argb(100,179,0,0))
                            colEstado.setTextColor(Color.WHITE)
                        }else if(jsonObject.getString("estado")=="Medio"){
                            colEstado.setBackgroundColor(Color.argb(100,255,255,0))
                            colEstado.setTextColor(Color.BLACK)
                        }else if(jsonObject.getString("estado")=="Lleno"){
                            colEstado.setBackgroundColor(Color.argb(100,0,118,0))
                            colEstado.setTextColor(Color.WHITE)
                        }
                        tlListaResultados?.addView(registro)
                    }
                    if(jsonArray.length()==0){
                        textoAdvertencia("amarillo", " No hay resultados para la fecha seleccionada " +
                                "\n  - Seleccione una nueva fecha " +
                                "\n  - O haga click en Recargar " +
                                "\n  - O en Tomar medida")
                    }
                }catch (e: JSONException){
                    e.printStackTrace()
                }
            }, { errorMediciones ->
                Toast.makeText(this,"No se encontro el servidor  "+errorMediciones.toString(),Toast.LENGTH_LONG).show()
                textoAdvertencia("rojo", "No se encontro el servidor  "+errorMediciones.toString())
                precargador?.visibility = View.INVISIBLE
                //Preguntamos si se quiere cambiar de red wifi
                if(yaPreguntoCambiarWifi==false) {
                    yaPreguntoCambiarWifi = true
                    preguntaAbrirConfiguracionWifi()
                }
            }
        )
        queueListaMediciones.add(jsonObjectRequest)
    }
    fun clickIrMedidor(view: MenuItem) {
        abrirCrearMedidor("menu")
    }
    fun abrirCrearMedidor(desde:String=""){
        val intent = Intent(this, CrearMedidor::class.java)
        if(desde=="menu") {
            intent.putExtra("desde", "menu");
        }
        startActivity(intent)
        finish()
    }
    fun abrirEntrenar(menu:MenuItem){
        val intent = Intent(this, Entrenar::class.java)
        startActivity(intent)
        finish()
    }

    fun clickTomarMedida(view: View) {
        precargador?.visibility = View.VISIBLE
        var queueEnciende = Volley.newRequestQueue(this)
        val mGetSharedPreferences = getSharedPreferences("medinako", Context.MODE_PRIVATE)
        val ip = mGetSharedPreferences.getString("ip", null)
        val mac = mGetSharedPreferences.getString("mac", null)
        var url = "http://$ip/encender"
        var stringRequestEncender = StringRequest(Request.Method.GET, url,
            { responseEncender ->
                Toast.makeText(this, "Tomando medida recargue en 20 segundos", Toast.LENGTH_LONG).show()
                textoAdvertencia("amarillo", "Tomando medida recargue en 20 segundos")
                sleep(18000)
                textoAdvertencia("", "")
                precargador?.visibility = View.INVISIBLE
                if(mac!=null){
                    cargaTabla()
                }else{
                    Toast.makeText(this, "No se encontro MAC del dispositivo porfavor reinicie la aplicacion", Toast.LENGTH_LONG).show()
                    textoAdvertencia("rojo", "No se encontro MAC del dispositivo porfavor reinicie la aplicacion")
                }
            }, { error ->
                Toast.makeText(this, "No se encontro el dispositivo "+error, Toast.LENGTH_LONG).show()
                textoAdvertencia("rojo", "No se encontro el dispositivo "+error)
                precargador?.visibility = View.INVISIBLE
                preguntaAbrirConfiguracionMedidor()
            })
        queueEnciende.add(stringRequestEncender)
    }
    fun preguntaAbrirConfiguracionMedidor(){
        val builder = AlertDialog.Builder(this)
        builder.apply {
            setTitle("No se encontró el medidor")
            setMessage("Revise que el dispositivo este funcionando.\n¿Desea abrir la cofiguración?")
            setPositiveButton("Si",
                DialogInterface.OnClickListener { dialog, id ->
                    abrirCrearMedidor("menu")
                }
            )
            setNegativeButton("No",
                DialogInterface.OnClickListener { dialog, id ->
                }
            )
            setIcon(R.drawable.icon_config_azul)
        }
        builder.create().show()
    }
    fun preguntaAbrirConfiguracionWifi(){
        val drawableID: Int = this.getResources().getIdentifier("icon_wifi", "drawable", this.getPackageName())
        val ssid= getSharedPreferences("medinako", Context.MODE_PRIVATE).getString("ssid", null)
        var ssidTexto=""
        if(ssid!=null){
            ssidTexto="Conéctese a la red "+ssid
        }
        val builder = AlertDialog.Builder(this)
        builder.apply {
            setTitle("No tiene acceso a internet")
            setMessage(ssidTexto+"\n¿Desea abrir la cofiguración wifi?")
            setPositiveButton("Si",
                DialogInterface.OnClickListener { dialog, id ->
                    startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
                }
            )
            setNegativeButton("No",
                DialogInterface.OnClickListener { dialog, id ->
                }
            )
            setIcon(R.drawable.icon_no_wifi_azul)
        }
        builder.create().show()

    }
    fun clickSalir(view: MenuItem) {
        finish()
    }
    fun clickIrConfig(view: View){
        //Abrir la actividad principal
        var intent = Intent(this, CrearMedidor::class.java)
        startActivity(intent)
        //Cerrar esta actividad
        finish()
    }

    fun clickDetalles(view: View){
        precargador?.visibility = View.VISIBLE
        var queueEnciende = Volley.newRequestQueue(this)
        val mGetSharedPreferences = getSharedPreferences("medinako", Context.MODE_PRIVATE)
        val ip = mGetSharedPreferences.getString("ip", null)
        val mac = mGetSharedPreferences.getString("mac", null)
        var urlDetalles = "http://$ip/detalles"
        var stringRequestDetalles = StringRequest(Request.Method.GET, urlDetalles,
            { responseDetalles ->
                val builder = AlertDialog.Builder(this)
                builder.apply {
                    setTitle("Detalles de su dispositivo")
                    setMessage(responseDetalles.replace("\\n","\n"))
                    setPositiveButton("Ok",
                        DialogInterface.OnClickListener { dialog, id ->
                            precargador?.visibility = View.INVISIBLE
                            textoAdvertencia("", "")
                        }
                    )
                    setIcon(R.drawable.icon_config_azul)
                }
                builder.create().show()
            }, { error ->
                Toast.makeText(this, "No se encontro el dispositivo "+error, Toast.LENGTH_LONG).show()
                textoAdvertencia("rojo", "No se encontro el dispositivo "+error)
                precargador?.visibility = View.INVISIBLE
            })
        queueEnciende.add(stringRequestDetalles)
    }
    fun clickConfigServ(view: View){
        //Abrir la actividad principal
        var intent = Intent(this, ConfiguracionServidor::class.java)
        startActivity(intent)
        //Cerrar esta actividad
        finish()
    }
    fun clickIrEntrenar(view: View){
        //Abrir la actividad principal
        var intent = Intent(this, Entrenar ::class.java)
        startActivity(intent)
        //Cerrar esta actividad
        finish()
    }
    fun clickVerCalendario(view: View){
        calDia?.visibility = View.VISIBLE
    }

    fun textoAdvertencia(color:String="rojo",texto:String=""){
        tvRes?.text=texto
        if(color=="rojo"){
            tvRes?.setBackgroundColor(Color.RED)
            tvRes?.setTextColor(Color.WHITE)
        }else if(color=="verde"){
            tvRes?.setBackgroundColor(Color.GREEN)
            tvRes?.setTextColor(Color.BLACK)
        }else if(color=="amarillo"){
            tvRes?.setBackgroundColor(Color.YELLOW)
            tvRes?.setTextColor(Color.BLACK)
        } else if(color==""){
            tvRes?.setBackgroundColor(Color.WHITE)
            tvRes?.setTextColor(Color.BLACK)
        }
    }
}

Los comentarios están cerrados.