Das (IOT) Weinachtsdorf
Das (IOT) Weinachtsdorf
17/12/2019
Weihnachten
IOT
iobroker
mqtt

# Das (IOT) Weinachtsdorf

So also ich habe mir be einem Bazar etwas zugelegt. Ich bin eher nicht der Typ für Bazare. Jedoch ist meine Frau da gern und stellt auch Ihre Handarbeiten und nebenbei auch den Honig zum Verkauf.

Als ich Sie mit unseren jüngsten besucht habe, sah ich an einem Stand ein Weihnachtsdorf.

Der Preis betrug lediglich fünf Euro. Da dachte ich nicht lange nach, das ist eigendlich kein Preis dafür. Als IT-Nerd sprudelten schon die ersten Gedanken über Möglichkeiten.

Ich wollte daraus ein kleines Weihnachtsdorf bauen. Was nun? Ich habe mir daraufhin ein Brett zugelegt, welches Weiß beschichtet ist. Lustigerweise habe ich das für ein paar Euro aus der Rumpelkiste bei Ikea gefunden.

Zuhause hab ich dann auch schon mal die Häuser drauf gestellt und mir mal ein Überblick verschafft. Ebenso auch mal ausgeirchtet wie es aussehen soll.

Erster Ausblick

Ebenso habe ich mir aus einem Kantholz 60x60 jeweils 4 gleich hohe Platten geschnitten. Diese werden als Füße verwendet. Somit ist die Platte nicht komplett auf den Boden aufliegend.

Soweit so gut. Da es nur ein Regalbrett war, welches ich verwendet habe, ist mir aufgefallen das nur vorne die Kante mit weiß abgeklebt ist. Die restlichen Seiten verschwinden gewöhnlich im Regal, nur ich habe das draußen stehen. Daher musste eine Lösung hier.

Die Lösung war eine Leiste, die ich auf Maß geschnitten hatte. ANschließend hat unser größter dann die große Aufgabe gehabt, diese an den Seiten zu befestigen.

Montage der Leisten

Sieht nach viel Arbeit aus. Er war auch ganz gut am schwitzen. Musste auch genau sein😉. Das Ergebnis war ein sauberer Abschluss.

# Die Planung der Elektronik

Ich habe daraufhin mit der Planung der Elektronik begonnen. Ich wollte, dass die Häuser beleuchtet werden. Ursprünglich habe ich dabei an normales Gelbes licht gedacht. Das war auch für den Anfang eine gute Idee.

Planung Schaltung

Das ganze wollte ich dann mittels Mikrokontroller steuern. Jedes Haus hat somit einen eigenen Stromkreis. Sprich, man konnte das Licht der einzelnen Häuser ansteuern.

# Benötigte Komponenten

Folgende Komponenten benötigte Ich dafür:

Name Beispielbild Anzahl
NodeMcu (opens new window) 1
LED (Gelb 5mm) (opens new window) 4
lochraster Platine (opens new window) 1

Joa das war es schon an Material. Ich habe in jedem Haus ein LED Licht angedacht, diese ganzen LED Lichter werden über einen GPIO Port verbunden.

Betrieben wird das per USB Ladekabel. Denn eine Batterie wird die lange laufzeit nicht dauerhaft standhalten. Denn der Mikrokontroller (ESP) verbraucht dazu zu viel. Daher war die Entscheidung das per USB-Kabel zu betreiben. Ist auch nicht schlimm, denn es kommt sowieso unter dem Weihnachtsbaum und hat eine Steckdose in der nähe.

Als Beispielhafte Verkabelung habe ich das einmal in Fritzing erstellt:

platine

Es ist also nichts Wildes. Habe lediglich die GPIO Ports mit den LED's verbunden. Bitte hier auch auf die richtige Polarität achten. Da sonst die LED's kaputt gehen können. In der Regel schaltet man einen Vorwiderstand davor. Jedoch war dies in meinem Fall nicht unbedingt notwendig. Da ich LED's besitze die mit 3,3 V arbeiten. Die GPIO Ports boten mir 3,3V.

