Photovoltaik Werte einer Kostal Piko in Node-Red

Hier ist ein „Flow“, um die Werte eines Photovoltaik-Inverters von Kostal per Node-Red auszulesen und zusätzlich als MQTT-Nachrichten zu versenden.

Der Hintergrund ist, dass die Anlage nicht per SNMP oder ähnlich gängigen Verfahren auszulesen war, sondern nur über eine Webseite die Werte anzeigte. Zwar gibt es eine Software, aber die hat meine Wünsche nicht wirklich erfüllt.

Mit diesem Flow ist es möglich, die aktuelle Leistung einer PV-Anlage aktiv alle z.B. 20 Sekunden abzufragen, und die gelieferten Werte als Diagramm im Dashboard darzustellen.

Node-Red Flow
Node-Red Flow

Zur Langzeitvisualisierung versende ich die Werte zusätzlich an ein weiteres System (Zabbix). Das sieht dann so aus:

Zabbix Visualisierung

Und hier kommt der „Flow“-Code:

[
{
"id": "347111747d6d4c72",
"type": "tab",
"label": "Kostal Pico",
"disabled": false,
"info": "",
"env": []
},
{
"id": "4ad0e46.7796d1c",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse http",
"func": "acPowerCurrent = parseInt(msg.payload[14].replace(/([^a-z0-9]+)/gi, ''));\ntotalEnergy = parseInt(msg.payload[17].replace(/([^A-Z0-9]+)/gi, ''));\ndailyEnergy = parseInt(msg.payload[26].replace(/([^a-z0-9]+)/gi, ''))/100;\nstring1voltage = parseInt(msg.payload[56].replace(/([^a-z0-9]+)/gi, ''));\nstring1current = parseInt(msg.payload[65].replace(/([^a-z0-9]+)/gi, ''))/100;\nstring2voltage = parseInt(msg.payload[82].replace(/([^a-z0-9]+)/gi, ''));\nstring2current = parseInt(msg.payload[91].replace(/([^a-z0-9]+)/gi, ''))/100;\nline1voltage = parseInt(msg.payload[59].replace(/([^a-z0-9]+)/gi, ''));\nline1power = parseInt(msg.payload[68].replace(/([^a-z0-9]+)/gi, ''));\nline2voltage = parseInt(msg.payload[85].replace(/([^a-z0-9]+)/gi, ''));\nline2power = parseInt(msg.payload[94].replace(/([^a-z0-9]+)/gi, ''));\nline3voltage = parseInt(msg.payload[111].replace(/([^a-z0-9]+)/gi, ''));\nline3power = parseInt(msg.payload[120].replace(/([^a-z0-9]+)/gi, ''));\nstatus = msg.payload[32].replace(/\r?\n|\r/g, '').replace(/\s/g, \"\");\n\n\nif (Number.isNaN(acPowerCurrent) === true){\n acPowerCurrent = 0;\n}\nif (Number.isNaN(totalEnergy) === true){\n totalEnergy = -1;\n}\nif (Number.isNaN(dailyEnergy) === true){\n dailyEnergy = 0;\n}\nif (Number.isNaN(string1voltage) === true){\n string1voltage = 0;\n}\nif (Number.isNaN(string1current) === true){\n string1current = 0;\n}\nif (Number.isNaN(string2voltage) === true){\n string2voltage = 0;\n}\nif (Number.isNaN(string2current) === true){\n string2current = 0;\n}\nif (Number.isNaN(line1voltage) === true){\n line1voltage = 0;\n}\nif (Number.isNaN(line1power) === true){\n line1power = 0;\n}\nif (Number.isNaN(line2voltage) === true){\n line2voltage = 0;\n}\nif (Number.isNaN(line2power) === true){\n line2power = 0;\n}\nif (Number.isNaN(line3voltage) === true){\n line3voltage = 0;\n}\nif (Number.isNaN(line3power) === true){\n line3power = 0;\n}\n\nmsg.payload = {\n \"acPowerCurrent\" : acPowerCurrent,\n \"totalEnergy\" : totalEnergy,\n \"dailyEnergy\" : dailyEnergy,\n \"status\" : status,\n \"string1voltage\" : string1voltage,\n \"string1current\" : string1current,\n \"string2voltage\" : string2voltage,\n \"string2current\" : string2current,\n \"line1voltage\" : line1voltage,\n \"line1power\" : line1power,\n \"line2voltage\" : line2voltage,\n \"line2power\" : line2power,\n \"line3voltage\" : line3voltage,\n \"line3power\" : line3power\n}\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 590,
"y": 40,
"wires": [
[
"34e425ddfbd52922",
"851d74df4b8af250",
"a0f4b6bc546a5feb",
"6f7347f07dbaddbc",
"debfb65e018929b6",
"796c0ba818f32273",
"4d2581af083ac9fa",
"f83bdf7d776677fd",
"bb682b4f55ea5261",
"0fc320415691c33b",
"c242a15391c6e138",
"cb1f12452ef3f638",
"b1ccbcd5cf01096d"
]
]
},
{
"id": "fd1711f2.7e7b4",
"type": "http request",
"z": "347111747d6d4c72",
"name": "kostal",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
"url": "http://192.168.1.2/index.fhtml",
"tls": "",
"persist": false,
"proxy": "",
"authType": "basic",
"senderr": false,
"credentials": {},
"x": 260,
"y": 40,
"wires": [
[
"3f445786.6a93b8"
]
]
},
{
"id": "3f445786.6a93b8",
"type": "html",
"z": "347111747d6d4c72",
"name": "",
"property": "payload",
"outproperty": "payload",
"tag": "td",
"ret": "text",
"as": "single",
"x": 410,
"y": 40,
"wires": [
[
"4ad0e46.7796d1c",
"f3549090d79f4c9c",
"ac418f3bb6f53c8c",
"e40d0ff0542d8491",
"eb1ef10bd2d98a04",
"aa0fd29746e7f82d",
"6bc46f3e373ea374",
"01fd97e66dd1e7ed",
"49d7fbfce0853df5",
"b749aec74297da98",
"1f90685264d36a3b",
"32d7bb0afd1faeb5",
"37e5e4eb0f275f2d",
"4ec5b28516254e78"
]
]
},
{
"id": "b32e7821.c1dc78",
"type": "inject",
"z": "347111747d6d4c72",
"name": "20 sec",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 90,
"y": 40,
"wires": [
[
"fd1711f2.7e7b4"
]
]
},
{
"id": "bf48b05b907a3b46",
"type": "debug",
"z": "347111747d6d4c72",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 270,
"y": 100,
"wires": []
},
{
"id": "34e425ddfbd52922",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "c8c536ef38e613a8",
"order": 3,
"width": 0,
"height": 0,
"name": "",
"label": "GesamtEnergie",
"format": "{{msg.payload.totalEnergy}}",
"layout": "row-spread",
"className": "",
"x": 1080,
"y": 40,
"wires": []
},
{
"id": "851d74df4b8af250",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "c8c536ef38e613a8",
"order": 5,
"width": 0,
"height": 0,
"name": "",
"label": "aktuelle AC-Leistung",
"format": "{{msg.payload.acPowerCurrent}}",
"layout": "row-spread",
"className": "",
"x": 1100,
"y": 120,
"wires": []
},
{
"id": "cb1f12452ef3f638",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "c8c536ef38e613a8",
"order": 4,
"width": 0,
"height": 0,
"name": "",
"label": "TagesEnergie",
"format": "{{msg.payload.dailyEnergy}}",
"layout": "row-spread",
"className": "",
"x": 1070,
"y": 80,
"wires": []
},
{
"id": "a0f4b6bc546a5feb",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "0816668bf0491bd9",
"order": 1,
"width": 0,
"height": 0,
"name": "",
"label": "string1voltage",
"format": "{{msg.payload.string1voltage}}",
"layout": "row-spread",
"className": "",
"x": 1080,
"y": 160,
"wires": []
},
{
"id": "debfb65e018929b6",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "0816668bf0491bd9",
"order": 3,
"width": 0,
"height": 0,
"name": "",
"label": "string2voltage",
"format": "{{msg.payload.string2voltage}}",
"layout": "row-spread",
"className": "",
"x": 1080,
"y": 240,
"wires": []
},
{
"id": "6f7347f07dbaddbc",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "0816668bf0491bd9",
"order": 2,
"width": 0,
"height": 0,
"name": "",
"label": "string1current",
"format": "{{msg.payload.string1current}}",
"layout": "row-spread",
"className": "",
"x": 1080,
"y": 200,
"wires": []
},
{
"id": "796c0ba818f32273",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "0816668bf0491bd9",
"order": 4,
"width": 0,
"height": 0,
"name": "",
"label": "string2current",
"format": "{{msg.payload.string2current}}",
"layout": "row-spread",
"className": "",
"x": 1080,
"y": 280,
"wires": []
},
{
"id": "b1ccbcd5cf01096d",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "2e650c287c8977c6",
"order": 1,
"width": 0,
"height": 0,
"name": "",
"label": "line1voltage",
"format": "{{msg.payload.line1voltage}}",
"layout": "row-spread",
"className": "",
"x": 1070,
"y": 320,
"wires": []
},
{
"id": "f83bdf7d776677fd",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "2e650c287c8977c6",
"order": 3,
"width": 0,
"height": 0,
"name": "",
"label": "line2voltage",
"format": "{{msg.payload.line2voltage}}",
"layout": "row-spread",
"className": "",
"x": 1070,
"y": 400,
"wires": []
},
{
"id": "4d2581af083ac9fa",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "2e650c287c8977c6",
"order": 2,
"width": 0,
"height": 0,
"name": "",
"label": "line1power",
"format": "{{msg.payload.line1power}}",
"layout": "row-spread",
"className": "",
"x": 1070,
"y": 360,
"wires": []
},
{
"id": "bb682b4f55ea5261",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "2e650c287c8977c6",
"order": 4,
"width": 0,
"height": 0,
"name": "",
"label": "line2power",
"format": "{{msg.payload.line2power}}",
"layout": "row-spread",
"className": "",
"x": 1070,
"y": 440,
"wires": []
},
{
"id": "0fc320415691c33b",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "2e650c287c8977c6",
"order": 5,
"width": 0,
"height": 0,
"name": "",
"label": "line3voltage",
"format": "{{msg.payload.line3voltage}}",
"layout": "row-spread",
"className": "",
"x": 1070,
"y": 480,
"wires": []
},
{
"id": "c242a15391c6e138",
"type": "ui_text",
"z": "347111747d6d4c72",
"group": "2e650c287c8977c6",
"order": 6,
"width": 0,
"height": 0,
"name": "",
"label": "line3power",
"format": "{{msg.payload.line3power}}",
"layout": "row-spread",
"className": "",
"x": 1070,
"y": 520,
"wires": []
},
{
"id": "9e8331d8f24e5508",
"type": "ui_chart",
"z": "347111747d6d4c72",
"name": "",
"group": "c8c536ef38e613a8",
"order": 2,
"width": 0,
"height": 0,
"label": "TagesEnergie",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "",
"ymax": "",
"removeOlder": "12",
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"useUTC": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"useDifferentColor": false,
"className": "",
"x": 830,
"y": 180,
"wires": [
[]
]
},
{
"id": "060a6f4f7709d212",
"type": "ui_chart",
"z": "347111747d6d4c72",
"name": "",
"group": "c8c536ef38e613a8",
"order": 1,
"width": 0,
"height": 0,
"label": "GesamtEnergie",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "",
"ymax": "",
"removeOlder": 1,
"removeOlderPoints": "",
"removeOlderUnit": "604800",
"cutout": 0,
"useOneColor": false,
"useUTC": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"useDifferentColor": false,
"className": "",
"x": 840,
"y": 140,
"wires": [
[]
]
},
{
"id": "f3549090d79f4c9c",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse totalEnergy",
"func": "totalEnergy = parseInt(msg.payload[17].replace(/([^A-Z0-9]+)/gi, ''));\n\n\nif (Number.isNaN(totalEnergy) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = totalEnergy\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 260,
"wires": [
[
"060a6f4f7709d212",
"5d7fd7bd61272bf3"
]
]
},
{
"id": "ac418f3bb6f53c8c",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse dailyEnergy",
"func": "dailyEnergy = parseInt(msg.payload[26].replace(/([^a-z0-9]+)/gi, ''))/100;\n\n\nif (Number.isNaN(dailyEnergy) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = dailyEnergy\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 300,
"wires": [
[
"9e8331d8f24e5508",
"b0d1ee8efbccf83c"
]
]
},
{
"id": "e40d0ff0542d8491",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse acPowerCurrent",
"func": "acPowerCurrent = parseInt(msg.payload[14].replace(/([^a-z0-9]+)/gi, ''));\n\n\nif (Number.isNaN(acPowerCurrent) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = acPowerCurrent\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 360,
"y": 340,
"wires": [
[
"6c98dadd8dfa1b2b",
"98b85716012ff0f1"
]
]
},
{
"id": "6c98dadd8dfa1b2b",
"type": "ui_chart",
"z": "347111747d6d4c72",
"name": "",
"group": "c8c536ef38e613a8",
"order": 2,
"width": 0,
"height": 0,
"label": "aktuelle Leistung",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "",
"ymax": "",
"removeOlder": "12",
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"useUTC": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"useDifferentColor": false,
"className": "",
"x": 850,
"y": 220,
"wires": [
[]
]
},
{
"id": "98b85716012ff0f1",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/acPowerCurrent",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 640,
"y": 340,
"wires": []
},
{
"id": "5d7fd7bd61272bf3",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/totalEnergy",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 620,
"y": 260,
"wires": []
},
{
"id": "b0d1ee8efbccf83c",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/dailyEnergy",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 620,
"y": 300,
"wires": []
},
{
"id": "68f495560987754b",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/string1voltage",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 630,
"y": 380,
"wires": []
},
{
"id": "e33e75fdf4b82aac",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/string1current",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 630,
"y": 420,
"wires": []
},
{
"id": "8d9268aef7b8eba8",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/string2voltage",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 630,
"y": 460,
"wires": []
},
{
"id": "960f3f76488c3e98",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/string2current",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 630,
"y": 500,
"wires": []
},
{
"id": "c5ccb0f701055bc1",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/line1voltage",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 630,
"y": 540,
"wires": []
},
{
"id": "f7dad6605a58f5c6",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/line1power",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 620,
"y": 580,
"wires": []
},
{
"id": "7d0a3ec6865e297e",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/line2voltage",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 630,
"y": 620,
"wires": []
},
{
"id": "7f9fed855e70fed7",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/line2power",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 620,
"y": 660,
"wires": []
},
{
"id": "771b4926c3e76ab5",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/line3voltage",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 630,
"y": 700,
"wires": []
},
{
"id": "6b3309a879659da4",
"type": "mqtt out",
"z": "347111747d6d4c72",
"name": "",
"topic": "tele/photovoltaic/line3power",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "634cbb5f.887d54",
"x": 620,
"y": 740,
"wires": []
},
{
"id": "eb1ef10bd2d98a04",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse string1voltage",
"func": "string1voltage = parseInt(msg.payload[56].replace(/([^a-z0-9]+)/gi, ''));\n\n\nif (Number.isNaN(string1voltage) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = string1voltage\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 360,
"y": 380,
"wires": [
[
"68f495560987754b"
]
]
},
{
"id": "aa0fd29746e7f82d",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse string1current",
"func": "string1current = parseInt(msg.payload[65].replace(/([^a-z0-9]+)/gi, ''))/100;\n\n\nif (Number.isNaN(string1current) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = string1current\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 360,
"y": 420,
"wires": [
[
"e33e75fdf4b82aac"
]
]
},
{
"id": "6bc46f3e373ea374",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse string2voltage ",
"func": "string2voltage = parseInt(msg.payload[82].replace(/([^a-z0-9]+)/gi, ''));\n\n\nif (Number.isNaN(string2voltage) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = string2voltage\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 360,
"y": 460,
"wires": [
[
"8d9268aef7b8eba8"
]
]
},
{
"id": "01fd97e66dd1e7ed",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse string2current",
"func": "string2current = parseInt(msg.payload[91].replace(/([^a-z0-9]+)/gi, ''))/100;\n\n\nif (Number.isNaN(string2current) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = string2current\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 360,
"y": 500,
"wires": [
[
"960f3f76488c3e98"
]
]
},
{
"id": "49d7fbfce0853df5",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse line1voltage",
"func": "line1voltage = parseInt(msg.payload[59].replace(/([^a-z0-9]+)/gi, ''));\n\n\nif (Number.isNaN(line1voltage) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = line1voltage\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 540,
"wires": [
[
"c5ccb0f701055bc1"
]
]
},
{
"id": "b749aec74297da98",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse line1power",
"func": "line1power = parseInt(msg.payload[68].replace(/([^a-z0-9]+)/gi, ''));\n\n\nif (Number.isNaN(line1power) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = line1power\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 580,
"wires": [
[
"f7dad6605a58f5c6"
]
]
},
{
"id": "1f90685264d36a3b",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse line2voltage",
"func": "line2voltage = parseInt(msg.payload[85].replace(/([^a-z0-9]+)/gi, ''));\n\n\nif (Number.isNaN(line2voltage) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = line2voltage\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 620,
"wires": [
[
"7d0a3ec6865e297e"
]
]
},
{
"id": "32d7bb0afd1faeb5",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse line2power",
"func": "line2power = parseInt(msg.payload[94].replace(/([^a-z0-9]+)/gi, ''));\n\n\nif (Number.isNaN(line2power) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = line2power\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 660,
"wires": [
[
"7f9fed855e70fed7"
]
]
},
{
"id": "37e5e4eb0f275f2d",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse line3voltage",
"func": "line3voltage = parseInt(msg.payload[111].replace(/([^a-z0-9]+)/gi, ''));\n\n\nif (Number.isNaN(line3voltage) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = line3voltage\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 700,
"wires": [
[
"771b4926c3e76ab5"
]
]
},
{
"id": "4ec5b28516254e78",
"type": "function",
"z": "347111747d6d4c72",
"name": "parse line3power",
"func": "line3power = parseInt(msg.payload[120].replace(/([^a-z0-9]+)/gi, ''));\n\n\nif (Number.isNaN(line3power) === true){\n totalEnergy = -1;\n}\n\n\nmsg.payload = line3power\n\n\nglobal.set(\"kostal\", msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 740,
"wires": [
[
"6b3309a879659da4"
]
]
},
{
"id": "c8c536ef38e613a8",
"type": "ui_group",
"name": "Werte",
"tab": "d3de2ec7ddd38014",
"order": 1,
"disp": true,
"width": "6",
"collapse": false,
"className": ""
},
{
"id": "0816668bf0491bd9",
"type": "ui_group",
"name": "PV-Generator",
"tab": "d3de2ec7ddd38014",
"order": 2,
"disp": true,
"width": "6",
"collapse": false,
"className": ""
},
{
"id": "2e650c287c8977c6",
"type": "ui_group",
"name": "Ausgangsleistung",
"tab": "d3de2ec7ddd38014",
"order": 3,
"disp": true,
"width": "6",
"collapse": false,
"className": ""
},
{
"id": "634cbb5f.887d54",
"type": "mqtt-broker",
"broker": "192.168.1.10",
"port": "1883",
"clientid": "nodeRed",
"autoConnect": true,
"usetls": false,
"protocolVersion": 4,
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"willTopic": "",
"willQos": "0",
"willPayload": ""
},
{
"id": "d3de2ec7ddd38014",
"type": "ui_tab",
"name": "PV-Anlage",
"icon": "dashboard",
"order": 6,
"disabled": false,
"hidden": false
}
]

