Issue with temperature units



  • Hello everyone,

    I'm just starting out with MySensors, but think it's just amazing. Thanks to Hek and everyone else who has contributed for putting this together. I recently tried to setup a v1.4 serial gateway and a simple temperature sensor but for some reason I'm having trouble with the temperature reporting back to imperial, despite Metric being selected in the gateway device within Vera. I've tried toggling the switch back and forth, restarting Vera etc., but the temperature keeps being reported in Fahrenheit. Does anyone have any suggestions?

    Thanks,
    Troy.


  • Plugin Developer

    Are you sure that the temperature sensor if it is an digital one, is not reporting Fahrenheit? I think 1.4 is set to SI and fahrenheit isn't.


  • Admin

    @TroyF
    Strange. Try clearing eeprom an re-include sensor.


  • Hero Member

    @TroyF

    I have the same problem (but reverse), and the only fix is to hard code the conversion..

    Replace this (for the Temperature sketch) from @hek

     float temperature = static_cast<float(static_cast<int((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
    

    With this

     float temperature = static_cast<float>(static_cast<int>((sensors.getTempFByIndex(i)) * 10.)) / 10.;
    

    and this is what I used for the Humidity & Temp. Sketch

    	//float temperature = dht.getTemperature();
    	float temperature = dht.getTemperature()*9/5 + 32;
    
    	if (isnan(temperature)) {
    		Serial.println("Failed reading temperature from DHT");
    	} else if (temperature != lastTemp) {
    	lastTemp = temperature;
    	if (!metric) {
    		temperature = dht.getTemperature()*9/5 + 32;   //dht.toFahrenheit(temperature);
    	}
    	gw.send(msgTemp.set(temperature, 1));
    	Serial.print("T: ");
    	Serial.println(temperature);
    	}
    

    EDIT: Keep in mind you will need to make the changes necessary to convert to Celsius



  • Strange. I actually just left it alone and a few hours later it was reading in Celsius like it should have been. Not sure why it took a while to start reading that way, but it's fine now. Thanks to everyone for their responses.



  • I have seen the same issue with 1.4 when using DHT or Dallas ...
    I have try to clean EEPROM, change on Vera from metric to Imperial and back to metric without any succes...
    So hardcode temperature in C was the solution for me...



  • I have the same problem with DallasSensor

    Startup says:

    sensor started, id 2
    send: 2-2-0-0 s=255,c=0,t=17,pt=0,l=3,st=ok:1.4
    send: 2-2-0-0 s=255,c=3,t=6,pt=1,l=1,st=ok:0
    read: 0-0-2 s=255,c=3,t=6,pt=0,l=2:M                          <<<==== Metric <<<
    send: 2-2-0-0 s=255,c=3,t=11,pt=0,l=17,st=ok:Light+Temp Sensor
    send: 2-2-0-0 s=255,c=3,t=12,pt=0,l=3,st=ok:1.0
    send: 2-2-0-0 s=0,c=0,t=16,pt=0,l=3,st=ok:1.4
    

    And I trace:

    Serial.println(gw.getConfig().isMetric);
    

    which output 0, not 1

    Switching to Imperial I get:

    sensor started, id 2
    send: 2-2-0-0 s=255,c=0,t=17,pt=0,l=3,st=ok:1.4
    send: 2-2-0-0 s=255,c=3,t=6,pt=1,l=1,st=ok:0
    read: 0-0-2 s=255,c=3,t=6,pt=0,l=2:I                          <<<==== Imperial <<<
    send: 2-2-0-0 s=255,c=3,t=11,pt=0,l=17,st=ok:Light+Temp Sensor
    

    and the trace says 0 as expected.

    Then I tried to trace in MySensors.cpp and added (not workin though 😉 😞

    } else if (type == I_CONFIG) {
        // Pick up configuration from controller (currently only metric/imperial)
        // and store it in eeprom if changed
        isMetric = msg.getByte() == 'M' ;
        debug(PSTR("isMetric=%s\n"), isMetric);
        debug(PSTR("cc.isMetric=%s\n"), cc.isMetric);
        if (cc.isMetric != isMetric) {
    

    But then it started to work 😄

    Removed the lines above and the problem is back....so something there...
    Don't have time right now to test....


  • Admin

    @jocke4u

    Are you saying adding debug prints makes it work?



  • @hek

    Yes for some strange reason 🙂
    However I used %s and not %d in the debug but have now used %d as below

    } else if (type == I_CONFIG) {
        // Pick up configuration from controller (currently only metric/imperial)
        // and store it in eeprom if changed
        isMetric = msg.getByte() == 'M' ;
        debug(PSTR("isMetric=%d\n"), isMetric);
        debug(PSTR("cc.isMetric=%d\n"), cc.isMetric);
        if (cc.isMetric != isMetric) {
            cc.isMetric = isMetric;
            debug(PSTR("Updating EEPROM\n"));	
            debug(PSTR("isMetric=%d\n"), isMetric);	
            debug(PSTR("cc.isMetric=%d\n"), cc.isMetric);						
            eeprom_write_byte((uint8_t*)EEPROM_CONTROLLER_CONFIG_ADDRESS, isMetric);
            //eeprom_write_block((const void*)&cc, (uint8_t*)EEPROM_CONTROLLER_CONFIG_ADDRESS, sizeof(ControllerConfig));
        }
    

    Gives the output

    sensor started, id 2
    send: 2-2-0-0 s=255,c=0,t=17,pt=0,l=3,st=ok:1.4
    send: 2-2-0-0 s=255,c=3,t=6,pt=1,l=1,st=ok:0
    read: 0-0-2 s=255,c=3,t=6,pt=0,l=2:M
    isMetric=0
    cc.isMetric=1
    Updating EEPROM
    isMetric=0
    cc.isMetric=0
    

    So it seems that "metric" flag is not unpacked correctly, or?


  • Mod

    @jocke4u said:

    l=2:M

    I find it strange that length is reported as 2 while only a single character seems to be sent. The protocol version 1.4 is correctly reported as length 3.


  • Admin

    @Yveaux

    uint8_t MyMessage::getByte() const {
    	if (miGetPayloadType() == P_BYTE) {
    		return data[0];
    	} else if (miGetPayloadType() == P_STRING) {
    		return atoi(data);
    	} else {
    		return 0;
    	}
    }
    

    Payload type will be P_STRING when controller sends the data. Yes, why does it get size 2?!


  • Admin

    Hmm.. we should probably not use atoi in case of String. Payload type should not matter in the getByte.


  • Admin

    Yep, this is a bug.

    I've also found that the newline character is included and transmitted on all outgoing messages from gateway! So payload length 2 was correct, and wrong 😉

    How is it possible no one has seen this before (me included)?



  • Sounds good anyway....one bug less 🙂
    I just setup a sensor with DHT22/AM2302 and get the same results here.


  • Admin

    Fix checked in. I'm creating a more comprehensive release note in the 1.4 thread.


  • Mod

    @hek said:

    How is it possible no one has seen this before (me included)?

    At least I saw it 😉
    I personally tend to read over all the details in the serial api... This time I noticed.

    Be glad you nailed it!



  • Thanks @hek and @Yveaux I can confirm it's working on both Dallas sensor and DHT22.
    Great support!!



  • Hmmm... how can one override this statement to be METRIC?
    float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?TemperatureSensors.getTempCByIndex(CHILD_ID_TEMPERATURE_FIRST+i):TemperatureSensors.getTempFByIndex(CHILD_ID_TEMPERATURE_FIRST+i)) * 10.)) / 10.;



  • hello,

    I must confess I have not read this thread completely. Too much for my bad english)

    We try MySensors support for FHEM (www.fhem.de) to impementieren. I noticed that when the I_CONFIG message is answered correctly with 'M' for metric, then the sensor sends in Imperial. Is not surprising, everything is interpreted as a string from Gateway, but also byte checked. My solution proposal: In MySensors.cpp:
    (isMetric = msg.getString()[0] == 'M' ; instead of isMetric = msg.getByte() == 'M' ;)

    			} else if (type == I_CONFIG) {
    				// Pick up configuration from controller (currently only metric/imperial)
    				// and store it in eeprom if changed
    				//isMetric = msg.getByte() == 'M' ;
    				isMetric = msg.getString()[0] == 'M' ;
    				if (cc.isMetric != isMetric) {
    					cc.isMetric = isMetric;
    					eeprom_write_byte((uint8_t*)EEPROM_CONTROLLER_CONFIG_ADDRESS, isMetric);
    					//eeprom_write_block((const void*)&cc, (uint8_t*)EEPROM_CONTROLLER_CONFIG_ADDRESS, sizeof(ControllerConfig));
    				}
    			} else if (type == I_CHILDREN) {
    

    Best regards,

    Alexander


  • Admin

    Welcome @hexenmeister!

    What version of MySensors library did you download? The current version in gihub/master already has getString()[0].



  • Thanks for the quick reply.
    I've downloaded the source here: https://github.com/mysensors/CodeBender/blob/master/MySensor.cpp
    Since it is still old.

    Now I see that https://github.com/mysensors/Arduino/blob/master/libraries/MySensors/MySensor.cpp would be better.


  • Admin

    Oh.. you downloaded from codebender. That explains it.

    Unfortunately it's still a bit too messy to update the public libraries over there (have to contact the codebender-people every time). Nowadays we keep a copy among in the MySensors-account which gets copied if you clone one of the examples.

    Github always contains the latest.



  • My mistake. Was unfortunately cost few hours time for the search. For that I have won something overview in MySensors Code 🙂


 

Suggested Topics

352
Online

8.3k
Users

9.1k
Topics

96.7k
Posts