Bei dem ersten Testbetrieb war mir aufgefallen das ein reines Gelbes Licht für die Kirche zwar Okay ist, jedoch im Wohnhaus nicht das Gefühl aufkam, das dort leben herrscht. Daher habe ich mich für eine Flackernde LED (5 mm) (opens new window) entschieden.

# Software Infrastrukur

Grob gilt folgende Infrastruktur

Ich habe mir gedacht, dass ich alles komplett über einen Wandschalter (den ich noch übrig habe) aus ud auch einschalten kann. Wenn es eingeschaltet ist dann läuft ein Automatischer Job der die Lichter Zeitgesteuert simuliert.

Hierbei ist beispielsweise die Kirche immer um 18 Uhr mit Licht versorgt, alle anderen Häuser aber nicht. Nach der Kirche sind die beiden Wohnhäuser mit Licht versorgt aber die Stadthalle nicht mehr.

Das sind einige Beispiele. Damit ich nicht abhängig davon bin, ob das IOT gerät im Netz ist, habe ich das ganze über ein Bus System laufen. So ann ich Nachrichten dort ablegen und das IOT gerät empfängt diese, wenn es im W-Lan angebunden ist und die Nachrichten abruft. Nach dem Abrufen werden diese entsprechend verarbeitet und so auch die Lichter gesteuert.

# Die Software auf dem IOT gerät

Ich habe mich entschieden auf Basis von Homie esp 8288 zu arbeiten. Dies hat den Vorteil, dass ich automatisch an den MQTT Server angemeldet werde. Auch die Verbindung mit dem W-Lan ist schon vorhanden. Durch die Konfiguration ist das auch sehr schnell eingestellt.

Das hat den Vorteil das mein Quelltext sehr übersichtlich ist.

#include <Homie.h>

#include <Ticker.h>

#define FW_NAME "bochumsba-iot-fw";#
##define FW_VERSION "2.0.0"
const int PIN_Church = 2;
const int PIN_TownHall = 0;
const int PIN_House1 = 4;
const int PIN_House2 = 16;
const int PIN_House3 = 5;

bool ChurchHandler(String property, String value);
bool TownHallHandler(String property, String value);
bool House1Handler(String property, String value);
bool House2Handler(String property, String value);
bool House3Handler(String property, String value);
bool PinOnHandler(String property, String value);
bool PinOffHandler(String property, String value);

HomieNode lightNodeChurch("Church", "switch");
HomieNode lightNodeTownHall("TownHall", "switch");
HomieNode lightNodeHouse1("House1", "switch");
HomieNode lightNodeHouse2("House2", "switch");
HomieNode lightNodeHouse3("House3", "switch");
HomieNode lightpinon("pinon", "switch");
HomieNode lightpinoff("pinoff", "switch");

HomieNode jsonNode("data", "__json__");

bool globalInputHandler(const HomieNode & node,
  const String & property,
  const HomieRange & range,
  const String & value) {
  Homie.getLogger() << "Calling event " << property << "" << node.getId() << endl;

  StaticJsonBuffer < 200 > jsonBuffer;
  JsonObject & root = jsonBuffer.createObject();

  if (node.getId() == "pinon") {

    Homie.getLogger() << "Running pinon" << endl;
    digitalWrite(value.toInt(), HIGH);
    lightpinon.setProperty("state").setRetained(true).send(value);
    Homie.getLogger() << "ran pinon" << endl;

  }
  if (node.getId() == "pinoff") {
    Homie.getLogger() << "Running pinoff" << endl;
    digitalWrite(value.toInt(), LOW);
    lightpinoff.setProperty("state").setRetained(true).send(value);
    Homie.getLogger() << "ran pinoff" << endl;

  }

  root["Actor"] = node.getId();
  root["LastState"] = (value == "true" ? "false" : "true");
  String values;
  root.printTo(values);
  Homie.getLogger() << "Json data:" << values << endl;
  jsonNode.setProperty("__json__").setRetained(false).send(values);

  return false;

}

