Navigation

    • Register
    • Login
    • Search
    • OpenHardware.io
    • Categories
    • Recent
    • Tags
    • Popular
    1. Home
    2. FotoFieber
    3. Best
    • Continue chat with FotoFieber
    • Start new chat with FotoFieber
    • Flag Profile
    • Profile
    • Following
    • Followers
    • Blocks
    • Topics
    • Posts
    • Best
    • Groups

    Best posts made by FotoFieber

    • Why IOYT matters...

      My current home automation setup uses sensors with different technologies:

      • MySensors (with node-red and serial gateway)
      • zWave (with fhem)
      • Homematic (with homegear)
      • Netatmo
      • Buderus (oil-fired heating, with fhem)
      • Sonoff Dual (hacked, with MQTT)

      I have adapters for all of them to/from MQTT. With node-red I have written an abstraction layer for all of them, which is heavily inspired by the mysensors API.

      The most complex thing I have implemented, is a regulation for the floor heating. The regulation algorithm takes in account:

      • open windows
      • room temperature
      • time
      • lead temperature

      Every room has it's own regulation. But it is dependent mostly on the room temperature sensor. I have written some fuzzy logic but if to many of them fail, it will get cold inside.

      Tomorrow the old api of netatmo will not work anymore. It is the third time, I have written an adapter for my home automation setup. The new api doesn't really bring new functionality but I have to use it.

      So I made a decision to replace all this netatmo stuff with MySensors (https://forum.mysensors.org/topic/4355/mh-z14a-co2-sensor/5).

      It will be

      • cheaper
      • not dependent of the internet or the cloud
      • up to me to decide, when or if I want to change the api
      • fully open sourced
      • not only IOT, bur IOYT

      IOYT... what else?

      posted in General Discussion
      FotoFieber
    • Geiger Counter

      As I live near a nuclear power plant, I thought it would be a good idea to have a radioactivity sensor:
      geiger.jpg
      Components used:

      Geiger Counter Kit:
      http://www.ebay.com/itm/321499888801?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

      An SBM-20 tube:
      http://www.ebay.com/itm/280865770387?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

      And MySensors with this sketch:

      #include <SPI.h>
      #include <MySensor.h>
      
      #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
      #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
      #define CHILD_ID 1   // Id of the sensor child
      
      #define LOG_PERIOD 60000     //Logging period in milliseconds, recommended value 15000-60000.
      
      #define MAX_PERIOD 60000    //Maximum logging period
      
      unsigned long counts;             //variable for GM Tube events
      
      unsigned long cpm;                 //variable for CPM
      
      unsigned int multiplier;             //variable for calculation CPM in this sketch
      
      unsigned long previousMillis;      //variable for time measurement
      
      unsigned long timeReceived = 0;
      unsigned long timeRequested = 0;
      
      MySensor gw;
      // Initialize motion message
      MyMessage msg(CHILD_ID, V_VAR1);
      
      void setup()
      {
        wdt_enable(WDTO_8S);
        gw.begin();
      
        // Send the sketch version information to the gateway and Controller
        gw.sendSketchInfo("Geiger Sensor", "1.1");
      
        wdt_reset();
        // Register all sensors to gw (they will be created as child devices)
        gw.present(CHILD_ID, S_ARDUINO_NODE);
        
        // Geiger initialise
        counts = 0;
      
        cpm = 0;
      
        multiplier = MAX_PERIOD / LOG_PERIOD;      //calculating multiplier, depend on your log period
      
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the geiger sensor digital pin as input
      
        digitalWrite(DIGITAL_INPUT_SENSOR, HIGH);                                 // turn on internal pullup resistors, solder C-INT on the PCB
      
        attachInterrupt(1, tube_impulse, FALLING);  //define external interrupts
      
      }
      
      void loop()
      { 
        wdt_reset();
        unsigned long currentMillis = millis();
      
        if (currentMillis - previousMillis >= LOG_PERIOD) {
      
          cpm = counts * multiplier;
      
          gw.send(msg.set(cpm));
      
          counts = 0;
          previousMillis = currentMillis;
      
        }
      }
      
      
      void tube_impulse() {              //procedure for capturing events from Geiger Kit
      
        counts++;
      
      }
      
      
      
      
      

      I get cpm and in Node-Red I calculate microsievert/per hour:

      [{"id":"ba386057.845d3","type":"mqtt-broker","broker":"192.168.92.4","port":"1883","clientid":"NodeRed"},{"id":"75acf1fb.8a531","type":"mqtt in","name":"Geiger CPM","topic":"MyMQTT/48/1/V_VAR1","broker":"ba386057.845d3","x":146,"y":52,"z":"d1478aa9.2eb878","wires":[["d17bbe2a.2e844"]]},{"id":"d17bbe2a.2e844","type":"function","name":"Nach uSievert umrechnen","func":"cpm = msg.payload;\n\n// für SBM 20 Röhre\n// http://cs.stanford.edu/people/nick/geiger/\nusv = cpm * 0.0057;\n\nmsg.topic = 'NodeRed/Geiger/usv';\nmsg.payload = usv;\n\nreturn msg;","outputs":1,"valid":true,"x":377,"y":52,"z":"d1478aa9.2eb878","wires":[["c53927ba.3ac6d8"]]},{"id":"c53927ba.3ac6d8","type":"mqtt out","name":"","topic":"","qos":"","retain":"","broker":"ba386057.845d3","x":647,"y":52,"z":"d1478aa9.2eb878","wires":[]}]```

      DIY Geiger Counter Kit Nuclear Radiation Detector for Arduino / fits iPhone

      $39.85
      193 available

      SBM-20 Geiger Counter Tube NEW! for Dosimeter Radiometer an. STS-5 Tested Boxed

      $16.00
      750 available
      posted in My Project
      FotoFieber
    • RE: MH-Z14A CO2 sensor

      The sensor is really simple to use, when attached via serial-ttl (3.3V) and powered with 5 volt.

      MH-Z14 co2 readings - PWM & UART with raspberry pi in C++ – 16:21
      — Gary Travell

      You get the values directly from the sensor and don't need to make calculations. Here is what I use:

      /*
         The MySensors Arduino library handles the wireless radio link and protocol
         between your home built sensors/actuators and HA controller of choice.
         The sensors forms a self healing radio network with optional repeaters. Each
         repeater and gateway builds a routing tables in EEPROM which keeps track of the
         network topology allowing messages to be routed to nodes.
      
         Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
         Copyright (C) 2013-2015 Sensnology AB
         Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
      
         Documentation: http://www.mysensors.org
         Support Forum: http://forum.mysensors.org
      
         This program is free software; you can redistribute it and/or
         modify it under the terms of the GNU General Public License
         version 2 as published by the Free Software Foundation.
      
       *******************************
      
         DESCRIPTION
      
          MH-Z14 CO2 sensor via rx/tx serial
      
          */
      
      // Enable debug prints to serial monitor
      //#define MY_DEBUG
      
      // Enable and select radio type attached
      //#define MY_RADIO_NRF24
      
      #define MY_RADIO_RFM69
      #define MY_RFM69_FREQUENCY RF69_868MHZ
      #define MY_RFM69_NETWORKID 13
      #define MY_RFM69_ENABLE_ENCRYPTION
      #define MY_IS_RFM69HW
      
      #include <MySensors.h>
      #include <SoftwareSerial.h>
      #include <Wire.h>
      #include "Adafruit_HTU21DF.h"
      
      SoftwareSerial mySerial(A0, A1); // RX, TX соответственно
      
      Adafruit_HTU21DF htu = Adafruit_HTU21DF();
      
      byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
      char response[9];
      
      #define CHILD_ID_AIQ 0
      #define CHILD_ID_TEMP  1
      #define CHILD_ID_HUM   2
      
      unsigned long SLEEP_TIME = 30 * 1000; // Sleep time between reads (in milliseconds)
      unsigned int TEMP_HUM_ROUNDS = 5; // wait 5 rounds for sending TEMP_HUM
      unsigned int loop_round = 0;
      boolean preheat = true;  // wait TEMP_HUM_ROUNDS for preheat
      
      int lastppm = 0;
      
      MyMessage msg(CHILD_ID_AIQ, V_LEVEL);
      MyMessage msg2(CHILD_ID_AIQ, V_UNIT_PREFIX);
      MyMessage msgHum(CHILD_ID_HUM, V_HUM);
      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
      
      boolean isMetric = true;
      
      void setup()
      {
        mySerial.begin(9600);
        isMetric = getConfig().isMetric;
      
        if (!htu.begin()) {
          Serial.println("Couldn't find sensor htu21!");
        }
      }
      
      void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("AIQ Sensor CO2 MH-Z14 Serial, HTU21 Temp Hum", "1.0");
      
        // Register all sensors to gateway (they will be created as child devices)
        present(CHILD_ID_AIQ, S_AIR_QUALITY);
        send(msg2.set("ppm"));
      
        present(CHILD_ID_TEMP, S_TEMP);
        present(CHILD_ID_HUM, S_HUM);
      }
      
      void loop() {
      
        mySerial.write(cmd, 9);
        mySerial.readBytes(response, 9);
        int responseHigh = (int) response[2];
        int responseLow = (int) response[3];
        int ppm = (256 * responseHigh) + responseLow;
      
        if ((loop_round == 0) || (abs(ppm - lastppm) >= 10)) {
          if (!preheat) {
            send(msg.set(ppm));
            lastppm = ppm;
          }
        }
      
      
      
        if (loop_round == 0) {
          float temp = htu.readTemperature();
          if (!isMetric) {
            temp = temp * 9 / 5 + 32; // convert to farenheit
          }
          send(msgTemp.set(temp, 1));
      
          float hum = htu.readHumidity();
          send(msgHum.set(hum, 1));
        }
      
        loop_round++;
        if (loop_round >= TEMP_HUM_ROUNDS) {
          loop_round = 0;
          preheat = false;
        }
      
        // Power down the radio.  Note that the radio will get powered back up
        // on the next write() call.
        sleep(SLEEP_TIME); //sleep for: sleepTime
      }
      
      posted in Hardware
      FotoFieber
    • RE: 💬 MySensors Contest 2017

      Hmm, I have so many ideas and not much time.

      • a push mysensors notification for amazon echo (alexa)
      • maybe could be the same hardware as above: notify via voice about: window state, air quality, doorbell from mysensors...
      • nice nextion display showing information about my home and the weather forecast
      • doorbell sensor without additional power supply
      • ac detection without additional power supply
      • a mysensors serial mqtt controller for up to 3 gateways based on arduino due

      Or should I first finish my heating circuit regulation which does work for more than two months now without any problem but isn't mysensorized...

      Or should I invest in a blog explaining all the things I did and could help others? (i.e. how do I distinguish an arduino pro mini 16 MHz from a 8 MHz model or how do I connect different protocols ie zWave, mysensors, homematic, netatmo.....)

      Or should I invest more time in my job? 😆

      What about photography? I really like to take pictures with old cameras on film but have done this last time 2 years ago... 😢

      Or should I paint my garage? It is really time to....

      What about tidy up my garage and all my electronic items I purchased with that many ideas in my mind?

      We don't talk about my family. I swear, they don't get to short.

      Maybe a 3d printing project with my 8 year old daughter?

      Sigh, life is to short...

      posted in Announcements
      FotoFieber
    • RE: German users

      https://forum.mysensors.org/topic/2258/german-speaking-members/15

      posted in General Discussion
      FotoFieber
    • RE: pro mini programming

      According to the schematic
      https://www.arduino.cc/en/uploads/Main/Arduino-Pro-Mini-schematic.pdf
      the ftdi header is attached to vcc and is not regulated. High level of cpu is then 5V.

      According to the specs 2.7 up to 5.5 V should be ok @ 8 MHZ
      http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Summary.pdf

      I usually do it the other way round: use a 16Mhz pro mini @ 3.3 V to use RFM69 without level shifters. This is out of specification but working fine.

      posted in Hardware
      FotoFieber
    • RE: MH-Z14A CO2 sensor

      @korttoma
      It is working like a charme for me. Important is, to have 5V for voltage and 3.3 V on the logical level. Here is a graf, the green "Badezimmer" line is the mysensors sensor with MH-Z14A, the others are from netatmo. The mysensors sensor is in the bathroom and therefore it will have usually less CO2.

      0_1479399795680_co2.JPG

      posted in Hardware
      FotoFieber
    • RE: 💬 Node RED

      Here is my solution with support for generating node-ids, multiple controllers and a generic mapping to/from mqtt.

      0_1473669025539_nodered-mys.txt

      posted in Announcements
      FotoFieber
    • RE: PCB Boards for MySensors

      Not keen on soldering SMD, I designed my own PCB.

      The PCB has a flexible design (use jumpers):

      • use with battery
      • use with 5 volt (and LE33 for NRF24L01+)
      • use with voltage stabilazitaion to 3.3V (LE33) for ATMEGA328P and NRF24l01+

      mysduino2.fzz

      OSH Park Link

      I am programming it with an ISP.

      Use a 8 MHz setup: select Lilypad/328p in the Arduino IDE and first burn the bootloader.

      Then I set fuses with mit usbtinyisp to not reset the eeprom with the upload of a sketch (no new node id)

      ./avrdude -C /Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -c usbtiny -p m328p -U hfuse:w:0xD2:m
      

      an enable low voltage usage with battery:

      ./avrdude -C /Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -c usbtiny -p m328p -U efuse:w:0x07:m
      
      posted in Hardware
      FotoFieber
    • RE: MQTT Client gateway

      Thanks Norbert for the great work! Works very well with mosquitto.

      I added support for gw.requestTime(...); by modifying MyMQTTClient.cpp after the lines handling I_CONFIG)

        else if (msg.type == I_TIME)
        {
          txBlink(1);
          if (!sendRoute(
                build(msg, GATEWAY_ADDRESS, msg.sender, 255, C_INTERNAL,
                      I_TIME, 0).set(now())))
            errBlink(1);
        }
      

      Now I have a timebase for low power (deep standby) sensors.

      Next I will try to set the time on the gateway with a MQTT Message or NTP....

      posted in Development
      FotoFieber
    • RE: What did you build today (Pictures) ?

      My actual project is a doorbell sensor with additional temperature and humidity sensors. Tried different ways to detect the ring:

      • hall sensor (failed)
      • microphone (FFT, ongoing research)
      • optocoupler to detect the 12V AC -> favorite solution

      As I was heavy prototyping, I tried wire wrapping and it is fun:
      0_1550390000040_SUNP0002_Moment.jpg

      posted in General Discussion
      FotoFieber
    • RE: Are there any RFM69 shields for Arduino pro mini?

      I love this one:
      https://www.openhardware.io/view/268/RFM69HW-interstitial-board-for-Pro-Mini-Temp-Humidity-sensor

      posted in Hardware
      FotoFieber
    • RE: 💬 scene controller, with motion, temp, hum and co2

      Box has enough space for everything. If I hace time before the end of the contest, I will improve the design to be more friendly to hardware replacement without soldering.

      0_1489923408141_image2.JPG

      Layer 2:
      0_1489923429138_image1.JPG

      posted in OpenHardware.io
      FotoFieber
    • RE: 💬 scene controller, with motion, temp, hum and co2

      Here is the start of the diary of my project,

      Printing first draft of case:
      0_1489232674648_IMG_2257.JPG

      • Hex lids are fine.
      • back cover of temp hum sensor is missing... where is it 😆
      • The nextion display is not centered. (It is not symdetric in the pcb.) If I want it to be centered I may have to make the box quite a bit larger.

      I am really impressed with the print quality of the wanhao i3 plus compare to the xyzprint davinci I had two years ago.

      posted in OpenHardware.io
      FotoFieber
    • RE: relay with button...relay not physically changing state

      @Ticupolu
      Are thes buttons switches or push buttons?

      You call setRelayState only from the recieve functions. (Do I miss something?) This means, that relay changes must be initiated from outside and don't occur only from a button press.

      posted in Troubleshooting
      FotoFieber
    • RE: node disconnects - workaround?

      Try to replace all "delay" with "wait", as the node is not responsible, when you are in a delay.

      Try to add a watchdog:

      • add a a wdt_enable(WDTO_8S) in setup
      • add a wdt_reset() at the start of the loop

      I had several problems with relays and power spikes when they are switched. I changed them all to SSRs and the problems are gone.

      Good luck
      Markus

      posted in Development
      FotoFieber
    • RE: AC Power controller with node to node remotes

      I use a similar design for a wireless door bell. To not be forced to push the button while the node is booting, I charge a large capacitor when a button is pressed.

      posted in My Project
      FotoFieber
    • RE: Battery based atmega328p sensor (no SMD)

      I found a label FTDI on one picture of the PCB. 😀

      I encourage you to read articles about arduino on breadboard and dive deeper or buy complete solutions like the sensebender micro.

      posted in Hardware
      FotoFieber
    • RE: Z-uno Gateway

      @thomme
      This gateway has to remember all the sensors on the mysensors network. If you would add a new sensor, you would have to detach and reattach the Z-Uno from zWave network.

      I don't think you have enough memory on the Z-Uno to do such a gateway and AFAIK the sensor types supported on the Z-Uno are very limited.

      My solution for integrating different iot systems is mqtt with node-red. All systems have an adapter to a generic message structure and can be connected to all the others.

      I use a mix of homegear,/homematic mysensors, netatmo, zWave, owntracks, Alexa, imperihome, Sonoff...

      posted in Feature Requests
      FotoFieber
    • RE: Simple Arduino Controller

      Do you want to control the nodes from outside (e.g. via MQTT) or will the communication be only inside the mysensors network?

      Implementing a controller on the gateway isn't that simple, as there is no plugin mechanism in the library, where you can extend for example the serial gateway.

      For implementation details you can look at
      https://github.com/mysensors/MySensorsSampleController/blob/master/NodeJsController.js

      It may be easier to have a seperate arduino for the controller and attach a serial gateway. (I am working on a arduino due controller where you can attach up to 3 serial gateways.)

      posted in Controllers
      FotoFieber
    • RE: Node only works for a few days

      I had a similar problem with the control of a heating mixer and three dallas sensors. I solved the problem with:

      • replacement of the relays with solid state relays
      • moved conttroller more in distance of the high voltage parts

      I also added a watchdog and a reboot mechanism in case of sensor problems.

      Maybe this sketch can give you an inspiration: (work in progress, MYS-Part not tested in depth)

      // Enable debug prints to serial monitor
      //#define MY_DEBUG      // in Mysensors
      #define EN_DEBUG      // in this sketch
      //#define NO_MYS      // ohne Mysensors Unterstützung?
      //#define SIMULATION
      #define NO_AC_DETECT  // ohne AC sensor
      #define NO_RTC
      
      // RTC nur zusammen mit Mysensors
      #ifdef NO_MYS
      #ifndef NO_RTC
      #define NO_RTC
      #endif
      #endif
      
      #ifdef SIMULATION
      // für Simulation ohne Sensoren
      #define SIMULATE_VOR  35
      #define SIMULATE_RUE  30
      #define SIMULATE_ZU   65
      
      
      #ifdef SIMULATE_VOR
      #warning Achtung! Keine Echtentemperaturmessungen -> Simulation
      #endif
      
      #ifdef SIMULATE_RUE
      #warning Achtung! Keine Echtentemperaturmessungen -> Simulation
      #endif
      
      #ifdef SIMULATE_ZU
      #warning Achtung! Keine Echtentemperaturmessungen -> Simulation
      #endif
      #endif
      
      
      #define START_TARGET_TEMP 40
      #define EEPROM_TARGET_TEMP 900            // Save Porisiton. It is above the Mysensors range of lib 2.1
      #define EEPROM_POWERSTATE  902            // Save Porisiton. It is above the Mysensors range of lib 2.1
      #define MAX_TEMP 50
      #define VORLAUF 0
      #define RUECKLAUF 1
      #define ZULAUF 2
      #define PUMPE 0
      #define MISCHER_ZU  1
      #define MISCHER_AUF 2
      #define POWERLED 7                        // 8. LED
      #define TEMPDOWNLED 5                     // 6. Led
      #define TEMPUPLED 6                       // 7. Led
      #ifndef NO_AC_DETECT
      #define BUDERUSLED 4                      // 5. Led
      #endif
      #define RETRY_TIMEOUT_PUMP 2*60*1000UL     // alle 2 Minuten testen, ob Vorlauf nicht besser (5 Sekunden pumpen)
      #define REGULATION_TIMEOUT_PUMP 30*1000UL  // 30 Sekunden warten nach neuer Einstellung
      #define PROBE_TIMEOUT_PUMP 5*1000UL        // 5 Sekunden Pumpe für Test einschalten, wenn Zulauf zu kalt
      #define BUDERUS_PIN 3                     // Buderus Powererkennung Pumpe auf PIN 3
      
      #ifndef SIMULATION
      #define MISCHER_RESET_TIME 120*1000UL      // 2 Minuten bis Nullstellung
      #else
      #define MISCHER_RESET_TIME 10*1000UL      // 10 Sekunden bis Nullstellung nei Simulation
      #endif
      
      
      
      #ifdef EN_DEBUG
      #define DEBUG_PRINT(x) Serial.print (x)
      #else
      #define DEBUG_PRINT(x)
      #endif
      
      #ifdef EN_DEBUG
      #define DEBUG_PRINTLN(x)  Serial.println (x)
      #else
      #define DEBUG_PRINTLN(x)
      #endif
      
      #ifndef NO_MYS
      // Radio Configuration
      #define MY_TRANSPORT_WAIT_READY_MS (10000ul)
      #define MY_RADIO_RFM69
      #define MY_RFM69_FREQUENCY RF69_868MHZ
      #define MY_RFM69_NETWORKID 13
      #define MY_RFM69_ENABLE_ENCRYPTION
      #define MY_NODE_ID 168
      //#define MY_IS_RFM69HW
      #endif
      
      
      #include <Arduino.h>
      #include <avr/wdt.h>
      #include <EEPROM.h>
      #include <MemoryFree.h>
      
      #ifndef NO_MYS
      #define MIN_REPORT_INTERVAL  5 * 60 * 1000L   // mindestens alle 5 Minuten melden
      #include <SPI.h>
      #include <MySensors.h>
      #include <Time.h>        //http://www.arduino.cc/playground/Code/Time
      #include <Timezone.h>    //https://github.com/JChristensen/Timezone
      #include <TimeLib.h>
      
      //Central European Time (Frankfurt, Paris)
      TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120};     //Central European Summer Time
      TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60};       //Central European Standard Time
      Timezone CE(CEST, CET);
      bool timeReceived = false;
      unsigned long lastUpdate = 0, lastRequest = 0;
      #endif
      
      #ifndef NO_RTC
      #include <DS3232RTC.h>  // A  DS3231/DS3232 library
      #endif
      
      #define MAX_LEDS 8
      
      byte lastButtonState = 0;
      #define RELAY_ON HIGH
      #define RELAY_OFF LOW
      #define RELAY_1  A0         // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
      #define NUMBER_OF_RELAYS 4  // Total number of attached relays
      
      
      boolean ledState[MAX_LEDS] = { false, false, false, false, false, false, false, false };
      boolean relState[NUMBER_OF_RELAYS] = { false, false, false, false };
      
      #include <TM1638.h>
      #include <DallasTemperature.h>
      #include <OneWire.h>
      
      #define ONE_WIRE_BUS 6 // Pin where dallase sensor is connected 
      #define TEMPERATURE_PRECISION 9
      #define MAX_ATTACHED_DS18B20 3
      
      //28B404080000804A
      DeviceAddress Probe01 = { 0x28, 0xB4, 0x04, 0x08, 0x00, 0x00, 0x80, 0x4A };
      //28C606080000803F
      DeviceAddress Probe02 = { 0x28, 0xC6, 0x06, 0x08, 0x00, 0x00, 0x80, 0x3F };
      //28750808000080C3
      DeviceAddress Probe03 = { 0x28, 0x75, 0x08, 0x08, 0x00, 0x00, 0x80, 0xC3 };
      
      OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
      DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
      int numSensors = 0;
      int lastTemperature[MAX_ATTACHED_DS18B20] = { -100, -100, -100 };
      int16_t conversionTime;
      unsigned long previousTempMillis = -1;
      static unsigned long nowms = millis();    // update at start of loop()
      
      
      // define LCD module
      TM1638 ledModule(8, 9, 7);
      
      int displayInfo = -1;
      unsigned long previousDisplayMillis = 0;
      
      int targetTemp = START_TARGET_TEMP;
      #ifdef SIMULATION
      bool powerOn = true;
      #ifndef NO_AC_DETECT
      bool powerOnBuderus = true;
      #endif
      #else
      bool powerOn = false;
      #ifndef NO_AC_DETECT
      bool powerOnBuderus = false;
      #endif
      #endif
      bool resetMischer = true; // mischer zuerst in Nullstellung
      
      #ifndef NO_AC_DETECT
      bool testStateBuderus = false;
      unsigned long lastResetBuderus = -1;
      #endif
      
      #ifndef NO_MYS
      // Initialize messages
      MyMessage msgTemp(0, V_TEMP);
      MyMessage msgStatus(0, V_STATUS);
      MyMessage msgTargetTemp(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS, V_HVAC_SETPOINT_HEAT);
      MyMessage msgPower(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 1, V_STATUS);
      #ifndef NO_AC_DETECT
      MyMessage msgPowerBuderus(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 2, V_STATUS);
      #endif
      MyMessage msgDebug(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 3, V_TEXT);
      #endif
      
      // the setup function runs once when you press reset or power the board
      void setup() {
        DEBUG_PRINTLN(F("Starte setup"));
        wdt_enable(WDTO_8S);
        Serial.begin(115200);
      
      #ifndef NO_RTC
        // the function to get the time from the RTC
        setSyncProvider(RTC.get);
      #endif
      #ifndef NO_MYS
        // Request latest time from controller at startup
        requestTime();
      #endif
      
      
      
      
        // Zieltemperatur aus EERPOM lesem:
        targetTemp = EEPROM.read(EEPROM_TARGET_TEMP);
        if ((targetTemp < 30) || (targetTemp > MAX_TEMP)) {
          targetTemp = START_TARGET_TEMP;
          EEPROM.write(EEPROM_TARGET_TEMP, targetTemp);
        }
      
        int state = EEPROM.read(EEPROM_POWERSTATE);
        if (state == 0) {
          powerOn = false;
        }
        else powerOn = true;
      
      #ifndef NO_AC_DETECT
        // Buderuserkennung auf PIN3
        attachInterrupt(digitalPinToInterrupt(BUDERUS_PIN), buderusSet, CHANGE);
        testStateBuderus = false;
        lastResetBuderus = millis();
      #ifndef NO_MYS
        send(msgPowerBuderus.set(powerOnBuderus));
      #endif
      #endif
      
        // Relayausgänge initialisiern
        for (int sensor = 1, pin = RELAY_1; sensor <= NUMBER_OF_RELAYS; sensor++, pin++) {
          // Then set relay pins in output mode
          pinMode(pin, OUTPUT);
          // Set relay to last known state (using eeprom storage)
          digitalWrite(pin, RELAY_OFF);
        }
      
        // Dallas Temperatursensoren
        sensors.begin();
        sensors.setWaitForConversion(false);
        numSensors = sensors.getDeviceCount();
        DEBUG_PRINT(F("Dallas Sensoren "));
        DEBUG_PRINTLN(numSensors);
        DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address
      
        for (int i = 0; i < numSensors; i++)
        {
          wdt_reset();
          // Search the wire for address
          if (sensors.getAddress(tempDeviceAddress, i))
          {
            DEBUG_PRINT(F("Found device "));
      #ifdef EN_DEBUG
            Serial.print(i, DEC);
      #endif
            DEBUG_PRINT(F(" with address: "));
            printAddress(tempDeviceAddress);
            DEBUG_PRINTLN();
      
            DEBUG_PRINT(F("Setting resolution to "));
      #ifdef EN_DEBUG
            Serial.println(TEMPERATURE_PRECISION, DEC);
      #endif
            // set the resolution to 12 bit (Each Dallas/Maxim device is capable of several different resolutions)
            sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
      
            DEBUG_PRINT(F("Resolution actually set to: "));
      
      #ifdef EN_DEBUG
            Serial.print(sensors.getResolution(tempDeviceAddress), DEC);
      #endif
            DEBUG_PRINTLN();
          } else {
            DEBUG_PRINT(F("Found ghost device at "));
      
      #ifdef EN_DEBUG
            Serial.print(i, DEC);
      #endif
            DEBUG_PRINT(F(" but could not detect address. Check power and cabling"));
          }
        }
      
        wdt_reset();
        sensors.requestTemperatures();
      
        // query conversion time and sleep until conversion completed
        conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
      }
      
      /*****************************************************/
      // the loop function runs over and over again forever
      void loop() {
        nowms = millis();
      
      #ifndef NO_MYS
        // If no time has been received yet, request it every 10 second from controller
        // When time has been received, request update every hour
        if ((!timeReceived && (nowms - lastRequest) > (10UL * 1000UL))
            || (timeReceived && (nowms - lastRequest) > (60UL * 1000UL * 60UL))) {
          // Request time from controller.
          DEBUG_PRINTLN("requesting time");
          requestTime();
          lastRequest = nowms;
        }
      #endif
      
        wdt_reset();
      
      #ifndef NO_AC_DETECT
        readAC();
      #endif
      
        readTemp();
        readButtons();
      
        updateDisp();
      
        // Temperaturen senden
      
      #ifndef NO_MYS
        sendTemp();
      #endif
      
        // Kontroller
        control();
      
        // Loop 2x pro Sekunde ist aureichend
        unsigned long loopTime = millis() - nowms;
        if (loopTime < 450) {
      #ifdef NO_MYS
          delay (500 - loopTime);
      #else
          wait (500 - loopTime);
      #endif
        }
      }
      // end loop
      
      /**************************************************************/
      // Steuerung
      void control()
      {
      
        wdt_reset();
      
        static unsigned long lastPumpTest = 0;
        static unsigned long lastRegulation = -REGULATION_TIMEOUT_PUMP;
        static unsigned long resetStart = 0;                     // wann wurde die Rücksetzung des Mischers gestartet
        static bool lastPower = powerOn;
        static float moveSeconds = 0.0;                 // Zeiten für Stellmotor Mischer
      
        // controllerState
        // 0 initialized
        // 1 Pumpe für kurzen test aktiviert, warten auf Timeout für Deaktivierung
        // 2 in der Regelung, warten auf Timeout für Deaktivierung
        // 3 in Ausganglage fahren
      
        static int controllerState = 0;
      
        // Emergency
        if  (lastTemperature[VORLAUF] > MAX_TEMP) {
          if (resetStart == 0) {
            if (relState[PUMPE]) {
              DEBUG_PRINT(F("Zu heiss. Emergency Mischer schliessen"));
              DEBUG_PRINTLN(lastTemperature[VORLAUF]);
            }
            closeMischer();
            controllerState = 0;
            return;
          }
        }
      
      
        // Temperatur noch nicht gelesen;
        if (lastTemperature[VORLAUF] == -100) return;
      
        // Fehler mit den Sensoren
        if ((lastTemperature[VORLAUF] < 0) ||
            (lastTemperature[VORLAUF] > 100) ||
            (lastTemperature[RUECKLAUF] < 0) ||
            (lastTemperature[RUECKLAUF] > 100) ||
            (lastTemperature[ZULAUF] < 0) ||
            (lastTemperature[ZULAUF] > 100)) {
          relState[PUMPE] = false;
          updateRelays();
          ledState[PUMPE] = relState[PUMPE];
          // Test
          //powerOn = false;
      #ifndef NO_MYS
          //send(msgPower.set(powerOn));
      #endif
      
          controllerState = 0;
          DEBUG_PRINTLN(F("Fehler mit den Sensoren, Temperaturen unter 0 oder über 100. Poweroff!"));
          return;
        }
      
        if (resetMischer) {
          DEBUG_PRINTLN(F("Mischer initialisieren"));
          closeMischer();
          resetStart = millis();
          resetMischer = false;
          controllerState = 0;
          return;
        }
      
        if (resetStart > 0) {
          if ((millis() - resetStart) > MISCHER_RESET_TIME) {
            DEBUG_PRINTLN(F("Mischer fertig initialisiert"));
            relState[MISCHER_ZU] = false;
            updateRelays();
            ledState[PUMPE] = relState[PUMPE];
            ledState[MISCHER_ZU] = relState[MISCHER_ZU];
            resetStart = 0;
            controllerState = 0;
          }
          return;
        }
      
        // wenn ausser Betrieb -> verlassen;
        if (powerOn == false) {
          if (lastPower == false) return;
      
          DEBUG_PRINTLN("Go to power off state");
      
      #ifndef NO_MYS
          send(msgPower.set(powerOn));
      #endif
      
          lastPower = false;
          relState[PUMPE] = false;
          relState[MISCHER_ZU] = false;
          relState[MISCHER_AUF] = false;
          updateRelays();
          ledState[PUMPE] = relState[PUMPE];
          ledState[MISCHER_ZU] = relState[MISCHER_ZU];
          ledState[MISCHER_AUF] = relState[MISCHER_AUF];
          controllerState = 0;
          EEPROM.write(EEPROM_POWERSTATE, 0);
          return;
        }
        //DEBUG_PRINTLN("a");
        lastPower = true;
      
        switch (controllerState) {
          case  0:  // Initialisiert
            if (lastTemperature[ZULAUF] < 30) {
              if ((millis() - lastPumpTest) > RETRY_TIMEOUT_PUMP) {
                controllerState = 1;
                lastPumpTest = millis();
                DEBUG_PRINTLN(F("Zulauf zu kalt. Schalte Pumpe für 5 Sekunden ein."));
                relState[PUMPE] = true;
                updateRelays();
                ledState[PUMPE] = relState[PUMPE];
              }
              return;
            }
            //DEBUG_PRINTLN("x");
      
            relState[PUMPE] = true;
            updateRelays();
            ledState[PUMPE] = relState[PUMPE];
      
      
            // nicht regulieren, wenn schon genau genug
            if (abs(lastTemperature[VORLAUF] - targetTemp) <= 1) {
              // DEBUG_PRINTLN("diff zu klein, keine Steuerung notwendig");
              return;
            }
      
      
            if ((millis() - lastRegulation) > REGULATION_TIMEOUT_PUMP) {
              controllerState = 2;
              lastRegulation = millis();
      
              int diffZualaufRuecklauf = lastTemperature[ZULAUF] - lastTemperature[RUECKLAUF];
      
              float actPercent = (float)(lastTemperature[VORLAUF] - lastTemperature[RUECKLAUF]) * 100.0 / (float)diffZualaufRuecklauf;
              float shoulPercent = (float)(targetTemp - lastTemperature[RUECKLAUF]) * 100.0 / (float)diffZualaufRuecklauf;
      
              // 120 Sekunden für ganzen Weg
              moveSeconds = (float)MISCHER_RESET_TIME / 1000.0 / 100.0 * abs(shoulPercent - actPercent);
              DEBUG_PRINT(F("Berechnete Sekunden fuer Mischerumstellung "));
              DEBUG_PRINTLN(moveSeconds);
              if (moveSeconds > 8)
                moveSeconds = 8;
      
              if (targetTemp > lastTemperature[VORLAUF]) {
                DEBUG_PRINTLN(F("Mischer auf"));
                relState[MISCHER_ZU] = false;
                relState[MISCHER_AUF] = true;
                updateRelays();
                ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                ledState[MISCHER_AUF] = relState[MISCHER_AUF];
              }
              else
              {
                DEBUG_PRINTLN(F("Mischer zu"));
                relState[MISCHER_ZU] = true;
                relState[MISCHER_AUF] = false;
                updateRelays();
                ledState[MISCHER_ZU] = relState[MISCHER_ZU];
                ledState[MISCHER_AUF] = relState[MISCHER_AUF];
              }
              return;
            }
            return;
            break;
          case  1: // in Testmodus bei zu wenig  Temp im Zulauf
            if ((millis() - lastPumpTest) > PROBE_TIMEOUT_PUMP) {
              relState[PUMPE] = false;
              updateRelays();
              ledState[PUMPE] = relState[PUMPE];
              DEBUG_PRINTLN(F("Pumpe ausgeschaltet"));
              controllerState = 0;
              lastPumpTest = millis();
            }
            return;
            break;
          case  2: // in der Regelung
            if ((millis() - lastRegulation) > moveSeconds * 1000.0) {
              DEBUG_PRINTLN("Mischer zu.");
              relState[MISCHER_ZU] = false;
              relState[MISCHER_AUF] = false;
              updateRelays();
              ledState[MISCHER_ZU] = relState[MISCHER_ZU];
              ledState[MISCHER_AUF] = relState[MISCHER_AUF];
              lastRegulation = millis();
              controllerState = 0;
            }
            return;
            break;
          default:
            DEBUG_PRINT(F("ERROR, unknown state :"));
            DEBUG_PRINTLN(controllerState);
            controllerState = 0;
            return;
        }
      }
      
      // function to print a device address
      void printAddress(DeviceAddress deviceAddress)
      {
        for (uint8_t i = 0; i < 8; i++)
        {
          if (deviceAddress[i] < 16) DEBUG_PRINT("0");
      
      #ifdef EN_DEBUG
          Serial.print(deviceAddress[i], HEX);
      #endif
        }
      }
      
      void updateRelays() {
        static boolean relayStateReported[8] = { false, false, false, false, false, false, false, false };
      #ifndef NO_MYS
        static unsigned long previousStateMillis[NUMBER_OF_RELAYS] = { 0, 0, 0, 0 };
      #endif
      
        for (int i = 0; i < NUMBER_OF_RELAYS; i++) {
          if (relState[i]) {
            digitalWrite(RELAY_1 + i, RELAY_ON);
          }
          else
          {
            digitalWrite(RELAY_1 + i, RELAY_OFF);
          }
      
      #ifndef NO_MYS
          bool bSend = false;
          if (previousStateMillis[i] == 0) {                               // noch nie gesendet
            bSend = true;
          }
          else if (relayStateReported[i] != relState[i] ) { // Änderungen melden
            bSend = true;
          }
          else if ((millis() - previousStateMillis[i]) > MIN_REPORT_INTERVAL) {
            bSend = true;
          }
      
          if (bSend) {
            // TODO: Check if we want to look at the return value of send
            send(msgStatus.setSensor(i + MAX_ATTACHED_DS18B20).set(relState[i] ? 1 : 0));
            previousStateMillis[i] = millis();
            relayStateReported[i] = relState[i];
          }
      #endif
        }
      }
      
      void updateDisp() {
        static char s[8];
        static unsigned long previousDisplayMillis = 0;
      
        // update display?
        if ((millis() - previousDisplayMillis) > 1000) {
          previousDisplayMillis = millis();
          displayInfo++;
      #ifdef NO_MYS
          if (displayInfo > 4) displayInfo = 0;
      #else
          if (displayInfo > 5) displayInfo = 0;
      #endif
      
      
      
          ledModule.clearDisplay();
          // sind die Temperaturen schon gelesen worden? Wenn nicht, abbrechen.
          if (lastTemperature[0] == -100) return;
      
          for (byte i = 0; i <= 7; i++) {
            if (ledState[i])
              ledModule.setLED(1, i);
            else
              ledModule.setLED(0, i);
          }
      
          // 0 Vorlauf, 1 Rücklauf, 2 Zulauf, 3 Sollwert
          switch (displayInfo) {
            case 0: // Vorlauf
              sprintf(s, "Vor %2i",  lastTemperature[VORLAUF]);
              break;
            case 1: // Rücklauf
              sprintf(s, "Rue %2i",  lastTemperature[RUECKLAUF]);
              break;
            case 2: // Zulauf
              sprintf(s, "Zu %2i",  lastTemperature[ZULAUF]);
              break;
            case 3: // Zielwert
              sprintf(s, "Soll %2i",  targetTemp);
              break;
            case 4: // Power
              if (powerOn) {
                sprintf(s, "PowerOn");
              }
              else {
                sprintf(s, "PowerOff");
              }
              break;
      #ifndef NO_MYS
            case 5: //clock
              TimeChangeRule *tcr;
              time_t utc = millis();
              time_t t = CE.toLocal(utc, &tcr);
              unsigned long dispTime = hour(t) * 100 * 100 + minute(t) * 100 + second(t);
              if (hour(t) < 10) {
                sprintf(s, "U 0%lu",  dispTime);
              }
              else
              {
                sprintf(s, "U %lu",  dispTime);
              }
              break;
      #endif
          }
      
          ledModule.setDisplayToString(s);
        }
      }
      
      void closeMischer() {
        relState[PUMPE] = false;
        relState[MISCHER_ZU] = true;
        relState[MISCHER_AUF] = false;
        updateRelays();
        ledState[PUMPE] = relState[PUMPE];
        ledState[MISCHER_ZU] = relState[MISCHER_ZU];
        ledState[MISCHER_AUF] = relState[MISCHER_AUF];
      }
      
      
      #ifndef NO_MYS
      
      void before()
      {
      
      }
      
      // 0 Vorlauf, 1 Rücklauf, 2 Zulauf
      void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Mischer Node", "1.1");
      
        // Fetch the number of attached temperature sensors
        numSensors = sensors.getDeviceCount();
        DEBUG_PRINT(F("Numsensors "));
        DEBUG_PRINTLN(numSensors);
      
        // Present all sensors to controller
        for (int i = 0; i < numSensors && i < MAX_ATTACHED_DS18B20; i++) {
          present(i, S_TEMP);
        }
      
        for (int sensor = MAX_ATTACHED_DS18B20, pin = RELAY_1; sensor < (MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS); sensor++, pin++) {
          // Register all sensors to gw (they will be created as child devices)
          present(sensor, S_BINARY);
        }
      
        // Thermopunkt
        present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS, S_HVAC);
      
        // Power
        present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 1, S_HEATER);
      
      #ifndef NO_AC_DETECT
        // AC Buderuus
        present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 2, S_BINATY);
      #endif
      
        // Power
        present(MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 3, S_INFO);
      
        // Initialltemperatur mitteilen
        send(msgTargetTemp.set(targetTemp));
        send(msgPower.set(powerOn));
      }
      
      
      void receive(const MyMessage & message)
      {
        DEBUG_PRINT(F("Meldung an Sensor "));
        DEBUG_PRINT(message.sensor);
        DEBUG_PRINT(F(" mit type "));
        DEBUG_PRINTLN(message.type);
        if (message.type == V_STATUS) {
          int i = message.sensor - MAX_ATTACHED_DS18B20;
          if ((i >= 0) && (i < NUMBER_OF_RELAYS)) {
            DEBUG_PRINT(F("Schaltbefehl für Relay "));
            DEBUG_PRINT(i);
            DEBUG_PRINT(F(" auf "));
            DEBUG_PRINTLN(message.getBool());
            relState[i] = message.getBool();
            ledState[i] = relState[i];
          }
          else if (i == MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS + 1) {
            powerOn = message.getBool();
            send(msgPower.set(powerOn));
      
            if (powerOn)
              EEPROM.write(EEPROM_POWERSTATE, 1);
            else
              EEPROM.write(EEPROM_POWERSTATE, 0);
      
            if (powerOn == false) {
              relState[PUMPE] = false;
              ledState[POWERLED] = false;
              DEBUG_PRINTLN(F("Befehl für PowerOff"));
            }
            else {
              ledState[POWERLED] = true;
              DEBUG_PRINTLN(F("Befehl für PowerOn"));
            }
          }
      
          updateRelays();
        }
        else if (message.type == V_HVAC_SETPOINT_HEAT) {
          if (message.sensor == (MAX_ATTACHED_DS18B20 + NUMBER_OF_RELAYS)) {
            targetTemp = message.getInt();
            DEBUG_PRINT(F("Zieltemp gesetzt auf "));
            DEBUG_PRINTLN(targetTemp);
            if (targetTemp > MAX_TEMP) targetTemp = START_TARGET_TEMP;
            if (targetTemp < 20) targetTemp = 20;
            send(msgTargetTemp.set(targetTemp));
          }
        }
      }
      
      // This is called when a new time value was received
      void receiveTime(unsigned long controllerTime) {
        // Ok, set incoming time
        DEBUG_PRINT(F("Time value received: "));
        DEBUG_PRINTLN(controllerTime);
      #ifndef NO_RTC
        RTC.set(controllerTime);
        else
          setTime(controllerTime);
      #endif
        timeReceived = true;
      }
      
      void sendTemp() {
        static int lastSentTemperature[MAX_ATTACHED_DS18B20] = { -100, -100, -100 };
        static unsigned long previousTempMillis[MAX_ATTACHED_DS18B20] = { 0, 0, 0 };
      
        for (int i = 0; i < MAX_ATTACHED_DS18B20 ; i++) {
          if (lastTemperature[i] != -100) {
            bool bSend = false;
            if (previousTempMillis[i] == 0) {                               // noch nie gesendet
              bSend = true;
            }
            else if (abs(lastSentTemperature[i] - lastTemperature[i]) >= 2) { // Differenz von >= zwei Grad werden gemeldet
              bSend = true;
            }
            else if ((millis() - previousTempMillis[i]) > MIN_REPORT_INTERVAL) {
              bSend = true;
            }
      
            if (bSend) {
              // TODO: Check if we want to look at the return value of send
              send(msgTemp.setSensor(i).set(lastTemperature[i], 1));
              previousTempMillis[i] = millis();
              lastSentTemperature[i] = lastTemperature[i];
            }
          }
        }
      }
      #endif
      
      #ifndef NO_AC_DETECT
      void buderusSet() {
        testStateBuderus = true;
      }
      #endif
      
      void reboot() {
        wdt_enable(WDTO_30MS);
        while (1) {};
      }
      
      void readButtons() {
      
        byte buttons = ledModule.getButtons();
      
        if (lastButtonState != buttons) {
          lastButtonState = buttons;
          if (buttons > 0) {
            for (byte i = 0; i <= 7; i++) {
              if ((buttons >> i) & 1) {
                ledState[i] = !ledState[i];
                if (i < NUMBER_OF_RELAYS) relState[i] = ledState[i];
                updateRelays();
                if (ledState[i])
                  ledModule.setLED(1, i);
                else
                  ledModule.setLED(0, i);
                if (i == POWERLED) {
                  powerOn = ledState[i];
      #ifndef NO_MYS
                  send(msgPower.set(powerOn));
      #endif
                  if (powerOn)
                    EEPROM.write(EEPROM_POWERSTATE, 1);
                  else
                    EEPROM.write(EEPROM_POWERSTATE, 0);
      
                }
      
                if (i == TEMPDOWNLED) {
                  targetTemp--;
                  if (targetTemp < 30) targetTemp = 30;
                  EEPROM.write(EEPROM_TARGET_TEMP, targetTemp);
                }
                if (i == TEMPUPLED) {
                  targetTemp++;
                  if (targetTemp > MAX_TEMP) targetTemp = MAX_TEMP;
                  EEPROM.write(EEPROM_TARGET_TEMP, targetTemp);
                }
                DEBUG_PRINT(F("ButtonState changed "));
                DEBUG_PRINTLN(i);
              }
            }
          }
        }
      }
      
      void readTemp() {
        static float temp;
        static int tempi;
        static unsigned long lastReadTemp1 = -1;
        static unsigned long lastReadTemp2 = -1;
        static unsigned long lastReadTemp3 = -1;
      
        if (previousTempMillis == -1) {
          // Dallas
          sensors.requestTemperatures();
          previousTempMillis = nowms;
        }
      
        if ((millis() - previousTempMillis) >= conversionTime) {
          temp = sensors.getTempC(Probe01);
          if (temp != DEVICE_DISCONNECTED_C) {
            tempi = (int)(temp + 0.5);
            lastTemperature[VORLAUF] = tempi;
            lastReadTemp1 = nowms;
          }
      
          if (temp != DEVICE_DISCONNECTED_C) {
            temp = sensors.getTempC(Probe02);
            tempi = (int)(temp + 0.5);
            lastTemperature[RUECKLAUF] = tempi;
            lastReadTemp2 = nowms;
          }
      
          if (temp != DEVICE_DISCONNECTED_C) {
            temp = sensors.getTempC(Probe03);
            tempi = (int)(temp + 0.5);
            lastTemperature[ZULAUF] = tempi;
            lastReadTemp3 = nowms;
          }
      
          if (nowms > 60000) {    // ersta nach einer minute prüfen
            unsigned long compare = nowms - 60000; // vor 1 Minute
            if ((lastReadTemp1 < compare) || (lastReadTemp2 < compare) || (lastReadTemp3 < compare)) {
              DEBUG_PRINTLN(F("Zu lange keine Temeratur -> reset"));
              lastReadTemp1 = -1;
              lastReadTemp2 = -1;
              lastReadTemp3 = -1;
              ledModule.setDisplayToString(F("ERR Reb"));
              delay(1000);
              reboot();
            }
          }
      
          previousTempMillis = -1;
        }
      
      #ifdef SIMULATE_VOR
        lastTemperature[VORLAUF] = SIMULATE_VOR;
        lastReadTemp1 = nowms;
      #endif
      
      #ifdef SIMULATE_RUE
        lastTemperature[RUECKLAUF] = SIMULATE_RUE;
        lastReadTemp3 = nowms;
      #endif
      
      #ifdef SIMULATE_ZU
        lastTemperature[ZULAUF] = SIMULATE_ZU;
        lastReadTemp3 = nowms;
      #endif
      }
      
      #ifndef NO_AC_DETECT
      
      void readAC() {
        if ((millis() - lastResetBuderus) > 100) // bei 50 HZ sind das 25 Durchgänge...
        {
          noInterrupts();
          if (testStateBuderus != powerOnBuderus ) {
            powerOnBuderus = testStateBuderus;
            testStateBuderus = false;
            interrupts();
            ledState[BUDERUSLED] = powerOnBuderus;
      #ifndef NO_MYS
            send(msgPowerBuderus.set(powerOnBuderus));
      #endif
          }
          lastResetBuderus = nowms;
          testStateBuderus = false;
        } else
          interrupts();
      }
      #endif
      
      posted in Troubleshooting
      FotoFieber
    • RE: im brand new to MySensor and its not going well

      Maybe this thread can help
      https://forum.mysensors.org/topic/1245/building-an-ethernet-gateway-on-an-arduino-mega/4

      posted in Troubleshooting
      FotoFieber
    • RE: Unique ID-value DS18B20 Temperature sensors

      There are several examples on the internet and I have cut and pasted my solution for a similar problem with 4 sensors (serial gateway with dallas sensors):

      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      //#define MY_RADIO_RFM69
      
      // Set LOW transmit power level as default, if you have an amplified NRF-module and
      // power your radio separately with a good regulator you can turn up PA level.
      #define MY_RF24_PA_LEVEL RF24_PA_LOW
      
      // Enable serial gateway
      #define MY_GATEWAY_SERIAL
      
      // Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
      #if F_CPU == 8000000L
      #define MY_BAUD_RATE 38400
      #endif
      
      // Flash leds on rx/tx/err
      #define MY_LEDS_BLINKING_FEATURE
      // Set blinking period
      #define MY_DEFAULT_LED_BLINK_PERIOD 300
      
      // Inverses the behavior of leds
      //#define MY_WITH_LEDS_BLINKING_INVERSE
      
      // Enable inclusion mode
      #define MY_INCLUSION_MODE_FEATURE
      // Enable Inclusion mode button on gateway
      #define MY_INCLUSION_BUTTON_FEATURE
      
      // Inverses behavior of inclusion button (if using external pullup)
      //#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP
      
      // Set inclusion mode duration (in seconds)
      #define MY_INCLUSION_MODE_DURATION 60
      // Digital pin used for inclusion mode button
      #define MY_INCLUSION_MODE_BUTTON_PIN  3
      
      // Uncomment to override default HW configurations
      //#define MY_DEFAULT_ERR_LED_PIN 4  // Error led pin
      //#define MY_DEFAULT_RX_LED_PIN  6  // Receive led pin
      //#define MY_DEFAULT_TX_LED_PIN  5  // the PCB, on board LED
      
      #include <SPI.h>
      #include <MySensors.h>
      
      // Dallas
      #include <DallasTemperature.h>
      #include <OneWire.h>
      
      DeviceAddress Probe01 = { 0x28, 0xFF, 0x2E, 0x3E, 0x66, 0x14, 0x01, 0xB2 };
      DeviceAddress Probe02 = { 0x28, 0xFF, 0xB9, 0x40, 0x66, 0x14, 0x01, 0xE9 };
      DeviceAddress Probe03 = { 0x28, 0xFF, 0x47, 0x64, 0x66, 0x14, 0x02, 0x71 };
      DeviceAddress Probe04 = { 0x28, 0xFF, 0x3F, 0x48, 0x66, 0x14, 0x01, 0xA2 };
      
      
      #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
      
      #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
      #define TEMPERATURE_PRECISION 12
      #define MAX_ATTACHED_DS18B20 16
      unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds)
      OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
      DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
      float lastTemperature[MAX_ATTACHED_DS18B20];
      int numSensors = 0;
      bool receivedConfig = false;
      bool metric = true;
      // Initialize temperature message
      MyMessage msg(0, V_TEMP);
      
      void before()
      {
        // Startup up the OneWire library
        sensors.begin();
      }
      
      void setup()
      {
        // requestTemperatures() will not block current thread
        sensors.setWaitForConversion(false);
      }
      
      void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Temperature Sensor on Gateway Mega2560", "1.2");
      
        // Fetch the number of attached temperature sensors
        numSensors = sensors.getDeviceCount();
        //Serial.print("Numsensors ");
        //Serial.println(numSensors);
      
        // Present all sensors to controller
        for (int i = 0; i < numSensors && i < MAX_ATTACHED_DS18B20; i++) {
          present(i, S_TEMP);
        }
      
        DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address
      
        for (int i = 0; i < numSensors; i++)
        {
          // Search the wire for address
          if (sensors.getAddress(tempDeviceAddress, i))
          {
            Serial.print("Found device ");
            Serial.print(i, DEC);
            Serial.print(" with address: ");
            printAddress(tempDeviceAddress);
            Serial.println();
      
            Serial.print("Setting resolution to ");
            Serial.println(TEMPERATURE_PRECISION, DEC);
      
            // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
            sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
      
            Serial.print("Resolution actually set to: ");
            Serial.print(sensors.getResolution(tempDeviceAddress), DEC);
            Serial.println();
          } else {
            Serial.print("Found ghost device at ");
            Serial.print(i, DEC);
            Serial.print(" but could not detect address. Check power and cabling");
          }
        }
      
      }
      
      void loop()
      {
        // Fetch temperatures from Dallas sensors
        //Serial.println("Readung Temperatures....");
        sensors.requestTemperatures();
      
        //Serial.println("Fetched");
      
        // query conversion time and sleep until conversion completed
        int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
        // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
        wait(conversionTime);
      
        // Read temperatures and send them to controller
        for (int i = 0; i < numSensors && i < MAX_ATTACHED_DS18B20; i++) {
      
          float temperature;
      
          // Fetch and round temperature to one decimal
          switch (i)  {
            case 0:
              temperature = sensors.getTempC(Probe01);
              break;
            case 1:
              temperature = sensors.getTempC(Probe02);
              break;
            case 2:
              temperature = sensors.getTempC(Probe03);
              break;
            case 3:
              temperature = sensors.getTempC(Probe04);
              break;
            default:
              temperature = sensors.getTempCByIndex(Probe04);
              break;
          }
      
          //Serial.println(temperature);
          // Only send data if temperature has changed and no error
      #if COMPARE_TEMP == 1
          if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
      #else
          if (temperature != -127.00 && temperature != 85.00) {
      #endif
      
            // Send in the new temperature
            send(msg.setSensor(i).set(temperature, 1));
            // Save new temperatures for next compare
            lastTemperature[i] = temperature;
          }
        }
        wait(SLEEP_TIME);
      }
      
      
      // function to print a device address
      void printAddress(DeviceAddress deviceAddress)
      {
        for (uint8_t i = 0; i < 8; i++)
        {
          if (deviceAddress[i] < 16) Serial.print("0");
          Serial.print(deviceAddress[i], HEX);
        }
      }
      

      With this I monitor my heat pump boiler.
      0_1473666670976_wp.JPG

      posted in My Project
      FotoFieber
    • RE: Ethernet Gateway On Arduino Mega 2056 Issues

      The SPI Pins are different on the MEGA2560 than on a 328-Arduino.

      How is your wiring of the NRF24L01+?

      posted in Troubleshooting
      FotoFieber
    • RE: Geiger Counter

      Here is the update for mysensors 2.0

      //
      #define SKETCH_NAME "Geiger Sensor"
      #define SKETCH_MAJOR_VER "2"
      #define SKETCH_MINOR_VER "0"
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      
      #define MY_RF24_CHANNEL  13
      #define MY_RF24_BASE_RADIO_ID ((uint64_t)0xF8A813FC09CL)
      
      
      //
      #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
      #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
      #define CHILD_ID 1   // Id of the sensor child
      
      #define LOG_PERIOD 60000     //Logging period in milliseconds, recommended value 15000-60000.
      
      #define MAX_PERIOD 60000    //Maximum logging period
      
      unsigned long counts;             //variable for GM Tube events
      
      unsigned long cpm;                 //variable for CPM
      
      unsigned int multiplier;             //variable for calculation CPM in this sketch
      
      unsigned long previousMillis;      //variable for time measurement
      
      unsigned long timeReceived = 0;
      unsigned long timeRequested = 0;
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      
      
      #include <SPI.h>
      #include <MySensors.h>
      
      MyMessage msg(CHILD_ID, V_VAR1);
      
      void setup()
      {
        wdt_enable(WDTO_8S);
        
        // Geiger initialise
        counts = 0;
      
        cpm = 0;
      
        multiplier = MAX_PERIOD / LOG_PERIOD;      //calculating multiplier, depend on your log period
      
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the geiger sensor digital pin as input
      
        digitalWrite(DIGITAL_INPUT_SENSOR, HIGH);                                 // turn on internal pullup resistors, solder C-INT on the PCB
      
        attachInterrupt(1, tube_impulse, FALLING);  //define external interrupts
      
        wdt_reset();
      }
      
      void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER "." SKETCH_MINOR_VER);
      
        wdt_reset();
        wait(500);
        present(CHILD_ID, S_ARDUINO_NODE);
        
        wdt_reset();
        wait(500);
       }
      
      void loop()
      { 
        wdt_reset();
        unsigned long currentMillis = millis();
      
        if (currentMillis - previousMillis >= LOG_PERIOD) {
      
          cpm = counts * multiplier;
      
          send(msg.set(cpm));
      
          counts = 0;
          previousMillis = currentMillis;
      
        }
      }
      
      
      void tube_impulse() {              //procedure for capturing events from Geiger Kit
      
        counts++;
      
      }
      
      
      
      

      @Hek
      What do you think about a sensor type geiger counter with cpm and microsievert? V_VAR1 for cpm ist not cool 🆒

      posted in My Project
      FotoFieber
    • RE: Node-Red as Controller

      Stability is not sufficient. The connection gets lost from time to time.

      Added a watchdog to add another connection, if no messages arrives.

      Seems, that this is only interesting for me. If I get no feedback I will stop spaming this thread. 😃

      [{"id":"ba386057.845d3","type":"mqtt-broker","broker":"192.168.92.4","port":"1883","clientid":"NodeRed"},{"id":"e6ce260d.1931d8","type":"switch","z":"9592163f.6a6de8","name":"switch message type","property":"messageType","rules":[{"t":"eq","v":"0"},{"t":"eq","v":"1"},{"t":"eq","v":"2"},{"t":"eq","v":"3"},{"t":"eq","v":"4"}],"checkall":"true","outputs":5,"x":1259.166648864746,"y":182.50001335144043,"wires":[["8c663d73.7399c"],["4a1e5f84.b5e1a"],["7753f9a2.88ac08"],["1e4aa61b.e1b55a"],["60a0dde4.9f5f24"]]},{"id":"8c663d73.7399c","type":"function","z":"9592163f.6a6de8","name":"presentation","func":"msg.subTypeString = context.global.MYS.SString(msg.subType);\n\nmsg.topic = context.global.MYS.TOPIC_PREFIX + '/' + msg.controller + \"/\" + msg.nodeId + \"/\" + msg.childSensorId + \"/\" + msg.subTypeString;\n\nreturn msg;","outputs":1,"noerr":0,"x":1488.916648864746,"y":45.24998474121094,"wires":[["df9e131d.2061f","4d15a037.b2ea6"]]},{"id":"7753f9a2.88ac08","type":"function","z":"9592163f.6a6de8","name":"req","func":"msg.topic = \"req\";\nreturn msg;","outputs":1,"noerr":0,"x":1484.5000228881836,"y":182.75000190734863,"wires":[["4d15a037.b2ea6"]]},{"id":"1e4aa61b.e1b55a","type":"function","z":"9592163f.6a6de8","name":"internal","func":"msg.subTypeString = context.global.MYS.IString(msg.subType);\n\nmsg.topic = context.global.MYS.TOPIC_PREFIX + '/' + msg.controller + \"/\" + msg.nodeId + \"/\" + msg.childSensorId + \"/\" + msg.subTypeString;\n\nreturn msg;","outputs":1,"noerr":0,"x":1488.5000228881836,"y":233.00000190734863,"wires":[["df9e131d.2061f","4d15a037.b2ea6","b5e4f17d.4a1b1"]]},{"id":"60a0dde4.9f5f24","type":"function","z":"9592163f.6a6de8","name":"stream","func":"msg.topic = \"stream\";\nreturn msg;","outputs":1,"x":1496.5000228881836,"y":328.00000190734863,"wires":[[]]},{"id":"4d15a037.b2ea6","type":"debug","z":"9592163f.6a6de8","name":"debug","active":false,"console":"false","complete":"true","x":1845.7500267028809,"y":242.00000286102295,"wires":[]},{"id":"4a1e5f84.b5e1a","type":"function","z":"9592163f.6a6de8","name":"set","func":"msg.subTypeString = context.global.MYS.VString(msg.subType);\n\nmsg.topic = context.global.MYS.TOPIC_PREFIX + '/' + msg.controller + \"/\" + msg.nodeId + \"/\" + msg.childSensorId + \"/\" + msg.subTypeString;\n\n\nreturn msg;","outputs":1,"noerr":0,"x":1492.166648864746,"y":107.5,"wires":[["4d15a037.b2ea6","df9e131d.2061f"]]},{"id":"fc54bb91.03ab48","type":"debug","z":"9592163f.6a6de8","name":"","active":false,"console":"false","complete":"true","x":1218.9166259765625,"y":41.66668510437012,"wires":[]},{"id":"6aa2d9f6.955d28","type":"function","z":"9592163f.6a6de8","name":"Split GW Message","func":"\n    var tokens = msg.payload.split(\";\")\n    \n    msg.rawData = tokens;\n    if(tokens.length >= 6)\n    {\n        msg.nodeId = parseInt(tokens[0]);\n        msg.childSensorId = parseInt(tokens[1]);\n        msg.messageType = parseInt(tokens[2]);\n        msg.ack = parseInt(tokens[3]);\n        msg.subType = parseInt(tokens[4]);\n        msg.payload = tokens[5];\n        for (j=6; j<tokens.length; j++) \n            msg.payload = msg.payload + ';' + tokens[j];\n    }\n\nreturn msg;","outputs":1,"noerr":0,"x":1023.6666488647461,"y":180.66664123535156,"wires":[["e6ce260d.1931d8","fc54bb91.03ab48","e0e76d62.1f189"]]},{"id":"df9e131d.2061f","type":"mqtt out","z":"9592163f.6a6de8","name":"Publish to MQTT","topic":"","qos":"","retain":"","broker":"ba386057.845d3","x":1858.9166526794434,"y":181.16665649414062,"wires":[]},{"id":"b5e4f17d.4a1b1","type":"function","z":"9592163f.6a6de8","name":"hanlde internal messages","func":"//msg.subTypeString = \"\";\n//msg.topic = \"internal respones\";\n\nif (msg.subTypeString == 'I_TIME')\n{\n    var payload = parseInt(new Date().getTime()/1000);\n\tvar command = context.global.MYS.T_INTERNAL; \n\tvar acknowledge = 0; // no ack\n\tvar type = context.global.MYS.I_TIME; // I_TIME\n\tmsg.payload = context.global.MYS.encode(msg.nodeId, msg.childSensorId, command, acknowledge, type, payload);\n    return msg;\n    \n}\nelse if  (msg.subTypeString == 'I_ID_REQUEST')\n{\n    msg.topic = \"I_ID_RESPONSE\";\n    msg.subTypeString = \"I_ID_RESPONSE\";\n    // 255;255;3;0;4;8 for ID 8\n    var command = context.global.MYS.T_INTERNAL;\n\tvar acknowledge = 0; // no ack\n\tvar type = context.global.MYS.I_ID_RESPONSE; // I_ID_RESPONSE\n\n\tif (context.global.mysnextid[msg.controller] === undefined) {\n\t    payload = context.global.MYS.MIN_NODEID;\n\t}    \n\telse\n\t{\n\t    payload = context.global.mysnextid[msg.controller];\n\t}\n\t\n    msg.payload = context.global.MYS.encode(msg.nodeId, msg.childSensorId, command, acknowledge, type, payload);\n    return msg; \n} \nelse if  (msg.subTypeString == 'I_CONFIG')\n{\n    var payload = 'M';\n\tvar command = context.global.MYS.T_INTERNAL; \n\tvar acknowledge = 0; // no ack\n\tvar type = context.global.MYS.I_CONFIG; // I_TIME\n\tmsg.payload = context.global.MYS.encode(msg.nodeId, msg.childSensorId, command, acknowledge, type, payload);\n    return msg;\n}\nelse if  (msg.subTypeString == 'I_INCLUSION_MODE')\n{\n    // not yet implemented\n}\n\nreturn;\n\n\n","outputs":1,"noerr":0,"x":1694.916648864746,"y":543.4166889190674,"wires":[["4d15a037.b2ea6","266b87b3.d99478"]]},{"id":"e6d67f33.19298","type":"inject","z":"9592163f.6a6de8","name":"Startup","topic":"","payload":"","payloadType":"none","repeat":"","crontab":"","once":true,"x":145.25,"y":81.41665363311768,"wires":[["64617800.9b9e88","56b9f6ab.a94608","3e866f6d.c1799"]]},{"id":"ebcef3df.14311","type":"function","z":"9592163f.6a6de8","name":"ToString","func":"msg.payload = msg.payload.toString().replace(/[\\n\\r]/g, '');\n\nreturn msg;","outputs":1,"noerr":0,"x":829.1666946411133,"y":181.91668796539307,"wires":[["6aa2d9f6.955d28"]]},{"id":"31047fa6.cefb8","type":"catch","z":"9592163f.6a6de8","name":"","x":58,"y":449,"wires":[["3622f9b9.c9dd06"]]},{"id":"3622f9b9.c9dd06","type":"debug","z":"9592163f.6a6de8","name":"","active":false,"console":"false","complete":"true","x":224,"y":450,"wires":[]},{"id":"64617800.9b9e88","type":"function","z":"9592163f.6a6de8","name":"MYS Initialize","func":"function MySHelper() { \n\nMySHelper.prototype.TOPIC_PREFIX = \"MYS-NODERED\";\n\nMySHelper.prototype.MIN_NODEID = 10;\n\n\n// don't touch below :)\n    \nMySHelper.prototype.T_PRESENTATION                = 0;\nMySHelper.prototype.T_SET                         = 1;\nMySHelper.prototype.T_REQ                         = 2;\nMySHelper.prototype.T_INTERNAL                    = 3;\nMySHelper.prototype.T_STREAM                      = 4;\n\nMySHelper.prototype.I_BATTERY_LEVEL               = 0;\nMySHelper.prototype.I_TIME                        = 1;\nMySHelper.prototype.I_VERSION                     = 2;\nMySHelper.prototype.I_ID_REQUEST                  = 3;\nMySHelper.prototype.I_ID_RESPONSE                 = 4;\nMySHelper.prototype.I_INCLUSION_MODE              = 5;\nMySHelper.prototype.I_CONFIG                      = 6;\nMySHelper.prototype.I_PING                        = 7;\nMySHelper.prototype.I_PING_ACK                    = 8;\nMySHelper.prototype.I_LOG_MESSAGE                 = 9;\nMySHelper.prototype.I_CHILDREN                    = 10;\nMySHelper.prototype.I_SKETCH_NAME                 = 11;\nMySHelper.prototype.I_SKETCH_VERSION              = 12;\nMySHelper.prototype.I_REBOOT                      = 13;\nMySHelper.prototype.I_GATEWAY_READY               = 14;\nMySHelper.prototype.I_REQUEST_SIGNING             = 15;\nMySHelper.prototype.I_GET_NONCE                   = 16;\nMySHelper.prototype.I_GET_NONCE_RESPONSE          = 17;\nMySHelper.prototype.I_HEARTBEAT                   = 18;\nMySHelper.prototype.I_PRESENTATION                = 19;\n \nvar itype = {\nI_BATTERY_LEVEL:                    MySHelper.prototype.I_BATTERY_LEVEL,\nI_TIME:                             MySHelper.prototype.I_TIME,\nI_VERSION:                          MySHelper.prototype.I_VERSION,\nI_ID_REQUEST:                       MySHelper.prototype.I_ID_REQUEST,\nI_ID_RESPONSE:                      MySHelper.prototype.I_ID_RESPONSE,\nI_INCLUSION_MODE:                   MySHelper.prototype.I_INCLUSION_MODE,\nI_CONFIG:                           MySHelper.prototype.I_CONFIG,\nI_PING:                             MySHelper.prototype.I_PING,\nI_PING_ACK:                         MySHelper.prototype.I_PING_ACK,\nI_LOG_MESSAGE:                      MySHelper.prototype.I_LOG_MESSAGE,\nI_CHILDREN:                         MySHelper.prototype.I_CHILDREN,\nI_SKETCH_NAME:                      MySHelper.prototype.I_SKETCH_NAME,\nI_SKETCH_VERSION:                   MySHelper.prototype.I_SKETCH_VERSION,\nI_REBOOT:                           MySHelper.prototype.I_REBOOT,\nI_GATEWAY_READY:                    MySHelper.prototype.I_GATEWAY_READY,\nI_REQUEST_SIGNING:                  MySHelper.prototype.I_REQUEST_SIGNING,\nI_GET_NONCE:                        MySHelper.prototype.I_GET_NONCE,\nI_GET_NONCE_RESPONSE:               MySHelper.prototype.I_GET_NONCE_RESPONSE,\nI_HEARTBEAT:                        MySHelper.prototype.I_HEARTBEAT,\nI_PRESENTATION:                     MySHelper.prototype.I_PRESENTATION\n};\n\nMySHelper.prototype.IString = function(I_SUBTYPE) {\n    for (var prop in itype ) \n    if( itype[ prop ] === parseInt(I_SUBTYPE) )\n        return prop;\n};\n\nMySHelper.prototype.V_TEMP                = 0;\nMySHelper.prototype.V_HUM                 = 1;\nMySHelper.prototype.V_LIGHT               = 2;\nMySHelper.prototype.V_STATUS              = 2;\nMySHelper.prototype.V_DIMMER              = 3;\nMySHelper.prototype.V_PRESSURE            = 4;\nMySHelper.prototype.V_FORECAST            = 5;\nMySHelper.prototype.V_RAIN                = 6;\nMySHelper.prototype.V_RAINRATE            = 7;\nMySHelper.prototype.V_WIND                = 8;\nMySHelper.prototype.V_GUST                = 9;\nMySHelper.prototype.V_DIRECTION           = 10;\nMySHelper.prototype.V_UV                  = 11;\nMySHelper.prototype.V_WEIGHT              = 12;\nMySHelper.prototype.V_DISTANCE            = 13;\nMySHelper.prototype.V_IMPEDANCE           = 14;\nMySHelper.prototype.V_ARMED               = 15;\nMySHelper.prototype.V_TRIPPED             = 16;\nMySHelper.prototype.V_WATT                = 17;\nMySHelper.prototype.V_KWH                 = 18;\nMySHelper.prototype.V_SCENE_ON            = 19;\nMySHelper.prototype.V_SCENE_OFF           = 20;\nMySHelper.prototype.V_HEATER              = 21;\nMySHelper.prototype.V_HEATER_SW           = 22;\nMySHelper.prototype.V_LIGHT_LEVEL         = 23;\nMySHelper.prototype.V_VAR1                = 24;\nMySHelper.prototype.V_VAR2                = 25;\nMySHelper.prototype.V_VAR3                = 26;\nMySHelper.prototype.V_VAR4                = 27;\nMySHelper.prototype.V_VAR5                = 28;\nMySHelper.prototype.V_UP                  = 29;\nMySHelper.prototype.V_DOWN                = 30;\nMySHelper.prototype.V_STOP                = 31;\nMySHelper.prototype.V_IR_SEND             = 32;\nMySHelper.prototype.V_IR_RECEIVE          = 33;\nMySHelper.prototype.V_FLOW                = 34;\nMySHelper.prototype.V_VOLUME              = 35;\nMySHelper.prototype.V_LOCK_STATUS         = 36;\nMySHelper.prototype.V_LEVEL               = 37; \nMySHelper.prototype.V_VOLTAGE             = 38; \nMySHelper.prototype.V_CURRENT             = 39; \nMySHelper.prototype.V_RGB                 = 40; \nMySHelper.prototype.V_RGBW                = 41;\nMySHelper.prototype.V_ID                  = 42;\nMySHelper.prototype.V_UNIT_PREFIX         = 43;\nMySHelper.prototype.V_HVAC_SETPOINT_COOL  = 44;\nMySHelper.prototype.V_HVAC_SETPOINT_HEAT  = 45;\nMySHelper.prototype.V_HVAC_FLOW_MODE      = 46;\nMySHelper.prototype.V_TEXT                = 47;\n\nvar vtype = {\nV_TEMP:              MySHelper.prototype.V_TEMP,\nV_HUM:               MySHelper.prototype.V_HUM,\nV_STATUS:            MySHelper.prototype.V_STATUS,\nV_LIGHT:             MySHelper.prototype.V_LIGHT,\nV_DIMMER:            MySHelper.prototype.V_DIMMER,\nV_PRESSURE:          MySHelper.prototype.V_PRESSURE,\nV_FORECAST:          MySHelper.prototype.V_FORECAST,\nV_RAIN:              MySHelper.prototype.V_RAIN,\nV_RAINRATE:          MySHelper.prototype.V_RAINRATE,\nV_WIND:              MySHelper.prototype.V_WIND,\nV_GUST:              MySHelper.prototype.V_GUST,\nV_DIRECTION:         MySHelper.prototype.V_DIRECTION,\nV_UV:                MySHelper.prototype.V_UV,\nV_WEIGHT:            MySHelper.prototype.V_WEIGHT,\nV_DISTANCE:          MySHelper.prototype.V_DISTANCE,\nV_IMPEDANCE:         MySHelper.prototype.V_IMPEDANCE,\nV_ARMED:             MySHelper.prototype.V_ARMED,\nV_TRIPPED:           MySHelper.prototype.V_TRIPPED,\nV_WATT:              MySHelper.prototype.V_WATT,\nV_KWH:               MySHelper.prototype.V_KWH,\nV_SCENE_ON:          MySHelper.prototype.V_SCENE_ON,\nV_SCENE_OFF:         MySHelper.prototype.V_SCENE_OFF,\nV_HEATER:            MySHelper.prototype.V_HEATER,\nV_HEATER_SW:         MySHelper.prototype.V_HEATER_SW,\nV_LIGHT_LEVEL:       MySHelper.prototype.V_LIGHT_LEVEL,\nV_VAR1:              MySHelper.prototype.V_VAR1,\nV_VAR2:              MySHelper.prototype.V_VAR2,\nV_VAR3:              MySHelper.prototype.V_VAR3,\nV_VAR4:              MySHelper.prototype.V_VAR4,\nV_VAR5:              MySHelper.prototype.V_VAR5,\nV_UP:                MySHelper.prototype.V_UP,\nV_DOWN:              MySHelper.prototype.V_DOWN,\nV_STOP:              MySHelper.prototype.V_STOP,\nV_IR_SEND:           MySHelper.prototype.V_IR_SEND,\nV_IR_RECEIVE:        MySHelper.prototype.V_IR_RECEIVE,\nV_FLOW:              MySHelper.prototype.V_FLOW,\nV_VOLUME:            MySHelper.prototype.V_VOLUME,\nV_LOCK_STATUS:       MySHelper.prototype.V_LOCK_STATUS,\nV_LEVEL:             MySHelper.prototype.V_LEVEL,\nV_VOLTAGE:           MySHelper.prototype.V_VOLTAGE, \nV_CURRENT:           MySHelper.prototype.V_CURRENT,\nV_RGB:               MySHelper.prototype.V_RGB,\nV_RGBW:              MySHelper.prototype.V_RGBW,\nV_ID:                MySHelper.prototype.V_ID,\nV_UNIT_PREFIX:       MySHelper.prototype.V_UNIT_PREFIX,\nV_HVAC_SETPOINT_COOL:MySHelper.prototype.V_HVAC_SETPOINT_COOL,\nV_HVAC_SETPOINT_HEAT:MySHelper.prototype.V_HVAC_SETPOINT_HEAT,\nV_HVAC_FLOW_MODE:    MySHelper.prototype.V_HVAC_FLOW_MODE,\nV_TEXT:              MySHelper.prototype.V_TEXT\n};\n\n\n\nMySHelper.prototype.VString = function(V_SUBTYPE) {\n    for (var prop in vtype ) \n    if( vtype[ prop ] === parseInt(V_SUBTYPE) )\n        return prop;\n};\n    \nMySHelper.prototype.VNum = function(V_SUBTYPE) {\n    sRet = vtype [V_SUBTYPE];\n    if (sRet === undefined)\n        sRet = V_SUBTYPE;\n    return sRet;\n}\n\nMySHelper.prototype.S_DOOR = 0; // Door sensor; V_TRIPPED; V_ARMED\nMySHelper.prototype.S_MOTION = 1;  // Motion sensor; V_TRIPPED; V_ARMED \nMySHelper.prototype.S_SMOKE = 2;  // Smoke sensor; V_TRIPPED; V_ARMED\nMySHelper.prototype.S_LIGHT = 3; // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT\nMySHelper.prototype.S_BINARY = 3; // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT (same as MySHelper.prototype.S_LIGHT)\nMySHelper.prototype.S_DIMMER = 4; // Dimmable light or fan device; V_STATUS (on/off); V_DIMMER (dimmer level 0-100); V_WATT\nMySHelper.prototype.S_COVER = 5; // Blinds or window cover; V_UP; V_DOWN; V_STOP; V_DIMMER (open/close to a percentage)\nMySHelper.prototype.S_TEMP = 6; // Temperature sensor; V_TEMP\nMySHelper.prototype.S_HUM = 7; // Humidity sensor; V_HUM\nMySHelper.prototype.S_BARO = 8; // Barometer sensor; V_PRESSURE; V_FORECAST\nMySHelper.prototype.S_WIND = 9; // Wind sensor; V_WIND; V_GUST\nMySHelper.prototype.S_RAIN = 10; // Rain sensor; V_RAIN; V_RAINRATE\nMySHelper.prototype.S_UV = 11; // Uv sensor; V_UV\nMySHelper.prototype.S_WEIGHT = 12; // Personal scale sensor; V_WEIGHT; V_IMPEDANCE\nMySHelper.prototype.S_POWER = 13; // Power meter; V_WATT; V_KWH\nMySHelper.prototype.S_HEATER = 14; // Header device; V_HVAC_SETPOINT_HEAT; V_HVAC_FLOW_STATE; V_TEMP\nMySHelper.prototype.S_DISTANCE = 15; // Distance sensor; V_DISTANCE\nMySHelper.prototype.S_LIGHT_LEVEL = 16; // Light level sensor; V_LIGHT_LEVEL (uncalibrated in percentage);  V_LEVEL (light level in lux)\nMySHelper.prototype.S_ARDUINO_NODE = 17 ; // Used (internally) for presenting a non-repeating Arduino node\nMySHelper.prototype.S_ARDUINO_REPEATER_NODE = 18; // Used (internally) for presenting a repeating Arduino node \nMySHelper.prototype.S_LOCK = 19; // Lock device; V_LOCK_STATUS\nMySHelper.prototype.S_IR = 20; // Ir device; V_IR_SEND; V_IR_RECEIVE\nMySHelper.prototype.S_WATER = 21; // Water meter; V_FLOW; V_VOLUME\nMySHelper.prototype.S_AIR_QUALITY = 22; // Air quality sensor; V_LEVEL\nMySHelper.prototype.S_CUSTOM = 23; // Custom sensor \nMySHelper.prototype.S_DUST = 24; // Dust sensor; V_LEVEL\nMySHelper.prototype.S_SCENE_CONTROLLER = 25; // Scene controller device; V_SCENE_ON; V_SCENE_OFF. \nMySHelper.prototype.S_RGB_LIGHT = 26; // RGB light. Send color component data using V_RGB. Also supports V_WATT \nMySHelper.prototype.S_RGBW_LIGHT = 27; // RGB light with an additional White component. Send data using V_RGBW. Also supports V_WATT\nMySHelper.prototype.S_COLOR_SENSOR = 28;  // Color sensor; send color information using V_RGB\nMySHelper.prototype.S_HVAC = 28; // Thermostat/HVAC device. V_HVAC_SETPOINT_HEAT; V_HVAC_SETPOINT_COLD; V_HVAC_FLOW_STATE; V_HVAC_FLOW_MODE; V_TEMP\nMySHelper.prototype.S_MULTIMETER = 29; // Multimeter device; V_VOLTAGE; V_CURRENT; V_IMPEDANCE \nMySHelper.prototype.S_SPRINKLER  = 30;  // Sprinkler; V_STATUS (turn on/off); V_TRIPPED (if fire detecting device)\nMySHelper.prototype.S_WATER_LEAK = 31; // Water leak sensor; V_TRIPPED; V_ARMED\nMySHelper.prototype.S_SOUND = 32; // Sound sensor; V_TRIPPED; V_ARMED; V_LEVEL (sound level in dB)\nMySHelper.prototype.S_VIBRATION = 33; // Vibration sensor; V_TRIPPED; V_ARMED; V_LEVEL (vibration in Hz)\nMySHelper.prototype.S_MOISTURE = 34; // Moisture sensor; V_TRIPPED; V_ARMED; V_LEVEL (water content or moisture in percentage?) \nMySHelper.prototype.S_INFO = 35; // LCD text device / Simple information device on controller; V_TEXT\nMySHelper.prototype.S_GAS = 36; // Gas meter; V_FLOW; V_VOLUME\nMySHelper.prototype.S_GPS = 37; // GPS Sensor; V_POSITION\n \nvar stype = {\nS_DOOR:                 MySHelper.prototype.S_DOOR, // Door sensor; V_TRIPPED; V_ARMED\nS_MOTION:               MySHelper.prototype.S_MOTION,  // Motion sensor; V_TRIPPED; V_ARMED \nS_SMOKE:                MySHelper.prototype.S_SMOKE,  // Smoke sensor; V_TRIPPED; V_ARMED\nS_LIGHT:                MySHelper.prototype.S_LIGHT, // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT\nS_BINARY:               MySHelper.prototype.S_BINARY, // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT (same as MySHelper.prototype.S_LIGHT)\nS_DIMMER:               MySHelper.prototype.S_DIMMER, // Dimmable light or fan device; V_STATUS (on/off); V_DIMMER (dimmer level 0-100); V_WATT\nS_COVER:                MySHelper.prototype.S_COVER, // Blinds or window cover; V_UP; V_DOWN; V_STOP; V_DIMMER (open/close to a percentage)\nS_TEMP:                 MySHelper.prototype.S_TEMP, // Temperature sensor; V_TEMP\nS_HUM:                  MySHelper.prototype.S_HUM, // Humidity sensor; V_HUM\nS_BARO:                 MySHelper.prototype.S_BARO, // Barometer sensor; V_PRESSURE; V_FORECAST\nS_WIND:                 MySHelper.prototype.S_WIND, // Wind sensor; V_WIND; V_GUST\nS_RAIN:                 MySHelper.prototype.S_RAIN, // Rain sensor; V_RAIN; V_RAINRATE\nS_UV:                   MySHelper.prototype.S_UV, // Uv sensor; V_UV\nS_WEIGHT:               MySHelper.prototype.S_WEIGHT, // Personal scale sensor; V_WEIGHT; V_IMPEDANCE\nS_POWER:                MySHelper.prototype.S_POWER, // Power meter; V_WATT; V_KWH\nS_HEATER:               MySHelper.prototype.S_HEATER, // Header device; V_HVAC_SETPOINT_HEAT; V_HVAC_FLOW_STATE; V_TEMP\nS_DISTANCE:             MySHelper.prototype.S_DISTANCE, // Distance sensor; V_DISTANCE\nS_LIGHT_LEVEL:          MySHelper.prototype.S_LIGHT_LEVEL, // Light level sensor; V_LIGHT_LEVEL (uncalibrated in percentage);  V_LEVEL (light level in lux)\nS_ARDUINO_NODE:         MySHelper.prototype.S_ARDUINO_NODE, // Used (internally) for presenting a non-repeating Arduino node\nS_ARDUINO_REPEATER_NODE:MySHelper.prototype.S_ARDUINO_REPEATER_NODE, // Used (internally) for presenting a repeating Arduino node \nS_LOCK:                 MySHelper.prototype.S_LOCK, // Lock device; V_LOCK_STATUS\nS_IR:                   MySHelper.prototype.S_IR, // Ir device; V_IR_SEND; V_IR_RECEIVE\nS_WATER:                MySHelper.prototype.S_WATER, // Water meter; V_FLOW; V_VOLUME\nS_AIR_QUALITY:          MySHelper.prototype.S_AIR_QUALITY, // Air quality sensor; V_LEVEL\nS_CUSTOM:               MySHelper.prototype.S_CUSTOM, // Custom sensor \nS_DUST:                 MySHelper.prototype.S_DUST, // Dust sensor; V_LEVEL\nS_SCENE_CONTROLLER:     MySHelper.prototype.S_SCENE_CONTROLLER, // Scene controller device; V_SCENE_ON; V_SCENE_OFF. \nS_RGB_LIGHT:            MySHelper.prototype.S_RGB_LIGHT, // RGB light. Send color component data using V_RGB. Also supports V_WATT \nS_RGBW_LIGHT:           MySHelper.prototype.S_RGBW_LIGHT, // RGB light with an additional White component. Send data using V_RGBW. Also supports V_WATT\nS_COLOR_SENSOR:         MySHelper.prototype.S_COLOR_SENSOR,  // Color sensor; send color information using V_RGB\nS_HVAC:                 MySHelper.prototype.S_HVAC, // Thermostat/HVAC device. V_HVAC_SETPOINT_HEAT; V_HVAC_SETPOINT_COLD; V_HVAC_FLOW_STATE; V_HVAC_FLOW_MODE; V_TEMP\nS_MULTIMETER:           MySHelper.prototype.S_MULTIMETER, // Multimeter device; V_VOLTAGE; V_CURRENT; V_IMPEDANCE \nS_SPRINKLER:            MySHelper.prototype.S_SPRINKLER,  // Sprinkler; V_STATUS (turn on/off); V_TRIPPED (if fire detecting device)\nS_WATER_LEAK:           MySHelper.prototype.S_WATER_LEAK, // Water leak sensor; V_TRIPPED; V_ARMED\nS_SOUND:                MySHelper.prototype.S_SOUND, // Sound sensor; V_TRIPPED; V_ARMED; V_LEVEL (sound level in dB)\nS_VIBRATION:            MySHelper.prototype.S_VIBRATION, // Vibration sensor; V_TRIPPED; V_ARMED; V_LEVEL (vibration in Hz)\nS_MOISTURE:             MySHelper.prototype.S_MOISTURE, // Moisture sensor; V_TRIPPED; V_ARMED; V_LEVEL (water content or moisture in percentage?) \nS_INFO:                 MySHelper.prototype.S_INFO, // LCD text device / Simple information device on controller; V_TEXT\nS_GAS:                  MySHelper.prototype.S_GAS, // Gas meter; V_FLOW; V_VOLUME\nS_GPS:                  MySHelper.prototype.S_GPS // GPS Sensor; V_POSITION\n};\n\nMySHelper.prototype.SString = function(S_SUBTYPE) {\n    for (var prop in stype ) \n    if( stype[ prop ] === parseInt(S_SUBTYPE) )\n        return prop;\n};    \n    \n MySHelper.prototype.encode = function(destination, sensor, command, acknowledge, type, payload) {\n\tvar msg = destination.toString(10) + \";\" + sensor.toString(10) + \";\" + command.toString(10) + \";\" + acknowledge.toString(10) + \";\" + type.toString(10) + \";\";\n\tif (command == 4) {\n\t\tfor (var i = 0; i < payload.length; i++) {\n\t\t\tif (payload[i] < 16)\n\t\t\t\tmsg += \"0\";\n\t\t\tmsg += payload[i].toString(16);\n\t\t}\n\t} else {\n\t\tmsg += payload;\n\t}\n\tmsg += '\\n';\n\treturn msg.toString();\n}\n}\n\n\nvar MySHelperObj = new MySHelper();\n\ncontext.global.MYS = MySHelperObj;\n\nreturn msg;","outputs":1,"noerr":0,"x":383.25,"y":20,"wires":[[]]},{"id":"df1e322.f20e1d","type":"function","z":"9592163f.6a6de8","name":"Set Controller 1","func":"msg.controller = 1\n\nreturn msg;","outputs":1,"noerr":0,"x":641.0000076293945,"y":147.49999809265137,"wires":[["ebcef3df.14311"]]},{"id":"266b87b3.d99478","type":"switch","z":"9592163f.6a6de8","name":"route to controller n","property":"controller","rules":[{"t":"eq","v":"1"},{"t":"eq","v":"2"},{"t":"eq","v":"3"},{"t":"eq","v":"4"}],"checkall":"false","outputs":4,"x":133,"y":214.25,"wires":[["3e866f6d.c1799"],["c7d0d88b.382f28"],[],[]]},{"id":"c7d0d88b.382f28","type":"tcp request","z":"9592163f.6a6de8","server":"192.168.92.14","port":"5003","out":"sit","splitc":"0","name":"MySWifi ESP8266 GW AES 14","x":410.5,"y":207.24999618530273,"wires":[["c5f14d8f.3a0eb"]]},{"id":"c5f14d8f.3a0eb","type":"function","z":"9592163f.6a6de8","name":"Set Controller 2","func":"msg.controller = 2\n\nreturn msg;","outputs":1,"noerr":0,"x":653.5,"y":205.7500114440918,"wires":[["ebcef3df.14311"]]},{"id":"56b9f6ab.a94608","type":"file in","z":"9592163f.6a6de8","name":"read store for next ids","filename":"mysids.dump","format":"utf8","x":395,"y":65,"wires":[["57db23d6.a824dc"]]},{"id":"e000bd09.1fff4","type":"debug","z":"9592163f.6a6de8","name":"Debug","active":false,"console":"false","complete":"true","x":732,"y":361,"wires":[]},{"id":"57db23d6.a824dc","type":"function","z":"9592163f.6a6de8","name":"store to context.global.mysnextid","func":"if (msg.payload === undefined) {\n          var mysnextid = {};\n\n        obj = mysnextid;  \n}\nelse \n{\ntry{\n        obj = JSON.parse(msg.payload);\n    }\n    catch(e){\n        \n        var mysnextid = {};\n\n        obj = mysnextid;\n        \n    }\n}    \n\ncontext.global.mysnextid = obj;\n\nmsg.payload = context.global.mysnextid;\n\nreturn msg;","outputs":1,"noerr":0,"x":658,"y":53,"wires":[[]]},{"id":"dfba7d69.20458","type":"file","z":"9592163f.6a6de8","name":"dump mysids","filename":"mysids.dump","appendNewline":true,"createDir":false,"overwriteFile":"true","x":1473,"y":381.99999618530273,"wires":[]},{"id":"e0e76d62.1f189","type":"function","z":"9592163f.6a6de8","name":"handle nextids","func":"// increase nextid, if nodeid >= nextid \n// node.log(\"Handling next ids\");\n// node.log(\"nodeId: \" + msg.nodeId);\n\nbChanged = false;\n\nif (msg.nodeId === 0) return;\n\nif (msg.nodeId < 255)\n{\n    // node.log(\"Test if next node-id must be set\");\n    if (context.global.mysnextid[msg.controller] === undefined) {\n        node.log(\"node-id not initialized yet\");\n        context.global.mysnextid[msg.controller] = msg.nodeId+1;\n        if (context.global.mysnextid[msg.controller] < context.global.MYS.MIN_NODEID)\n            context.global.mysnextid[msg.controller] = context.global.MYS.MIN_NODEID;\n        bChanged = true;\n    }\n    \n    // node.log(\"Nexid stored \" + parseInt(context.global.mysnextid[msg.controller]));\n    \n    if (msg.nodeId >= parseInt(context.global.mysnextid[msg.controller])) {\n        node.log(\"node-id >= next -> increase\");\n        // convert to int\n        context.global.mysnextid[msg.controller] = parseInt(context.global.mysnextid[msg.controller]);\n        context.global.mysnextid[msg.controller] = msg.nodeId+1; \n        if (context.global.mysnextid[msg.controller] < context.global.MYS.MIN_NODEID)\n            context.global.mysnextid[msg.controller] = context.global.MYS.MIN_NODEID;\n        bChanged = true;\n    }\n\n    if (bChanged) {\n        node.log(\"next id must be stored\");\n        msg.payload = JSON.stringify(context.global.mysnextid);   \n        return msg;\n    }\n}\n\n\n","outputs":1,"noerr":0,"x":1262,"y":374.99999618530273,"wires":[["dfba7d69.20458","5c074c19.a3f8b4"]]},{"id":"8da09002.725f7","type":"function","z":"9592163f.6a6de8","name":"MQTT to MYS convert","func":"// topic = MYS-NODERED/set/controller/node-id/sensor-id/ack/sub-type\n// payload = payload :)\n\n    var tokens = msg.topic.split(\"/\");\n    \n    msg.rawData = tokens;\n    msg.tokens = tokens.length;\n    if(tokens.length == 7)\n    {\n        if (tokens[0] != context.global.MYS.TOPIC_PREFIX) // not for us\n            return;\n        if (tokens[1] != 'set') // not for us\n            return;\n            \n        msg.controller = parseInt(tokens[2]);\n        msg.messageType = context.global.MYS.T_SET;\n        msg.nodeId = parseInt(tokens[3]);\n        msg.childSensorId = parseInt(tokens[4]);\n        msg.ack = parseInt(tokens[5]);\n        msg.subType = context.global.MYS.VNum(tokens[6]);\n        \n        msg.payload = context.global.MYS.encode(msg.nodeId, msg.childSensorId, msg.messageType, msg.ack, msg.subType, msg.payload);\n    \n        return msg;        \n    }\n","outputs":1,"noerr":0,"x":490,"y":361,"wires":[["e000bd09.1fff4","266b87b3.d99478"]]},{"id":"3e866f6d.c1799","type":"tcp request","z":"9592163f.6a6de8","server":"192.168.92.13","port":"5003","out":"sit","splitc":"0","name":"MySWifi ESP8266 GW AES 13","x":407,"y":145.99999618530273,"wires":[["df1e322.f20e1d","9386fdb0.6c79"]]},{"id":"5c074c19.a3f8b4","type":"debug","z":"9592163f.6a6de8","name":"","active":true,"console":"false","complete":"false","x":1454,"y":543.9999961853027,"wires":[]},{"id":"c75fd7f4.38a028","type":"mqtt in","z":"9592163f.6a6de8","name":"Read MQTT Stream: change Topic to your needs","topic":"MYS-NODERED/set/#","broker":"ba386057.845d3","x":183.5,"y":362,"wires":[["8da09002.725f7"]]},{"id":"9386fdb0.6c79","type":"function","z":"9592163f.6a6de8","name":"Watchdog controller 1","func":"if (isNaN(context.global.controller1count))\n    context.global.controller1count=0;\n\n\ncontext.global.controller1count++;\n\n","outputs":1,"noerr":0,"x":630,"y":105,"wires":[[]]},{"id":"d465a67.f2b9a58","type":"inject","z":"9592163f.6a6de8","name":"Check health controller 1 every 5 minutes","topic":"","payload":"","payloadType":"none","repeat":"60","crontab":"","once":false,"x":173,"y":516,"wires":[["aa935a.ff556ca8"]]},{"id":"aa935a.ff556ca8","type":"function","z":"9592163f.6a6de8","name":"check health controlller 1","func":"if (isNaN(context.global.controller1count))\n    context.global.controller1count=0;\n    \nif (context.global.controller1count === 0) {\n    // make a new connection to the controller\n    msg.payload = \"\";\n    node.log(\"no message recieved on mys controller 1, try to connect\");\n    \n    return msg;\n}\nelse\n{\n    // reset counter\n    context.global.controller1count=0;\n}\n","outputs":1,"noerr":0,"x":470,"y":510,"wires":[["c8b342e9.374cc","3e866f6d.c1799"]]},{"id":"c8b342e9.374cc","type":"debug","z":"9592163f.6a6de8","name":"","active":true,"console":"false","complete":"false","x":682,"y":511,"wires":[]}]```
      posted in Node-RED
      FotoFieber
    • RE: Node-Red as Controller
      • Fixed node-id handling for new nodes.
      • added write support (see "MQTT to MYS" convert for details)
      • parameters can be set in 'MYS initialize'
      [{"id":"ba386057.845d3","type":"mqtt-broker","broker":"192.168.92.4","port":"1883","clientid":"NodeRed"},{"id":"e6ce260d.1931d8","type":"switch","z":"9592163f.6a6de8","name":"switch message type","property":"messageType","rules":[{"t":"eq","v":"0"},{"t":"eq","v":"1"},{"t":"eq","v":"2"},{"t":"eq","v":"3"},{"t":"eq","v":"4"}],"checkall":"true","outputs":5,"x":1259.166648864746,"y":182.50001335144043,"wires":[["8c663d73.7399c"],["4a1e5f84.b5e1a"],["7753f9a2.88ac08"],["1e4aa61b.e1b55a"],["60a0dde4.9f5f24"]]},{"id":"8c663d73.7399c","type":"function","z":"9592163f.6a6de8","name":"presentation","func":"msg.subTypeString = context.global.MYS.SString(msg.subType);\n\nmsg.topic = context.global.MYS.TOPIC_PREFIX + '/' + msg.controller + \"/\" + msg.nodeId + \"/\" + msg.childSensorId + \"/\" + msg.subTypeString;\n\nreturn msg;","outputs":1,"noerr":0,"x":1488.916648864746,"y":45.24998474121094,"wires":[["df9e131d.2061f","4d15a037.b2ea6"]]},{"id":"7753f9a2.88ac08","type":"function","z":"9592163f.6a6de8","name":"req","func":"msg.topic = \"req\";\nreturn msg;","outputs":1,"noerr":0,"x":1484.5000228881836,"y":182.75000190734863,"wires":[["4d15a037.b2ea6"]]},{"id":"1e4aa61b.e1b55a","type":"function","z":"9592163f.6a6de8","name":"internal","func":"msg.subTypeString = context.global.MYS.IString(msg.subType);\n\nmsg.topic = context.global.MYS.TOPIC_PREFIX + '/' + msg.controller + \"/\" + msg.nodeId + \"/\" + msg.childSensorId + \"/\" + msg.subTypeString;\n\nreturn msg;","outputs":1,"noerr":0,"x":1488.5000228881836,"y":233.00000190734863,"wires":[["df9e131d.2061f","4d15a037.b2ea6","b5e4f17d.4a1b1"]]},{"id":"60a0dde4.9f5f24","type":"function","z":"9592163f.6a6de8","name":"stream","func":"msg.topic = \"stream\";\nreturn msg;","outputs":1,"x":1496.5000228881836,"y":328.00000190734863,"wires":[[]]},{"id":"4d15a037.b2ea6","type":"debug","z":"9592163f.6a6de8","name":"debug","active":false,"console":"false","complete":"true","x":1845.7500267028809,"y":242.00000286102295,"wires":[]},{"id":"4a1e5f84.b5e1a","type":"function","z":"9592163f.6a6de8","name":"set","func":"msg.subTypeString = context.global.MYS.VString(msg.subType);\n\nmsg.topic = context.global.MYS.TOPIC_PREFIX + '/' + msg.controller + \"/\" + msg.nodeId + \"/\" + msg.childSensorId + \"/\" + msg.subTypeString;\n\n\nreturn msg;","outputs":1,"noerr":0,"x":1492.166648864746,"y":107.5,"wires":[["4d15a037.b2ea6","df9e131d.2061f"]]},{"id":"fc54bb91.03ab48","type":"debug","z":"9592163f.6a6de8","name":"","active":false,"console":"false","complete":"true","x":1218.9166259765625,"y":41.66668510437012,"wires":[]},{"id":"6aa2d9f6.955d28","type":"function","z":"9592163f.6a6de8","name":"Split GW Message","func":"\n    var tokens = msg.payload.split(\";\")\n    \n    msg.rawData = tokens;\n    if(tokens.length >= 6)\n    {\n        msg.nodeId = parseInt(tokens[0]);\n        msg.childSensorId = parseInt(tokens[1]);\n        msg.messageType = parseInt(tokens[2]);\n        msg.ack = parseInt(tokens[3]);\n        msg.subType = parseInt(tokens[4]);\n        msg.payload = tokens[5];\n        for (j=6; j<tokens.length; j++) \n            msg.payload = msg.payload + ';' + tokens[j];\n    }\n\nreturn msg;","outputs":1,"noerr":0,"x":1023.6666488647461,"y":180.66664123535156,"wires":[["e6ce260d.1931d8","fc54bb91.03ab48","e0e76d62.1f189"]]},{"id":"df9e131d.2061f","type":"mqtt out","z":"9592163f.6a6de8","name":"Publish to MQTT","topic":"","qos":"","retain":"","broker":"ba386057.845d3","x":1858.9166526794434,"y":181.16665649414062,"wires":[]},{"id":"b5e4f17d.4a1b1","type":"function","z":"9592163f.6a6de8","name":"hanlde internal messages","func":"//msg.subTypeString = \"\";\n//msg.topic = \"internal respones\";\n\nif (msg.subTypeString == 'I_TIME')\n{\n    var payload = parseInt(new Date().getTime()/1000);\n\tvar command = context.global.MYS.T_INTERNAL; \n\tvar acknowledge = 0; // no ack\n\tvar type = context.global.MYS.I_TIME; // I_TIME\n\tmsg.payload = context.global.MYS.encode(msg.nodeId, msg.childSensorId, command, acknowledge, type, payload);\n    return msg;\n    \n}\nelse if  (msg.subTypeString == 'I_ID_REQUEST')\n{\n    msg.topic = \"I_ID_RESPONSE\";\n    msg.subTypeString = \"I_ID_RESPONSE\";\n    // 255;255;3;0;4;8 for ID 8\n    var command = context.global.MYS.T_INTERNAL;\n\tvar acknowledge = 0; // no ack\n\tvar type = context.global.MYS.I_ID_RESPONSE; // I_ID_RESPONSE\n\n\tif (context.global.mysnextid[msg.controller] === undefined) {\n\t    payload = context.global.MYS.MIN_NODEID;\n\t}    \n\telse\n\t{\n\t    payload = context.global.mysnextid[msg.controller];\n\t}\n\t\n    msg.payload = context.global.MYS.encode(msg.nodeId, msg.childSensorId, command, acknowledge, type, payload);\n    return msg; \n} \nelse if  (msg.subTypeString == 'I_CONFIG')\n{\n    var payload = 'M';\n\tvar command = context.global.MYS.T_INTERNAL; \n\tvar acknowledge = 0; // no ack\n\tvar type = context.global.MYS.I_CONFIG; // I_TIME\n\tmsg.payload = context.global.MYS.encode(msg.nodeId, msg.childSensorId, command, acknowledge, type, payload);\n    return msg;\n}\nelse if  (msg.subTypeString == 'I_INCLUSION_MODE')\n{\n    // not yet implemented\n}\n\nreturn;\n\n\n","outputs":1,"noerr":0,"x":1694.916648864746,"y":543.4166889190674,"wires":[["4d15a037.b2ea6","266b87b3.d99478"]]},{"id":"e6d67f33.19298","type":"inject","z":"9592163f.6a6de8","name":"Startup","topic":"","payload":"","payloadType":"none","repeat":"","crontab":"","once":true,"x":145.25,"y":81.41665363311768,"wires":[["64617800.9b9e88","56b9f6ab.a94608","3e866f6d.c1799"]]},{"id":"ebcef3df.14311","type":"function","z":"9592163f.6a6de8","name":"ToString","func":"msg.payload = msg.payload.toString().replace(/[\\n\\r]/g, '');\n\nreturn msg;","outputs":1,"noerr":0,"x":829.1666946411133,"y":181.91668796539307,"wires":[["6aa2d9f6.955d28"]]},{"id":"31047fa6.cefb8","type":"catch","z":"9592163f.6a6de8","name":"","x":58,"y":449,"wires":[["3622f9b9.c9dd06"]]},{"id":"3622f9b9.c9dd06","type":"debug","z":"9592163f.6a6de8","name":"","active":false,"console":"false","complete":"true","x":224,"y":450,"wires":[]},{"id":"64617800.9b9e88","type":"function","z":"9592163f.6a6de8","name":"MYS Initialize","func":"function MySHelper() { \n\nMySHelper.prototype.TOPIC_PREFIX = \"MYS-NODERED\";\n\nMySHelper.prototype.MIN_NODEID = 10;\n\n\n// don't touch below :)\n    \nMySHelper.prototype.T_PRESENTATION                = 0;\nMySHelper.prototype.T_SET                         = 1;\nMySHelper.prototype.T_REQ                         = 2;\nMySHelper.prototype.T_INTERNAL                    = 3;\nMySHelper.prototype.T_STREAM                      = 4;\n\nMySHelper.prototype.I_BATTERY_LEVEL               = 0;\nMySHelper.prototype.I_TIME                        = 1;\nMySHelper.prototype.I_VERSION                     = 2;\nMySHelper.prototype.I_ID_REQUEST                  = 3;\nMySHelper.prototype.I_ID_RESPONSE                 = 4;\nMySHelper.prototype.I_INCLUSION_MODE              = 5;\nMySHelper.prototype.I_CONFIG                      = 6;\nMySHelper.prototype.I_PING                        = 7;\nMySHelper.prototype.I_PING_ACK                    = 8;\nMySHelper.prototype.I_LOG_MESSAGE                 = 9;\nMySHelper.prototype.I_CHILDREN                    = 10;\nMySHelper.prototype.I_SKETCH_NAME                 = 11;\nMySHelper.prototype.I_SKETCH_VERSION              = 12;\nMySHelper.prototype.I_REBOOT                      = 13;\nMySHelper.prototype.I_GATEWAY_READY               = 14;\nMySHelper.prototype.I_REQUEST_SIGNING             = 15;\nMySHelper.prototype.I_GET_NONCE                   = 16;\nMySHelper.prototype.I_GET_NONCE_RESPONSE          = 17;\nMySHelper.prototype.I_HEARTBEAT                   = 18;\nMySHelper.prototype.I_PRESENTATION                = 19;\n \nvar itype = {\nI_BATTERY_LEVEL:                    MySHelper.prototype.I_BATTERY_LEVEL,\nI_TIME:                             MySHelper.prototype.I_TIME,\nI_VERSION:                          MySHelper.prototype.I_VERSION,\nI_ID_REQUEST:                       MySHelper.prototype.I_ID_REQUEST,\nI_ID_RESPONSE:                      MySHelper.prototype.I_ID_RESPONSE,\nI_INCLUSION_MODE:                   MySHelper.prototype.I_INCLUSION_MODE,\nI_CONFIG:                           MySHelper.prototype.I_CONFIG,\nI_PING:                             MySHelper.prototype.I_PING,\nI_PING_ACK:                         MySHelper.prototype.I_PING_ACK,\nI_LOG_MESSAGE:                      MySHelper.prototype.I_LOG_MESSAGE,\nI_CHILDREN:                         MySHelper.prototype.I_CHILDREN,\nI_SKETCH_NAME:                      MySHelper.prototype.I_SKETCH_NAME,\nI_SKETCH_VERSION:                   MySHelper.prototype.I_SKETCH_VERSION,\nI_REBOOT:                           MySHelper.prototype.I_REBOOT,\nI_GATEWAY_READY:                    MySHelper.prototype.I_GATEWAY_READY,\nI_REQUEST_SIGNING:                  MySHelper.prototype.I_REQUEST_SIGNING,\nI_GET_NONCE:                        MySHelper.prototype.I_GET_NONCE,\nI_GET_NONCE_RESPONSE:               MySHelper.prototype.I_GET_NONCE_RESPONSE,\nI_HEARTBEAT:                        MySHelper.prototype.I_HEARTBEAT,\nI_PRESENTATION:                     MySHelper.prototype.I_PRESENTATION\n};\n\nMySHelper.prototype.IString = function(I_SUBTYPE) {\n    for (var prop in itype ) \n    if( itype[ prop ] === parseInt(I_SUBTYPE) )\n        return prop;\n};\n\nMySHelper.prototype.V_TEMP                = 0;\nMySHelper.prototype.V_HUM                 = 1;\nMySHelper.prototype.V_LIGHT               = 2;\nMySHelper.prototype.V_STATUS              = 2;\nMySHelper.prototype.V_DIMMER              = 3;\nMySHelper.prototype.V_PRESSURE            = 4;\nMySHelper.prototype.V_FORECAST            = 5;\nMySHelper.prototype.V_RAIN                = 6;\nMySHelper.prototype.V_RAINRATE            = 7;\nMySHelper.prototype.V_WIND                = 8;\nMySHelper.prototype.V_GUST                = 9;\nMySHelper.prototype.V_DIRECTION           = 10;\nMySHelper.prototype.V_UV                  = 11;\nMySHelper.prototype.V_WEIGHT              = 12;\nMySHelper.prototype.V_DISTANCE            = 13;\nMySHelper.prototype.V_IMPEDANCE           = 14;\nMySHelper.prototype.V_ARMED               = 15;\nMySHelper.prototype.V_TRIPPED             = 16;\nMySHelper.prototype.V_WATT                = 17;\nMySHelper.prototype.V_KWH                 = 18;\nMySHelper.prototype.V_SCENE_ON            = 19;\nMySHelper.prototype.V_SCENE_OFF           = 20;\nMySHelper.prototype.V_HEATER              = 21;\nMySHelper.prototype.V_HEATER_SW           = 22;\nMySHelper.prototype.V_LIGHT_LEVEL         = 23;\nMySHelper.prototype.V_VAR1                = 24;\nMySHelper.prototype.V_VAR2                = 25;\nMySHelper.prototype.V_VAR3                = 26;\nMySHelper.prototype.V_VAR4                = 27;\nMySHelper.prototype.V_VAR5                = 28;\nMySHelper.prototype.V_UP                  = 29;\nMySHelper.prototype.V_DOWN                = 30;\nMySHelper.prototype.V_STOP                = 31;\nMySHelper.prototype.V_IR_SEND             = 32;\nMySHelper.prototype.V_IR_RECEIVE          = 33;\nMySHelper.prototype.V_FLOW                = 34;\nMySHelper.prototype.V_VOLUME              = 35;\nMySHelper.prototype.V_LOCK_STATUS         = 36;\nMySHelper.prototype.V_LEVEL               = 37; \nMySHelper.prototype.V_VOLTAGE             = 38; \nMySHelper.prototype.V_CURRENT             = 39; \nMySHelper.prototype.V_RGB                 = 40; \nMySHelper.prototype.V_RGBW                = 41;\nMySHelper.prototype.V_ID                  = 42;\nMySHelper.prototype.V_UNIT_PREFIX         = 43;\nMySHelper.prototype.V_HVAC_SETPOINT_COOL  = 44;\nMySHelper.prototype.V_HVAC_SETPOINT_HEAT  = 45;\nMySHelper.prototype.V_HVAC_FLOW_MODE      = 46;\nMySHelper.prototype.V_TEXT                = 47;\n\nvar vtype = {\nV_TEMP:              MySHelper.prototype.V_TEMP,\nV_HUM:               MySHelper.prototype.V_HUM,\nV_STATUS:            MySHelper.prototype.V_STATUS,\nV_LIGHT:             MySHelper.prototype.V_LIGHT,\nV_DIMMER:            MySHelper.prototype.V_DIMMER,\nV_PRESSURE:          MySHelper.prototype.V_PRESSURE,\nV_FORECAST:          MySHelper.prototype.V_FORECAST,\nV_RAIN:              MySHelper.prototype.V_RAIN,\nV_RAINRATE:          MySHelper.prototype.V_RAINRATE,\nV_WIND:              MySHelper.prototype.V_WIND,\nV_GUST:              MySHelper.prototype.V_GUST,\nV_DIRECTION:         MySHelper.prototype.V_DIRECTION,\nV_UV:                MySHelper.prototype.V_UV,\nV_WEIGHT:            MySHelper.prototype.V_WEIGHT,\nV_DISTANCE:          MySHelper.prototype.V_DISTANCE,\nV_IMPEDANCE:         MySHelper.prototype.V_IMPEDANCE,\nV_ARMED:             MySHelper.prototype.V_ARMED,\nV_TRIPPED:           MySHelper.prototype.V_TRIPPED,\nV_WATT:              MySHelper.prototype.V_WATT,\nV_KWH:               MySHelper.prototype.V_KWH,\nV_SCENE_ON:          MySHelper.prototype.V_SCENE_ON,\nV_SCENE_OFF:         MySHelper.prototype.V_SCENE_OFF,\nV_HEATER:            MySHelper.prototype.V_HEATER,\nV_HEATER_SW:         MySHelper.prototype.V_HEATER_SW,\nV_LIGHT_LEVEL:       MySHelper.prototype.V_LIGHT_LEVEL,\nV_VAR1:              MySHelper.prototype.V_VAR1,\nV_VAR2:              MySHelper.prototype.V_VAR2,\nV_VAR3:              MySHelper.prototype.V_VAR3,\nV_VAR4:              MySHelper.prototype.V_VAR4,\nV_VAR5:              MySHelper.prototype.V_VAR5,\nV_UP:                MySHelper.prototype.V_UP,\nV_DOWN:              MySHelper.prototype.V_DOWN,\nV_STOP:              MySHelper.prototype.V_STOP,\nV_IR_SEND:           MySHelper.prototype.V_IR_SEND,\nV_IR_RECEIVE:        MySHelper.prototype.V_IR_RECEIVE,\nV_FLOW:              MySHelper.prototype.V_FLOW,\nV_VOLUME:            MySHelper.prototype.V_VOLUME,\nV_LOCK_STATUS:       MySHelper.prototype.V_LOCK_STATUS,\nV_LEVEL:             MySHelper.prototype.V_LEVEL,\nV_VOLTAGE:           MySHelper.prototype.V_VOLTAGE, \nV_CURRENT:           MySHelper.prototype.V_CURRENT,\nV_RGB:               MySHelper.prototype.V_RGB,\nV_RGBW:              MySHelper.prototype.V_RGBW,\nV_ID:                MySHelper.prototype.V_ID,\nV_UNIT_PREFIX:       MySHelper.prototype.V_UNIT_PREFIX,\nV_HVAC_SETPOINT_COOL:MySHelper.prototype.V_HVAC_SETPOINT_COOL,\nV_HVAC_SETPOINT_HEAT:MySHelper.prototype.V_HVAC_SETPOINT_HEAT,\nV_HVAC_FLOW_MODE:    MySHelper.prototype.V_HVAC_FLOW_MODE,\nV_TEXT:              MySHelper.prototype.V_TEXT\n};\n\n\n\nMySHelper.prototype.VString = function(V_SUBTYPE) {\n    for (var prop in vtype ) \n    if( vtype[ prop ] === parseInt(V_SUBTYPE) )\n        return prop;\n};\n    \nMySHelper.prototype.VNum = function(V_SUBTYPE) {\n    sRet = vtype [V_SUBTYPE];\n    if (sRet === undefined)\n        sRet = V_SUBTYPE;\n    return sRet;\n}\n\nMySHelper.prototype.S_DOOR = 0; // Door sensor; V_TRIPPED; V_ARMED\nMySHelper.prototype.S_MOTION = 1;  // Motion sensor; V_TRIPPED; V_ARMED \nMySHelper.prototype.S_SMOKE = 2;  // Smoke sensor; V_TRIPPED; V_ARMED\nMySHelper.prototype.S_LIGHT = 3; // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT\nMySHelper.prototype.S_BINARY = 3; // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT (same as MySHelper.prototype.S_LIGHT)\nMySHelper.prototype.S_DIMMER = 4; // Dimmable light or fan device; V_STATUS (on/off); V_DIMMER (dimmer level 0-100); V_WATT\nMySHelper.prototype.S_COVER = 5; // Blinds or window cover; V_UP; V_DOWN; V_STOP; V_DIMMER (open/close to a percentage)\nMySHelper.prototype.S_TEMP = 6; // Temperature sensor; V_TEMP\nMySHelper.prototype.S_HUM = 7; // Humidity sensor; V_HUM\nMySHelper.prototype.S_BARO = 8; // Barometer sensor; V_PRESSURE; V_FORECAST\nMySHelper.prototype.S_WIND = 9; // Wind sensor; V_WIND; V_GUST\nMySHelper.prototype.S_RAIN = 10; // Rain sensor; V_RAIN; V_RAINRATE\nMySHelper.prototype.S_UV = 11; // Uv sensor; V_UV\nMySHelper.prototype.S_WEIGHT = 12; // Personal scale sensor; V_WEIGHT; V_IMPEDANCE\nMySHelper.prototype.S_POWER = 13; // Power meter; V_WATT; V_KWH\nMySHelper.prototype.S_HEATER = 14; // Header device; V_HVAC_SETPOINT_HEAT; V_HVAC_FLOW_STATE; V_TEMP\nMySHelper.prototype.S_DISTANCE = 15; // Distance sensor; V_DISTANCE\nMySHelper.prototype.S_LIGHT_LEVEL = 16; // Light level sensor; V_LIGHT_LEVEL (uncalibrated in percentage);  V_LEVEL (light level in lux)\nMySHelper.prototype.S_ARDUINO_NODE = 17 ; // Used (internally) for presenting a non-repeating Arduino node\nMySHelper.prototype.S_ARDUINO_REPEATER_NODE = 18; // Used (internally) for presenting a repeating Arduino node \nMySHelper.prototype.S_LOCK = 19; // Lock device; V_LOCK_STATUS\nMySHelper.prototype.S_IR = 20; // Ir device; V_IR_SEND; V_IR_RECEIVE\nMySHelper.prototype.S_WATER = 21; // Water meter; V_FLOW; V_VOLUME\nMySHelper.prototype.S_AIR_QUALITY = 22; // Air quality sensor; V_LEVEL\nMySHelper.prototype.S_CUSTOM = 23; // Custom sensor \nMySHelper.prototype.S_DUST = 24; // Dust sensor; V_LEVEL\nMySHelper.prototype.S_SCENE_CONTROLLER = 25; // Scene controller device; V_SCENE_ON; V_SCENE_OFF. \nMySHelper.prototype.S_RGB_LIGHT = 26; // RGB light. Send color component data using V_RGB. Also supports V_WATT \nMySHelper.prototype.S_RGBW_LIGHT = 27; // RGB light with an additional White component. Send data using V_RGBW. Also supports V_WATT\nMySHelper.prototype.S_COLOR_SENSOR = 28;  // Color sensor; send color information using V_RGB\nMySHelper.prototype.S_HVAC = 28; // Thermostat/HVAC device. V_HVAC_SETPOINT_HEAT; V_HVAC_SETPOINT_COLD; V_HVAC_FLOW_STATE; V_HVAC_FLOW_MODE; V_TEMP\nMySHelper.prototype.S_MULTIMETER = 29; // Multimeter device; V_VOLTAGE; V_CURRENT; V_IMPEDANCE \nMySHelper.prototype.S_SPRINKLER  = 30;  // Sprinkler; V_STATUS (turn on/off); V_TRIPPED (if fire detecting device)\nMySHelper.prototype.S_WATER_LEAK = 31; // Water leak sensor; V_TRIPPED; V_ARMED\nMySHelper.prototype.S_SOUND = 32; // Sound sensor; V_TRIPPED; V_ARMED; V_LEVEL (sound level in dB)\nMySHelper.prototype.S_VIBRATION = 33; // Vibration sensor; V_TRIPPED; V_ARMED; V_LEVEL (vibration in Hz)\nMySHelper.prototype.S_MOISTURE = 34; // Moisture sensor; V_TRIPPED; V_ARMED; V_LEVEL (water content or moisture in percentage?) \nMySHelper.prototype.S_INFO = 35; // LCD text device / Simple information device on controller; V_TEXT\nMySHelper.prototype.S_GAS = 36; // Gas meter; V_FLOW; V_VOLUME\nMySHelper.prototype.S_GPS = 37; // GPS Sensor; V_POSITION\n \nvar stype = {\nS_DOOR:                 MySHelper.prototype.S_DOOR, // Door sensor; V_TRIPPED; V_ARMED\nS_MOTION:               MySHelper.prototype.S_MOTION,  // Motion sensor; V_TRIPPED; V_ARMED \nS_SMOKE:                MySHelper.prototype.S_SMOKE,  // Smoke sensor; V_TRIPPED; V_ARMED\nS_LIGHT:                MySHelper.prototype.S_LIGHT, // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT\nS_BINARY:               MySHelper.prototype.S_BINARY, // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT (same as MySHelper.prototype.S_LIGHT)\nS_DIMMER:               MySHelper.prototype.S_DIMMER, // Dimmable light or fan device; V_STATUS (on/off); V_DIMMER (dimmer level 0-100); V_WATT\nS_COVER:                MySHelper.prototype.S_COVER, // Blinds or window cover; V_UP; V_DOWN; V_STOP; V_DIMMER (open/close to a percentage)\nS_TEMP:                 MySHelper.prototype.S_TEMP, // Temperature sensor; V_TEMP\nS_HUM:                  MySHelper.prototype.S_HUM, // Humidity sensor; V_HUM\nS_BARO:                 MySHelper.prototype.S_BARO, // Barometer sensor; V_PRESSURE; V_FORECAST\nS_WIND:                 MySHelper.prototype.S_WIND, // Wind sensor; V_WIND; V_GUST\nS_RAIN:                 MySHelper.prototype.S_RAIN, // Rain sensor; V_RAIN; V_RAINRATE\nS_UV:                   MySHelper.prototype.S_UV, // Uv sensor; V_UV\nS_WEIGHT:               MySHelper.prototype.S_WEIGHT, // Personal scale sensor; V_WEIGHT; V_IMPEDANCE\nS_POWER:                MySHelper.prototype.S_POWER, // Power meter; V_WATT; V_KWH\nS_HEATER:               MySHelper.prototype.S_HEATER, // Header device; V_HVAC_SETPOINT_HEAT; V_HVAC_FLOW_STATE; V_TEMP\nS_DISTANCE:             MySHelper.prototype.S_DISTANCE, // Distance sensor; V_DISTANCE\nS_LIGHT_LEVEL:          MySHelper.prototype.S_LIGHT_LEVEL, // Light level sensor; V_LIGHT_LEVEL (uncalibrated in percentage);  V_LEVEL (light level in lux)\nS_ARDUINO_NODE:         MySHelper.prototype.S_ARDUINO_NODE, // Used (internally) for presenting a non-repeating Arduino node\nS_ARDUINO_REPEATER_NODE:MySHelper.prototype.S_ARDUINO_REPEATER_NODE, // Used (internally) for presenting a repeating Arduino node \nS_LOCK:                 MySHelper.prototype.S_LOCK, // Lock device; V_LOCK_STATUS\nS_IR:                   MySHelper.prototype.S_IR, // Ir device; V_IR_SEND; V_IR_RECEIVE\nS_WATER:                MySHelper.prototype.S_WATER, // Water meter; V_FLOW; V_VOLUME\nS_AIR_QUALITY:          MySHelper.prototype.S_AIR_QUALITY, // Air quality sensor; V_LEVEL\nS_CUSTOM:               MySHelper.prototype.S_CUSTOM, // Custom sensor \nS_DUST:                 MySHelper.prototype.S_DUST, // Dust sensor; V_LEVEL\nS_SCENE_CONTROLLER:     MySHelper.prototype.S_SCENE_CONTROLLER, // Scene controller device; V_SCENE_ON; V_SCENE_OFF. \nS_RGB_LIGHT:            MySHelper.prototype.S_RGB_LIGHT, // RGB light. Send color component data using V_RGB. Also supports V_WATT \nS_RGBW_LIGHT:           MySHelper.prototype.S_RGBW_LIGHT, // RGB light with an additional White component. Send data using V_RGBW. Also supports V_WATT\nS_COLOR_SENSOR:         MySHelper.prototype.S_COLOR_SENSOR,  // Color sensor; send color information using V_RGB\nS_HVAC:                 MySHelper.prototype.S_HVAC, // Thermostat/HVAC device. V_HVAC_SETPOINT_HEAT; V_HVAC_SETPOINT_COLD; V_HVAC_FLOW_STATE; V_HVAC_FLOW_MODE; V_TEMP\nS_MULTIMETER:           MySHelper.prototype.S_MULTIMETER, // Multimeter device; V_VOLTAGE; V_CURRENT; V_IMPEDANCE \nS_SPRINKLER:            MySHelper.prototype.S_SPRINKLER,  // Sprinkler; V_STATUS (turn on/off); V_TRIPPED (if fire detecting device)\nS_WATER_LEAK:           MySHelper.prototype.S_WATER_LEAK, // Water leak sensor; V_TRIPPED; V_ARMED\nS_SOUND:                MySHelper.prototype.S_SOUND, // Sound sensor; V_TRIPPED; V_ARMED; V_LEVEL (sound level in dB)\nS_VIBRATION:            MySHelper.prototype.S_VIBRATION, // Vibration sensor; V_TRIPPED; V_ARMED; V_LEVEL (vibration in Hz)\nS_MOISTURE:             MySHelper.prototype.S_MOISTURE, // Moisture sensor; V_TRIPPED; V_ARMED; V_LEVEL (water content or moisture in percentage?) \nS_INFO:                 MySHelper.prototype.S_INFO, // LCD text device / Simple information device on controller; V_TEXT\nS_GAS:                  MySHelper.prototype.S_GAS, // Gas meter; V_FLOW; V_VOLUME\nS_GPS:                  MySHelper.prototype.S_GPS // GPS Sensor; V_POSITION\n};\n\nMySHelper.prototype.SString = function(S_SUBTYPE) {\n    for (var prop in stype ) \n    if( stype[ prop ] === parseInt(S_SUBTYPE) )\n        return prop;\n};    \n    \n MySHelper.prototype.encode = function(destination, sensor, command, acknowledge, type, payload) {\n\tvar msg = destination.toString(10) + \";\" + sensor.toString(10) + \";\" + command.toString(10) + \";\" + acknowledge.toString(10) + \";\" + type.toString(10) + \";\";\n\tif (command == 4) {\n\t\tfor (var i = 0; i < payload.length; i++) {\n\t\t\tif (payload[i] < 16)\n\t\t\t\tmsg += \"0\";\n\t\t\tmsg += payload[i].toString(16);\n\t\t}\n\t} else {\n\t\tmsg += payload;\n\t}\n\tmsg += '\\n';\n\treturn msg.toString();\n}\n}\n\n\nvar MySHelperObj = new MySHelper();\n\ncontext.global.MYS = MySHelperObj;\n\nreturn msg;","outputs":1,"noerr":0,"x":364.25,"y":65.99999809265137,"wires":[[]]},{"id":"df1e322.f20e1d","type":"function","z":"9592163f.6a6de8","name":"Set Controller 1","func":"msg.controller = 1\n\nreturn msg;","outputs":1,"noerr":0,"x":641.0000076293945,"y":147.49999809265137,"wires":[["ebcef3df.14311"]]},{"id":"266b87b3.d99478","type":"switch","z":"9592163f.6a6de8","name":"route to controller n","property":"controller","rules":[{"t":"eq","v":"1"},{"t":"eq","v":"2"},{"t":"eq","v":"3"},{"t":"eq","v":"4"}],"checkall":"false","outputs":4,"x":133,"y":214.25,"wires":[["3e866f6d.c1799"],["c7d0d88b.382f28"],[],[]]},{"id":"c7d0d88b.382f28","type":"tcp request","z":"9592163f.6a6de8","server":"192.168.92.14","port":"5003","out":"sit","splitc":"0","name":"MySWifi ESP8266 GW AES 14","x":410.5,"y":207.24999618530273,"wires":[["c5f14d8f.3a0eb"]]},{"id":"c5f14d8f.3a0eb","type":"function","z":"9592163f.6a6de8","name":"Set Controller 2","func":"msg.controller = 2\n\nreturn msg;","outputs":1,"noerr":0,"x":653.5,"y":205.7500114440918,"wires":[["ebcef3df.14311"]]},{"id":"56b9f6ab.a94608","type":"file in","z":"9592163f.6a6de8","name":"read store for next ids","filename":"mysids.dump","format":"utf8","x":385,"y":103.99999618530273,"wires":[["57db23d6.a824dc"]]},{"id":"e000bd09.1fff4","type":"debug","z":"9592163f.6a6de8","name":"Debug","active":false,"console":"false","complete":"true","x":732,"y":361,"wires":[]},{"id":"57db23d6.a824dc","type":"function","z":"9592163f.6a6de8","name":"store to context.global.mysnextid","func":"if (msg.payload === undefined) {\n          var mysnextid = {};\n\n        obj = mysnextid;  \n}\nelse \n{\ntry{\n        obj = JSON.parse(msg.payload);\n    }\n    catch(e){\n        \n        var mysnextid = {};\n\n        obj = mysnextid;\n        \n    }\n}    \n\ncontext.global.mysnextid = obj;\n\nmsg.payload = context.global.mysnextid;\n\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":102.99999618530273,"wires":[[]]},{"id":"dfba7d69.20458","type":"file","z":"9592163f.6a6de8","name":"dump mysids","filename":"mysids.dump","appendNewline":true,"createDir":false,"overwriteFile":"true","x":1473,"y":381.99999618530273,"wires":[]},{"id":"e0e76d62.1f189","type":"function","z":"9592163f.6a6de8","name":"handle nextids","func":"// increase nextid, if nodeid >= nextid \n// node.log(\"Handling next ids\");\n// node.log(\"nodeId: \" + msg.nodeId);\n\nbChanged = false;\n\nif (msg.nodeId === 0) return;\n\nif (msg.nodeId < 255)\n{\n    // node.log(\"Test if next node-id must be set\");\n    if (context.global.mysnextid[msg.controller] === undefined) {\n        node.log(\"node-id not initialized yet\");\n        context.global.mysnextid[msg.controller] = msg.nodeId+1;\n        if (context.global.mysnextid[msg.controller] < context.global.MYS.MIN_NODEID)\n            context.global.mysnextid[msg.controller] = context.global.MYS.MIN_NODEID;\n        bChanged = true;\n    }\n    \n    // node.log(\"Nexid stored \" + parseInt(context.global.mysnextid[msg.controller]));\n    \n    if (msg.nodeId >= parseInt(context.global.mysnextid[msg.controller])) {\n        node.log(\"node-id >= next -> increase\");\n        // convert to int\n        context.global.mysnextid[msg.controller] = parseInt(context.global.mysnextid[msg.controller]);\n        context.global.mysnextid[msg.controller] = msg.nodeId+1; \n        if (context.global.mysnextid[msg.controller] < context.global.MYS.MIN_NODEID)\n            context.global.mysnextid[msg.controller] = context.global.MYS.MIN_NODEID;\n        bChanged = true;\n    }\n\n    if (bChanged) {\n        node.log(\"next id must be stored\");\n        msg.payload = JSON.stringify(context.global.mysnextid);   \n        return msg;\n    }\n}\n\n\n","outputs":1,"noerr":0,"x":1262,"y":374.99999618530273,"wires":[["dfba7d69.20458","5c074c19.a3f8b4"]]},{"id":"8da09002.725f7","type":"function","z":"9592163f.6a6de8","name":"MQTT to MYS convert","func":"// topic = MYS-NODERED/set/controller/node-id/sensor-id/ack/sub-type\n// payload = payload :)\n\n    var tokens = msg.topic.split(\"/\")\n    \n    msg.rawData = tokens;\n    msg.tokens = tokens.length;\n    if(tokens.length == 7)\n    {\n        if (tokens[0] != context.global.MYS.TOPIC_PREFIX) // not for us\n            return;\n        if (tokens[1] != 'set') // not for us\n            return;\n            \n        msg.controller = parseInt(tokens[2]);\n        msg.messageType = context.global.MYS.T_SET;\n        msg.nodeId = parseInt(tokens[3]);\n        msg.childSensorId = parseInt(tokens[4]);\n        msg.ack = parseInt(tokens[5]);\n        msg.subType = context.global.MYS.VNum(tokens[6]);\n        \n        msg.payload = context.global.MYS.encode(msg.nodeId, msg.childSensorId, msg.messageType, msg.ack, msg.subType, msg.payload);\n    \n        return msg;        \n    }\n","outputs":1,"noerr":0,"x":490,"y":361,"wires":[["e000bd09.1fff4","266b87b3.d99478"]]},{"id":"3e866f6d.c1799","type":"tcp request","z":"9592163f.6a6de8","server":"192.168.92.13","port":"5003","out":"sit","splitc":"0","name":"MySWifi ESP8266 GW AES 13","x":407,"y":145.99999618530273,"wires":[["df1e322.f20e1d"]]},{"id":"5c074c19.a3f8b4","type":"debug","z":"9592163f.6a6de8","name":"","active":true,"console":"false","complete":"false","x":1454,"y":543.9999961853027,"wires":[]},{"id":"c75fd7f4.38a028","type":"mqtt in","z":"9592163f.6a6de8","name":"Read MQTT Stream: change Topic to your needs","topic":"MYS-NODERED/set/#","broker":"ba386057.845d3","x":183.5,"y":362,"wires":[["8da09002.725f7"]]}]```
      posted in Node-RED
      FotoFieber
    • RE: Node-Red as Controller

      Here my approach:

      
      [{"id":"ba386057.845d3","type":"mqtt-broker","broker":"192.168.92.4","port":"1883","clientid":"NodeRed"},{"id":"b5e4f17d.4a1b1","type":"function","name":"hanlde internal messages","func":"//msg.subTypeString = \"\";\n//msg.topic = \"internal respones\";\n\nif (msg.subTypeString == 'I_TIME')\n{\n    var payload = parseInt(new Date().getTime()/1000);\n\tvar command = context.global.MYS.T_INTERNAL; \n\tvar acknowledge = 0; // no ack\n\tvar type = context.global.MYS.I_TIME; // I_TIME\n\tmsg.payload = encode(msg.nodeId, msg.childSensorId, command, acknowledge, type, payload);\n    return msg;\n    \n}\nelse if  (msg.subTypeString == 'I_ID_REQUEST')\n{\n    msg.topic = \"I_ID_RESPONSE\";\n    msg.subTypeString = \"I_ID_RESPONSE\";\n    // 255;255;3;0;4;8 for ID 8\n    var command = context.global.MYS.T_INTERNAL;\n\tvar acknowledge = 0; // no ack\n\tvar type = context.global.MYS.I_ID_RESPONSE; // I_ID_RESPONSE\n\n\tif (context.global.mysnextid[msg.controller] === undefined) {\n\t    payload = context.global.MYS.MIN_NODEID;\n\t}    \n\telse\n\t{\n\t    payload = context.global.mysnextid[msg.controller];\n\t}\n\t\n    msg.payload = encode(msg.nodeId, msg.childSensorId, command, acknowledge, type, payload);\n    return msg; \n} \nelse if  (msg.subTypeString == 'I_INCLUSION_MODE')\n{\n    // not yet implemented\n}\n\nreturn;\n\nfunction encode(destination, sensor, command, acknowledge, type, payload) {\n\tvar msg = destination.toString(10) + \";\" + sensor.toString(10) + \";\" + command.toString(10) + \";\" + acknowledge.toString(10) + \";\" + type.toString(10) + \";\";\n\tif (command == 4) {\n\t\tfor (var i = 0; i < payload.length; i++) {\n\t\t\tif (payload[i] < 16)\n\t\t\t\tmsg += \"0\";\n\t\t\tmsg += payload[i].toString(16);\n\t\t}\n\t} else {\n\t\tmsg += payload;\n\t}\n\tmsg += '\\n';\n\treturn msg.toString();\n}\n","outputs":1,"noerr":0,"x":1655.916648864746,"y":536.4166927337646,"z":"9592163f.6a6de8","wires":[["4d15a037.b2ea6","266b87b3.d99478"]]},{"id":"e6ce260d.1931d8","type":"switch","name":"switch message type","property":"messageType","rules":[{"t":"eq","v":"0"},{"t":"eq","v":"1"},{"t":"eq","v":"2"},{"t":"eq","v":"3"},{"t":"eq","v":"4"}],"checkall":"true","outputs":5,"x":1220.166648864746,"y":175.5000171661377,"z":"9592163f.6a6de8","wires":[["8c663d73.7399c"],["4a1e5f84.b5e1a"],["7753f9a2.88ac08"],["1e4aa61b.e1b55a"],["60a0dde4.9f5f24"]]},{"id":"8c663d73.7399c","type":"function","name":"presentation","func":"msg.subTypeString = context.global.MYS.SString(msg.subType);\n\nmsg.topic = context.global.MYS.TOPIC_PREFIX + '/' + msg.controller + \"/\" + msg.nodeId + \"/\" + msg.childSensorId + \"/\" + msg.subTypeString;\n\nreturn msg;","outputs":1,"noerr":0,"x":1449.916648864746,"y":38.2499885559082,"z":"9592163f.6a6de8","wires":[["df9e131d.2061f","4d15a037.b2ea6"]]},{"id":"7753f9a2.88ac08","type":"function","name":"req","func":"msg.topic = \"req\";\nreturn msg;","outputs":1,"noerr":0,"x":1445.5000228881836,"y":175.7500057220459,"z":"9592163f.6a6de8","wires":[["4d15a037.b2ea6"]]},{"id":"1e4aa61b.e1b55a","type":"function","name":"internal","func":"msg.subTypeString = context.global.MYS.IString(msg.subType);\n\nmsg.topic = context.global.MYS.TOPIC_PREFIX + '/' + msg.controller + \"/\" + msg.nodeId + \"/\" + msg.childSensorId + \"/\" + msg.subTypeString;\n\nreturn msg;","outputs":1,"noerr":0,"x":1449.5000228881836,"y":226.0000057220459,"z":"9592163f.6a6de8","wires":[["df9e131d.2061f","4d15a037.b2ea6","b5e4f17d.4a1b1"]]},{"id":"60a0dde4.9f5f24","type":"function","name":"stream","func":"msg.topic = \"stream\";\nreturn msg;","outputs":1,"x":1457.5000228881836,"y":321.0000057220459,"z":"9592163f.6a6de8","wires":[[]]},{"id":"4d15a037.b2ea6","type":"debug","name":"debug","active":true,"console":"false","complete":"true","x":1806.7500267028809,"y":235.00000667572021,"z":"9592163f.6a6de8","wires":[]},{"id":"4a1e5f84.b5e1a","type":"function","name":"set","func":"msg.subTypeString = context.global.MYS.VString(msg.subType);\n\nmsg.topic = context.global.MYS.TOPIC_PREFIX + '/' + msg.controller + \"/\" + msg.nodeId + \"/\" + msg.childSensorId + \"/\" + msg.subTypeString;\n\n\nreturn msg;","outputs":1,"noerr":0,"x":1453.166648864746,"y":100.50000381469727,"z":"9592163f.6a6de8","wires":[["4d15a037.b2ea6","df9e131d.2061f"]]},{"id":"fc54bb91.03ab48","type":"debug","name":"","active":false,"console":"false","complete":"true","x":1179.9166259765625,"y":34.66668891906738,"z":"9592163f.6a6de8","wires":[]},{"id":"6aa2d9f6.955d28","type":"function","name":"Split GW Message","func":"\n    var tokens = msg.payload.split(\";\")\n    \n    msg.rawData = tokens;\n    if(tokens.length >= 6)\n    {\n        msg.nodeId = tokens[0];\n        msg.childSensorId = tokens[1];\n        msg.messageType = tokens[2];\n        msg.ack = tokens[3];\n        msg.subType = tokens[4];\n        msg.payload = tokens[5];\n        for (j=6; j<tokens.length; j++) \n            msg.payload = msg.payload + ';' + tokens[j];\n    }\n\nreturn msg;","outputs":1,"noerr":0,"x":984.6666488647461,"y":173.66664505004883,"z":"9592163f.6a6de8","wires":[["e6ce260d.1931d8","fc54bb91.03ab48","e0e76d62.1f189"]]},{"id":"df9e131d.2061f","type":"mqtt out","name":"Publish to MQTT","topic":"","qos":"","retain":"","broker":"ba386057.845d3","x":1819.9166526794434,"y":174.1666603088379,"z":"9592163f.6a6de8","wires":[]},{"id":"5f03c10e.a0fc4","type":"tcp request","server":"192.168.92.13","port":"5003","out":"char","splitc":"\\n","name":"MySWifi ESP8266 GW AES 13","x":376.6666946411133,"y":140.1666316986084,"z":"9592163f.6a6de8","wires":[["df1e322.f20e1d"]]},{"id":"e6d67f33.19298","type":"inject","name":"Startup","topic":"","payload":"","payloadType":"none","repeat":"","crontab":"","once":true,"x":106.25,"y":74.41665744781494,"z":"9592163f.6a6de8","wires":[["5f03c10e.a0fc4","64617800.9b9e88","c7d0d88b.382f28","56b9f6ab.a94608"]]},{"id":"ebcef3df.14311","type":"function","name":"ToString","func":"msg.payload = msg.payload.toString().replace(/[\\n\\r]/g, '');\n\nreturn msg;","outputs":1,"noerr":0,"x":790.1666946411133,"y":174.91669178009033,"z":"9592163f.6a6de8","wires":[["6aa2d9f6.955d28"]]},{"id":"31047fa6.cefb8","type":"catch","name":"","x":71,"y":642,"z":"9592163f.6a6de8","wires":[["3622f9b9.c9dd06"]]},{"id":"3622f9b9.c9dd06","type":"debug","name":"","active":false,"console":"false","complete":"true","x":216,"y":642,"z":"9592163f.6a6de8","wires":[]},{"id":"64617800.9b9e88","type":"function","name":"MYS Initialize","func":"function MySHelper() { \n\nMySHelper.prototype.TOPIC_PREFIX = \"MYS-NODERED\";\n\nMySHelper.prototype.MIN_NODEID = 10;\n\n\n// don't touch below :)\n    \nMySHelper.prototype.T_PRESENTATION                = 0;\nMySHelper.prototype.T_SET                         = 1;\nMySHelper.prototype.T_REQ                         = 2;\nMySHelper.prototype.T_INTERNAL                    = 3;\nMySHelper.prototype.T_STREAM                      = 4;\n\nMySHelper.prototype.I_BATTERY_LEVEL               = 0;\nMySHelper.prototype.I_TIME                        = 1;\nMySHelper.prototype.I_VERSION                     = 2;\nMySHelper.prototype.I_ID_REQUEST                  = 3;\nMySHelper.prototype.I_ID_RESPONSE                 = 4;\nMySHelper.prototype.I_INCLUSION_MODE              = 5;\nMySHelper.prototype.I_CONFIG                      = 6;\nMySHelper.prototype.I_PING                        = 7;\nMySHelper.prototype.I_PING_ACK                    = 8;\nMySHelper.prototype.I_LOG_MESSAGE                 = 9;\nMySHelper.prototype.I_CHILDREN                    = 10;\nMySHelper.prototype.I_SKETCH_NAME                 = 11;\nMySHelper.prototype.I_SKETCH_VERSION              = 12;\nMySHelper.prototype.I_REBOOT                      = 13;\nMySHelper.prototype.I_GATEWAY_READY               = 14;\nMySHelper.prototype.I_REQUEST_SIGNING             = 15;\nMySHelper.prototype.I_GET_NONCE                   = 16;\nMySHelper.prototype.I_GET_NONCE_RESPONSE          = 17;\nMySHelper.prototype.I_HEARTBEAT                   = 18;\nMySHelper.prototype.I_PRESENTATION                = 19;\n \nvar itype = {\nI_BATTERY_LEVEL:                    MySHelper.prototype.I_BATTERY_LEVEL,\nI_TIME:                             MySHelper.prototype.I_TIME,\nI_VERSION:                          MySHelper.prototype.I_VERSION,\nI_ID_REQUEST:                       MySHelper.prototype.I_ID_REQUEST,\nI_ID_RESPONSE:                      MySHelper.prototype.I_ID_RESPONSE,\nI_INCLUSION_MODE:                   MySHelper.prototype.I_INCLUSION_MODE,\nI_CONFIG:                           MySHelper.prototype.I_CONFIG,\nI_PING:                             MySHelper.prototype.I_PING,\nI_PING_ACK:                         MySHelper.prototype.I_PING_ACK,\nI_LOG_MESSAGE:                      MySHelper.prototype.I_LOG_MESSAGE,\nI_CHILDREN:                         MySHelper.prototype.I_CHILDREN,\nI_SKETCH_NAME:                      MySHelper.prototype.I_SKETCH_NAME,\nI_SKETCH_VERSION:                   MySHelper.prototype.I_SKETCH_VERSION,\nI_REBOOT:                           MySHelper.prototype.I_REBOOT,\nI_GATEWAY_READY:                    MySHelper.prototype.I_GATEWAY_READY,\nI_REQUEST_SIGNING:                  MySHelper.prototype.I_REQUEST_SIGNING,\nI_GET_NONCE:                        MySHelper.prototype.I_GET_NONCE,\nI_GET_NONCE_RESPONSE:               MySHelper.prototype.I_GET_NONCE_RESPONSE,\nI_HEARTBEAT:                        MySHelper.prototype.I_HEARTBEAT,\nI_PRESENTATION:                     MySHelper.prototype.I_PRESENTATION\n};\n\nMySHelper.prototype.IString = function(I_SUBTYPE) {\n    for (var prop in itype ) \n    if( itype[ prop ] === parseInt(I_SUBTYPE) )\n        return prop;\n};\n\nMySHelper.prototype.V_TEMP                = 0;\nMySHelper.prototype.V_HUM                 = 1;\nMySHelper.prototype.V_LIGHT               = 2;\nMySHelper.prototype.V_DIMMER              = 3;\nMySHelper.prototype.V_PRESSURE            = 4;\nMySHelper.prototype.V_FORECAST            = 5;\nMySHelper.prototype.V_RAIN                = 6;\nMySHelper.prototype.V_RAINRATE            = 7;\nMySHelper.prototype.V_WIND                = 8;\nMySHelper.prototype.V_GUST                = 9;\nMySHelper.prototype.V_DIRECTION           = 10;\nMySHelper.prototype.V_UV                  = 11;\nMySHelper.prototype.V_WEIGHT              = 12;\nMySHelper.prototype.V_DISTANCE            = 13;\nMySHelper.prototype.V_IMPEDANCE           = 14;\nMySHelper.prototype.V_ARMED               = 15;\nMySHelper.prototype.V_TRIPPED             = 16;\nMySHelper.prototype.V_WATT                = 17;\nMySHelper.prototype.V_KWH                 = 18;\nMySHelper.prototype.V_SCENE_ON            = 19;\nMySHelper.prototype.V_SCENE_OFF           = 20;\nMySHelper.prototype.V_HEATER              = 21;\nMySHelper.prototype.V_HEATER_SW           = 22;\nMySHelper.prototype.V_LIGHT_LEVEL         = 23;\nMySHelper.prototype.V_VAR1                = 24;\nMySHelper.prototype.V_VAR2                = 25;\nMySHelper.prototype.V_VAR3                = 26;\nMySHelper.prototype.V_VAR4                = 27;\nMySHelper.prototype.V_VAR5                = 28;\nMySHelper.prototype.V_UP                  = 29;\nMySHelper.prototype.V_DOWN                = 30;\nMySHelper.prototype.V_STOP                = 31;\nMySHelper.prototype.V_IR_SEND             = 32;\nMySHelper.prototype.V_IR_RECEIVE          = 33;\nMySHelper.prototype.V_FLOW                = 34;\nMySHelper.prototype.V_VOLUME              = 35;\nMySHelper.prototype.V_LOCK_STATUS         = 36;\nMySHelper.prototype.V_LEVEL               = 37; \nMySHelper.prototype.V_VOLTAGE             = 38; \nMySHelper.prototype.V_CURRENT             = 39; \nMySHelper.prototype.V_RGB                 = 40; \nMySHelper.prototype.V_RGBW                = 41;\nMySHelper.prototype.V_ID                  = 42;\nMySHelper.prototype.V_UNIT_PREFIX         = 43;\nMySHelper.prototype.V_HVAC_SETPOINT_COOL  = 44;\nMySHelper.prototype.V_HVAC_SETPOINT_HEAT  = 45;\nMySHelper.prototype.V_HVAC_FLOW_MODE      = 46;\nMySHelper.prototype.V_TEXT                = 47;\n\nvar vtype = {\nV_TEMP:              MySHelper.prototype.V_TEMP,\nV_HUM:               MySHelper.prototype.V_HUM,\nV_LIGHT:             MySHelper.prototype.V_LIGHT,\nV_DIMMER:            MySHelper.prototype.V_DIMMER,\nV_PRESSURE:          MySHelper.prototype.V_PRESSURE,\nV_FORECAST:          MySHelper.prototype.V_FORECAST,\nV_RAIN:              MySHelper.prototype.V_RAIN,\nV_RAINRATE:          MySHelper.prototype.V_RAINRATE,\nV_WIND:              MySHelper.prototype.V_WIND,\nV_GUST:              MySHelper.prototype.V_GUST,\nV_DIRECTION:         MySHelper.prototype.V_DIRECTION,\nV_UV:                MySHelper.prototype.V_UV,\nV_WEIGHT:            MySHelper.prototype.V_WEIGHT,\nV_DISTANCE:          MySHelper.prototype.V_DISTANCE,\nV_IMPEDANCE:         MySHelper.prototype.V_IMPEDANCE,\nV_ARMED:             MySHelper.prototype.V_ARMED,\nV_TRIPPED:           MySHelper.prototype.V_TRIPPED,\nV_WATT:              MySHelper.prototype.V_WATT,\nV_KWH:               MySHelper.prototype.V_KWH,\nV_SCENE_ON:          MySHelper.prototype.V_SCENE_ON,\nV_SCENE_OFF:         MySHelper.prototype.V_SCENE_OFF,\nV_HEATER:            MySHelper.prototype.V_HEATER,\nV_HEATER_SW:         MySHelper.prototype.V_HEATER_SW,\nV_LIGHT_LEVEL:       MySHelper.prototype.V_LIGHT_LEVEL,\nV_VAR1:              MySHelper.prototype.V_VAR1,\nV_VAR2:              MySHelper.prototype.V_VAR2,\nV_VAR3:              MySHelper.prototype.V_VAR3,\nV_VAR4:              MySHelper.prototype.V_VAR4,\nV_VAR5:              MySHelper.prototype.V_VAR5,\nV_UP:                MySHelper.prototype.V_UP,\nV_DOWN:              MySHelper.prototype.V_DOWN,\nV_STOP:              MySHelper.prototype.V_STOP,\nV_IR_SEND:           MySHelper.prototype.V_IR_SEND,\nV_IR_RECEIVE:        MySHelper.prototype.V_IR_RECEIVE,\nV_FLOW:              MySHelper.prototype.V_FLOW,\nV_VOLUME:            MySHelper.prototype.V_VOLUME,\nV_LOCK_STATUS:       MySHelper.prototype.V_LOCK_STATUS,\nV_LEVEL:             MySHelper.prototype.V_LEVEL,\nV_VOLTAGE:           MySHelper.prototype.V_VOLTAGE, \nV_CURRENT:           MySHelper.prototype.V_CURRENT,\nV_RGB:               MySHelper.prototype.V_RGB,\nV_RGBW:              MySHelper.prototype.V_RGBW,\nV_ID:                MySHelper.prototype.V_ID,\nV_UNIT_PREFIX:       MySHelper.prototype.V_UNIT_PREFIX,\nV_HVAC_SETPOINT_COOL:MySHelper.prototype.V_HVAC_SETPOINT_COOL,\nV_HVAC_SETPOINT_HEAT:MySHelper.prototype.V_HVAC_SETPOINT_HEAT,\nV_HVAC_FLOW_MODE:    MySHelper.prototype.V_HVAC_FLOW_MODE,\nV_TEXT:              MySHelper.prototype.V_TEXT\n};\n\n\n\nMySHelper.prototype.VString = function(V_SUBTYPE) {\n    for (var prop in vtype ) \n    if( vtype[ prop ] === parseInt(V_SUBTYPE) )\n        return prop;\n};\n    \n\nMySHelper.prototype.S_DOOR = 0; // Door sensor; V_TRIPPED; V_ARMED\nMySHelper.prototype.S_MOTION = 1;  // Motion sensor; V_TRIPPED; V_ARMED \nMySHelper.prototype.S_SMOKE = 2;  // Smoke sensor; V_TRIPPED; V_ARMED\nMySHelper.prototype.S_LIGHT = 3; // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT\nMySHelper.prototype.S_BINARY = 3; // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT (same as MySHelper.prototype.S_LIGHT)\nMySHelper.prototype.S_DIMMER = 4; // Dimmable light or fan device; V_STATUS (on/off); V_DIMMER (dimmer level 0-100); V_WATT\nMySHelper.prototype.S_COVER = 5; // Blinds or window cover; V_UP; V_DOWN; V_STOP; V_DIMMER (open/close to a percentage)\nMySHelper.prototype.S_TEMP = 6; // Temperature sensor; V_TEMP\nMySHelper.prototype.S_HUM = 7; // Humidity sensor; V_HUM\nMySHelper.prototype.S_BARO = 8; // Barometer sensor; V_PRESSURE; V_FORECAST\nMySHelper.prototype.S_WIND = 9; // Wind sensor; V_WIND; V_GUST\nMySHelper.prototype.S_RAIN = 10; // Rain sensor; V_RAIN; V_RAINRATE\nMySHelper.prototype.S_UV = 11; // Uv sensor; V_UV\nMySHelper.prototype.S_WEIGHT = 12; // Personal scale sensor; V_WEIGHT; V_IMPEDANCE\nMySHelper.prototype.S_POWER = 13; // Power meter; V_WATT; V_KWH\nMySHelper.prototype.S_HEATER = 14; // Header device; V_HVAC_SETPOINT_HEAT; V_HVAC_FLOW_STATE; V_TEMP\nMySHelper.prototype.S_DISTANCE = 15; // Distance sensor; V_DISTANCE\nMySHelper.prototype.S_LIGHT_LEVEL = 16; // Light level sensor; V_LIGHT_LEVEL (uncalibrated in percentage);  V_LEVEL (light level in lux)\nMySHelper.prototype.S_ARDUINO_NODE = 17 ; // Used (internally) for presenting a non-repeating Arduino node\nMySHelper.prototype.S_ARDUINO_REPEATER_NODE = 18; // Used (internally) for presenting a repeating Arduino node \nMySHelper.prototype.S_LOCK = 19; // Lock device; V_LOCK_STATUS\nMySHelper.prototype.S_IR = 20; // Ir device; V_IR_SEND; V_IR_RECEIVE\nMySHelper.prototype.S_WATER = 21; // Water meter; V_FLOW; V_VOLUME\nMySHelper.prototype.S_AIR_QUALITY = 22; // Air quality sensor; V_LEVEL\nMySHelper.prototype.S_CUSTOM = 23; // Custom sensor \nMySHelper.prototype.S_DUST = 24; // Dust sensor; V_LEVEL\nMySHelper.prototype.S_SCENE_CONTROLLER = 25; // Scene controller device; V_SCENE_ON; V_SCENE_OFF. \nMySHelper.prototype.S_RGB_LIGHT = 26; // RGB light. Send color component data using V_RGB. Also supports V_WATT \nMySHelper.prototype.S_RGBW_LIGHT = 27; // RGB light with an additional White component. Send data using V_RGBW. Also supports V_WATT\nMySHelper.prototype.S_COLOR_SENSOR = 28;  // Color sensor; send color information using V_RGB\nMySHelper.prototype.S_HVAC = 28; // Thermostat/HVAC device. V_HVAC_SETPOINT_HEAT; V_HVAC_SETPOINT_COLD; V_HVAC_FLOW_STATE; V_HVAC_FLOW_MODE; V_TEMP\nMySHelper.prototype.S_MULTIMETER = 29; // Multimeter device; V_VOLTAGE; V_CURRENT; V_IMPEDANCE \nMySHelper.prototype.S_SPRINKLER  = 30;  // Sprinkler; V_STATUS (turn on/off); V_TRIPPED (if fire detecting device)\nMySHelper.prototype.S_WATER_LEAK = 31; // Water leak sensor; V_TRIPPED; V_ARMED\nMySHelper.prototype.S_SOUND = 32; // Sound sensor; V_TRIPPED; V_ARMED; V_LEVEL (sound level in dB)\nMySHelper.prototype.S_VIBRATION = 33; // Vibration sensor; V_TRIPPED; V_ARMED; V_LEVEL (vibration in Hz)\nMySHelper.prototype.S_MOISTURE = 34; // Moisture sensor; V_TRIPPED; V_ARMED; V_LEVEL (water content or moisture in percentage?) \nMySHelper.prototype.S_INFO = 35; // LCD text device / Simple information device on controller; V_TEXT\nMySHelper.prototype.S_GAS = 36; // Gas meter; V_FLOW; V_VOLUME\nMySHelper.prototype.S_GPS = 37; // GPS Sensor; V_POSITION\n \nvar stype = {\nS_DOOR:                 MySHelper.prototype.S_DOOR, // Door sensor; V_TRIPPED; V_ARMED\nS_MOTION:               MySHelper.prototype.S_MOTION,  // Motion sensor; V_TRIPPED; V_ARMED \nS_SMOKE:                MySHelper.prototype.S_SMOKE,  // Smoke sensor; V_TRIPPED; V_ARMED\nS_LIGHT:                MySHelper.prototype.S_LIGHT, // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT\nS_BINARY:               MySHelper.prototype.S_BINARY, // Binary light or relay; V_STATUS (or V_LIGHT); V_WATT (same as MySHelper.prototype.S_LIGHT)\nS_DIMMER:               MySHelper.prototype.S_DIMMER, // Dimmable light or fan device; V_STATUS (on/off); V_DIMMER (dimmer level 0-100); V_WATT\nS_COVER:                MySHelper.prototype.S_COVER, // Blinds or window cover; V_UP; V_DOWN; V_STOP; V_DIMMER (open/close to a percentage)\nS_TEMP:                 MySHelper.prototype.S_TEMP, // Temperature sensor; V_TEMP\nS_HUM:                  MySHelper.prototype.S_HUM, // Humidity sensor; V_HUM\nS_BARO:                 MySHelper.prototype.S_BARO, // Barometer sensor; V_PRESSURE; V_FORECAST\nS_WIND:                 MySHelper.prototype.S_WIND, // Wind sensor; V_WIND; V_GUST\nS_RAIN:                 MySHelper.prototype.S_RAIN, // Rain sensor; V_RAIN; V_RAINRATE\nS_UV:                   MySHelper.prototype.S_UV, // Uv sensor; V_UV\nS_WEIGHT:               MySHelper.prototype.S_WEIGHT, // Personal scale sensor; V_WEIGHT; V_IMPEDANCE\nS_POWER:                MySHelper.prototype.S_POWER, // Power meter; V_WATT; V_KWH\nS_HEATER:               MySHelper.prototype.S_HEATER, // Header device; V_HVAC_SETPOINT_HEAT; V_HVAC_FLOW_STATE; V_TEMP\nS_DISTANCE:             MySHelper.prototype.S_DISTANCE, // Distance sensor; V_DISTANCE\nS_LIGHT_LEVEL:          MySHelper.prototype.S_LIGHT_LEVEL, // Light level sensor; V_LIGHT_LEVEL (uncalibrated in percentage);  V_LEVEL (light level in lux)\nS_ARDUINO_NODE:         MySHelper.prototype.S_ARDUINO_NODE, // Used (internally) for presenting a non-repeating Arduino node\nS_ARDUINO_REPEATER_NODE:MySHelper.prototype.S_ARDUINO_REPEATER_NODE, // Used (internally) for presenting a repeating Arduino node \nS_LOCK:                 MySHelper.prototype.S_LOCK, // Lock device; V_LOCK_STATUS\nS_IR:                   MySHelper.prototype.S_IR, // Ir device; V_IR_SEND; V_IR_RECEIVE\nS_WATER:                MySHelper.prototype.S_WATER, // Water meter; V_FLOW; V_VOLUME\nS_AIR_QUALITY:          MySHelper.prototype.S_AIR_QUALITY, // Air quality sensor; V_LEVEL\nS_CUSTOM:               MySHelper.prototype.S_CUSTOM, // Custom sensor \nS_DUST:                 MySHelper.prototype.S_DUST, // Dust sensor; V_LEVEL\nS_SCENE_CONTROLLER:     MySHelper.prototype.S_SCENE_CONTROLLER, // Scene controller device; V_SCENE_ON; V_SCENE_OFF. \nS_RGB_LIGHT:            MySHelper.prototype.S_RGB_LIGHT, // RGB light. Send color component data using V_RGB. Also supports V_WATT \nS_RGBW_LIGHT:           MySHelper.prototype.S_RGBW_LIGHT, // RGB light with an additional White component. Send data using V_RGBW. Also supports V_WATT\nS_COLOR_SENSOR:         MySHelper.prototype.S_COLOR_SENSOR,  // Color sensor; send color information using V_RGB\nS_HVAC:                 MySHelper.prototype.S_HVAC, // Thermostat/HVAC device. V_HVAC_SETPOINT_HEAT; V_HVAC_SETPOINT_COLD; V_HVAC_FLOW_STATE; V_HVAC_FLOW_MODE; V_TEMP\nS_MULTIMETER:           MySHelper.prototype.S_MULTIMETER, // Multimeter device; V_VOLTAGE; V_CURRENT; V_IMPEDANCE \nS_SPRINKLER:            MySHelper.prototype.S_SPRINKLER,  // Sprinkler; V_STATUS (turn on/off); V_TRIPPED (if fire detecting device)\nS_WATER_LEAK:           MySHelper.prototype.S_WATER_LEAK, // Water leak sensor; V_TRIPPED; V_ARMED\nS_SOUND:                MySHelper.prototype.S_SOUND, // Sound sensor; V_TRIPPED; V_ARMED; V_LEVEL (sound level in dB)\nS_VIBRATION:            MySHelper.prototype.S_VIBRATION, // Vibration sensor; V_TRIPPED; V_ARMED; V_LEVEL (vibration in Hz)\nS_MOISTURE:             MySHelper.prototype.S_MOISTURE, // Moisture sensor; V_TRIPPED; V_ARMED; V_LEVEL (water content or moisture in percentage?) \nS_INFO:                 MySHelper.prototype.S_INFO, // LCD text device / Simple information device on controller; V_TEXT\nS_GAS:                  MySHelper.prototype.S_GAS, // Gas meter; V_FLOW; V_VOLUME\nS_GPS:                  MySHelper.prototype.S_GPS // GPS Sensor; V_POSITION\n};\n\nMySHelper.prototype.SString = function(S_SUBTYPE) {\n    for (var prop in stype ) \n    if( stype[ prop ] === parseInt(S_SUBTYPE) )\n        return prop;\n};    \n    \n}\n\n\nvar MySHelperObj = new MySHelper();\n\ncontext.global.MYS = MySHelperObj;\n\nreturn msg;","outputs":1,"noerr":0,"x":325.25,"y":59.00000190734863,"z":"9592163f.6a6de8","wires":[[]]},{"id":"df1e322.f20e1d","type":"function","name":"Set Controller 1","func":"msg.controller = 1\n\nreturn msg;","outputs":1,"noerr":0,"x":602.0000076293945,"y":140.50000190734863,"z":"9592163f.6a6de8","wires":[["ebcef3df.14311"]]},{"id":"266b87b3.d99478","type":"switch","name":"route to controller n","property":"controller","rules":[{"t":"eq","v":"1"},{"t":"eq","v":"2"},{"t":"eq","v":"3"},{"t":"eq","v":"4"}],"checkall":"false","outputs":4,"x":94,"y":207.25000381469727,"z":"9592163f.6a6de8","wires":[["5f03c10e.a0fc4"],["c7d0d88b.382f28"],[],[]]},{"id":"c7d0d88b.382f28","type":"tcp request","server":"192.168.92.14","port":"5003","out":"char","splitc":"\\n","name":"MySWifi ESP8266 GW AES 14","x":370.5,"y":217.25000381469727,"z":"9592163f.6a6de8","wires":[["c5f14d8f.3a0eb"]]},{"id":"c5f14d8f.3a0eb","type":"function","name":"Set Controller 2","func":"msg.controller = 2\n\nreturn msg;","outputs":1,"noerr":0,"x":597.5000076293945,"y":218.750018119812,"z":"9592163f.6a6de8","wires":[["ebcef3df.14311"]]},{"id":"56b9f6ab.a94608","type":"file in","name":"read store for next ids","filename":"mysids.dump","format":"utf8","x":346,"y":97,"z":"9592163f.6a6de8","wires":[["57db23d6.a824dc"]]},{"id":"e000bd09.1fff4","type":"debug","name":"Debug","active":true,"console":"false","complete":"true","x":785,"y":470,"z":"9592163f.6a6de8","wires":[]},{"id":"57db23d6.a824dc","type":"function","name":"store to context.global.mysnextid","func":"if (msg.payload === undefined) {\n          var mysnextid = {};\n\n        obj = mysnextid;  \n}\nelse \n{\ntry{\n        obj = JSON.parse(msg.payload);\n    }\n    catch(e){\n        \n        var mysnextid = {};\n\n        obj = mysnextid;\n        \n    }\n}    \n\ncontext.global.mysnextid = obj;\n\nmsg.payload = context.global.mysnextid;\n\nreturn msg;","outputs":1,"noerr":0,"x":591,"y":96,"z":"9592163f.6a6de8","wires":[[]]},{"id":"dfba7d69.20458","type":"file","name":"dump mysids","filename":"mysids.dump","appendNewline":true,"createDir":false,"overwriteFile":"true","x":1434,"y":375,"z":"9592163f.6a6de8","wires":[]},{"id":"25efb0d3.da105","type":"inject","name":"Test Backup","topic":"","payload":"","payloadType":"none","repeat":"","crontab":"","once":false,"x":209,"y":456,"z":"9592163f.6a6de8","wires":[["e7d998a7.182668"]]},{"id":"e7d998a7.182668","type":"function","name":"Show context.global.mysnextid","func":"msg.payload = JSON.stringify(context.global.mysnextid);\n\nreturn msg;","outputs":1,"noerr":0,"x":427,"y":453,"z":"9592163f.6a6de8","wires":[["e000bd09.1fff4"]]},{"id":"e0e76d62.1f189","type":"function","name":"handle nextids","func":"// increase nextid, if nodeid >= nextid \n\nif (msg.nodeid < 255)\n{\n    if (context.global.mysnextid[msg.controller] === undefined) {\n        context.global.mysnextid[msg.controller] = msg.nodeid+1;\n    }\n    \n    if (msg.nodeid >= context.global.mysnextid[msg.controller]) {\n       context.global.mysnextid[msg.controller] = msg.nodeid+1; \n    }\n    \n}\n\nreturn msg;","outputs":1,"noerr":0,"x":1223,"y":368,"z":"9592163f.6a6de8","wires":[["dfba7d69.20458"]]},{"id":"a7d335f6.582cc8","type":"inject","name":"Test GetNodeId","topic":"","payload":"255;0;3;0;3;","payloadType":"string","repeat":"","crontab":"","once":false,"x":456,"y":264,"z":"9592163f.6a6de8","wires":[["c5f14d8f.3a0eb"]]}]
      
      

      Features:

      • Publish states to mqtt
      • handle node-ids
      • support multiple ethernet conrollers
      • should be adoptable to serial controllers

      Restrictions:

      • read only, no values can be sent to nodes
      • you will find others 🙂
      posted in Node-RED
      FotoFieber
    • RE: German speaking members

      👍👍

      posted in General Discussion
      FotoFieber
    • Many nodes with simple sketches or less nodes with complex sketches?

      Nodes are quite cheap and why not use one node per function? On the other side, you can save many nodes, if you implement multiple functions in one node.

      What do you prefer?

      Why?

      What are the cons and pros?

      posted in General Discussion
      FotoFieber
    • Motion Sensor Recycled based on minimalistic PCB arduino design

      Take an old motion sensor:
      IMG_0795.JPG
      Remove existing PCB:
      IMG_0794.JPG
      Insert mysensors technology:
      IMG_0797.JPG
      With more skills, it would look nicer:
      IMG_0796.JPG

      Sketch:

      #include <SPI.h>
      #include <MySensor.h>
      
      
      unsigned long SLEEP_TIME = 7200000; // Sleep time between reports (in milliseconds)
      unsigned long SLEEP_TIME_AFTER_MOTION = 30000; // Forced Sleep after motion report
      
      
      
      
      #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
      #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
      #define CHILD_ID 1   // Id of the sensor child
      
      boolean interrupted = false;
      int batteryRound = 0;
      
      #define BATTERY_ROUNDS 20
      
      
      MySensor gw;
      // Initialize motion message
      MyMessage msg(CHILD_ID, V_TRIPPED);
      
      
      void setup()
      {
        //switchClock(1<<CLKPS2);
        delay(1000);
      
        gw.begin();
      
        // Send the sketch version information to the gateway and Controller
        gw.sendSketchInfo("Motion Sensor VC Int", "1.2");
      
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
        // Register all sensors to gw (they will be created as child devices)
        gw.present(CHILD_ID, S_MOTION);
      
      
        gw.sleep(1000);
      
      }
      
      void loop()
      {
      
        
        // Read digital motion value
        boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
        gw.send(msg.set(tripped ? "1" : "0")); // Send tripped value to gw
      
        batteryRound++;
      
        if ((interrupted == false) || // wake up from timer?
            (batteryRound >= BATTERY_ROUNDS) )
        {
          batteryRound = 0;
          // measure battery state
          long sensorValue = readVcc();
      
          // 100 -> 3000, 0 -> 2000
          if (sensorValue < 2000)
          {
            sensorValue = 0;
          }
          else
          {
            sensorValue -= 2000;
          }
      
      
          int batteryPcnt = (int)((float)(sensorValue) / 10.0);
      
          if (batteryPcnt > 100) batteryPcnt = 100;
          
          gw.sleep(1000);
      
          gw.sendBatteryLevel(batteryPcnt);
        }
        ;
      
      
      
        if (tripped == true) {
          // take a brake and do not report motion for some time
          interrupted = true;  // don't send vcc after short sleep
          gw.sleep(SLEEP_TIME_AFTER_MOTION);
        }
        // Sleep until interrupt comes in on motion sensor
        else interrupted = gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME);
      
      }
      
      
      
      // see http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
      long readVcc() {
        // Read 1.1V reference against AVcc
        // set the reference to Vcc and the measurement to the internal 1.1V reference
      #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
        ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
        ADMUX = _BV(MUX5) | _BV(MUX0);
      #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
        ADMUX = _BV(MUX3) | _BV(MUX2);
      #else
        ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      #endif
      
        delay(2); // Wait for Vref to settle
        ADCSRA |= _BV(ADSC); // Start conversion
        while (bit_is_set(ADCSRA, ADSC)); // measuring
      
        uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
        uint8_t high = ADCH; // unlocks both
      
        long result = (high << 8) | low;
      
        result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
        return result; // Vcc in millivolts
      }
      
      void switchClock(unsigned char clk)
      {
        cli();
      
        CLKPR = 1 << CLKPCE; // Set CLKPCE to enable clk switching
        CLKPR = clk;
        sei();
      }
      
      
      
      
      
      

      Minimalistic PCB (self designed with fritzing):
      mysduino2.fzz

      https://oshpark.com/shared_projects/mcUfoUxu

      The PCB has a flexible design (use jumpers):

      • use with battery (used here)
      • use with 5 volt (and LE33 for NRF24L01+)
      • use with voltage stabilazitaion to 3.3V (LE33) for ATMEGA328P and NRF24l01+
      posted in My Project
      FotoFieber
    • RE: Question concerning low voltage arduino Pro mini

      The 328P is working with
      8 MHz in the range of +2.7 - +5.5 V

      I do program all my arduinos with 5V.

      Detach the NRF24L01+ and other 3.3V sensors or they may die while you attach 5V.

      Use at your own risk. 🙂

      posted in General Discussion
      FotoFieber
    • RE: MQTT Request from a node

      Please try again. Lesson learned: Don't answer posts on holiday with a tablet... 👍

      posted in Feature Requests
      FotoFieber
    • RE: MQTT Request from a node

      It is a prototype and not finished yet.

      I use a namespace for the different technologies for the MQTT Topic:
      MyMQTT for MySensors
      Netatmo for netatmo devices
      homegear for Homematic
      nodered for messages generated fom node-red
      openHAB for the openHAB eventbus

      Most of the wiring is defined in a hashtable. As this is more of a hack, I want to clean it up before I publish it.

      Here an example for an RGB Led (MySensors) wired to openhab colorpicker and a homematic wall switch. Note: the wiring is bidirectional, I see the RGB Color in openHAB of the MySensors LED independent of the method I used to set it and openHAB doesn't know anything about Homematic or MySensors. I can evan add another UI (openHAB 2?) and other switches (MySensors Motion or Lux nodes) and everything would be in sync.

      [{"id":"ba386057.845d3","type":"mqtt-broker","broker":"192.168.92.4","port":"1883","clientid":"NodeRed"},{"id":"c1a0dd11.3e5f2","type":"mqtt in","name":"RGB Colorpicker","topic":"openHAB/out/RGBLight/command","broker":"ba386057.845d3","x":152.33332061767578,"y":179.66666412353516,"z":"914d079b.6eb2f8","wires":[["46c3882f.b93c78","c1246f87.3edb9"]]},{"id":"1ab94043.e546c","type":"mqtt out","name":"MyRGBLed","topic":"MyMQTT/30/1/S_LIGHT_LEVEL","qos":"","retain":"","broker":"ba386057.845d3","x":617.3333231608073,"y":98.66666412353516,"z":"914d079b.6eb2f8","wires":[]},{"id":"46c3882f.b93c78","type":"function","name":"HSV convert","func":"if (msg.payload == 'OFF') {\n    msg.payload = 'RGB 0,0,0';\n    return msg;\n} \n\nif (msg.payload == 'ON') {\n    msg.payload = 'RGB 255,255,255';\n    return msg;\n} \n\n\nvar res = msg.payload.split(\",\");\n\nh = res[0];\ns = res[1];\nv = res[2];\n\nvar r, g, b;\n\tvar i;\n\tvar f, p, q, t;\n \n\t// Make sure our arguments stay in-range\n\th = Math.max(0, Math.min(360, h));\n\ts = Math.max(0, Math.min(100, s));\n\tv = Math.max(0, Math.min(100, v));\n \n\t// We accept saturation and value arguments from 0 to 100 because that's\n\t// how Photoshop represents those values. Internally, however, the\n\t// saturation and value are calculated from a range of 0 to 1. We make\n\t// That conversion here.\n\ts /= 100;\n\tv /= 100;\n \n\tif(s == 0) {\n\t\t// Achromatic (grey)\n\t\tr = g = b = v;\n\t\t\n\t} else\n\t{\n \n\th /= 60; // sector 0 to 5\n\ti = Math.floor(h);\n\tf = h - i; // factorial part of h\n\tp = v * (1 - s);\n\tq = v * (1 - s * f);\n\tt = v * (1 - s * (1 - f));\n \n\tswitch(i) {\n\t\tcase 0:\n\t\t\tr = v;\n\t\t\tg = t;\n\t\t\tb = p;\n\t\t\tbreak;\n \n\t\tcase 1:\n\t\t\tr = q;\n\t\t\tg = v;\n\t\t\tb = p;\n\t\t\tbreak;\n \n\t\tcase 2:\n\t\t\tr = p;\n\t\t\tg = v;\n\t\t\tb = t;\n\t\t\tbreak;\n \n\t\tcase 3:\n\t\t\tr = p;\n\t\t\tg = q;\n\t\t\tb = v;\n\t\t\tbreak;\n \n\t\tcase 4:\n\t\t\tr = t;\n\t\t\tg = p;\n\t\t\tb = v;\n\t\t\tbreak;\n \n\t\tdefault: // case 5:\n\t\t\tr = v;\n\t\t\tg = p;\n\t\t\tb = q;\n\t}\n\t\n\t}\n\tr = Math.round(r * 255);\n\tg = Math.round(g * 255);\n\tb = Math.round(b * 255);\n\t\n    //var erg = {hue:h,saturation:s,value:v, red:r, green:g, blue:b};\n    \n    msg.payload = 'RGB ' + r + ',' + g + ',' + b;\n\n\n\n\nreturn msg;","outputs":1,"valid":true,"x":395.3333231608073,"y":126.66666412353516,"z":"914d079b.6eb2f8","wires":[["1ab94043.e546c","c1246f87.3edb9"]]},{"id":"c1246f87.3edb9","type":"debug","name":"","active":true,"console":"false","complete":"false","x":621.3333129882812,"y":255.6666488647461,"z":"914d079b.6eb2f8","wires":[]},{"id":"e8effb31.171008","type":"mqtt in","name":"RGBLED Returncode Lichwert","topic":"MyMQTT/30/2/V_LIGHT_LEVEL","broker":"ba386057.845d3","x":195.99996948242188,"y":240.66665649414062,"z":"914d079b.6eb2f8","wires":[["a5d4d602.5a2b28"]]},{"id":"a5d4d602.5a2b28","type":"function","name":"RGB to HSV","func":"b = msg.payload % 256 ;\ng = ((msg.payload - b) / 256) % 256;\nr = (msg.payload - b - g*256) / 256 / 256;\n\n\t\n    r = r/255, g = g/255, b = b/255;\n    var max = Math.max(r, g, b), min = Math.min(r, g, b);\n    var h, s, v = max;\n\n    var d = max - min;\n    s = max == 0 ? 0 : d / max;\n\n    if(max == min){\n        h = 0; // achromatic\n    }else{\n        switch(max){\n            case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n            case g: h = (b - r) / d + 2; break;\n            case b: h = (r - g) / d + 4; break;\n        }\n        h /= 6;\n    }\n\n    h *=360;\n    s*=100;\n    v*=100;\n\n\t\n// var erg = {hue:h,saturation:s,value:v, red:r, green:g, blue:b};\n    \nmsg.payload = h + ',' + s + ',' + v;\n\n\nreturn msg;","outputs":1,"valid":true,"x":505.3333231608073,"y":343.66666412353516,"z":"914d079b.6eb2f8","wires":[["c1246f87.3edb9","792d7484.86d28c"]]},{"id":"792d7484.86d28c","type":"mqtt out","name":"RGB in Openhab setzen","topic":"openHAB/in/RGBLight/state","qos":"","retain":"","broker":"ba386057.845d3","x":736.3333231608073,"y":339.66666412353516,"z":"914d079b.6eb2f8","wires":[]},{"id":"85a991b0.7a567","type":"mqtt in","name":"Laura Fernbedienung","topic":"homegear/1234-5678-9abc/event/10/#","broker":"ba386057.845d3","x":129,"y":36,"z":"914d079b.6eb2f8","wires":[["e913dcc9.16ec2","c1246f87.3edb9"]]},{"id":"e913dcc9.16ec2","type":"function","name":"Fernbedienung auf RGB Licht","func":"if (msg.payload != '[true]') return;\n\n\nif (msg.topic == 'homegear/1234-5678-9abc/event/10/1/PRESS_SHORT') {\n    msg.payload ='OFF';    \n} \nelse if (msg.topic == 'homegear/1234-5678-9abc/event/10/2/PRESS_SHORT') {\n    msg.payload = 'RGB 255,187,0';\n}\nelse if (msg.topic == 'homegear/1234-5678-9abc/event/10/3/PRESS_SHORT') {\n    msg.payload = 'RGB 255,0,0';\n}\nelse if (msg.topic == 'homegear/1234-5678-9abc/event/10/4/PRESS_SHORT') {\n    msg.payload = 'RGB 255,6,226';\n}\nelse if (msg.topic == 'homegear/1234-5678-9abc/event/10/5/PRESS_SHORT') {\n    msg.payload = 'RGB 177,10,255';\n}\nelse if (msg.topic == 'homegear/1234-5678-9abc/event/10/6/PRESS_SHORT') {\n    msg.payload = 'RGB 0,255,0';\n}\n\nreturn msg;","outputs":1,"valid":true,"x":388,"y":57,"z":"914d079b.6eb2f8","wires":[["1ab94043.e546c","c1246f87.3edb9"]]}]
      
      posted in Feature Requests
      FotoFieber
    • RE: MQTT Request from a node

      On my pi2 I have installed node-red and do all the 'wiring' of messages between different nodes there. Maybe this could be a solution for you too.

      posted in Feature Requests
      FotoFieber
    • RE: Node-Red as Controller

      Here is my setup:

      • MyMQTT Client Gateway, OpenHAB, HomeMatic and node-red all connected to mosquitto
      • OpenHab configured to expose the internal bus to mosquitto
      • All glued together with node-red: the OpenHab Items have no mqtt binding, all messages are exchanged via the OpenHab internal bus.
      • Messages from any sensors are transformed in node-red to the destination (topic and payload)

      The advantage of this setup is:

      • OpenHab is only the GUI and doesn't need to know anything about the sensors
      • I can exchange any sensor/actuator without any change in OpenHab. I can even change from a netatmo device to a mysensor device or vice versa.

      I was thinking about replacing the MyMQTT Client Gateway with a Serial Gateway and node-red, but the gateway is stable since weeks.... never touch a running system. This would solve my biggest concern with the MyMQTT Client Gateway: it doesn't support encryption....

      posted in Node-RED
      FotoFieber
    • RE: MQTT Client gateway

      Added support for:

      • sketchinfo
      • sketchversion
      • time
      • batterylevel
      • dallas RTC and message to set time from outside

      https://github.com/FotoFieber/MySensors/tree/mqttclient/libraries/MySensors/examples/MQTTClientGateway

      posted in Development
      FotoFieber