genielabs / HomeGenie

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

Danfoss Living Connect 014G0012 Faucet #120

Closed ErikDeBruijn closed 9 years ago

ErikDeBruijn commented 9 years ago

Hi! I'm really loving HomeGenie on an old netbook running Ubuntu and an Aeon Z-Stick 2. I currently use it for a basic Z-Wave based soft-alarm that I can turn on/off whenever I want to and where ever I am (with the HG Android App). Also, I can control several Hue Bulbs, which I can also control from my wrist using my pebble (directly to the hue bridge). Works great. Now there most important device left for this winter is heating. I'd love to schedule the thermostat to conserve energy.

I'm trying to get the 014G0012 edition of the Danfoss LivingConnect to work. It finds the module (nr. 9) and shows up in the dashboard: image

When I push the central button on the device I get this: screen shot 2015-02-05 at 21 17 45

In terms of UI everything looks good, it seems like I can change the set point, however it doesn't do anything yet: image

If I try to change the heating set point it says the following: image

If I go into the setup for the device I can "Get" some information from the device: screen shot 2015-02-05 at 21 22 14

Supported Classes Battery, 46, 81, Manufacturer Specific, 8F, 75, 43, Version, Wake Up, EF, 46

I found the device manufacturer string in the source code, too: http://www.pepper1.net/zwavedb/device/426 https://github.com/genielabs/HomeGenie/blob/977a92afd01f90317f4bc48abe0c7afb55fbd898/BaseFiles/Common/html/ext/zwave/pepper1db/0002_0005_0003.json

I hope this helps to get this device supported and working well.

Let me know if I should provide more information or what I could do to help!

ErikDeBruijn commented 9 years ago

Hi @genielabs . I started testing again.

Apart from some mismatches in Fahrenheit and Celsius the temperature reading now gets sent from the LC device and ends up in the UI. This is without pushing a button.

  1. The temp has been set manually to 14,5 deg C on the LC.
  2. This appears in the UI (the device pushes it).
  3. I set the temp to 76. If the device would have been awake (coincidentally), it would actually commit the setting to the LC. Now it gets a timeout:
015-02-07T09:28:57.9970360+01:00       MIG.Gateways.WebServiceGateway  10.0.0.23       api/HomeAutomation.ZWave/9/Thermostat.SetPointSet/Heating/76/1423297740553     HTTP    GET
[09:28:57.998727] SPO < 01 0C 00 13 09 05 43 01 01 09 4C 05 18 F7
[09:28:58.039885] SPI > 06 01 04 01 13 01 E8
[09:28:58.042530] SPO < 06
[09:28:58.142415] SPI > 01 05 00 13 18 01 F0
[09:28:58.143928] SPO < 06
2015-02-07T09:28:58.2999380+01:00       HomeAutomation.ZWave    9       ZWave Node      Thermostat.SetPoint.Heating     76
[09:28:58.300181] SPO < 01 0C 00 13 09 05 43 01 01 09 4C 05 18 F7
[09:28:58.344142] SPI > 06 01 04 01 13 01 E8
[09:28:58.345589] SPO < 06
[09:28:58.445565] SPI > 01 05 00 13 18 01 F0
[09:28:58.447126] SPO < 06
[09:28:58.603026] SPO < 01 0C 00 13 09 05 43 01 01 09 4C 05 18 F7
[09:28:58.647517] SPI > 06 01 04 01 13 01 E8
[09:28:58.648581] SPO < 06
[09:28:58.798994] SPI > 01 05 00 13 18 01 F0
[09:28:58.800616] SPO < 06
[09:28:58.905948] SPO < 01 0C 00 13 09 05 43 01 01 09 4C 05 18 F7
[09:28:58.950662] SPI > 06 01 04 01 13 01 E8
[09:28:58.951829] SPO < 06
[09:28:59.051911] SPI > 01 05 00 13 18 01 F0
[09:28:59.053390] SPO < 06
  1. As soon as the device does it's 300s interval wake, it does the following:
