Wall Display mit externem DS18B20

Nach einem etwas enthusiastischen Weihnachsteinkauf und der ersten Ernüchterung zu den Problemen des internen Sensors kam natürlich nach dem Kauf des Shelly-Addons mit einem DS18B20 die zweite Ernüchterung, da sich ein DS18B20 nicht direkt als externer Sensor einbinden lässt.

Aber frei nach dem Motto – „geht nicht, gibt es nicht“, verhalf etwas Scripting zu einer funktionierenden Lösung.

Neben dem Wall Display verwende ich dafür ein Shelly Plus 1, welches mit dem Shelly-Addon verheiratet wurde, und an dem wiederum der DS18B20. Das Shelly Plus 1 selbst wird direkt über den Schaltausgang vom Wall Display geschalten, die Heizung sodann über den potentialfreien Kontakt des Shelly Plus 1.

Die Lösung über Script liegt darin, dass ich über ein Script den Messwert aus dem Wall-Display mit dem Messwert vom DS18B20 vergleiche. Daraus wird der notwendige Offset für das Wall-Display berechnet und in das Wall-Display geschrieben. Somit hat man den Wert auch mit schwankenden Offset immer auf dem „richtigen“ Wert. Es ist dadurch auch möglich, das Display eingeschaltet zu lassen, ohne dass der Messwert durch die Eigenerwärmung „davon läuft“. Ein allfällig notwendige Kompensation (Offset) wird rein über den DS18B20 durchgeführt.

In Summe sind drei RPC-Calls erforderlich um die erforderlichen Werte abzufragen, sowie ein Call um den neuen Offset zu setzen. Der Aufruf aller Funktionen erfolgt über einen Timer, wobei sichergestellt wird, dass alle drei Aufrufe zur Abfrage erfolgreich waren, bevor ein neuer Offset berechnet und geschrieben wird. Das Schreiben des neuen Offsets erfolgt dabei immer um einen Timer-Zyklus verzögert.

Das Script ist sicher noch nicht perfekt. Es fehlt in jedem Fall noch die eine oder andere Fehlerprüfung. Insbesondere werden die Rückgabewerte der verschiedenen Calls nicht auf Plausibilität geprüft. Schlagend wird dieser Umstand aber nur, wenn die IP für das Wall-Display auf einen anderen Shelly zeigt.

// Shelly Addon to Wall Display
//
// changelog V2
// + errorhandling within each function
// + errorhandling for RPC-calls
// + named callback functions for RPC-calls

var wallStatus = {};
var wallConfig = {};
var sensorStatus = {};

var nextLevel = 0;
var lastError = 0;
var offsetThreshold = 0.2;

function CallbackGetWallStatus(result, error_code, error_message)
{
  try {
    print("callback GetWallStatus");
    if (error_code != 0) {
      print(error_code + " " + error_message);
      lastError = error_code;
    } else {
      wallStatus = JSON.parse(result.body);
      print(JSON.stringify(wallStatus));
      nextLevel++;
    }
  }
  catch(e) {
    print("callback GetWallStatus - error: " + e);
    lastError = -1;
  }
}

function GetWallStatus() {
  try {
    Shelly.call(
    "HTTP.GET",
    {url: "http://<IP-WallDisplay>/rpc/Temperature.GetStatus?id=0", timeout: 5 },
    CallbackGetWallStatus);
  }
  catch(e) {
    print("callback GetWallStatus - error: " + e);
    lastError = -1;
  }
}

function CallbackGetWallConfig(result, error_code, error_message)
{
  try {
    print("callback GetWallConfig");
    if (error_code != 0) {
      print(error_code + " " + error_message);
      lastError = error_code;
    } else {
      wallConfig = JSON.parse(result.body);
      print(JSON.stringify(wallConfig));
      nextLevel++;
    }
  }
  catch(e) {
    print("callback GetWallConfig - error: " + e);
    lastError = -1;
  }
}

function GetWallConfig()
{
  try {
    Shelly.call(
    "HTTP.GET",
    {url: "http://<IP-WallDisplay>/rpc/Temperature.GetConfig?id=0", timeout: 5 },
    CallbackGetWallConfig);
  }
  catch(e) {
    print("GetWallConfig - error: " + e);
    lastError = -1;
  }
}

function CallbackGetSensorStatus(result, error_code, error_message)
{
  try {
    print("callback GetSensorStatus");
    if (error_code != 0) {
      print(error_code + " " + error_message);
      lastError = error_code;
    } else {
      print(result);
      sensorStatus = result;

      nextLevel++;
    }
  }
  catch(e) {
    print("callback GetSensorStatus - error: " + e);
    lastError = -1;
  }
}

function GetSensorStatus()
{
  try {
    Shelly.call(
    "Temperature.GetStatus",
    {id: 100},
    CallbackGetSensorStatus);
  }
  catch(e) {
    print("GetSensorStatus - error: " + e);
    lastError = -1;
  }
}

function CallbackSetWallConfig(result, error_code, error_message)
{
  try {
    print(result.body);
    if (error_code != 0) {
      print(error_message);
      lastError = error_code;
      print(error_code);
    }
  }
  catch(e) {
    print("callback SetWallConfig - error: " + e);
    lastError = -1
  }   
}

function SetWallConfig()
{
  try {
    sensorWall = wallStatus.tC - wallConfig.offset_C;
    sensorB10  = sensorStatus.tC;
    newWallTC  = sensorB10 - sensorWall;
    print("SetWallConfig " + sensorWall + " " + sensorB10 + " " + newWallTC);

    if(Math.abs(wallConfig.offset_C - newWallTC) >= offsetThreshold) { 
      wallConfig.offset_C = newWallTC;

      urlConfig = "http://<IP-WallDisplay>/rpc/Temperature.SetConfig?id=0&config=" + JSON.stringify(wallConfig);
      print(urlConfig);
	
      Shelly.call(
      "HTTP.GET",
      {url: urlConfig, timeout: 5 },
      CallbackSetWallConfig);
    }
  }
  catch(e) {
    print("SetSensorStatus - error: " + e);
    lastError = -1;
  }
}

function timer_callback()
{
  print("");
  print("timer callback " + nextLevel + " " + lastError);

  try {
    if(lastError !== 0) {
      nextLevel = 0;
      lastError = 0;
    }

    if(nextLevel >= 3) {
      print("SetWallConfig");
      SetWallConfig();
      nextLevel = 0;
    }
  	  
    if(nextLevel < 3) {
      GetWallStatus();
      GetWallConfig();
      GetSensorStatus();
    }
  }
  catch(e) {
    print("timer_callback - error: " + e);
    lastError = -1;
    nextLevel = 0;
  }
}

Timer.set(30000, true, timer_callback);
print("timer started");
timer_callback();
UG nJ Sg

Durch die weitere Nutzung der Seite stimmst du der Verwendung von Cookies zu. Weitere Informationen

Die Cookie-Einstellungen auf dieser Website sind auf "Cookies zulassen" eingestellt, um das beste Surferlebnis zu ermöglichen. Wenn du diese Website ohne Änderung der Cookie-Einstellungen verwendest oder auf "Akzeptieren" klickst, erklärst du sich damit einverstanden.

Schließen