void setup() {
  Serial.begin(115200);
  Serial << endl << endl;
  pinMode(2, OUTPUT);
  pinMode(0, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(16, OUTPUT);

  digitalWrite(0, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);

  Serial << endl << endl;
  Homie.__setBrand("Christmas-town");
  Homie_setFirmware(FW_NAME, FW_VERSION);
  Homie.disableResetTrigger();
  Homie.disableLedFeedback(); // collides with Serial on ESP07
  Homie.setGlobalInputHandler(globalInputHandler); // before Homie.setup()

  lightNodeChurch.advertise("on").settable();
  lightNodeTownHall.advertise("on").settable();
  lightNodeHouse1.advertise("on").settable();
  lightNodeHouse2.advertise("on").settable();
  lightNodeHouse3.advertise("on").settable();

  lightpinon.advertise("on").settable();
  lightpinoff.advertise("on").settable();

  lightpinon.advertise("state");
  lightpinoff.advertise("state");

  lightNodeChurch.advertise("state");
  lightNodeTownHall.advertise("state");
  lightNodeHouse1.advertise("state");
  lightNodeHouse2.advertise("state");
  lightNodeHouse3.advertise("state");

  lightpinoff.setProperty("state").send("1");
  lightpinon.setProperty("state").send("1");

  lightNodeChurch.setProperty("state").send("false");
  lightNodeTownHall.setProperty("state").send("false");
  lightNodeHouse1.setProperty("state").send("false");
  lightNodeHouse2.setProperty("state").send("false");
  lightNodeHouse3.setProperty("state").send("false");

  Homie.setup();
}

void loop() {

  Homie.loop();
}

Ich habe das ganze hier (opens new window) auch als git bereitgestellt.

Was wird also gemacht? Ich habe im MQTT ein Topic "pinon" und "pinoff". In jedem dieser wird eine Zahl enthalten sein. Wenn ich pinon die Zahl 5 vorhanden ist. Dann wird der GPIO Pin 5 eingeschaltet. Will man den GPIO wieder ausschalten dann ist die Zahl 5 auf pinoff zu legen.

Damit bin ich flexibel was die Ansteuerung des GPIO’s angeht.

# Die Software in iobroker

In iobroker kann ich mit Hilfe von JavaScript Daten auf den MQTT Server absetzen. Da mein MQTT Server ain Mosuiqtto Server ist (näheres zu meiner IT Infrastruktur habe ich hier beschrieben).

So kam nun folgendes JavaScript zusammen

// Required libs
var mqtt = require('mqtt');
var moment = require('moment');
var recure = require('moment-recur');
// Mqt Adresses
let mqttAdress = 'mqtt://172.20.0.6';
// Rquired Topics
let switchAdress = "fhem.0.WS_3.state";
let pinOn = "homie/christmas-town/pinon/on/set";
let pinOff = "homie/christmas-town/pinoff/on/set";

// Generall start times
var startLights = moment("01:00", "HH:mm");
var endLights = moment("23:00", "HH:mm");

/*
Check if the light is on
*/
function IsOn(start, end, intervall, duration, title) {
    var m = new moment();
    var isOnValue = m.isAfter(start) && m.isBefore(end);
    if (isOnValue) {
        var minute = parseInt(m.format("mm"));
        var rest = minute % intervall;
        log("minute " + minute + " intervall: " + intervall + " rest :" + rest + " duration:" + duration);
        isOnValue = rest <= duration;
    }
    log(title + " is not on: " + isOnValue);
    return isOnValue;
}

function execute() {
    let switchValue = getState(switchAdress).val;
    var client = mqtt.connect(mqttAdress);

    client.on('connect', function () {

        if (switchValue == "on") {
            var m = new moment();
            log(m.format("DD.MM.YYYY HH:mm"));

            client.publish((isTimeInRange('18:00:00', '19:00:00') ? pinOn : pinOff), "5"); 
            client.publish((isTimeInRange('15:30:00', '22:00:00') ? pinOn : pinOff), "4"); 
            client.publish((isTimeInRange('09:30:00', '18:00:00') ? pinOn : pinOff), "2"); 
            client.publish((isTimeInRange('19:30:00', '23:00:00') ? pinOn : pinOff), "0"); 
            client.publish((isTimeInRange('22:30:00', '23:00:00') ? pinOn : pinOff), "16"); 
        }
        else {
            log("Switching off, because the switch was turned off");
            client.publish(pinOff, "0");
            client.publish(pinOff, "2");
            client.publish(pinOff, "4");
            client.publish(pinOff, "5");
            client.publish(pinOff, "16");

        }
    });
}
schedule("* * * * *", execute);
on({ id: switchAdress }, execute)

Hierbei sieht man das ich die Komplette Steuerung abhängi mache von einem Wandschalter. Dieser Schalter bewirkt das die komplette Beleuchtung im Modelhaus ein und auch ausgeschaltet wird.

Im Eingeschalteten Zustand wird jede Minute, das hinterlegte Intervall, jedes einzelnen Hauses geprüft. Ist dieser zutreffend, dann wird das Licht eingeschaltet, sprich es wird eine Nachricht auf das entsprechende Topic gesendet.

# Montage

# Häuser

Nun nachdem ich die Teile alle besitze, ging ich dazu über die Häuser erst einmal auf dem Holzbrett zu kleben. Dazu nahm ich gewöhnlichen Holzleim. Danach habe ich die LED's mit den Dünnen Kabeln verlötet. Diese dann auch entsprechend mit Schrumpfschläufen isoliert. Somit habe ich an einer Seite die LED und an der anderen Seite kann ich dann die Kabel an die Platine montieren.

# Platine

Die Platine habe ich verlötet und anstatt die LED's direkt an die GPIO's zu löten, habe ich mich entschlossen, die Verbindung über Anschlussbuchsen (opens new window) zu erledigen. Das erleichtert das hantieren mit der Platine und somit auch das eventuelle Auswechseln der LED's.

# Verkabelung

Nachdem dieser getrocknet war. Ging es daran die Kabel in die Häuser zu verlegen. Da kein Haus einen Hintereingang besitzt, in dem ich die Kabel von hintern herein einschieben konnte, habe ich diese Kabel also klassisch von unten einführen müssen. Dazu musste aber erstmal ein Loch geborht werden. Mit einem 6mm Holzborher wurde also ein loch im boden eines jeden Hauses (mittig) gebohrt. Dort dann die LED's durchgesteckt. Dadurch dass die LED's einen Durchmesser von 5 mm haben passten diese auch durch die Löcher hindurch.

Die andere Seite der LED's habe ich daraufhin an die Platine über die Anschlussbuchsen angeklemmt.

# Schnee

Was ist nun ein Weihnachtsdorf ohne Schnee? Ich habe erst gedacht das ich mir Schnee selbst mache. Dazu existieren div. Anleitungen eine habe ich ausprobiert. Dabei vermisscht man Rasierschaum mit Kaiser Natron. Das klappte eigendlich ganz gut, jedoch ist der Schnee nach ein paar Tagen gelblich geworden und ausgesehen wie Pulverschnee hat er auch leider nicht so recht. Auch hatte nichts gehaftet. Ich habe das einmal als Video festgehalten.

Ich habe mir dann doch dann Kunstschnee (opens new window) bestellt. Kunstschnee

Dies konnte ich sehr simpel auf dem Dorf verteilen. Fixiert habe ich das ganze mit Sprühkleber.

So sieht das Ganze dann mit Kunstschnee aus

Haus mit Schnee

Es wirkt halt optisch viel schöner und gemütlicher.

Nun nachdem alles zusammengebaut und fertig angeschlossen ist, kann das ganze hier in Aktion unter dem Weihnachtsbaum angeschaut werden

# Fazit

Ich habe mit einem Versuch begonnen. Jedoch angeflammt von den ersten Ergebnissen habe ich nun doch schon mit realtiv wenig Mitteln und auch wenig Aufwand ein selbst gebautes Weihnachtsdorf erstellt. Ich würde jetzt nur noch kleinigkeiten hinzufügen wie eventuell Figuren. Oder einen kleinen Soundgenerator der beispielsweise das Leuten der Glocken simuliert usw.

Jetzt wird aber damit Weihnachten gefeiert 😉. In diesem Sinne:

Frohe Weihnachten!

Übrigends: Wenn Ihr Anregungen habt dann immer her damit! Bin für alles offen.

👋 Hi ich bin's, Sascha