09:09:18.896437] SPI > 01 09 00 04 00 09 03 80 03 2D 56
[09:09:18.898201] SPO < 06
2015-02-07T09:09:18.8990350+01:00       HomeAutomation.ZWave    9       ZWave Node      ZWaveNode.Battery       45
2015-02-07T09:09:18.9003540+01:00       HomeAutomation.ZWave    9       ZWave Node      Status.Battery  45
[09:09:18.948013] SPI > 01 0C 00 04 00 09 06 43 03 01 42 05 AA 54
[09:09:18.949140] SPO < 06
2015-02-07T09:09:18.9500520+01:00       HomeAutomation.ZWave    9       ZWave Node      Thermostat.SetPoint.Heating     -9.7222222222222232
[09:09:18.999290] SPI > 01 0A 00 04 00 09 04 46 08 00 7F CD
[09:09:19.000359] SPO < 06
ZWaveLib UNHANDLED message: 01 0A 00 04 00 09 04 46 08 00 7F CD
[09:09:19.050446] SPI > 01 08 00 04 00 09 02 84 07 7B
[09:09:19.051604] SPO < 06
2015-02-07T09:09:19.0522180+01:00       HomeAutomation.ZWave    9       ZWave Node      ZWaveNode.WakeUpNotify  1
2015-02-07T09:09:19.0535600+01:00       HomeAutomation.HomeGenie.Automation     91      Automation Program      Program.Notification  {"Title":"Z-Wave Node WakeUp","Message":"<br>9 Thermostat SetPoint Get Heating"}
[09:09:19.054828] SPO < 01 0A 00 13 09 03 43 02 01 05 0E A7
[09:09:19.101577] SPI > 06 01 04 01 13 01 E8
[09:09:19.102595] SPO < 06
[09:09:19.152670] SPI > 01 05 00 13 0E 00 E7
[09:09:19.154042] SPO < 06
[09:09:19.203885] SPI > 01 0C 00 04 00 09 06 43 03 01 42 05 AA 54
[09:09:19.205932] SPO < 06
2015-02-07T09:09:19.2072170+01:00       HomeAutomation.ZWave    9       ZWave Node      Thermostat.SetPoint.Heating     -9.7222222222222232
2015-02-07T09:09:19.3683330+01:00       MIG.Gateways.WebServiceGateway  127.0.0.1       api/HomeAutomation.HomeGenie/Config/Modules.Get/HomeAutomation.HomeGenie.Automation/91/1423296559361   HTTP    GET
2015-02-07T09:09:19.4558450+01:00       HomeAutomation.HomeGenie.Automation     91      Automation Program      Program.Notification  {"Title":"Z-Wave Node WakeUp","Message":"<br>9 Battery Get"}
[09:09:19.456345] SPO < 01 09 00 13 09 02 80 02 05 0F 66
[09:09:19.506807] SPI > 06 01 04 01 13 01 E8
[09:09:19.508189] SPO < 06
[09:09:19.558306] SPI > 01 05 00 13 0F 00 E6
[09:09:19.559499] SPO < 06
[09:09:19.609634] SPI > 01 09 00 04 00 09 03 80 03 2D 56
[09:09:19.610778] SPO < 06
2015-02-07T09:09:19.6111010+01:00       HomeAutomation.ZWave    9       ZWave Node      ZWaveNode.Battery       45
2015-02-07T09:09:19.6118840+01:00       HomeAutomation.ZWave    9       ZWave Node      Status.Battery  45

The UI reads this: image

However I was thinking that it makes sense that a "desiredSetPointValue" is be stored in HG. If the device wakes periodically, there the opportunity to read if the temp was changed on the LC. If it is, that might be a desiredSetPoint for the entire system or you can make HG the master that only orders slaves and doesn't listen to them, the analogy is pretty horrible ;) ). Regardless of that choice, the desiredSetPoint should be available to LC devices that poll for the desired temperature.

Now that the device actually "listens" periodically I think most of what needs to be done can be done from the Automation program. I'll play with it a bit on my side. But any advice is welcome.

ErikDeBruijn commented 9 years ago

B.t.w. If I call api/HomeAutomation.ZWave/9/Thermostat.SetPointSet/Heating/61 I get this: image

ErikDeBruijn commented 9 years ago

