Martin's corner on the web

Duck DNS updater in Node-RED

Dyn and No-IP have been for long time my choice for dynamic DNS, but both have recently made steps towards commercializing their services and implementing monthly confirmation process. I think it is time for me to move away and look for alternative. DuckDNS seems to be exactly what I was looking for, easy to use, reliable and most important – free. They support a number of devices already, but I wanted to implement my updater in Node-RED. The reason for this is so that I can keep all of my setup in one packaged environment for ease of management/transfer.

Here is my Node-RED flow to update DuckDNS, the flow was heavily influenced from Paul’s No-Ip updater:

duckdns

 

[
  {
    "id": "a34035d4.5cbfc8",
    "type": "inject",
    "name": "Every 30 minutes",
    "topic": "",
    "payload": "",
    "payloadType": "none",
    "repeat": "1800",
    "crontab": "",
    "once": true,
    "x": 149,
    "y": 55,
    "z": "f810b109.07ef5",
    "wires": [
      [
        "83464437.7cb9b8"
      ]
    ]
  },
  {
    "id": "e06ab7d2.1f9548",
    "type": "http request",
    "name": "Update DuckDNS",
    "method": "GET",
    "url": "https://www.duckdns.org/update?domains=****YOUR-DOMAIN****&token=***YOUR-TOKEN****&ip=",
    "x": 335,
    "y": 273,
    "z": "f810b109.07ef5",
    "wires": [
      [
        "38e88442.c7177c"
      ]
    ]
  },
  {
    "id": "38e88442.c7177c",
    "type": "switch",
    "name": "Was update sucessful?",
    "property": "payload",
    "rules": [
      {
        "t": "eq",
        "v": "OK"
      },
      {
        "t": "neq",
        "v": "OK"
      }
    ],
    "checkall": "true",
    "outputs": 2,
    "x": 316,
    "y": 325,
    "z": "f810b109.07ef5",
    "wires": [
      [
        "78932790.876cd8"
      ],
      [
        "efc4308c.103bd",
        "b78d5573.4872a8"
      ]
    ]
  },
  {
    "id": "ae6e141.f5191e8",
    "type": "delay",
    "name": "One notification/day",
    "pauseType": "rate",
    "timeout": "5",
    "timeoutUnits": "seconds",
    "rate": "1",
    "rateUnits": "day",
    "randomFirst": "1",
    "randomLast": "5",
    "randomUnits": "seconds",
    "drop": true,
    "x": 322,
    "y": 448,
    "z": "f810b109.07ef5",
    "wires": [
      [
        "fb043e44.04fbc"
      ]
    ]
  },
  {
    "id": "fb043e44.04fbc",
    "type": "pushbullet",
    "title": "DuckDNS update failed",
    "name": "DuckDNS update failed",
    "x": 315,
    "y": 502,
    "z": "f810b109.07ef5",
    "wires": []
  },
  {
    "id": "3b8d48f5.c472b8",
    "type": "comment",
    "name": "No",
    "info": "",
    "x": 70,
    "y": 398,
    "z": "f810b109.07ef5",
    "wires": []
  },
  {
    "id": "f16adf9d.0e952",
    "type": "comment",
    "name": "Yes?",
    "info": "",
    "x": 530,
    "y": 320,
    "z": "f810b109.07ef5",
    "wires": []
  },
  {
    "id": "efc4308c.103bd",
    "type": "debug",
    "name": "",
    "active": false,
    "console": false,
    "complete": false,
    "x": 99,
    "y": 444,
    "z": "f810b109.07ef5",
    "wires": []
  },
  {
    "id": "78932790.876cd8",
    "type": "function",
    "name": "Reset fail counter",
    "func": "context.duckdnsfails=0;\nreturn msg;\n",
    "outputs": "0",
    "x": 716,
    "y": 320,
    "z": "f810b109.07ef5",
    "wires": []
  },
  {
    "id": "b78d5573.4872a8",
    "type": "function",
    "name": "Increment fail counter, check if >5",
    "func": "duckdnsfails = context.duckdnsfails || 0;\nduckdnsfails++;\ncontext.duckdnsfails = duckdnsfails;\n\n//Fsiled to update 5+ times?\nif(duckdnsfails <=6) {\n\treturn [msg,null];\n}\nelse {\n    //shout out last known IP\n    msg.payload=context.lastip;\n\treturn [null,msg];\n}",
    "outputs": "2",
    "x": 283,
    "y": 400,
    "z": "f810b109.07ef5",
    "wires": [
      [],
      [
        "ae6e141.f5191e8"
      ]
    ]
  },
  {
    "id": "dd239510.22dc68",
    "type": "function",
    "name": "Has IP Changed?",
    "func": "context.lastip = context.lastip || 'initial';\nvar currentip = msg.payload;\n\nif (context.lastip == 'initial') {\ncontext.lastip = currentip;\n}\nelse if (context.lastip != currentip) {\nmsg.payload = currentip;\ncontext.lastip = currentip;\nreturn msg;\n}\n\n",
    "outputs": "1",
    "x": 327,
    "y": 224.5,
    "z": "f810b109.07ef5",
    "wires": [
      [
        "e06ab7d2.1f9548"
      ]
    ]
  },
  {
    "id": "83464437.7cb9b8",
    "type": "exec",
    "command": "wget -qO- http://bot.whatismyipaddress.com/ ; echo",
    "append": "",
    "useSpawn": "",
    "name": "Check my IP - whatismyipaddress.com",
    "x": 266,
    "y": 119.5,
    "z": "f810b109.07ef5",
    "wires": [
      [
        "652e3ea5.9ad1c"
      ],
      [],
      []
    ]
  },
  {
    "id": "652e3ea5.9ad1c",
    "type": "switch",
    "name": "Integrity check",
    "property": "payload",
    "rules": [
      {
        "t": "regex",
        "v": "\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"
      },
      {
        "t": "else"
      }
    ],
    "checkall": "true",
    "outputs": 2,
    "x": 340,
    "y": 173.5,
    "z": "f810b109.07ef5",
    "wires": [
      [
        "dd239510.22dc68"
      ],
      []
    ]
  }
]

 

 

One thought on “Duck DNS updater in Node-RED

  1. Pingback: Monitoring my home automation system uptime | Martin's corner on the web