IPv6-Routing im Telekom-Netz

Bisher bin ich davon ausgegangen, dass die Telekom als ausgewachsener Carrier im Jahr 2018 bereits ausreichend Erfahrung mit IPv6 gesammelt hat. Und dass die Telekom Routing-Fehler in ihrem Netz mittels vorhandener Tools schnell und effizient beheben kann. Weit gefehlt.

Ein Kunde hatte die letzten drei Jahre als Glasfaser Internetanschluss „Company Connect 34MBit“ für 899€/Monat am laufen, inklusive IPv6 Netz in der Größe /48, was auch funktionierte.

Nun kam es dazu, dass der Anschluss zu „DeutschlandLAN Connect IP“ 100Mbit (für knapp 800€/Monat) umgeschaltet wurde. Neue Glasfaser beleuchtet, Router und Netzabschluss ausgetauscht, Routen auf die neue Schnittstelle umgeschaltet. IPv4-Netze sind nach dem Umschalten nach ein paar Minuten da, es scheint alles ok soweit. IPv6 an der WAN-Schnittstelle ist  erreichbar, sieht auch gut aus.

Nebenbei wurden die Firewalls beim Kunden hochgepatcht, weil ein Update verfügbar war.

Nun kam es jedoch, dass interne Rechner nicht mehr per IPv6 ins große weite Netz kamen, pings endeten an der Firewall. Lange doktere ich herum, verfluche die Firewall, die letztendlich unschuldig war. Pings funktionieren von A nach B, von B nach C, aber nie von A nach C. Wobei B die Firewall ist. TCPDump zeigt auch, dass Pakete rausgehen, aber nicht zurück kommen. Ich suche nach dem Fehler, warum die IPv6 Paket an der WAN-Schnittstelle gar nicht erst zu sehen sind,  während Pings, die von der Firewall selbst abgesetzt werden, einwandfrei zurück kommen. Ich bin erstmal ratlos. Von dem /48 Netz nutze ich als Transfernetz zwischen Telekom-Router und der Kunden-Firewall allerdings nur ein /64-Netz. Und genau dieses ist auch erreichbar. Es kann nur noch eine Erklärung für das Phänomen geben: Die Ursache muss extern liegen.