B.t.w. this document might also be useful about the version I have bought (on purpose, this is the edition that's supposed to be interoperable with open Z-Wave systems): https://www.robbshop.nl/index.php/lanotattachments/download/file/id/33/store/2/dan_livc_rak_manual3_eng.pdf

genemars commented 9 years ago

@ErikDeBruijn did you use latest source code? could we make a teamviewer session?

ErikDeBruijn commented 9 years ago

Hi @genielabs I've been on the road a lot and now I'm not at home until tomorrow evening. Maybe tomorrow I might be available for it, but it depends on a few things. I found out that right after the device wakes up it will be available for receiving a new SetPointValue. I exported, imported and rewrote the ZWave 91 script a bit. This allowed me to use a configurable value to push as soon as the device reports back. Also, I found that instead of 300 seconds a 60 s wake interval also works, which rapidly increases development iterations. The param is retrieved in the script: var desiredTemp = Program.InputField("desiredTemp"); Upon wake it executes: module.Command("Thermostat.SetPointSet").Execute("Heating/" + (desiredTemp.DecimalValue+0)); However I would like to change the param based on an API call. Changing it through the Web interface doesn't show me an API command in the logs. I would expect something like 10.0.0.69:8080/api/HomeAutomation.HomeGenie.Automation/1000/Param.Set/desiredTemp/70 but it takes a lot of guesses to brute force it. So far I couldn't find this in the documentation yet.

genemars commented 9 years ago

@ErikDeBruijn to add a custom API call you can use When.WebServiceCallRecevied helper method:

http://www.homegenie.it/docs/doxy/d4/dd7/class_home_genie_1_1_automation_1_1_scripting_1_1_events_helper.html#a58515455945c35783cde47d21f844663

many hg programs already use it, as an example you can see how the Security Alarm System use it. With my last commit, HG now support message queue for devices powered on batteries. So if you try to control the device while it is "asleep", hg will queue the request and send it as soon as the device wake up. I also made some more work for making the Thermostat.SetPointSet work. Hope we are getting closer to a working version.

ErikDeBruijn commented 9 years ago

Hi @genielabs . I managed to create a thermostat API for my own adjusted script based on 91 (Query on Wake Up). The API is controlled via a Pebble App that I wrote. I will release and document my Pebble App as soon as it has a configuration screen and in the Pebble store.

The Pebble App controls my lighting, alarm and thermostat. To change the "options".

Back on topic: I've tried the update and I don't really see different behavior. Changing the setpoint in the UI gives me the same timeout (which is expected for such a battery powered device that isn't going to respond)

2015-02-08T14:51:29.0867500+01:00       MIG.Gateways.WebServiceGateway  82.176.180.207  api/HomeAutomation.ZWave/9/Thermostat.SetPointSet/Heating/82/1423403496473     HTTP    GET
[14:51:29.088037] SPO < 01 0C 00 13 09 05 43 01 01 09 52 05 13 E2
[14:51:29.104353] SPI > 06 01 04 01 13 01 E8
[14:51:29.105369] SPO < 06
[14:51:29.255761] SPI > 01 05 00 13 13 01 FB
[14:51:29.257047] SPO < 06
2015-02-08T14:51:29.3891330+01:00       HomeAutomation.ZWave    9       ZWave Node      Thermostat.SetPoint.Heating     82
[14:51:29.390974] SPO < 01 0C 00 13 09 05 43 01 01 09 52 05 13 E2
[14:51:29.407400] SPI > 06 01 04 01 13 01 E8
[14:51:29.408774] SPO < 06
[14:51:29.560294] SPI > 01 05 00 13 13 01 FB
[14:51:29.561663] SPO < 06
[14:51:29.693008] SPO < 01 0C 00 13 09 05 43 01 01 09 52 05 13 E2
[14:51:29.712956] SPI > 06 01 04 01 13 01 E8
[14:51:29.714385] SPO < 06
[14:51:29.864748] SPI > 01 05 00 13 13 01 FB
[14:51:29.866211] SPO < 06
[14:51:29.995187] SPO < 01 0C 00 13 09 05 43 01 01 09 52 05 13 E2
[14:51:30.016714] SPI > 06 01 04 01 13 01 E8
[14:51:30.018110] SPO < 06
[14:51:30.168231] SPI > 01 05 00 13 13 01 FB
[14:51:30.170037] SPO < 06
2015-02-08T14:51:30.1707530+01:00       HomeAutomation.ZWave    1       Z-Wave Controller       Controller.Status       Node 9 response timeout!

However I don't see a different behavior when the device wakes:

[14:52:13.265963] SPI > 01 09 00 04 00 09 03 80 03 2C 57
[14:52:13.266713] SPO < 06
2015-02-08T14:52:13.2675680+01:00       HomeAutomation.ZWave    9       ZWave Node      ZWaveNode.Battery       44
2015-02-08T14:52:13.2687950+01:00       HomeAutomation.ZWave    9       ZWave Node      Status.Battery  44
[14:52:13.316855] SPI > 01 0C 00 04 00 09 06 43 03 01 42 07 29 D5
[14:52:13.318076] SPO < 06
2015-02-08T14:52:13.3187310+01:00       HomeAutomation.ZWave    9       ZWave Node      Thermostat.SetPoint.Heating     -7.594444444444
4459
[14:52:13.368197] SPI > 01 0A 00 04 00 09 04 46 08 00 7F CD
[14:52:13.369620] SPO < 06
ZWaveLib UNHANDLED message: 01 0A 00 04 00 09 04 46 08 00 7F CD
[14:52:13.419785] SPI > 01 08 00 04 00 09 02 84 07 7B
[14:52:13.420999] SPO < 06
2015-02-08T14:52:13.4216540+01:00       HomeAutomation.ZWave    9       ZWave Node      ZWaveNode.WakeUpNotify  1
2015-02-08T14:52:13.6059290+01:00       HomeAutomation.HomeGenie.Automation     91      Automation Program      Program.Notification  {"Title":"Z-Wave Node WakeUp","Message":"<br>9 Thermostat SetPoint Get Heating"}
[14:52:13.606411] SPO < 01 0A 00 13 09 03 43 02 01 05 14 BD
[14:52:13.621490] SPI > 06 01 04 01 13 01 E8
[14:52:13.622343] SPO < 06
[14:52:13.672513] SPI > 01 05 00 13 14 00 FD
[14:52:13.673479] SPO < 06
[14:52:13.723596] SPI > 01 0C 00 04 00 09 06 43 03 01 42 07 29 D5
[14:52:13.724169] SPO < 06
2015-02-08T14:52:13.7246010+01:00       HomeAutomation.ZWave    9       ZWave Node      Thermostat.SetPoint.Heating     -7.5944444444444459
2015-02-08T14:52:14.0071990+01:00       HomeAutomation.HomeGenie.Automation     91      Automation Program      Program.Notification  {"Title":"Z-Wave Node WakeUp","Message":"<br>9 Battery Get"}
[14:52:14.007684] SPO < 01 09 00 13 09 02 80 02 05 15 7C
[14:52:14.025430] SPI > 06 01 04 01 13 01 E8
[14:52:14.026251] SPO < 06
[14:52:14.077758] SPI > 01 05 00 13 15 00 FC
[14:52:14.078389] SPO < 06
[14:52:14.128596] SPI > 01 09 00 04 00 09 03 80 03 2C 57
[14:52:14.129715] SPO < 06
2015-02-08T14:52:14.1300890+01:00       HomeAutomation.ZWave    9       ZWave Node      ZWaveNode.Battery       44
2015-02-08T14:52:14.1305330+01:00       HomeAutomation.ZWave    9       ZWave Node      Status.Battery  44

The Automation program 91 is responsible for this, right? Could it be that it still uses the old version, e.g. if I've changed a script, does it still update them?

I might have time tonight when I'm back at home. Right now I'm using SSH and port forwards to the Homegenie laptop.

Since I've got it working, I'll post my C# script adjusted from Automation 91:

Program.Setup(()=>
{              
    Program.AddInputField("desiredTemp", "70", "Keep level at this temp Fahrenheit");
});

When.ModuleParameterChanged((module, parameter) => {
  var desiredTemp = Program.InputField("desiredTemp");

  if (parameter.Name == "ZWaveNode.WakeUpNotify")
  {     
    var nodeinfo = module.Parameter("ZWaveNode.NodeInfo");
    if (nodeinfo != null)
    {
      // nif contains all command classes supported by this module
      string nif = " " + nodeinfo.Value + " ";
      if (nif.Contains(" 84 ") || nif.Contains(" 25 ") || nif.Contains(" 26 ") || nif.Contains(" 43 "))
      {
        if (nif.Contains(" 60 ")) // MultiInstance
        {
          Program.Notify("Z-Wave Node WakeUp", module.Instance.Name + "<br>" + module.Instance.Address + " MultiInstance Get");
          // query first 4 instances
          for (int instance = 1; instance < 4; instance ++)
          {
            if (nif.Contains(" 30 ")) // Sensor Binary
            {
              module.Command("MultiInstance.Get").Execute("Sensor.Binary/" + instance);
              Pause(.2);
            }
            else if (nif.Contains(" 31 ")) // Sensor MultiLevel
            {
              module.Command("MultiInstance.Get").Execute("Sensor.MultiLevel/" + instance);
              Pause(.2);
            }
            else if (nif.Contains(" 25 ")) // Switch Binary
            {
              module.Command("MultiInstance.Get").Execute("Switch.Binary/" + instance);
              Pause(.2);
            }
            else if (nif.Contains(" 26 ")) // Switch MultiLevel
            {
              module.Command("MultiInstance.Get").Execute("Switch.MultiLevel/" + instance);
              Pause(.2);
            }
          }
        }
        //
        // query Thermostat set point
        if (nif.Contains(" 43 ")) // Thermostat
        {
          //Program.Notify("Z-Wave Node WakeUp (Erik)", module.Instance.Name + "<br>" + module.Instance.Address + " Thermostat SetPoint Get Heating");
          //module.Command("Thermostat.SetPointGet").Execute("Heating");
          Program.Notify("Z-Wave Node WakeUp (Erik v2)", module.Instance.Name + "<br>" + module.Instance.Address + " Thermostat SetPoint Set " + (desiredTemp.DecimalValue+0) + "Heating");
          module.Command("Thermostat.SetPointSet").Execute("Heating/" + (desiredTemp.DecimalValue+0));
          //module.Command("Thermostat.SetPointSet").Execute("Heating/85");
          //Execute("Heating/" + (setPoint.DecimalValue + 1));
          Pause(.2);
        }
        //
        // query Battery level
        if (nif.Contains(" 80 ")) // Battery
        {
          Program.Notify("Z-Wave Node WakeUp (Erik)", module.Instance.Name + "<br>" + module.Instance.Address + " Battery Get");
          module.Command("Battery.Get").Execute();
          Pause(.2);
        }
        //
        // query Basic value
        if (nif.Contains(" 20 ")) // Basic
        {
          Program.Notify("Z-Wave Node WakeUp (Erik)", module.Instance.Name + "<br>" + module.Instance.Address + " Basic Get");
          module.Command("Basic.Get").Execute();
          Pause(.2);
        }
      }
    }
  }

  return true; // continue processing event
});

//
// web service calls handling
//
When.WebServiceCallReceived(Program.Module.Domain + "/" + Program.Module.Address, (args) =>
{
    var desiredTemp = Program.InputField("desiredTemp");
    string[] reqs = ((string)args).Split('/');
    var res = "";

    try
    {
      string cmdVal = reqs[3];
      string command = reqs[2];
      string pid = reqs[1];
      if (pid == Program.Module.Address)
      {

        switch(command)
        {
          case "desiredTemp.Fahrenheit":
            desiredTemp.Value = cmdVal;
            res = "{ 'ResponseValue' : 'CONFIRMED', 'newFahrenheit' : '" + cmdVal + "' }";
            break;
          //case "desiredTemp.Celsius":
          //  desiredTemp.Value = numVal * 1.8 + 32;
          //  res = "{ 'ResponseValue' : 'CONFIRMED', 'newFahrenheit' : '" + cmdVal + "' }";
          //  break;
        }
        Program.Notify("Z-Wave Node WakeUp (Erik)", "DesiredTemp: " + cmdVal + " F");

      }
    } 
    catch (Exception ex) 
    { 
      res = "{ 'ResponseValue' : 'ERROR: " + ex.Message + " " + ex.StackTrace + "' }";
    }
    // unable to process request
    return res;

});

Program.GoBackground();

The API call I can now use is /api/HomeAutomation.HomeGenie.Automation/1002/desiredTemp.Fahrenheit/[newTargetTempF]. This works fine, but I'm working around all of the widget/UI functionality, right now. So it works for my purposes, but isn't really according to your plans.

genemars commented 9 years ago

@ErikDeBruijn I just cannot think of other stuff right now. First would like to solve the Thermostat.SetPoitSet issue. Hope we can make more tests soon. Also I am a bit confused. Since your logs shows only the Thermostat.SetPointGet (which I see it fails by returning a negative value). Did you try the SetPointSet at all (waking up the device) and see if it changes on the device display accordingly? So, again, this is what I need to fix: 1) Thermostat.SetPoitSet 2) Thermostat.SetPoitGet after that we can talk and go over with other stuff. =)

