{"id":3798,"date":"2021-10-24T17:07:25","date_gmt":"2021-10-24T22:07:25","guid":{"rendered":"http:\/\/blog.espol.edu.ec\/girni\/?p=3798"},"modified":"2025-04-07T11:43:34","modified_gmt":"2025-04-07T16:43:34","slug":"lorawan-leer-registros-en-states-json-de-un-punto-con-python","status":"publish","type":"post","link":"https:\/\/blog.espol.edu.ec\/girni\/lorawan-leer-registros-en-states-json-de-un-punto-con-python\/","title":{"rendered":"2.2. Lectura de registros en states.json de un Punto con Python"},"content":{"rendered":"<p>El procesamiento de los datos hist\u00f3ricos de \"<strong>un sensor<\/strong>\" en una ubicaci\u00f3n se realiza con Python desde el archivo generado en la secci\u00f3n anterior. Esta forma se obtiene un archivo nuevo y de menor tama\u00f1o para procesar con los datos de solo el dispositivo que se propone analizar.<\/p>\n<p style=\"text-align: center\"><a href=\"https:\/\/www.dropbox.com\/s\/otm3mshga4jr2k3\/states20211022.json?dl=0\">states20211022.json<\/a><\/p>\n<p>El formato de la tabla es el mismo que el observado en \"DB Browser\".<\/p>\n<p><a href=\"http:\/\/blog.espol.edu.ec\/girni\/files\/2021\/10\/DBBrowser04.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-3799 size-full\" src=\"http:\/\/blog.espol.edu.ec\/girni\/files\/2021\/10\/DBBrowser04.png\" alt=\"DB Browser 04\" width=\"1294\" height=\"323\" srcset=\"https:\/\/blog.espol.edu.ec\/girni\/files\/2021\/10\/DBBrowser04.png 1294w, https:\/\/blog.espol.edu.ec\/girni\/files\/2021\/10\/DBBrowser04-300x75.png 300w, https:\/\/blog.espol.edu.ec\/girni\/files\/2021\/10\/DBBrowser04-768x192.png 768w, https:\/\/blog.espol.edu.ec\/girni\/files\/2021\/10\/DBBrowser04-1024x256.png 1024w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>Los campos a usar son principalmente:<\/p>\n<ul>\n<li>\"<strong><em>entity_id<\/em><\/strong>\" para la selecci\u00f3n de un sensor,<\/li>\n<li>\"<strong><em>attributes<\/em><\/strong>\" donde previamente se configur\u00f3 para guardar\u00a0 el mensaje mqtt de cada transmisi\u00f3n<\/li>\n<li>\"<strong><em>created<\/em><\/strong>\" que contine la fecha y hora de creaci\u00f3n del registro. referenciada a GMT=0.<\/li>\n<\/ul>\n<h2>Parametros guardados en attributes<\/h2>\n<p>El campo \"<em><strong>attributes<\/strong><\/em>\" de cada registro contiene varios par\u00e1metros posibles a usar en el formato del mensaje. Un ejemplo del contenido se indica en el recuadro en rojo mostrado en lala figura anterior, y se presenta a continuaci\u00f3n.<\/p>\n<pre>{<span style=\"color: #008000\">\"applicationID\"<\/span>:<span style=\"color: #008000\">\"4\"<\/span>,\r\n <span style=\"color: #008000\">\"applicationName\"<\/span>:<span style=\"color: #008000\">\"Leer_RssiSNR\"<\/span>,\r\n <span style=\"color: #008000\">\"deviceName\"<\/span>:<span style=\"color: #008000\">\"cc11Pruebas\"<\/span>,\r\n <span style=\"color: #008000\">\"devEUI\"<\/span>:<span style=\"color: #008000\">\"pT7GFa7ePxE=\"<\/span>,\r\n <span style=\"color: #008000\">\"rxInfo\"<\/span>:[{<span style=\"color: #008000\">\"gatewayID\"<\/span>:<span style=\"color: #008000\">\"uCfr\/\/4dylc=\"<\/span>,\r\n            <span style=\"color: #008000\">\"time\"<\/span>:null,<span style=\"color: #008000\">\"timeSinceGPSEpoch\"<\/span>:null,\r\n            <span style=\"color: #008000\">\"rssi\"<\/span>:-63,\r\n            <span style=\"color: #008000\">\"loRaSNR\"<\/span>:10.8,\r\n            <span style=\"color: #008000\">\"channel\"<\/span>:3,\r\n            <span style=\"color: #008000\">\"rfChain\"<\/span>:0,\r\n            <span style=\"color: #008000\">\"board\"<\/span>:0,\r\n            <span style=\"color: #008000\">\"antenna\"<\/span>:0,\r\n            <span style=\"color: #008000\">\"location\"<\/span>:{<span style=\"color: #008000\">\"latitude\"<\/span>:-2.1418242484279535,\r\n                        <span style=\"color: #008000\">\"longitude\"<\/span>:-79.96711134910585,\r\n                        <span style=\"color: #008000\">\"altitude\"<\/span>:20,\r\n                        <span style=\"color: #008000\">\"source\"<\/span>:<span style=\"color: #008000\">\"UNKNOWN\"<\/span>,\r\n                        <span style=\"color: #008000\">\"accuracy\"<\/span>:0},\r\n            <span style=\"color: #008000\">\"fineTimestampType\"<\/span>:<span style=\"color: #008000\">\"NONE\"<\/span>,\r\n            <span style=\"color: #008000\">\"context\"<\/span>:<span style=\"color: #008000\">\"CmMVZA==\"<\/span>,\r\n            <span style=\"color: #008000\">\"uplinkID\"<\/span>:<span style=\"color: #008000\">\"I7NWhENCQyaFtYoZIDw3KQ==\"<\/span>,\r\n            <span style=\"color: #008000\">\"crcStatus\"<\/span>:<span style=\"color: #008000\">\"CRC_OK\"<\/span>}],\r\n <span style=\"color: #008000\">\"txInfo\"<\/span>:{<span style=\"color: #008000\">\"frequency\"<\/span>:902900000,\r\n           <span style=\"color: #008000\">\"modulation\"<\/span>:<span style=\"color: #008000\">\"LORA\"<\/span>,\r\n           <span style=\"color: #008000\">\"loRaModulationInfo\"<\/span>:{<span style=\"color: #008000\">\"bandwidth\"<\/span>:125,\r\n                                 <span style=\"color: #008000\">\"spreadingFactor\"<\/span>:10,\r\n                                 <span style=\"color: #008000\">\"codeRate\"<\/span>:<span style=\"color: #008000\">\"4\/5\"<\/span>,\r\n                                 <span style=\"color: #008000\">\"polarizationInversion\"<\/span>:false}\r\n           },\r\n <span style=\"color: #008000\">\"adr\"<\/span>:true,\r\n <span style=\"color: #008000\">\"dr\"<\/span>:0,\r\n <span style=\"color: #008000\">\"fCnt\"<\/span>:778,\r\n <span style=\"color: #008000\">\"fPort\"<\/span>:4,\r\n <span style=\"color: #008000\">\"data\"<\/span>:<span style=\"color: #008000\">\"KwcK9A8=\"<\/span>,\r\n <span style=\"color: #008000\">\"objectJSON\"<\/span>:<span style=\"color: #008000\">\"{\\\"Down_datarate\\\":10,\\\"Down_rssi\\\":-43,\\\"Down_snr\\\":7,\\\"bateria_V\\\":4.08}\"<\/span>,\r\n <span style=\"color: #008000\">\"tags\"<\/span>:{},\r\n <span style=\"color: #008000\">\"confirmedUplink\"<\/span>:true,\r\n <span style=\"color: #008000\">\"devAddr\"<\/span>:<span style=\"color: #008000\">\"AVqCdA==\"<\/span>,\r\n <span style=\"color: #008000\">\"publishedAt\"<\/span>:<span style=\"color: #008000\">\"2021-10-21T16:28:36.265518462Z\"<\/span>,\r\n <span style=\"color: #008000\">\"unit_of_measurement\"<\/span>:<span style=\"color: #008000\">\"dBm\"<\/span>,\r\n <span style=\"color: #008000\">\"friendly_name\"<\/span>:<span style=\"color: #008000\">\"rssi_up_cc11\"<\/span>\r\n }\r\n<\/pre>\n<p>El formato del ejemplo mostrado se realiz\u00f3 con el editor de Python para facilidad de lectura,<\/p>\n<h2>Procesamiento de datos para un sensor<\/h2>\n<p>El procesamiento de cada registro se realiza separando los <strong>campos<\/strong> a usar, en una tabla los campos representan las\u00a0 columnas a usar.<\/p>\n<p>La selecci\u00f3n del dispositivos se realiza comparando con \"<strong>entity_id<\/strong>\".<\/p>\n<p>El intervalo de fechas permite usar ventanas de tiempo de observaci\u00f3n. La fecha y hora registrada se encuentra referenciadas a GMT=0, dado que en el pais donde se realizan las muestras usa GMT=-5, se realiza un desplazamiento en las horas para facilitar la identificaci\u00f3n de las franjas horarias.<\/p>\n<p>Los identificadores de gateways se simplifican con el diccionario gateway, que deben ser previamente identificados buscando en el archivo.json como \"gatewayID\". Tambi\u00e9n se revisa el n\u00famero de trama (fCnt) para registrar las recepci\u00f3n de tramas repetidas en cada gateway, registrando los valores en una lista, para posteriormente, seleccionar el valor mayor, menor, promedio).<\/p>\n<p>Los par\u00e1metros de recepci\u00f3n en el gateway se encuentran en \"<strong><em>rx_datos<\/em><\/strong>\" en el siguiente orden: rssi, loRaSNR, channel, rfChain, frequency<\/p>\n<p>El resultado de la selecci\u00f3n de los datos se guarda en un nuevo archivo en formato<strong>.csv<\/strong> para facilitar la lectura de los datos con otros programas.<\/p>\n<p>Otra forma de guardar los datos en en formato.json, que puede ser leida con la librer\u00eda Pandas.<\/p>\n<h2>Instrucciones en Python para tabla CSV<\/h2>\n<pre><span style=\"color: #ff0000\"># Lectura de archivo.json hacia una tabla0<\/span>\r\n<span style=\"color: #ff0000\"># selecciona registros de \"un sensor\"<\/span>\r\n<span style=\"color: #ff0000\"># graba unreporte.csv con pandas<\/span>\r\n<span style=\"color: #ff0000\"># http:\/\/blog.espol.edu.ec\/girni\/<\/span>\r\n\r\n<span style=\"color: #d35400\">import<\/span> numpy <span style=\"color: #d35400\">as<\/span> np\r\n<span style=\"color: #d35400\">import<\/span> json\r\n<span style=\"color: #d35400\">import<\/span> pandas <span style=\"color: #d35400\">as<\/span> pd\r\n<span style=\"color: #d35400\">import<\/span> datetime <span style=\"color: #d35400\">as<\/span> dt\r\n<span style=\"color: #d35400\">import<\/span> os\r\n\r\n<span style=\"color: #ff0000\"># INGRESO<\/span>\r\n<span style=\"color: #ff0000\"># archivo de entrada<\/span>\r\nunarchivoDB = <span style=\"color: #008000\">\"states20211022.json\"<\/span>\r\ncarpeta_DB  = <span style=\"color: #008000\">\"BaseDatosJSON\"<\/span>\r\n\r\n<span style=\"color: #ff0000\"># fecha intervalo<\/span>\r\nfechainicio = <span style=\"color: #008000\">\"2021-10-21 11:00:00.0\"<\/span>\r\nfechafin    = <span style=\"color: #008000\">\"2021-10-22 11:50:00.0\"<\/span>\r\nzonaGMT     = -5\r\n\r\nunsensor    = <span style=\"color: #008000\">\"sensor.rssi_up_cc12\"<\/span>\r\nmodelo_disp = <span style=\"color: #008000\">\"modulo\"<\/span> <span style=\"color: #ff0000\"># capsula, modulo desarrollo<\/span>\r\nubicado     = <span style=\"color: #008000\">\"LOS22\"<\/span>\r\ncarpeta_rsm = <span style=\"color: #008000\">\"resultado_Test\"<\/span>\r\n\r\n<span style=\"color: #ff0000\"># gatewayID simplifica identificador <\/span>\r\ngatewayDB   = {<span style=\"color: #008000\">'uCfr\/\/4dylc='<\/span>:<span style=\"color: #008000\">'Gw03'<\/span>}\r\n\r\n<span style=\"color: #ff0000\"># PROCEDIMIENTO -----<\/span>\r\ncampos = [<span style=\"color: #008000\">'domain'<\/span>,<span style=\"color: #008000\">'entity_id'<\/span>,<span style=\"color: #008000\">'state'<\/span>,<span style=\"color: #008000\">'attributes'<\/span>,<span style=\"color: #008000\">'created'<\/span>]\r\n\r\n<span style=\"color: #ff0000\"># Lectura de archivo json, cambia a formato DataFrame<\/span>\r\ntabla0 = pd.DataFrame()\r\narchivo_ruta  = carpeta_DB + <span style=\"color: #008000\">'\/'<\/span> + unarchivoDB\r\narchivoexiste = os.path.exists(archivo_ruta)\r\n<span style=\"color: #d35400\">if<\/span> archivoexiste:\r\n    tabla0 = pd.read_json(archivo_ruta)\r\n    tabla0 = pd.DataFrame(tabla0,columns=campos)\r\n<span style=\"color: #d35400\">else<\/span>:\r\n    <span style=\"color: #ff00ff\">print<\/span>(<span style=\"color: #008000\">' ERROR: NO se encuentra el archivo...'<\/span>)\r\n    <span style=\"color: #ff00ff\">print<\/span>(<span style=\"color: #008000\">'        revise el nombre de archivo. '<\/span>)\r\n\r\n<span style=\"color: #ff0000\"># Revisa cada registro <\/span>\r\nleidos = 0\r\ntabla  = {}\r\n<span style=\"color: #d35400\">if<\/span> archivoexiste:\r\n    <span style=\"color: #ff0000\"># Intervalo de fecha como datetime<\/span>\r\n    hora_desplaza  = dt.timedelta(hours = <span style=\"color: #ff00ff\">abs<\/span>(zonaGMT))\r\n    fechaformatoDB = <span style=\"color: #008000\">'%Y-%m-%dT%H:%M:%S.%f'<\/span>\r\n    fechaformato   = <span style=\"color: #008000\">'%Y-%m-%d %H:%M:%S.%f'<\/span>\r\n    fechatxt     = fechainicio[0:np.min([26,<span style=\"color: #ff00ff\">len<\/span>(fechainicio)])]\r\n    fechainicio  = dt.datetime.strptime(fechatxt,fechaformato)\r\n    fechatxt     = fechafin[0:np.min([26,<span style=\"color: #ff00ff\">len<\/span>(fechafin)])]\r\n    fechafin     = dt.datetime.strptime(fechatxt,fechaformato)\r\n\r\n    <span style=\"color: #ff0000\"># datos de trama<\/span>\r\n    <span style=\"color: #d35400\">for<\/span> cadaregistro <span style=\"color: #d35400\">in<\/span> tabla0.index:\r\n        unatrama   = tabla0[<span style=\"color: #008000\">'attributes'<\/span>][cadaregistro]\r\n        trama_mqtt = json.loads(unatrama)\r\n        \r\n        <span style=\"color: #ff0000\"># selecciona registro por sensor, en fecha y con datos<\/span>\r\n        cualsensor = (tabla0[<span style=\"color: #008000\">'entity_id'<\/span>][cadaregistro] == unsensor)\r\n        \r\n        unafecha = tabla0[<span style=\"color: #008000\">'created'<\/span>][cadaregistro]\r\n        unafecha = unafecha[0:np.min([26,<span style=\"color: #ff00ff\">len<\/span>(unafecha)])]\r\n        unafecha = dt.datetime.strptime(unafecha,fechaformato)\r\n        unafecha = unafecha - hora_desplaza\r\n        \r\n        enfecha  = (unafecha&gt;=fechainicio) <span style=\"color: #d35400\">and<\/span> (unafecha&lt;=fechafin)\r\n        condatos = <span style=\"color: #008000\">'applicationID'<\/span> <span style=\"color: #d35400\">in<\/span> trama_mqtt.keys()\r\n        \r\n        selecciona = cualsensor <span style=\"color: #d35400\">and<\/span> condatos <span style=\"color: #d35400\">and<\/span> enfecha\r\n        <span style=\"color: #d35400\">if<\/span> (selecciona == <span style=\"color: #d35400\">True<\/span>):        \r\n            <span style=\"color: #ff0000\"># datos en la mensaje MQTT<\/span>\r\n            publishedAt = trama_mqtt[<span style=\"color: #008000\">\"publishedAt\"<\/span>]\r\n            publishedAt = publishedAt[0:np.min([26,<span style=\"color: #ff00ff\">len<\/span>(publishedAt)])]\r\n            publishedAt = dt.datetime.strptime(publishedAt,fechaformatoDB)\r\n            publishedAt = publishedAt - hora_desplaza\r\n            \r\n            friendly_name = trama_mqtt[<span style=\"color: #008000\">\"friendly_name\"<\/span>]\r\n            deviceName    = trama_mqtt[<span style=\"color: #008000\">\"deviceName\"<\/span>]\r\n            dispositivo   = friendly_name.split(<span style=\"color: #008000\">'_'<\/span>)[2]\r\n            \r\n            dr      = trama_mqtt[<span style=\"color: #008000\">\"dr\"<\/span>]\r\n            fCnt    = trama_mqtt[<span style=\"color: #008000\">\"fCnt\"<\/span>]\r\n            fPort   = trama_mqtt[<span style=\"color: #008000\">\"fPort\"<\/span>]\r\n            freq_tx = trama_mqtt[<span style=\"color: #008000\">\"txInfo\"<\/span>][<span style=\"color: #008000\">\"frequency\"<\/span>]\r\n            bandwidth = trama_mqtt[<span style=\"color: #008000\">\"txInfo\"<\/span>][<span style=\"color: #008000\">\"loRaModulationInfo\"<\/span>][<span style=\"color: #008000\">\"bandwidth\"<\/span>]\r\n            spreadingFactor = trama_mqtt[<span style=\"color: #008000\">\"txInfo\"<\/span>][<span style=\"color: #008000\">\"loRaModulationInfo\"<\/span>][<span style=\"color: #008000\">\"spreadingFactor\"<\/span>]\r\n\r\n            objectJSON = trama_mqtt[<span style=\"color: #008000\">\"objectJSON\"<\/span>]\r\n            datosensor = json.loads(objectJSON)\r\n                 \r\n            datostrama = {<span style=\"color: #008000\">\"publishedAt\"<\/span>: publishedAt,\r\n                          <span style=\"color: #008000\">\"dispositivo\"<\/span>: dispositivo,\r\n                          <span style=\"color: #008000\">\"fCnt\"<\/span>: fCnt}\r\n            \r\n            <span style=\"color: #ff0000\"># revisa gateway en la red LoRaWan<\/span>\r\n            tamano = <span style=\"color: #ff00ff\">len<\/span>(trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>])\r\n            i = 0\r\n            <span style=\"color: #d35400\">while<\/span> i&lt;tamano:\r\n                gatewayID = trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>][i][<span style=\"color: #008000\">\"gatewayID\"<\/span>]\r\n                rssi      = trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>][i][<span style=\"color: #008000\">\"rssi\"<\/span>]\r\n                loRaSNR   = trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>][i][<span style=\"color: #008000\">\"loRaSNR\"<\/span>]\r\n                channel   = trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>][i][<span style=\"color: #008000\">\"channel\"<\/span>]\r\n                rfChain   = trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>][i][<span style=\"color: #008000\">\"rfChain\"<\/span>]\r\n                gtwNum    = gatewayDB[gatewayID]\r\n                \r\n                <span style=\"color: #ff0000\"># registra en tabla, incluyendo tramas repetidas<\/span>\r\n                datostrama[<span style=\"color: #008000\">'rssi_up'<\/span>]    = rssi\r\n                datostrama[<span style=\"color: #008000\">'snr_up'<\/span>]     = loRaSNR\r\n                datostrama[<span style=\"color: #008000\">'channel_up'<\/span>] = channel\r\n                datostrama[<span style=\"color: #008000\">'rfChain_up'<\/span>] = rfChain\r\n                datostrama[<span style=\"color: #008000\">'gtw_rx'<\/span>]     = gtwNum\r\n                i = i + 1\r\n\r\n            <span style=\"color: #ff0000\"># dato del sensor<\/span>\r\n            equivale = {<span style=\"color: #008000\">'Down_datarate'<\/span>: <span style=\"color: #008000\">'dr_down'<\/span>,\r\n                        <span style=\"color: #008000\">'Down_rssi'<\/span>    : <span style=\"color: #008000\">'rssi_down'<\/span>,\r\n                        <span style=\"color: #008000\">'Down_snr'<\/span>     : <span style=\"color: #008000\">'snr_down'<\/span>,\r\n                        <span style=\"color: #008000\">'bateria_V'<\/span>    : <span style=\"color: #008000\">'bateria_V'<\/span>}\r\n            <span style=\"color: #d35400\">for<\/span> undato <span style=\"color: #d35400\">in<\/span> datosensor:\r\n                <span style=\"color: #d35400\">if<\/span> undato <span style=\"color: #d35400\">in<\/span> equivale.keys():\r\n                    datostrama[equivale[undato]] = datosensor[undato]\r\n                <span style=\"color: #d35400\">else<\/span>:\r\n                    datostrama[undato] = datosensor[undato]\r\n\r\n            <span style=\"color: #ff0000\"># datos, otros valores<\/span>\r\n            datostrama[<span style=\"color: #008000\">\"frequency\"<\/span>] = freq_tx\r\n            datostrama[<span style=\"color: #008000\">\"bandwidth\"<\/span>] = bandwidth\r\n            datostrama[<span style=\"color: #008000\">\"spreadingFactor\"<\/span>] = spreadingFactor\r\n            datostrama[<span style=\"color: #008000\">\"fPort\"<\/span>]   = fPort\r\n            datostrama[<span style=\"color: #008000\">\"dr\"<\/span>]      = dr\r\n            datostrama[<span style=\"color: #008000\">\"created\"<\/span>] = unafecha\r\n\r\n            leidos = leidos + 1\r\n            \r\n            <span style=\"color: #ff0000\"># revisa registro repetido<\/span>\r\n            repetido = <span style=\"color: #d35400\">False<\/span>\r\n            <span style=\"color: #d35400\">if<\/span> leidos&gt;1:\r\n                trama_num  = (fCnt == tabla[leidos-1][<span style=\"color: #008000\">'fCnt'<\/span>])\r\n                fecha_pub  = (publishedAt == tabla[leidos-1][<span style=\"color: #008000\">'publishedAt'<\/span>])\r\n                gtwNum_rep = (gtwNum == tabla[leidos-1][<span style=\"color: #008000\">'gtw_rx'<\/span>])\r\n                repetido   = (trama_num <span style=\"color: #d35400\">and<\/span> fecha_pub <span style=\"color: #d35400\">and<\/span> gtwNum_rep)\r\n            <span style=\"color: #d35400\">if<\/span> <span style=\"color: #d35400\">not<\/span>(repetido):\r\n                tabla[leidos] = datostrama\r\n            <span style=\"color: #d35400\">else<\/span>:\r\n                leidos = leidos - 1\r\n\r\n    <span style=\"color: #ff0000\"># convierte diccionario a DataFrame<\/span>\r\n    <span style=\"color: #d35400\">if<\/span> <span style=\"color: #ff00ff\">len<\/span>(tabla)&gt;0:\r\n        tabla = pd.DataFrame(tabla)\r\n        tabla = tabla.T\r\n        <span style=\"color: #ff0000\"># a\u00f1ade ubicaci\u00f3n y modelo (capsula o modulo desarrollo)<\/span>\r\n        tabla.insert(1,<span style=\"color: #008000\">'ubicado'<\/span>,ubicado)\r\n        tabla.insert(2,<span style=\"color: #008000\">'modelo_disp'<\/span>,modelo_disp)\r\n        \r\n<span style=\"color: #ff0000\"># directorio de resultados<\/span>\r\n<span style=\"color: #d35400\">if<\/span> <span style=\"color: #ff00ff\">len<\/span>(carpeta_rsm) &gt; 0:\r\n    <span style=\"color: #d35400\">if<\/span> <span style=\"color: #d35400\">not<\/span>(os.path.exists(carpeta_rsm)):\r\n        os.makedirs(carpeta_rsm)\r\n    carpeta_rsm = carpeta_rsm + <span style=\"color: #008000\">'\/'<\/span>\r\n\r\n<span style=\"color: #ff0000\"># SALIDA<\/span>\r\n<span style=\"color: #ff00ff\">print<\/span>(<span style=\"color: #008000\">'registros leidos:     '<\/span>, <span style=\"color: #ff00ff\">len<\/span>(tabla0))\r\n<span style=\"color: #ff00ff\">print<\/span>(<span style=\"color: #008000\">'registros procesados: '<\/span>, leidos)\r\n<span style=\"color: #ff00ff\">print<\/span>(tabla)\r\n\r\n<span style=\"color: #ff0000\"># guarda el reporte en csv<\/span>\r\n<span style=\"color: #d35400\">if<\/span> <span style=\"color: #ff00ff\">len<\/span>(tabla)&gt;0:\r\n    unreporte = carpeta_rsm+<span style=\"color: #008000\">'data_'<\/span>+ubicado+<span style=\"color: #008000\">'.csv'<\/span>\r\n    tabla.to_csv(unreporte)\r\n<\/pre>\n<p>el resultado de puede visualiza como:<\/p>\n<pre>registros leidos:      7090\r\nregistros procesados:  98\r\n                  publishedAt ubicado modelo_disp dispositivo  ... spreadingFactor fPort dr                    created\r\n1  2021-10-21 11:34:07.079188   LOS22      modulo        cc12  ...              10     4  0 2021-10-21 11:34:07.105036\r\n2  2021-10-21 11:49:07.862255   LOS22      modulo        cc12  ...              10     4  0 2021-10-21 11:49:07.876219\r\n3  2021-10-21 12:04:07.931128   LOS22      modulo        cc12  ...              10     4  0 2021-10-21 12:04:07.943781\r\n4  2021-10-21 12:19:08.489097   LOS22      modulo        cc12  ...              10     4  0 2021-10-21 12:19:08.504848\r\n5  2021-10-21 12:34:08.479274   LOS22      modulo        cc12  ...              10     4  0 2021-10-21 12:34:08.494229\r\n..                        ...     ...         ...         ...  ...             ...   ... ..                        ...\r\n94 2021-10-22 10:49:46.742877   LOS22      modulo        cc12  ...              10     4  0 2021-10-22 10:49:46.756601\r\n95 2021-10-22 11:04:47.636628   LOS22      modulo        cc12  ...              10     4  0 2021-10-22 11:04:47.652299\r\n96 2021-10-22 11:19:48.310535   LOS22      modulo        cc12  ...              10     4  0 2021-10-22 11:19:48.331143\r\n97 2021-10-22 11:34:49.209626   LOS22      modulo        cc12  ...              10     4  0 2021-10-22 11:34:49.224717\r\n98 2021-10-22 11:49:49.638194   LOS22      modulo        cc12  ...              10     4  0 2021-10-22 11:49:49.651398\r\n\r\n[98 rows x 20 columns]\r\n&gt;&gt;&gt;<\/pre>\n<p>y el archivo resultante se presenta como:<\/p>\n<p style=\"text-align: center\"><a href=\"https:\/\/www.dropbox.com\/s\/b8tvcwvj3ggavxx\/data_LOS22.csv?dl=0\">data_LOS22.csv<\/a><\/p>\n<hr \/>\n<h2>Instrucciones en Python para tabla JSON<\/h2>\n<pre><span style=\"color: #ff0000\"># Lectura de archivo.json hacia una tabla1<\/span>\r\n<span style=\"color: #ff0000\"># selecciona registros de \"un sensor\"<\/span>\r\n<span style=\"color: #ff0000\"># graba unreporte.json con pandas<\/span>\r\n\r\n<span style=\"color: #d35400\">import<\/span> numpy <span style=\"color: #d35400\">as<\/span> np\r\n<span style=\"color: #d35400\">import<\/span> json\r\n<span style=\"color: #d35400\">import<\/span> pandas <span style=\"color: #d35400\">as<\/span> pd\r\n<span style=\"color: #d35400\">import<\/span> datetime <span style=\"color: #d35400\">as<\/span> dt\r\n\r\n<span style=\"color: #ff0000\"># INGRESO<\/span>\r\n\r\n<span style=\"color: #ff0000\"># archivo de entrada<\/span>\r\nunarchivo   = <span style=\"color: #008000\">'states20211022.json'<\/span>\r\n\r\nfechainicio = <span style=\"color: #008000\">'2021-10-21 19:00:00.0'<\/span>\r\nfechafin    = <span style=\"color: #008000\">'2021-10-22 17:10:00.0'<\/span>\r\n\r\nunsensor    = <span style=\"color: #008000\">'sensor.rssi_up_cc22'<\/span>\r\n<span style=\"color: #ff0000\"># archivo de salida<\/span>\r\nunreporte   = <span style=\"color: #008000\">'tramas20211022_cc12.json'<\/span>\r\n\r\n<span style=\"color: #ff0000\"># PROCEDIMIENTO -----<\/span>\r\n<span style=\"color: #ff0000\"># columnas o campos a usar<\/span>\r\ncampos    = [<span style=\"color: #008000\">'domain'<\/span>,<span style=\"color: #008000\">'entity_id'<\/span>,<span style=\"color: #008000\">'state'<\/span>,\r\n             <span style=\"color: #008000\">'attributes'<\/span>,<span style=\"color: #008000\">'created'<\/span>]\r\n<span style=\"color: #ff0000\"># gatewayID simplifica identificador <\/span>\r\ngateway   = {<span style=\"color: #008000\">'uCfr\/\/5zvhk='<\/span>:<span style=\"color: #008000\">'Gw01'<\/span>,\r\n             <span style=\"color: #008000\">'uCfr\/\/4dylc='<\/span>:<span style=\"color: #008000\">'Gw03'<\/span>}\r\n\r\n<span style=\"color: #ff0000\"># Lectura de archivo json<\/span>\r\ntabla0 = pd.read_json(unarchivo)\r\n<span style=\"color: #ff0000\"># Cambia a formato DataFrame<\/span>\r\ntabla0 = pd.DataFrame(tabla0,columns=campos)\r\n\r\n<span style=\"color: #ff0000\"># Revisa cada registro <\/span>\r\nleidos = 0\r\ntabla  = {}\r\n\r\n<span style=\"color: #ff0000\"># Intervalo de fecha como datetime<\/span>\r\nformato     = <span style=\"color: #008000\">'%Y-%m-%d %H:%M:%S.%f'<\/span>\r\nfechainicio = fechainicio[0:np.min([26,<span style=\"color: #ff00ff\">len<\/span>(fechainicio)])]\r\nfechainicio = dt.datetime.strptime(fechainicio,formato)\r\nfechafin    = fechafin[0:np.min([26,<span style=\"color: #ff00ff\">len<\/span>(fechafin)])]\r\nfechafin    = dt.datetime.strptime(fechafin,formato)\r\n\r\n<span style=\"color: #ff0000\"># datos de trama<\/span>\r\n<span style=\"color: #d35400\">for<\/span> cadaregistro <span style=\"color: #d35400\">in<\/span> tabla0.index:\r\n    unatrama   = tabla0[<span style=\"color: #008000\">'attributes'<\/span>][cadaregistro]\r\n    trama_mqtt = json.loads(unatrama)\r\n    \r\n    <span style=\"color: #ff0000\"># selecciona registro por sensor, en fecha y con datos<\/span>\r\n    cualsensor = (tabla0[<span style=\"color: #008000\">'entity_id'<\/span>][cadaregistro] == unsensor)\r\n    \r\n    unafecha = tabla0[<span style=\"color: #008000\">'created'<\/span>][cadaregistro]\r\n    unafecha = unafecha[0:np.min([26,<span style=\"color: #ff00ff\">len<\/span>(unafecha)])]\r\n    unafecha = dt.datetime.strptime(unafecha,formato)\r\n    \r\n    enfecha  = (unafecha&gt;=fechainicio) <span style=\"color: #d35400\">and<\/span> (unafecha&lt;=fechafin)\r\n    condatos   = <span style=\"color: #008000\">'applicationID'<\/span> <span style=\"color: #d35400\">in<\/span> trama_mqtt.keys()\r\n    \r\n    selecciona = cualsensor <span style=\"color: #d35400\">and<\/span> condatos <span style=\"color: #d35400\">and<\/span> enfecha\r\n    <span style=\"color: #d35400\">if<\/span> (selecciona == <span style=\"color: #d35400\">True<\/span>):\r\n        leidos =  leidos + 1\r\n        \r\n        <span style=\"color: #ff0000\"># datos en la mensaje MQTT<\/span>\r\n        publishedAt = trama_mqtt[<span style=\"color: #008000\">\"publishedAt\"<\/span>]\r\n        friendly_name = trama_mqtt[<span style=\"color: #008000\">\"friendly_name\"<\/span>]\r\n        deviceName    = trama_mqtt[<span style=\"color: #008000\">\"deviceName\"<\/span>]\r\n        dr    = trama_mqtt[<span style=\"color: #008000\">\"dr\"<\/span>]\r\n        fCnt  = trama_mqtt[<span style=\"color: #008000\">\"fCnt\"<\/span>]\r\n        fPort = trama_mqtt[<span style=\"color: #008000\">\"fPort\"<\/span>]\r\n\r\n        objectJSON  = trama_mqtt[<span style=\"color: #008000\">\"objectJSON\"<\/span>]\r\n        datosensor  = json.loads(objectJSON)\r\n        \r\n        frequency   = trama_mqtt[<span style=\"color: #008000\">\"txInfo\"<\/span>][<span style=\"color: #008000\">\"frequency\"<\/span>]\r\n        bandwidth   = trama_mqtt[<span style=\"color: #008000\">\"txInfo\"<\/span>][<span style=\"color: #008000\">\"loRaModulationInfo\"<\/span>][<span style=\"color: #008000\">\"bandwidth\"<\/span>]\r\n        spreadingFactor = trama_mqtt[<span style=\"color: #008000\">\"txInfo\"<\/span>][<span style=\"color: #008000\">\"loRaModulationInfo\"<\/span>][<span style=\"color: #008000\">\"spreadingFactor\"<\/span>]\r\n             \r\n        datostrama = {<span style=\"color: #008000\">\"publishedAt\"<\/span>:publishedAt,\r\n                      <span style=\"color: #008000\">\"fPort\"<\/span>:fPort, <span style=\"color: #008000\">\"dr\"<\/span>: dr,<span style=\"color: #008000\">\"fCnt\"<\/span>: fCnt,\r\n                      <span style=\"color: #008000\">\"frequency\"<\/span>:  frequency,\r\n                      <span style=\"color: #008000\">\"bandwidth\"<\/span>:  bandwidth,\r\n                      <span style=\"color: #008000\">\"spreadingFactor\"<\/span>: spreadingFactor,\r\n                      <span style=\"color: #008000\">\"datosensor\"<\/span>:datosensor}\r\n        \r\n        <span style=\"color: #ff0000\"># revisa por cada gateway en la red LoRaWan<\/span>\r\n        tamano = <span style=\"color: #ff00ff\">len<\/span>(trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>])\r\n        i = 0\r\n        <span style=\"color: #d35400\">while<\/span> i&lt;tamano:\r\n            gatewayID = trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>][i][<span style=\"color: #008000\">\"gatewayID\"<\/span>]\r\n            rssi      = trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>][i][<span style=\"color: #008000\">\"rssi\"<\/span>]\r\n            loRaSNR   = trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>][i][<span style=\"color: #008000\">\"loRaSNR\"<\/span>]\r\n            channel   = trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>][i][<span style=\"color: #008000\">\"channel\"<\/span>]\r\n            rfChain   = trama_mqtt[<span style=\"color: #008000\">\"rxInfo\"<\/span>][i][<span style=\"color: #008000\">\"rfChain\"<\/span>]\r\n            gtwNum    = gateway[gatewayID]\r\n            i = i+1\r\n            \r\n            <span style=\"color: #ff0000\"># registra en tabla, incluyendo tramas repetidas<\/span>\r\n            rx_datos = [rssi, loRaSNR,\r\n                        channel, rfChain,frequency\/1e6]  \r\n            <span style=\"color: #d35400\">if<\/span> <span style=\"color: #d35400\">not<\/span>(gtwNum <span style=\"color: #d35400\">in<\/span> datostrama.keys()):\r\n                datostrama[gtwNum] = [rx_datos]\r\n            <span style=\"color: #d35400\">else<\/span>:\r\n                <span style=\"color: #d35400\">if<\/span> <span style=\"color: #d35400\">not<\/span>(rx_datos <span style=\"color: #d35400\">in<\/span> datostrama[gtwNum]):\r\n                    datostrama[gwNum].append(rx_datos)\r\n        dispositivo = friendly_name.split(<span style=\"color: #008000\">'_'<\/span>)[2]\r\n\r\n        <span style=\"color: #ff0000\"># revisa registro repetido<\/span>\r\n        disp_existe = dispositivo <span style=\"color: #d35400\">in<\/span> tabla\r\n        <span style=\"color: #d35400\">if<\/span> <span style=\"color: #d35400\">not<\/span>(disp_existe):\r\n            tabla[dispositivo] = {leidos:datostrama}\r\n        <span style=\"color: #d35400\">else<\/span>:\r\n            trama_num = (fCnt == tabla[dispositivo][leidos-1][<span style=\"color: #008000\">'fCnt'<\/span>])\r\n            fecha_pub = (publishedAt == tabla[dispositivo][leidos-1][<span style=\"color: #008000\">'publishedAt'<\/span>])\r\n            repetido  = (trama_num <span style=\"color: #d35400\">and<\/span> fecha_pub)\r\n            <span style=\"color: #d35400\">if<\/span> <span style=\"color: #d35400\">not<\/span>(repetido):\r\n                tabla[dispositivo][leidos] = datostrama\r\n            <span style=\"color: #d35400\">else<\/span>:\r\n                leidos = leidos - 1\r\n\r\n<span style=\"color: #ff0000\"># convierte diccionario en DataFrame<\/span>\r\ntabla = pd.DataFrame(tabla)\r\n\r\n<span style=\"color: #ff0000\"># SALIDA<\/span>\r\n<span style=\"color: #ff00ff\">print<\/span>(<span style=\"color: #008000\">'registros leidos:     '<\/span>,<span style=\"color: #ff00ff\">len<\/span>(tabla0))\r\n<span style=\"color: #ff00ff\">print<\/span>(<span style=\"color: #008000\">'registros procesados: '<\/span>, leidos)\r\n\r\n<span style=\"color: #ff0000\"># guarda el reporte en json<\/span>\r\ntabla.to_json(unreporte)\r\n<\/pre>\n<p>El procesamiento de los datos se puede realizar con librerias como Pandas.<\/p>\n<p>En el procesamiento de registros, se descarta el registro de \"join\".<\/p>\n<p>Una muestra del reporte es:<\/p>\n<pre>registros leidos:      7090\r\nregistros procesados:  98\r\n&gt;&gt;&gt; tabla.keys()\r\nIndex(['cc12'], dtype='object')\r\n&gt;&gt;&gt; tabla['cc12'].keys()\r\nInt64Index([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,\r\n            18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,\r\n            35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\r\n            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,\r\n            69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,\r\n            86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98],\r\n           dtype='int64')\r\n&gt;&gt;&gt; tabla['cc12'][2].keys()\r\ndict_keys(['publishedAt', 'fPort', 'dr', 'fCnt',\r\n 'frequency', 'bandwidth', 'spreadingFactor', 'datosensor',\r\n 'Gw03'])\r\n&gt;&gt;&gt; \r\n\r\n&gt;&gt;&gt; tabla['cc12'][2]['datosensor'].keys()\r\ndict_keys(['Down_datarate', 'Down_rssi', 'Down_snr',\r\n 'bateria_V'])\r\n\r\n&gt;&gt;&gt; tabla['cc12'][2]['Gw03']\r\n[[-84, 8.5, 1, 0, 902.5]]\r\n<\/pre>\n<p>Esta forma se obtiene un nuevo y mas peque\u00f1o archivo para procesar con los datos de solo el dispositivo que se propone analizar.<\/p>\n<p style=\"text-align: center\"><a href=\"https:\/\/www.dropbox.com\/s\/uorqt9lp4mqln12\/tramas20211022_cc12.json?dl=0\">tramas20211022_cc12.json<\/a><\/p>\n<p><strong><em>Referencia<\/em><\/strong>: <a href=\"http:\/\/blog.espol.edu.ec\/ccpg1001\/archivos-json-pandas\/\">Archivos.json \u2013 Pandas<\/a> en blog de Fundamentos de Programaci\u00f3n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>El procesamiento de los datos hist\u00f3ricos de \"un sensor\" en una ubicaci\u00f3n se realiza con Python desde el archivo generado en la secci\u00f3n anterior. Esta forma se obtiene un archivo nuevo y de menor tama\u00f1o para procesar con los datos de solo el dispositivo que se propone analizar. states20211022.json El formato de la tabla es &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blog.espol.edu.ec\/girni\/lorawan-leer-registros-en-states-json-de-un-punto-con-python\/\" class=\"more-link\">Continuar leyendo<span class=\"screen-reader-text\"> \"2.2. Lectura de registros en states.json de un Punto con Python\"<\/span><\/a><\/p>\n","protected":false},"author":8043,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1466681],"tags":[],"class_list":["post-3798","post","type-post","status-publish","format-standard","hentry","category-lorawan-registro-de-estados"],"_links":{"self":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/3798","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/users\/8043"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/comments?post=3798"}],"version-history":[{"count":29,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/3798\/revisions"}],"predecessor-version":[{"id":4157,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/3798\/revisions\/4157"}],"wp:attachment":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/media?parent=3798"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/categories?post=3798"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/tags?post=3798"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}