genielabs / HomeGenie

HomeGenie, the programmable automation intelligence
https://homegenie.it
GNU General Public License v3.0
392 stars 155 forks source link

Wrong temperature reading with Vision Security ZP 3102 #129

Closed Klagopsalmer closed 9 years ago

Klagopsalmer commented 9 years ago

Hello,

Following my post on the forum (http://www.homegenie.it/forum/index.php?topic=66.new;topicseen#new), I have found the cause of the wrong temperature reading.

In the method "Parse" (see code below), the value is extracted once in the beginning by "Utility.ExtractValueFromBytes" and a second time by "ExtractTemperatureFromBytes".

The code of "ExtractTemperatureFromBytes" doesn't work because it takes a subset of the message and doesn't read the value at the correct index.

If I comment the call to "ExtractTemperatureFromBytes" the temperature reading is correct.

Does the method "ExtractTemperatureFromBytes" work ?

If this is done on purpose, I will write a specific device handler for the sensor.

Regards Alexandre Schnegg

From "SensorValue.cs":

        public static SensorValue Parse(byte[] message)
        {
            SensorValue sensor = new SensorValue();
            //
            ZWaveValue zvalue = Utility.ExtractValueFromBytes(message, 11);
            //
            byte key = message[9];
            if (key == (byte)ZWaveSensorParameter.Temperature)
            {
                zvalue = ExtractTemperatureFromBytes(message);
                sensor.Parameter = ZWaveSensorParameter.Temperature;
                // convert from Fahrenheit to Celsius if needed
                sensor.Value = (zvalue.Scale == (int)ZWaveTemperatureScaleType.Fahrenheit ? SensorValue.FahrenheitToCelsius(zvalue.Value) : zvalue.Value);
                sensor.EventType = ParameterEvent.SensorTemperature;
            }
            else if (key == (byte)ZWaveSensorParameter.GeneralPurposeValue)
            {
                sensor.Parameter = ZWaveSensorParameter.GeneralPurposeValue;
                sensor.Value = zvalue.Value;
                sensor.EventType = ParameterEvent.Generic;
            }
            else if (key == (byte)ZWaveSensorParameter.Luminance)
            {
                sensor.Parameter = ZWaveSensorParameter.Luminance;
                sensor.Value = zvalue.Value;
                sensor.EventType = ParameterEvent.SensorLuminance;
            }
            else if (key == (byte)ZWaveSensorParameter.RelativeHumidity)
            {
                sensor.Parameter = ZWaveSensorParameter.RelativeHumidity;
                sensor.Value = zvalue.Value;
                sensor.EventType = ParameterEvent.SensorHumidity;
            }
            else if (key == (byte)ZWaveSensorParameter.Power)
            {
                //sensor.Value = BitConverter.ToUInt16(new byte[2] { message[12], message[11] }, 0) / 10D;
                //sensor.Value = ((double)int.Parse(
                //    message[12].ToString("X2") + message[13].ToString("X2") + message[14].ToString("X2"),
                //    System.Globalization.NumberStyles.HexNumber
                //    )) / 1000D;
                // TODO: this might be very buggy.... to be tested
                EnergyValue energy = EnergyValue.Parse(message);
                sensor.Parameter = ZWaveSensorParameter.Power;
                sensor.Value = energy.Value;
                sensor.EventType = ParameterEvent.MeterPower;
            }
            else
            {
                sensor.Value = zvalue.Value;
            }
            //
            return sensor;
        }

        public static ZWaveValue ExtractTemperatureFromBytes(byte[] message)
        {
            byte[] tmp = new byte[4];
            System.Array.Copy(message, message.Length - 4, tmp, 0, 4);
            message = tmp;

            ZWaveValue zvalue = Utility.ExtractValueFromBytes(message, 1);
            // zvalue.Scale == 1 -> Fahrenheit
            // zvalue.Scale == 0 -> Celsius 

            return zvalue;
        }
genemars commented 9 years ago

fixed