genemars commented 9 years ago

@ErikDeBruijn I tried to pass the input I see in your logs to the method that extracts the value:

 01 0C 00 04 00 09 06 43 03 01 42 07 29 D5

and it returns the following data:

Precision = 2
Scale = 0   <-- your device is using Celsius scale
Size = 2
Value = 18,33

So I just wonder... are you sure you're using latest source code? :) because in your logs I see the value is interpreted as -7.594444444444 by the same method I tested manually and it returns 18.33. Also wonder why are you trying to set the setpoint to 82, since your device accept Celsius scale as I can see from the extracted data (Scale == 0 --> Celsius, Scale == 1 Fahrenheit).

ErikDeBruijn commented 9 years ago

Okay, we can work to get the bugs out. I'll be available for a few hours this evening (after dinner && after our baby.sleeps()). You're in Italy or at least EU time zone?

A quick note. I am able to set the setpoint with the adjusted automation script (based on 91) posted above.

We can do synchronous chat on Google hangouts, erikdebruijn1@gmail.com. might work slightly better than github issue discussion ..

ErikDeBruijn commented 9 years ago

I did do a git pull but I just realized that I probably need to rebuild in monodevelop, right? I use a setpoint of 80'ish because the entire UI uses Fahrenheit in my case. I'd like to be able to override and choose Celsius. My user agent might be set to en-US, could that be why it's Fahrenheit?

