JAERO/SatDump to ACARS HUB

Converts Airframes.io JAERO JSONdump or SatDump to the JSON format for ACARS Hub using UDP

https://github.com/airframesio/JAERO

https://github.com/SatDump/SatDump

https://github.com/sdr-enthusiasts/docker-acarshub

[{"id":"f6f2187d.f17ca8","type":"tab","label":"JAERO/SatDump to ACARS HUB V11","disabled":false,"info":"Made by RoseO\r\n\r\nDiscord: RoseO#6521"},{"id":"291a5e40dcd96b0d","type":"udp in","z":"f6f2187d.f17ca8","name":"JAERO JSONdump 2000/udp","iface":"","port":"2000","ipv":"udp4","multicast":"false","group":"","datatype":"buffer","x":140,"y":40,"wires":[["41d41583490d2d98"]]},{"id":"937144df279567d6","type":"debug","z":"f6f2187d.f17ca8","d":true,"name":"source","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":370,"y":40,"wires":[]},{"id":"41d41583490d2d98","type":"json","z":"f6f2187d.f17ca8","name":"","property":"payload","action":"obj","pretty":false,"x":250,"y":100,"wires":[["fe0bf49e01644fef","937144df279567d6"]]},{"id":"44822987686359ba","type":"comment","z":"f6f2187d.f17ca8","name":"JSON Samples","info":"\n//ACARS HUB FORMAT\n{\"timestamp\":1516206744.1849549,\"channel\":2,\"freq\":130.025,\"level\":-22,\"error\":0,\"mode\":\"2\",\"label\":\"H1\",\"block_id\":\"6\",\"ack\":false,\"tail\":\".N842UA\",\"flight\":\"UA1412\",\"msgno\":\"D04G\",\"text\":\"#DFB9102,0043,188/9S101,0039,181/S0101,0043,188/0S100,0039,182/T1100,0043,188/1T099,0039,182/T2099,0043,189/2T098,0039,182/T3098,0043,189/3T097,0039,182/T4098,0043,189/4T097,0039,183/T5098,0043,189/5T097,0039,1\",\"end\":true,\"station_id\":\"sigint\"}\n\n//JAERO JSON DUMP\n{\"app\":{\"name\":\"JAERO\",\"ver\":\"VFO14\"},\"isu\":{\"acars\":{\"ack\":\"!\",\"arinc622\":{\"adsc\":{\"err\":false,\"tags\":[{\"event_contract_req\":{\"contract_num\":2,\"groups\":[{\"report_wpt_changes\":{}},{\"report_when_lateral_dev_exceeds\":{\"lat_dev_treshold_nm\":16}}]}}]},\"air_addr\":\".OO-SFC\",\"crc_ok\":true,\"gs_addr\":\"FIHCAYA\",\"msg_type\":\"adsc_msg\"},\"blk_id\":\"B\",\"label\":\"A6\",\"mode\":\"2\",\"msg_text\":\"/FIHCAYA.ADS.OO-SFC0802140A80D92B\",\"reg\":\"OO-SFC\"},\"dst\":{\"addr\":\"44CCC3\",\"type\":\"Aircraft Earth Station\"},\"qno\":\"07\",\"refno\":\"01\",\"src\":{\"addr\":\"90\",\"type\":\"Ground Earth Station\"}},\"station\":\"RO-LBAND-EUR\",\"t\":{\"sec\":1676825265,\"usec\":652000}}\n\n//satdump\n{\"bi\":77,\"has_text\":true,\"label\":\"AA\",\"libacars\":{\"arinc622\":{\"air_addr\":\".TC-LGJ\",\"cpdlc\":{\"atc_uplink_msg\":{\"atc_uplink_msg_element_id\":{\"choice\":\"uM169FreeText\",\"choice_label\":\"[freetext]\",\"data\":{\"free_text\":\"ROGER\"}},\"header\":{\"msg_id\":6,\"timestamp\":{\"hour\":22,\"min\":28,\"sec\":38}}},\"err\":false},\"crc_ok\":true,\"gs_addr\":\"KRTCAYA\",\"msg_type\":\"fans1a_cpdlc_msg\"}},\"message\":\"/KRTCAYA.AT1.TC-LGJ2359C9AA41294F8F1690EDB5\",\"mode\":50,\"more_to_come\":false,\"msg_name\":\"ACARS\",\"plane_reg\":\".TC-LGJ\",\"signal_unit\":{\"aes_id\":4960490,\"ges_id\":144,\"message_type\":113,\"no_of_bytes_in_last_su\":5,\"q_no\":7,\"ref_no\":10,\"seq_no\":8},\"tak\":21,\"timestamp\":1677709719}","x":100,"y":200,"wires":[]},{"id":"2e6ea11895a8a8e6","type":"udp out","z":"f6f2187d.f17ca8","name":"ACARS HUB 5550/udp","addr":"172.20.0.16","iface":"","port":"5550","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":650,"y":220,"wires":[]},{"id":"1967c0d1165728b1","type":"debug","z":"f6f2187d.f17ca8","d":true,"name":"transformed","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":790,"y":40,"wires":[]},{"id":"fe0bf49e01644fef","type":"function","z":"f6f2187d.f17ca8","name":"Convert VFO to Freq","func":"//JSONdump format will send whatever text is entered\n//when JAERO is launched with the -s option\n//in payload.app.ver\n\n//SDRReceiver config file VFOs 25E\nconst vfoLut = {\n    VFO01: \"1545.005146\",\n    VFO02: \"1545.214573\",\n    VFO03: \"1545.219706\",\n    VFO04: \"1545.224996\",\n    VFO05: \"1545.114134\",\n    VFO06: \"1545.119063\",\n    VFO07: \"1545.124261\",\n    VFO08: \"1545.129563\",\n    VFO09: \"1545.159288\",\n    VFO10: \"1545.164682\",\n    VFO11: \"1545.183905\",\n    VFO12: \"1545.189244\",\n    VFO13: \"1546.019800\",\n    VFO14: \"1546.019800\",\n    VFO15: \"1546.034700\",\n    VFO16: \"1546.084600\",\n    VFO17: \"1546.099900\",\n    VFO18: \"1546.114200\",\n    VFO19: \"1546.137300\",\n    VFO20: \"1546.142500\",\n    VFO21: \"1546.147700\",\n    VFO22: \"1546.152300\",\n    VFO23: \"1546.157500\",\n    VFO24: \"1546.162600\",\n    VFO25: \"1546.168300\",\n    VFO26: \"1546.173430\",\n    VFO27: \"1546.178430\"\n};\nconst vfoLookup = (vfo) => vfoLut[vfo] || \"\";\n\nmsg.payload.freq = vfoLookup(msg.payload.app.ver)\n\n//If the lookup failed just use whatever is sent\nif(!msg.payload.freq){\n    msg.payload.freq = msg.payload.app.ver\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":100,"wires":[["bc900ef6e7e196c5"]]},{"id":"bc900ef6e7e196c5","type":"function","z":"f6f2187d.f17ca8","name":"message format","func":"//Ground Earth Station LUT\nconst gesLoc = {\n    ANCXFXA: \"Anchorage Domestic (USA)\",\n    ANCATYA: \"Anchorage Oceanic (USA)\",\n    AKLCDYA: \"Auckland Oceanic (NZ)\",\n    BKKGWXA: \"Bangkok (Thailand)\",\n    BNECAYA: \"Brisbane (AUS)\",\n    CTUGWYA: \"Chengdu (China)\",\n    MAACAYA: \"Chennai (India)\",\n    FUKJJYA: \"Fukuoka (Japan)\",\n    YQXE2YA: \"Gander Oceanic (Canada)\",\n    YQXD2YA: \"Gander Domestic (Canada)\",\n    YQME2YA: \"Moncton (Canada)\",\n    YULE2YA: \"Montreal (Canada)\",\n    YYZE2YA: \"Toronto (Canada)\",\n    YWGE2YA: \"Winnipeg (Canada)\",\n    YVRE2YA: \"Vancouver (Canada)\",\n    USADCXA: \"USA Domestic (USA)\",\n    JNBCAYA: \"Johannesburg Oceanic (SA)\",\n    KMGGWYA: \"Kunming (China)\",\n    LHWGWYA: \"Lanzhou (China)\",\n    MELCAYA: \"Melbourne (AUS)\",\n    BOMCAYA: \"Mumbai (India)\",\n    NANCDYA: \"Nadi (Fiji)\",\n    NYCODYA: \"New York Oceanic (USA)\",\n    OAKODYA: \"Oakland Oceanic (USA)\",\n    REKCAYA: \"Reykjavik (Iceland)\",\n    SMACAYA: \"Santa Maria (Portugal)\",\n    PIKCPYA: \"Shanwick (UK)\",\n    SINCDYA: \"Singapore\",\n    PPTCDYA: \"Tahiti (French Polynesia)\",\n    UPGCAYA: \"Makassar (Indonesia)\",\n    NIMCAYA: \"Niamey (Niger)\",\n    DKRCAYA: \"Dakar Oceanic (Senegal)\",\n    NKCCAYA: \"Dakar Domestic (Senegal)\",\n    GVSCAYA: \"Sal Oceanic (Cape Verde)\",\n    BZVCAYA: \"Brazzaville (Congo)\",\n    CAICAYA: \"Egypt\",\n    PAREUYA: \"France\",\n    MEXCAYA: \"Mexico\",\n    BKKCAYA: \"Thailand\",\n    NDJCAYA: \"Ndjamena (Chad)\",\n    LPAFAYA: \"Canarias (Spain)\",\n    ALGCAYA: \"Alger (Algeria)\",\n    SEZCAYA: \"Seychelles\",\n    LADCAYA: \"Angola (Luanda)\",\n    ABJCAYA: \"Ivory Coast (Abidjan)\",\n    TNRCAYA: \"Antananarivo (Madagascar)\",\n    KRTCAYA: \"Khartoum (Sudan)\",\n    CCUCAYA: \"Kolkata (India)\",\n    SNNCPXA: \"Shannon (Ireland)\",\n    PIKCAYA: \"Scottish (UK)\",\n    SOUCAYA: \"London (UK)\",\n    MSTEC7X: \"Maastricht (NL)\",\n    POSCLYA: \"Piarco (Trinidad)\",\n    TGUACYA: \"Cenamar (Honduras)\",\n    CAYCAYA: \"Cayenne (French Guiana)\",\n    RECOEYA: \"Atlantico (Brazil)\",\n    SCLCAYA: \"Antofagasta (Chile)\",\n    GDXE1XA: \"Magadan (Russia)\",\n    URCE1YA: \"Urumqi (China)\",\n    RPHIAYA: \"Manila (Philippines)\",\n    SGNGWXA: \"Ho Chi Minh (Vietnam)\",\n    RGNCAYA: \"Yangon (Myanmar)\",\n    SINCXYA: \"Singapore\",\n    KULCAYA: \"Kuala Lumpur (Malaysia)\",\n    POMCAYA: \"Port Moresby (PG)\",\n    DELCAYA: \"Delhi (India)\",\n    CMBCBYA: \"Colombo (Sri Lanka)\",\n    MRUCAYA: \"Mauritius (Mauritius)\",\n    TGUACAY: \"Honduras (CENAMER)\",\n    MLECAYA: \"Male (Maldives)\",\n    BDOCAYA: \"Bodo Oceanic (Norway)\",\n    NBOCAYA: \"Kenya (Niarobi)\",\n    ACCFAYA: \"Gahna (Accra)\",\n    BJSGWYA: \"Beijing (China)\",\n    CAICDYA: \"Cairo (Egypt)\",\n    CANGWYA: \"Guangzhou (China)\",\n    CCUCBYA: \"Kolkata (India)\",\n    CMBCAYA: \"Colombo (Sri Lanka)\",\n    DDLCVXA: \"Bodo (Norway)\",\n    GDXGWXA: \"Magadan (Russia)\",\n    HKGCCYA: \"Hong Kong\",\n    HRBGWYA: \"Harbin (China)\",\n    JAKGWXA: \"Jakarta (Indonesia)\",\n    KANCAYA: \"Kano (Nigeria)\",\n    KRTCDYA: \"Sudan\",\n    LISACYA: \"Lisboa (Portugal)\",\n    LXAGWYA: \"Lhasa (China)\",\n    MNLCBYA: \"Manila (Philippines)\",\n    SELCAXH: \"Seoul (Korea)\",\n    SHAGWYA: \"Shanghai (China)\",\n    TASCAXH: \"Tashkent (Uzbekistan)\",\n    ULNGWXA: \"Ulan Bataar (Mongolia)\",\n    URCGWYA: \"Urum-Qi (China)\",\n    YEGCDYA: \"Edmonton (Canada)\", //ADS-C\n    YEGE2YA: \"Edmonton (Canada)\", //CPDLC\n    SPLATYA: \"Amsterdam Schipol (NL)\",\n    CDGATYA: \"Paris (France)\",\n    MGQCAYA: \"Ethiopia\", //Possibly\n    FIHCAYA: \"Congo\", //likely\n    PIKCLYA: \"Prestwick Oceanic (UK)\",\n    PIKCLXS: \"Prestwick Domestic (UK)\",\n    DOHATYA: \"Doha (Qatar)\",\n    MCTASWY: \"Muscat (Oman)\",\n    JEDAAYA: \" \",\n    DXBEGEK: \" \",\n    RUHAAYA: \" \",\n    BOMCDYA: \" \",\n    BJSATYA: \" \",\n    MADAAYA: \" \",\n    JEDATYA: \" \",\n    GVACBYA: \" \",\n    DATSAXS: \" \",\n    AUHCAYA: \" \",\n    BAHCEYA: \" \",\n    MADCDYA: \" \",\n    AUHABYA: \" \",\n    GYDCDYA: \" \",\n    HDQOILX: \" \",\n    RIOCDYA: \" \",\n};\n\nconst gesLookup = (addr) => gesLoc[addr] || \"\";\n\n//convert to/from station IDs to decimal\nmsg.payload.isu.dst.addr = parseInt(msg.payload.isu.dst.addr, 16)\nmsg.payload.isu.src.addr = parseInt(msg.payload.isu.src.addr, 16)\n\n//set ICAO if the source or destination type is an an aircraft\nlet icao = \"\";\nif (msg.payload.isu.dst.type == \"Aircraft Earth Station\") {\n    icao = msg.payload.isu.dst.addr\n}\n\nif (msg.payload.isu.src.type == \"Aircraft Earth Station\") {\n    icao = msg.payload.isu.src.addr\n}\n\nlet from_decoded = \"\";\nlet to_decoded = \"\";\n\nlet msg_text = \"\";\nlet dataHasDecoded = false;\nlet decodedText = \"\";\nlet formattedMsg = \"\";\nlet gesName = \"\";\n\n//Do some stuff is arinc622 data is present\nif (typeof msg.payload.isu.acars.arinc622 != \"undefined\") {\n    //Fill in the GS name if provided\n    if (gesName = gesLookup(msg.payload.isu.acars.arinc622.gs_addr)) {\n        gesName = \"/\" + gesName;\n    }\n    if (msg.payload.isu.dst.type == \"Ground Earth Station\") {\n        to_decoded = msg.payload.isu.acars.arinc622.gs_addr + gesName\n    }\n\n    if (msg.payload.isu.src.type == \"Ground Earth Station\") {\n        from_decoded = msg.payload.isu.acars.arinc622.gs_addr + gesName\n    }\n    //Stringify arnic622 data and add to decodedText\n    dataHasDecoded = true;\n\n    //Try to format the message\n    if (msg.payload.isu.acars.arinc622.cpdlc) {\n        formattedMsg = {\n            label: msg.payload.isu.acars.arinc622.msg_type,\n            value: JSON.stringify(msg.payload.isu.acars.arinc622.cpdlc, null, 2)\n        };\n    } else if (msg.payload.isu.acars.arinc622.adsc) {\n        formattedMsg = {\n            label: msg.payload.isu.acars.arinc622.msg_type,\n            value: JSON.stringify(msg.payload.isu.acars.arinc622.adsc, null, 2)\n        };\n    } else {\n        formattedMsg = {\n            label: msg.payload.isu.acars.arinc622.msg_type,\n            value: JSON.stringify(msg.payload.isu.acars.arinc622, null, 2)\n        };\n    }\n\n    decodedText = {\n        \"decoder\": {\n            //\"decodedStatus\": \"full\",\n            \"decodedStatus\": \"partial\",\n        },\n        formatted: [formattedMsg]\n    };\n}\n\n//Find flight number FN in string\nlet flight = \"\";\nlet fnIndex = msg.payload.isu.acars.msg_text.indexOf(\"/FN\");\nif (fnIndex != -1) {\n    flight = msg.payload.isu.acars.msg_text.substring(fnIndex + 3, msg.payload.isu.acars.msg_text.indexOf(\"/\", fnIndex + 1));\n    //console.log(\"fn1: \"+ flight)\n} else {\n    //Try the other format\n    fnIndex = msg.payload.isu.acars.msg_text.indexOf(\"/FMH\");\n    if (fnIndex != -1) {\n        flight = msg.payload.isu.acars.msg_text.substring(fnIndex + 4, msg.payload.isu.acars.msg_text.indexOf(\",\", fnIndex + 1));\n        //console.log(\"fn2: \" + flight)\n    }\n}\n\n//Check if we have totally messed up and made some impossibly long FN\nif (flight.length > 9) {\n    flight = \"\";\n}\n\n//Have a go at the ges name if we were not provided it\n//this is a little hacky\nlet fromIndex = msg.payload.isu.acars.msg_text.indexOf(\"/\");\nlet station = \"\"\nif (!from_decoded && fromIndex != -1) {\n    station = msg.payload.isu.acars.msg_text.substring(fromIndex + 1, msg.payload.isu.acars.msg_text.indexOf(\".\", fromIndex));\n    //console.log(\"\\n\\n\\n\\n\\n--------\\n\"+station);\n    station = station.split(\" \").filter(id => id.length == 7)\n    \n    console.log(station);\n    if (gesName = gesLookup(station[0])) {\n        from_decoded = station[0] + \"/\" + gesName;\n        //console.log(from_decoded);\n    }\n}\n//Format message for ACARS HUB\nlet acarsMessage = {\n    \"timestamp\": msg.payload.t.sec + \".\" + msg.payload.t.usec,\n    \"channel\": msg.payload.app.ver,\n    \"freq\": msg.payload.freq,\n    \"level\": 0,\n    \"error\": 0,\n    \"mode\": msg.payload.isu.acars.mode,\n    \"label\": msg.payload.isu.acars.label,\n    \"block_id\": msg.payload.isu.acars.blk_id,\n    \"ack\": msg.payload.isu.acars.ack,\n    \"tail\": msg.payload.isu.acars.reg,\n    \"flight\": flight,\n    \"msgno\": msg.payload.isu.refno,\n    \"fromaddr\": msg.payload.isu.src.addr,\n    \"fromaddr_decoded\": from_decoded,\n    \"toaddr\": msg.payload.isu.dst.addr,\n    \"toaddr_decoded\": to_decoded,\n    \"icao\": icao,\n    \"end\": true,\n    \"station_id\": msg.payload.station + \"-\" + msg.payload.app.ver,\n    \"text\": msg.payload.isu.acars.msg_text\n}\n//Add the JAERO decoded output if it exists\nif (dataHasDecoded) {\n    acarsMessage.decodedText = decodedText;\n}\n//Escape strings\nmsg.payload = JSON.stringify(acarsMessage) + '\\n';\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":620,"y":100,"wires":[["1967c0d1165728b1","2e6ea11895a8a8e6"]]},{"id":"ef45b19de915869f","type":"function","z":"f6f2187d.f17ca8","name":"arnic622 filter","func":"//Stringify arnic622 data and append to text if it exists\nif (typeof msg.payload.isu.acars.arinc622 != \"undefined\") {\n} else {\n    msg = null;\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":100,"y":240,"wires":[[]]},{"id":"821dde9379ca9e56","type":"udp in","z":"f6f2187d.f17ca8","name":"SatDump JSON 2001/udp","iface":"","port":"2001","ipv":"udp4","multicast":"false","group":"","datatype":"buffer","x":130,"y":320,"wires":[["af0eca5541f7bd98"]]},{"id":"a21042b822ef7fcf","type":"debug","z":"f6f2187d.f17ca8","d":true,"name":"source","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":470,"y":340,"wires":[]},{"id":"af0eca5541f7bd98","type":"json","z":"f6f2187d.f17ca8","name":"","property":"payload","action":"obj","pretty":false,"x":170,"y":400,"wires":[["4879ae84af3ef661"]]},{"id":"4879ae84af3ef661","type":"function","z":"f6f2187d.f17ca8","name":"rubbish filter","func":"//if (msg.payload.msg_name == \"AES System Table Broadcast (Index)\" || msg.payload.msg_name == \"SSU\") {\n//    msg = null;\n//}\n\nif (msg.payload.msg_name != \"ACARS\") {\n    msg = null;\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":400,"wires":[["a21042b822ef7fcf","0e950aaa749ab41d"]]},{"id":"0e950aaa749ab41d","type":"function","z":"f6f2187d.f17ca8","name":"message format","func":"//This is pretty fresh so it may break\n//Station ID for acarshub\nlet station_id = \"RO-LBAND-SATDUMP\";\n\n//Ground Earth Station LUT\nconst gesLoc = {\n    ANCXFXA: \"Anchorage Domestic (USA)\",\n    ANCATYA: \"Anchorage Oceanic (USA)\",\n    AKLCDYA: \"Auckland Oceanic (NZ)\",\n    BKKGWXA: \"Bangkok (Thailand)\",\n    BNECAYA: \"Brisbane (AUS)\",\n    CTUGWYA: \"Chengdu (China)\",\n    MAACAYA: \"Chennai (India)\",\n    FUKJJYA: \"Fukuoka (Japan)\",\n    YQXE2YA: \"Gander Oceanic (Canada)\",\n    YQXD2YA: \"Gander Domestic (Canada)\",\n    YQME2YA: \"Moncton (Canada)\",\n    YULE2YA: \"Montreal (Canada)\",\n    YYZE2YA: \"Toronto (Canada)\",\n    YWGE2YA: \"Winnipeg (Canada)\",\n    YVRE2YA: \"Vancouver (Canada)\",\n    USADCXA: \"USA Domestic (USA)\",\n    JNBCAYA: \"Johannesburg Oceanic (SA)\",\n    KMGGWYA: \"Kunming (China)\",\n    LHWGWYA: \"Lanzhou (China)\",\n    MELCAYA: \"Melbourne (AUS)\",\n    BOMCAYA: \"Mumbai (India)\",\n    NANCDYA: \"Nadi (Fiji)\",\n    NYCODYA: \"New York Oceanic (USA)\",\n    OAKODYA: \"Oakland Oceanic (USA)\",\n    REKCAYA: \"Reykjavik (Iceland)\",\n    SMACAYA: \"Santa Maria (Portugal)\",\n    PIKCPYA: \"Shanwick (UK)\",\n    SINCDYA: \"Singapore\",\n    PPTCDYA: \"Tahiti (French Polynesia)\",\n    UPGCAYA: \"Makassar (Indonesia)\",\n    NIMCAYA: \"Niamey (Niger)\",\n    DKRCAYA: \"Dakar Oceanic (Senegal)\",\n    NKCCAYA: \"Dakar Domestic (Senegal)\",\n    GVSCAYA: \"Sal Oceanic (Cape Verde)\",\n    BZVCAYA: \"Brazzaville (Congo)\",\n    CAICAYA: \"Egypt\",\n    PAREUYA: \"France\",\n    MEXCAYA: \"Mexico\",\n    BKKCAYA: \"Thailand\",\n    NDJCAYA: \"Ndjamena (Chad)\",\n    LPAFAYA: \"Canarias (Spain)\",\n    ALGCAYA: \"Alger (Algeria)\",\n    SEZCAYA: \"Seychelles\",\n    LADCAYA: \"Angola (Luanda)\",\n    ABJCAYA: \"Ivory Coast (Abidjan)\",\n    TNRCAYA: \"Antananarivo (Madagascar)\",\n    KRTCAYA: \"Khartoum (Sudan)\",\n    CCUCAYA: \"Kolkata (India)\",\n    SNNCPXA: \"Shannon (Ireland)\",\n    PIKCAYA: \"Scottish (UK)\",\n    SOUCAYA: \"London (UK)\",\n    MSTEC7X: \"Maastricht (NL)\",\n    POSCLYA: \"Piarco (Trinidad)\",\n    TGUACYA: \"Cenamar (Honduras)\",\n    CAYCAYA: \"Cayenne (French Guiana)\",\n    RECOEYA: \"Atlantico (Brazil)\",\n    SCLCAYA: \"Antofagasta (Chile)\",\n    GDXE1XA: \"Magadan (Russia)\",\n    URCE1YA: \"Urumqi (China)\",\n    RPHIAYA: \"Manila (Philippines)\",\n    SGNGWXA: \"Ho Chi Minh (Vietnam)\",\n    RGNCAYA: \"Yangon (Myanmar)\",\n    SINCXYA: \"Singapore\",\n    KULCAYA: \"Kuala Lumpur (Malaysia)\",\n    POMCAYA: \"Port Moresby (PG)\",\n    DELCAYA: \"Delhi (India)\",\n    CMBCBYA: \"Colombo (Sri Lanka)\",\n    MRUCAYA: \"Mauritius (Mauritius)\",\n    TGUACAY: \"Honduras (CENAMER)\",\n    MLECAYA: \"Male (Maldives)\",\n    BDOCAYA: \"Bodo Oceanic (Norway)\",\n    NBOCAYA: \"Kenya (Niarobi)\",\n    ACCFAYA: \"Gahna (Accra)\",\n    BJSGWYA: \"Beijing (China)\",\n    CAICDYA: \"Cairo (Egypt)\",\n    CANGWYA: \"Guangzhou (China)\",\n    CCUCBYA: \"Kolkata (India)\",\n    CMBCAYA: \"Colombo (Sri Lanka)\",\n    DDLCVXA: \"Bodo (Norway)\",\n    GDXGWXA: \"Magadan (Russia)\",\n    HKGCCYA: \"Hong Kong\",\n    HRBGWYA: \"Harbin (China)\",\n    JAKGWXA: \"Jakarta (Indonesia)\",\n    KANCAYA: \"Kano (Nigeria)\",\n    KRTCDYA: \"Sudan\",\n    LISACYA: \"Lisboa (Portugal)\",\n    LXAGWYA: \"Lhasa (China)\",\n    MNLCBYA: \"Manila (Philippines)\",\n    SELCAXH: \"Seoul (Korea)\",\n    SHAGWYA: \"Shanghai (China)\",\n    TASCAXH: \"Tashkent (Uzbekistan)\",\n    ULNGWXA: \"Ulan Bataar (Mongolia)\",\n    URCGWYA: \"Urum-Qi (China)\",\n    YEGCDYA: \"Edmonton (Canada)\", //ADS-C\n    YEGE2YA: \"Edmonton (Canada)\", //CPDLC\n    SPLATYA: \"Amsterdam Schipol (NL)\",\n    CDGATYA: \"Paris (France)\",\n    MGQCAYA: \"Ethiopia\", //Possibly\n    FIHCAYA: \"Congo\", //likely\n    PIKCLYA: \"Prestwick Oceanic (UK)\",\n    PIKCLXS: \"Prestwick Domestic (UK)\",\n    DOHATYA: \"Doha (Qatar)\",\n    MCTASWY: \"Muscat (Oman)\",\n    JEDAAYA: \" \",\n    DXBEGEK: \" \",\n    RUHAAYA: \" \",\n    BOMCDYA: \" \",\n    BJSATYA: \" \",\n    MADAAYA: \" \",\n    JEDATYA: \" \",\n    GVACBYA: \" \",\n    DATSAXS: \" \",\n    AUHCAYA: \" \",\n    BAHCEYA: \" \",\n    MADCDYA: \" \",\n    AUHABYA: \" \",\n    GYDCDYA: \" \",\n    HDQOILX: \" \",\n    RIOCDYA: \" \",\n};\n\nconst gesLookup = (addr) => gesLoc[addr] || \"\";\n\n//convert to/from station IDs to decimal\n//msg.payload.isu.dst.addr = parseInt(msg.payload.isu.dst.addr, 16)\n//msg.payload.isu.src.addr = parseInt(msg.payload.isu.src.addr, 16)\n\n//set ICAO if the source or destination type is an an aircraft\nlet icao = msg.payload.signal_unit.aes_id;\n\n\nlet from_decoded = \"\";\nlet to_decoded = \"\";\n\nlet msg_text = \"\";\nlet dataHasDecoded = false;\nlet decodedText = \"\";\nlet formattedMsg = \"\";\nlet gesName = \"\";\n\n//Do some stuff is arinc622 data is present\nif (typeof msg.payload.libacars != \"undefined\") {\n    //Fill in the GS name if provided\n    if (gesName = gesLookup(msg.payload.libacars.arinc622.gs_addr)) {\n        gesName = \"/\" + gesName;\n    }\n   // if (msg.payload.isu.dst.type == \"Ground Earth Station\") {\n   //     to_decoded = msg.payload.libacars.arinc622.gs_addr + gesName\n    //}\n\n   // if (msg.payload.isu.src.type == \"Ground Earth Station\") {\n   //     from_decoded = msg.payload.libacars.arinc622.gs_addr + gesName\n   // }\n    //Stringify arnic622 data and add to decodedText\n    dataHasDecoded = true;\n\n    //Try to format the message\n    if (msg.payload.libacars.arinc622.cpdlc) {\n        formattedMsg = {\n            label: msg.payload.libacars.arinc622.msg_type,\n            value: JSON.stringify(msg.payload.libacars.arinc622.cpdlc, null, 2)\n        };\n    } else if (msg.payload.libacars.arinc622.adsc) {\n        formattedMsg = {\n            label: msg.payload.libacars.arinc622.msg_type,\n            value: JSON.stringify(msg.payload.libacars.arinc622.adsc, null, 2)\n        };\n    } else {\n        formattedMsg = {\n            label: msg.payload.libacars.arinc622.msg_type,\n            value: JSON.stringify(msg.payload.libacars.arinc622, null, 2)\n        };\n    }\n\n    decodedText = {\n        \"decoder\": {\n            //\"decodedStatus\": \"full\",\n            \"decodedStatus\": \"partial\",\n        },\n        formatted: [formattedMsg]\n    };\n}\n\n//Find flight number FN in string\nlet flight = \"\";\nlet fnIndex = msg.payload.message.indexOf(\"/FN\");\nif (fnIndex != -1) {\n    flight = msg.payload.message.substring(fnIndex + 3, msg.payload.message.indexOf(\"/\", fnIndex + 1));\n    //console.log(\"fn1: \"+ flight)\n} else {\n    //Try the other format\n    fnIndex = msg.payload.message.indexOf(\"/FMH\");\n    if (fnIndex != -1) {\n        flight = msg.payload.message.substring(fnIndex + 4, msg.payload.message.indexOf(\",\", fnIndex + 1));\n        //console.log(\"fn2: \" + flight)\n    }\n}\n\n//Check if we have totally messed up and made some impossibly long FN\nif (flight.length > 9) {\n    flight = \"\";\n}\n\n//Have a go at the ges name if we were not provided it\n//this is a little hacky\nlet fromIndex = msg.payload.message.indexOf(\"/\");\nlet station = \"\"\nif (!from_decoded && fromIndex != -1) {\n    station = msg.payload.message.substring(fromIndex + 1, msg.payload.message.indexOf(\".\", fromIndex));\n    //console.log(\"\\n\\n\\n\\n\\n--------\\n\"+station);\n    station = station.split(\" \").filter(id => id.length == 7)\n    \n    console.log(station);\n    if (gesName = gesLookup(station[0])) {\n        from_decoded = station[0] + \"/\" + gesName;\n        //console.log(from_decoded);\n    }\n}\n//Format message for ACARS HUB\nlet acarsMessage = {\n    \"timestamp\": msg.payload.timestamp,\n    \"channel\": \"satdump\",\n    \"freq\": msg.payload.freq,\n    \"level\": 0,\n    \"error\": 0,\n    \"mode\": msg.payload.mode,\n    \"label\": msg.payload.label,\n    \"block_id\": msg.payload.bi,\n    \"ack\": \"\",\n    \"tail\": msg.payload.plane_reg.substring(1),\n    \"flight\": flight,\n    \"msgno\": msg.payload.signal_unit.ref_no,\n    \"fromaddr\": msg.payload.signal_unit.ges_id,\n    \"fromaddr_decoded\": from_decoded,\n    \"toaddr\": msg.payload.signal_unit.aes_id,\n    \"toaddr_decoded\": to_decoded,\n    \"icao\": icao,\n    \"end\": true,\n    \"station_id\": station_id,\n    \"text\": msg.payload.message\n}\n//Add the JAERO decoded output if it exists\nif (dataHasDecoded) {\n    acarsMessage.decodedText = decodedText;\n}\n//Escape strings\nmsg.payload = JSON.stringify(acarsMessage) + '\\n';\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":400,"wires":[["b51016fe467ec389","2e6ea11895a8a8e6"]]},{"id":"b51016fe467ec389","type":"debug","z":"f6f2187d.f17ca8","d":true,"name":"transformed","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":710,"y":340,"wires":[]}]

Flow Info

Created 2 years, 4 months ago
Rating: not yet rated

Owner

Actions

Rate:

Node Types

Core
  • comment (x1)
  • debug (x4)
  • function (x5)
  • json (x2)
  • udp in (x2)
  • udp out (x1)
Other
  • tab (x1)

Tags

  • jareo
  • acars
  • ads-c
  • acarshub
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option