Alles deutet darauf hin, dass nur noch ein /64 geroutet wird, die Firewall ist außen erreichbar, nicht jedoch dahinter liegende Netze. Anruf bei der Telekom Business-Hotline. Der Mitarbeiter bestätigt, dass irgendetwas faul ist, ich soll den Fall per Email schildern. Schreibe Email an die Telekom mit detaillierter Beschreibung.

Sehr geehrte Damen und Herren,

wir bitten um Überprüfung der IPv6-Konnektivität auf dem /48-Netz [2003:58:802A:0:0:0:0:0].
Seit Umstellung der Leitung auf DeutschlandLAN Connect IP kann nur noch das /64 Netz (z.B. [2003:58:802A::8] erreicht werden. „Dahinter“ liegende Netze werden ab Router [2003:0:8400:e800::1] nicht weiter geleitet.
Zum Testen läuft IP:[2003:58:802A:2:250:56af:fea7:8e7c], welcher per ICMPv6 erreichbar sein sollte.

Es folgt gegen 17:30 Uhr ein Anruf der Business-Hotline. Der Mitarbeiter gibt zu Wort, dass das Problem in der Tat so bestätigt werden kann. Leider könne er die Routen derzeit nicht korrigieren, da die benötigten Tools (noch) nicht zu Verfügung ständen. Wir sollten eine Änderungsauftrag über den entsprechenden Vertriebsmitarbeiter eingeben.

Ich schicke die Email mit erweiterter Erklärung an unseren Vertrieb’ler und seinen Mitarbeiter im Office. Mir schwant schon, dass das eine längere Sache wird, da ich von Vertrieb’lern bisher wenig zufriedenstellende Antworten bekommen habe. Die Antwort kommt prompt in Form einer fehladressierten Emaill, die eigentlich an den Vertrieb’er gehen sollte:

Hallo Cheffe,

ist dir bekannt, was hier zu tun ist?
So ein Thema hatte ich noch nicht.

Da IPv6 glücklicherweise nicht geschäftskritisch ist und die IPv4-Netze funktionieren, lasse ich dem Vertrieb freundliche drei Tage Zeit, bis ich per Anruf nachharke. Der Vertriebsmitarbeiter, hörbar bemüht, möchte seinerseits nachharken. Mich erreicht eine Information, die „IP-Adressänderung sei über den Innendienst angewiesen“.
<zyn on>Wie ab die doch gehen.<zyn off>

Fünf Tage später ist alles noch beim Alten. Zur Abwechslung rufe ich wieder die Business-Hotline an. Die Dame am andere Ende der Leitung ruft sich den Fall auf und entscheidet sofort, die Angelegenheit an ihren Kollegen weitergeben zu müssen, er wird sind melden.
Am nächsten Tag erreicht mich morgens folgende Email:

bei der Übernahme von Company Connect (CoCo) auf Deutschland LAN IP (DCIP) ist auf dem RD eine statische Route vergessen worden.
Diese Route wurde nun im RD-Profil zugefügt.

Sollten Sie in einer verkehrs-schwachen-Zeit Ihren RD neu starten, sollte die IPv6-Connectivity wie gewohnt funktionieren.

Ich möchte Sie jedoch bitten, sich an Ihren vertrieblichen Ansprechpartner zu wenden und über ihn, einen Korrekturauftrag (IP-Adressauftrag einzustellen).

Ich wünsche Ihnen noch eine angenehme Restwoche und verbleibe mit freundlichen Grüßen

Aha, aha. Professionell wurden Abkürzungen für die Produktnamen in Klammern eingefügt (wozu?), aber RD nicht erklärt. Glücklicherweise ist aus dem Kontext ableitbar, dass es sich um unseren Telekom-Router handeln muss. Aber was um Himmels willen soll ich mit dem letzten Absatz anfangen? Klappt’s nun, wenn die den Router neu starte, oder soll ich nun wiederholt einen IP-Korrekturauftrag an den vertrieblichen Ansprechpartner stellen? Und wenn ja, warum?

Ich wähle wieder die Hotline-Nummer. Wer logisch inkonsistente Informationen sendet, darf sich gerne erklären.
Der Mitarbeiter am Telefon ist gleich im Bilde – noch bevor ich unsere Kundennummer nennen darf. Ich bin verblüfft. Üblicherweise darf ich erstmal alles erklären, unsere Kundennummer nennen, ggf. ein Password und noch eine Leitungsbezeichnung, um dann drei mal hin- und herverbunden zu werden und stets die selbe „Geschichte“ von Neuem zu erzählen. Und dieser Mitarbeiter weiß sofort bescheid.
Ich frage nach dem tieferen Sinn, speziell des letzten Absatzes in der letzten Email. Er bestätigt, dass man das nicht so ganz verstehen kann. Aber letzten Endes müsse diese „quick&dirty“-Änderung noch dokumentiert werden, und dafür sei wiederum der Vertrieb zuständig. Ich erspare ihm meine Frage, warum ICH das nun machen solle, denn die Antwort kann ja eigentlich nur lauten: „weil wir’s einfach nicht drauf haben“.
Ich erkundige mich allerdings noch danach, ob die Änderung in unserem Telekom-Router ausreiche, da meine Diagnose darauf hindeute, dass die Route auch im tiefer liegenden Netz korrigiert werden müsse. Die Antwort fällt wie erwartet aus: „Das sehe man ja dann, wenn es immer noch nicht funktioniere“.

Für 21 Uhr habe ich von entfernt über das Outlet-Segment der USV, an welcher der Router hängt, einen Hard-Reset programmiert. Nachdem die Internetverbindung wieder online war, funktionierte IPv6 tatsächlich wieder im kompletten /48-Raum.

Ritto over IP

Es war schon lange ein Wunsch von mir, darüber informiert zu werden, wenn der Postbote geklingelt hat. Bzw. wenn er nicht geklingelt hat.

Die Lösung zu dieser Aufgabe konnte ich nun endlich durch Vorarbeit anderer Bastler (Link funktioniert 2020 nicht mehr) und Dokumentierer  fertig stellen: Ein ausgefeilter Hack der Ritto Türsprechanlage, der das Klingelsignal abgreift, per WLAN an MQTT meldet und auf dem Rückweg  obendrein noch ermöglicht, den Türöffner von entfernt zu betätigen. Wie geil ist das eigentlich?

Bei dem bei uns verbauten Modell handelt es sich um ein Ritto Wohntelefon Twinbus 7630. Vermutlich wird der Eingriff jedoch auch bei ähnlichen Modellen funktionieren. Im Notfall kann man den Pins einfach mal mit dem Multimeter auf die Pelle rücken und  nachmessen, ob sich spannungsmäßig etwas tut, wenn man klingelt.

Die Weiterentwicklung gegenüber der „Version“ meines Vorgängers besteht hauptsächtlich darin, dass dieses Modul nun auch von der Gesamtanlage gespeist wird, d.h. es ist keine weitere Stromversorgung notwendig. Wer würde auch sonst eine extra Leitung zum „Wohntelefon“ (was ein däml…. Name *Anm. d. Red.) legen, der Aufwand rentiert in den meisten Fällen schlicht nicht. Und Batteriebetrieb fällt sowieso schon mal ganz aus, es sei denn, man hat den seltenen Hang zum permaneten Akkuwechsel.
Das ESP-Modul samt Anhang über den Twinbus „schmarotzenderweise“ zu speisen ist im Übrigen wieder mal eine Angelegenheit der Kategorie „nicht trivial„. Wie in vielen Foren zu lesen ist, ist das gesamte Twinbus-System ziemlich zimperlich, was Eingriffe angeht und alles andere als robust. Die ganzen Warnungen, tunlichst die Finger davon zu lassen, es sei denn, man sei darauf aus, die Gegensprechanlage für das gesamte Haus lahm zu legen (inkl. der Kosten für den Technikereinsatz danach) rief selbstverständlich meine Neugierde auf den Plan.

Um Haftungsfragen auszuschließen, hier mein Disclaimer: Diese Dokumentation ist kein Aufruf zum Nachbau. Dass dieser Hack bei mir seit nun gut drei Jahren funktioniert ist keine Gewähr dafür, dass es nicht doch zu Schäden an der Ritto-Anlage kommen kann. D.h. jeder Nachbau erfolgt immer auf eigenes Risiko und eigene Verantwortung!

Die Platine bietet 24V an Kontakt Nr.5, das NodeMCU Board braucht 5V. Also braucht’s einen Spannungsregler. Testweise habe ich erst mal einen dumpfen 7805 genommen, der den Spannungsabfall einfach in Wärme verbrät.

Spannungregler 7805

Der wurde aber auch wegen der hohen Differenz von 19V bei den maximal 260mA ordentlich heiß. Hätte funktioniert, aber mangels Konvektionsmöglichkeit habe ich davon abgesehen. Außerdem bin ich auch nicht der Typ, der den Bug zum Feature macht alla „Hey, unser Wohntelefon hat noch eine Fingerwärmfunktion“.
Probiert habe ich also noch einen DC-DC Wandler (TracoPower TSR 1-2450 24 V/DC 5 V/DC 1 A 6 W), der mit der Anlage nicht funktionierte, aber der Zweite tut seine Arbeit perfekt. Es ist ein „FISM Fixed Isolated Modul“ (Würth Elektronik 177920531 24 V 5 V 0.2 A 1 W), macht zwar dauerhaft nur 200mA mit, aber für 5 Sekunden auch 300mA und sollte damit für die Stromspitzen ausreichen.

DC/DC Wandler

Davon abgesehen sollte ein obligatorischer Kondensator auch die Spitzen abfangen. Das Teil ist nun auch schon ein Jahr in Betrieb und funktioniert tadellos, nicht mal der Prozessor ESP8266 ist abgeschmiert.

Zur Übertragung des Klingelsignals ins WLAN habe ich mich für ein NodeMCU entschieden, da ich damit „quick & dirty“ schnell zum Ziel komme.

NodeMCU mit ESP12

Es gibt auch elegantere oder schlankere Lösungen.

Heute würde ich nur noch ein ESP12F-Modul nehmen und gleich einen 24V->3,3V DC/DC Wandler davor setzen.

ESP12F mit ESP8266

Ein ESP12 hat halt keine Spannungswandlung, keinen Serial-zu-USB-Chip (UART) und auch keine Flash-Logik. Diese Funktionen sind auf dem NodeMCU-Board „drumrum“ gebaut und erleichtern den Einstieg. Durch seine Verwendung kann ich zukünftig wesentlich einfacher Updates über die USB-Schnittstelle einspielen, sollte mal beim OTA-Update (über WLAN) etwas schief laufen.

Wemos D1 mini

Die selbe Funktionalität bietet übrigens auch ein Wemos D1-Board, falls das jemand noch nicht kennt.

Zur Ritto-Platine zurück: Mitte oben befindet sich die 24V Speisespannung für das WLAN-Modul und am Pin in der Mitte das Klingelsignal. Wenn jemand die Klingel betätigt, liegen dort 5 Volt an, die man auswerten kann. Der linke der drei Pins in Ground.

Unten rechts befinden sich die beiden Kontakte um den Türöffner zu betätigen. Diese kann man mit einem CMOS 4066, eine Art elektronisches Relais, durchschalten. Das kommt dem Tastendruck am Gerät gleich.

Umgekehrt funktioniert das Durchschalten per CMOS4066 zum ESP3266 leider nicht, da die Schaltzustände bei dieser elektronischen Variante sich nur in einer größeren Änderung des Widerstands unterscheiden. D.h. bei „Aus“ ist beim 4066 der  Widerstand nicht unendlich und bei „Ein“ ist der Widerstand nicht gleich Null. Welchen Wert diese Widerstände haben, hängt mit der Speisespannung zusammen und ist nicht linear. Also muss eine andere Möglichkeit her, um den GPIO Pin zu schalten.

Diese Aufgabe kann man per Transistor bewältigen, indem man D2 auf Ground bzw. Low Level zieht. Wenn am Klingelkontakt die 5 V anliegen, wird der Transistor leitend und welchselt am  GPIO D2 den Level. Ich habe einen BC547B genommen, aber ich gehe davon aus, dass auch sonst fast jeder übliche NPN-Transistor funktioniert. Davor ist zum Kingelkontakt ein 1 kΩ Widerstand.

Zur Stabilisierung und Entstörung habe ich noch einen 470 μF Kondensator hinter den DC-DC Wandler gehängt.

Die Schaltung kurz aufskizziert:

Der Versuchsaufbau auf dem Breadboard sieht folgendermaßen aus:

… und zum Testen muss die Schaltung natürlich auch an die Anlage:

Was bisher fehlt, ist die Software. Ich habe mich für die Firmware „Tasmota“ von Theo Arends entschieden.

Selbstverständlich kann man mit ein paar Bibliotheken relativ schnell selbst etwas zusammenschustern, aber das Angebot von Theo hat alles an Board, was man benötigt. Wer im ersten Step (noch) keine Lust auf das volle Paket mit MQTT und Node-Red hat, der kann den Türöffner erst mal nur über das Webfrontend steuern, welches sogar „responsive design’t“ ist und damit auch auf dem Smartphone schlank aussieht.

Das gesamte Konstrukt vom Breadboard habe ich, nach Versicherung dass auch alles funktioniert, schlicht auf einer Lochrasterplatine  eingelötet. Bei einer nächsten Version würde ich vielleicht eine extra Platine fertigen lassen, aber es funktioniert auch so einwandfrei.

Richtig interessant wird die Sache, wenn man sich nun noch einen MQTT-Server mit z.B. Node-Red gönnt. Zugegebenermaßen ist das alles am Anfang natürlich etwas viel, aber mancher Bastler hat ja schon einen Teil der Infrastruktur zu Hause. Und MQTT ist nun wirklich nicht die Hürde. Es ist mit „apt-get install mosquitto“ ruckzuck auf Debian installiert und funktioniert danach einfach nur noch. -> Ja, der Satz ist zu Ende.  Es tut was es soll und ist wartungsarm.
Als Server(-hardware) nutze ist selbst (aus Performancegründen) einen Intel NUC5CPYH, weil er einen AES-NI Chip und ausreichend Power/RAM hat, um immer alles „schnell mal noch“ drauf zu packen. Wer bereit ist, mehr mit Ressourcen zu haushalten kann auf den doch wesentlich günstigeren Raspberry 3b zurück greifen. Ein Einrichtungstutorial ist hier. Für die Einrichtung von Node-Red mit node.js unter Debian empfehle ich diese Anleitung. Zusätzliche Hinweise wegen dem begrenzten Arbeitsspeicher auf dem Raspberry Pi finden sich in diesen Artikel von Markus Ulsass.

Um letztendlich über das eigentliche Klingeln an der Tür benachrichtigt zu werden setze ich den Dienst Pushover, aufsetzend auf Node-Red, ein.

Da das ausführliche Beschreiben aller beteiligten Komponenten über die Hardware hinaus diesen Artikel sprengen würde, habe ich oben die wichtigsten Punkte gegen aussagekräftige Hilfeseiten verlinkt. Ich wünsche somit viel Spaß bei Nachbauen (wieder der Hinweis aus rechtlichen Gründen: NICHT NACHBAUEN) und freue mich auch über Feedback oder Verbesserungsvorschläge.

WLAN Probleme mit der Fritzbox 7590

Die neue AVM Fritzbox 7590 hat derzeit in einigen Fällen Probleme mit dem WLAN. Bei mir ist es das 2,4 GHz Band. Kein Gerät kann sich damit verbinden. Alle Versuche sind bei mir gescheitert, trotz Umbennen der SSID oder Wechsel des Passworts.

Auch fällt auf, dass man bei abgeschaltetem 5GHz-Band den Kanal im 2,4GHz-Band nicht verstellen kann, aber im (abgeschalteten!) 5GHz-Band. Ergibt irgendwie keine Sinn, oder?

Der Support von AVM bestätigt das Problem und fordert Logs an, ich warte auf Lösung.

Auch die Übernahme der Konfiguration aus der 7490 war ein steiniger Weg: Die 7590 wird ab Werk mit älterer Firmware ausgeliefert. Da die alte 7490 jedoch bereits den Stand 06.93 hat und diese Firmware offizielle für die neue 7590 noch gar nicht verfügbar ist, versagt der Konfigurations-Import im neuen Modell. Zuerst muss die neue 7590 mit der manuell heruntergeladenen FRITZ!OS 06.93-49653 BETA hochgepatcht werden, damit der Konfigurationsimport überhaupt funktioniert. Das hätte man besser lösen können, indem man entweder das Firmware-Update für das ältere Modell zurückhält, oder den Importer in der Neuen derart anpasst, dass er auch die ältere Konfig verdauen kann.

Update:
Nach einem weiteren Konfigurations-Übernahmeversuch funktioniert das 2,4GHz WLAN nun endlich. Bei diesem zweiten Export (Sichern) der Einstellungen von der Fraitzbox 7490 habe ich zuvor die SSID’s beider WLAN-Bäder gleich (um-) benannt. D.h. nach dem Import in die neue Fritzbox 7590 sind nun von anfang an die SSID’s gleich und das WLAN funktionierte sofort, ebenso wie die Kanalauswahl. Ansonsten war der gesamte Ablauf (Sichern, Wiederherstellen) exakt der Selbe wie beim ersten Mal.
Da bei den letzten Firmware-Versionen besonders viele Änderungen im WLAN-Mesh implementiert wurden, gehe ich davon aus, dass beim Import ungleicher SSID’s der Fehler zu suchen ist.

Update 2:
Auch ein importierter VPN-Zugang macht Probleme:
Der VPN-Zugang vom Smartphone zum Heimnetz funktioniert nur eingeschränkt. Die VPN-Verbindung zur Fritzbox 7590 wird zwar hergestellt und der Zugriff auf einige interne Geräte funktioniert auch. Ominöserweise funktioniert jedoch der Zugriff auf den Debian-Server auf allen Diensten und Ports nicht.
Das Fehlerbild hinterlässt Fragezeichen. Tcpdump zeigt auf dem Debian-Server Datenpakete an, die vom Smartphone per VPN gesendet werden, jedoch kommen die Rückläufer beim Smartphone nicht an. Also muss es an der Fritzbox liegen.
Nach Entfernen und dem Neuanlegen des entsprechenden VPN-Zugangs funktioniert auch der Zugriff auf den Debian Server wieder wie gewohnt. Wie ist das Ganze eigentlich zu erklären? Warum „schluckte“ die Fritzbox Datenpakete vom Debian-Server, während sie die Pakete von z.B. ESP8288-Modulen einwandfrei durchließ?