genemars commented 9 years ago

@ErikDeBruijn yes the unit is F because of the locale set in your browser. Firefox has an addin that allow easily switch between locales.

ErikDeBruijn commented 9 years ago

Okay, no way to override other than choosing a different language? I don't want to have to set it to nl-NL. Tell me: do I need to rebuild build the code when I get home?

genemars commented 9 years ago

User selectable settings for language date formatting and units will be added soon. You will have to recompile the new code or run it in debug mode (the Play button).

ErikDeBruijn commented 9 years ago

okay, I'm online on G Hangouts. I can also share a code for screen sharing. Let me know when you want to get started!

ErikDeBruijn commented 9 years ago

Hi, can't stay online for much longer. One question: I've changed from EN-US to EN-UK and refreshed, closed and reopened the window. No change to the Fahrenheit indication for sensors or thermostat on the Control section of the UI.

genemars commented 9 years ago

@ErikDeBruijn sorry I've been away. r478 is available for download too, so you can test from package if source code is problematic for you. If the UI shows Fahrenheit indication (see #92 and #76), you can still test the command using the API from the browser setting a consistent value manually.

ErikDeBruijn commented 9 years ago

I have been able to build. Just didn't realize that I needed to to see the new functionality after a git pull.

I do use the API and the log to be sure of what is being sent. I will have to get back to collaboratively debugging next week. This week will be crazy busy.

KnutssonDevelopment commented 9 years ago

Hi, how did this turn out. I am having more or less the same issues with a just installed HomeGenie. (Not from source)

Best Regards Brian

extremecuda commented 9 years ago

Hi, I'm running the r496 and the problem with the Danfoss Thermostats persists. Are there any news on this?

Kind regards, David

KnutssonDevelopment commented 8 years ago

I am running the latest version. And it works great now.

Thanks!

zarkov74 commented 7 years ago

hi gene. I'm trying to solve an "E5" error on my domotic system based on HG-Raspberry-ZStick S2- Danfoss living connect thermostatic valve and also other roller shutter and dimmers.

The error occur on the thermostaic valve, and at this moment, I'n mot still able to solve the problem. Seems that the valve loose the comunication with the Zstick. I upgraded HG to the latest version, but nothig changes.. I changed also the "wake up interval" but nothing happens. Can you help me to solve this problem? If you need a donation to implemente the code, please let me know ;-) Thanks