Enviar temperaturas a thinger de un ds18b20 a través de raspberry


#1

Hola, estoy intentando enviar las temperaturas de unos termometros ds18b20 a través de una Rasberry, para ello tengo dos funciones, una me saca el código del sensor y la otra con el código del sensor me saca la temperatura, funcionan las dos perfectamente, pero después a la hora de mandar la información a thinger.io me da error, he estado buscando información pero teniendo raspberry como cliente, no he encontrado mucha, copio el códio a ver si alguien me puede ayudar. gracias, un saludo.

#include "thinger/thinger.h"

#include <iostream>
#include <dirent.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <cstdio>

#define USER_ID             "usuario"
#define DEVICE_ID           "rasberry1"
#define DEVICE_CREDENTIAL   "password"


using namespace std;
vector<string> termometros;
float min_temp=-30;
float max_temp=20;

void busca_termometros()
{
  DIR * directorio;
  struct dirent * elemento;
  string elem, ruta="";
  string rutaTermometros="/sys/bus/w1/devices/";
  if (directorio = opendir(rutaTermometros.c_str()))
  {
   while (elemento = readdir(directorio))
   {
    elem = elemento->d_name;
   // if (elem != "." && elem != "..") cout << elem << endl;
      if (elem.substr(0,2)=="28"){ 
         // ruta="/sys/bus/w1/devices/"+elem+"/w1_slave";
          termometros.push_back(elem);
          //cout << ruta << endl;
          //cout << elem << endl;
      }
   }
  }
  closedir(directorio);
}

float get_temperaturaf (string ruta_termometro){
    //pasamos el estring de ruta_termometro a un char*
    std::string sf = "3.14";
    char* char_ruta_termometro = new char[ruta_termometro.size()+1];
    std::copy(ruta_termometro.begin(), ruta_termometro.end(), char_ruta_termometro);
    char_ruta_termometro[ruta_termometro.size()] = '\0';
    
    
    float num_temperatura=0, posicion=0;
    string str_temperatura="", temporal="";
    FILE * archivo;
    archivo = fopen(char_ruta_termometro, "r");
    char linea[255];
    while(fgets(linea, sizeof(linea), archivo)){
        temporal=linea;
      posicion = temporal.find_last_of("t=");
      
    }  
    fclose(archivo);
    sf=temporal.substr(posicion+1,4);
   // sf=str_temperatura;
    float float_temperatura = std::stof(sf);
    float temperatura_real;
    temperatura_real= float_temperatura/100;
    return temperatura_real;  
}




int main(int argc, char *argv[])
{
    thinger_device thing(USER_ID, DEVICE_ID, DEVICE_CREDENTIAL);

string ruta_termometro;  
busca_termometros();

for (int i=0; i<termometros.size(); i++){
    ruta_termometro="/sys/bus/w1/devices/"+termometros[i]+"/w1_slave";
	
 thing[termometros[i]] = [](pson& in, pson& out){
        out["temperatura"] = get_temperaturaf(ruta_termometro);
    };
    
    // cout << "La temperatura del termometro " <<termometros[i] <<"es: " << get_temperaturaf(ruta_termometro) << endl;
} 

    thing.start();
    return 0;
}

#2

Hola @abrahamms,
Ahora mismo no tengo una Raspberry a mano para verificar el código, pero parece que está todo correcto,
pero lo intentaré a lo largo de la semana ¿Podrías aportar algo más de información sobre el tipo de error que te está dando el programa? ¿el dispositivo se conecta con el servidor de Thinger.io correctamente?

un saludo


#3

Hola @jtrinc26, gracias por tu respuesta, no sabia si me iban a responder habiendo escrito en castellano, leer en ingles vale pero escribir… buff y tampoco queria usar el traductor para que dijera cualquier patujada :wink:
Te explico, el problema que tengo es que no encuentra los sensores, encuentra la Raspberry , aparece como conectada pero no ve los sensores (No se si saldrá la imagen que intento mostrarte):

… no se si lo ves en el codigo, pero lo que intento hacer es obtener la dirección física del sensor y pasarla como nombre del sensor en Thinger con su correspondiente temperatura.
La parte de leer la dirección o el código del sensor y su correspondiente temperatura me sale bien, es la parte de enviar estos dos datos a thinger lo que no consigo hacer, supongo que no estoy usando bien el método de thinger.

Muchas gracias.

Te copio el error que me da al ejecutar el run.h:

– OpenSSL Version: 1.1.0f
– Configuring done
– Generating done
– Build files have been written to: /root/Linux-Client/build
Scanning dependencies of target thinger
[ 50%] Building CXX object CMakeFiles/thinger.dir/src/main.cpp.o
/root/Linux-Client/src/main.cpp: In function ‘int main(int, char**)’:
/root/Linux-Client/src/main.cpp:109:8: error: no match for ‘operator[]’ (operand types are ‘thinger_device {aka thinger_tls_client}’ and ‘__gnu_cxx::__alloc_tra its<std::allocator<std::cxx11::basic_string > >::value_type {aka std:: cxx11::basic_string}’)
thing[termometros[i]] = [](pson& in, pson& out){
^
In file included from /root/Linux-Client/src/thinger/thinger_client.h:43:0,
from /root/Linux-Client/src/thinger/thinger.h:28,
from /root/Linux-Client/src/main.cpp:24:
/root/Linux-Client/src/thinger/core/thinger.h:90:28: note: candidate: thinger::t hinger_resource& thinger::thinger::operator[](const char*)
thinger_resource & operator[](const char* res){
^~~~~~~~
/root/Linux-Client/src/thinger/core/thinger.h:90:28: note: no known conversion for argument 1 from ‘__gnu_cxx::__alloc_traits<std::allocator<std::__cxx11::bas ic_string > >::value_type {aka std::__cxx11::basic_string}’ to ‘cons t char*’
/root/Linux-Client/src/main.cpp: In lambda function:
/root/Linux-Client/src/main.cpp:110:50: error: ‘ruta_termometro’ is not captured
out[“temperatura”] = get_temperaturaf(ruta_termometro);
^~~~~~~~~~~~~~~
/root/Linux-Client/src/main.cpp:109:28: note: the lambda has no capture-default
thing[termometros[i]] = [](pson& in, pson& out){
^
/root/Linux-Client/src/main.cpp:100:8: note: ‘std::__cxx11::string ruta_termomet ro’ declared here
string ruta_termometro;
^~~~~~~~~~~~~~~
CMakeFiles/thinger.dir/build.make:62: fallo en las instrucciones para el objetiv o 'CMakeFiles/thinger.dir/src/main.cpp.o’
make[3]: *** [CMakeFiles/thinger.dir/src/main.cpp.o] Error 1
CMakeFiles/Makefile2:67: fallo en las instrucciones para el objetivo 'CMakeFiles /thinger.dir/all’
make[2]: *** [CMakeFiles/thinger.dir/all] Error 2
CMakeFiles/Makefile2:79: fallo en las instrucciones para el objetivo 'CMakeFiles /thinger.dir/rule’
make[1]: *** [CMakeFiles/thinger.dir/rule] Error 2
Makefile:118: fallo en las instrucciones para el objetivo 'thinger’
make: *** [thinger] Error 2
[534066.610000]: Not connected!
[534066.654000]: Connecting to iot.thinger.io:25202
[534067.124000]: Connected!
[534067.124000]: Authenticating…
[534067.198000]: Authenticated!


#4

… he cambiado el código para que el método me devolviera directamente e array con los sensores y aparte he corregido un error ortográfico (me equivoque a la hora de llamar al método que me da las temperaturas), ahora me da otro error… copio el código y el error

using namespace std;
//vector termometros;
float min_temp=-30;
float max_temp=20;

vector busca_termometros()
{
vector termometros;
DIR * directorio;
struct dirent * elemento;
string elem, ruta="";
string rutaTermometros="/sys/bus/w1/devices/";
if (directorio = opendir(rutaTermometros.c_str()))
{
while (elemento = readdir(directorio))
{
elem = elemento->d_name;
// if (elem != “.” && elem != “…”) cout << elem << endl;
if (elem.substr(0,2)==“28”){ //buscamos los directorios que empiezan por 28 que son los termometros
termometros.push_back(elem);

  }

}
}
closedir(directorio);
return termometros;
}

float get_temperaturaf (string ruta_termometro){
//pasamos el estring de ruta_termometro a un char*
std::string sf = “3.14”;
char* char_ruta_termometro = new char[ruta_termometro.size()+1];
std::copy(ruta_termometro.begin(), ruta_termometro.end(), char_ruta_termometro);
char_ruta_termometro[ruta_termometro.size()] = ‘\0’;

float num_temperatura=0, posicion=0;
string str_temperatura="", temporal="";
FILE * archivo;
archivo = fopen(char_ruta_termometro, "r");
char linea[255];
while(fgets(linea, sizeof(linea), archivo)){
    temporal=linea;
  posicion = temporal.find_last_of("t=");

}
fclose(archivo);
sf=temporal.substr(posicion+1,4);

// sf=str_temperatura;
float float_temperatura = std::stof(sf);
float temperatura_real;
temperatura_real= float_temperatura/100;
return temperatura_real;
}

string ruta_termometro;

int main(int argc, char *argv[])
{
thinger_device thing(USER_ID, DEVICE_ID, DEVICE_CREDENTIAL);

//string ruta_termometro;
//busca_termometros();

    for (int i=0; i<busca_termometros().size(); i++){ //muestra el contenido de la ruta de los termometros
            ruta_termometro="/sys/bus/w1/devices/"+busca_termometros()[i]+"/w1_slave";

            thing[busca_termometros()[i]] = [](pson& in, pson& out){
                      out["temperatura"] = get_temperaturaf(ruta_termometro);
            };
    };

thing.start();
return 0;

}

ERROR
– OpenSSL Version: 1.1.0f
– Configuring done
– Generating done
– Build files have been written to: /root/Linux-Client/build
Scanning dependencies of target thinger
[ 50%] Building CXX object CMakeFiles/thinger.dir/src/main.cpp.o
/root/Linux-Client/src/main.cpp: In function ‘int main(int, char
)’:
/root/Linux-Client/src/main.cpp:110:8: error: no match for ‘operator[]’ (operand types are ‘thinger_device {aka thinger _tls_client}’ and ‘__gnu_cxx::__alloc_traits<std::allocator<std::__cxx11::basic_string > >::value_type {aka std:: __cxx11::basic_string}’)
thing[busca_termometros()[i]] = [](pson& in, pson& out){
^
In file included from /root/Linux-Client/src/thinger/thinger_client.h:43:0,
from /root/Linux-Client/src/thinger/thinger.h:28,
from /root/Linux-Client/src/main.cpp:24:
/root/Linux-Client/src/thinger/core/thinger.h:90:28: note: candidate: thinger::thinger_resource& thinger::thinger::oper ator[](const char
)
thinger_resource & operator[](const char
res){
^~~~~~~~
/root/Linux-Client/src/thinger/core/thinger.h:90:28: note: no known conversion for argument 1 from ‘__gnu_cxx::__allo c_traits<std::allocator<std::__cxx11::basic_string > >::value_type {aka std::__cxx11::basic_string}’ to ‘co nst char*’
CMakeFiles/thinger.dir/build.make:62: fallo en las instrucciones para el objetivo 'CMakeFiles/thinger.dir/src/main.cpp. o’
make[3]: *** [CMakeFiles/thinger.dir/src/main.cpp.o] Error 1
CMakeFiles/Makefile2:67: fallo en las instrucciones para el objetivo 'CMakeFiles/thinger.dir/all’
make[2]: *** [CMakeFiles/thinger.dir/all] Error 2
CMakeFiles/Makefile2:79: fallo en las instrucciones para el objetivo 'CMakeFiles/thinger.dir/rule’
make[1]: *** [CMakeFiles/thinger.dir/rule] Error 2
Makefile:118: fallo en las instrucciones para el objetivo 'thinger’
make: *** [thinger] Error 2
[537701.246000]: Not connected!
[537701.249000]: Connecting to iot.thinger.io:25202
[537701.663000]: Connected!
[537701.663000]: Authenticating…
[537701.736000]: Authenticated!


#5

creo que ya he encontrado el fallo viendo este post:

… el tema es que estaba mandando el nombre de los sensores como string en vez de char* …

thing[busca_termometros()[i].c_str()] >> [](pson& out){
out[“temperatura”] = get_temperaturaf(ruta_termometro);
};