//mod-edit posty zostały przeniesone z wątku Karta z śledzeniem paczek (Polish Shipment Tracking)
@stirante Dziękuję za szybką reakcję
Integracja działa bardzo ok.
Przetestowana dziś rano z powiadomieniem
//mod-edit posty zostały przeniesone z wątku Karta z śledzeniem paczek (Polish Shipment Tracking)
@stirante Dziękuję za szybką reakcję
Integracja działa bardzo ok.
Wrzuć może flow dla innych. Szybko będe mógł wkleić. Przyda się każdemu
Nie widzę problemu, tylko czy mieszanie w tym wątku będzie zasadne ?
Flow jest spersonalizowany pod telegram bot , czyli trzeba w NR doinstalować
Sam proces jest dość prosty, na podstawie atrybutów czujnika z integracji tworzymy wiadomość i ewentualnie dodajemy przypominanie
flows.json (3,7 KB)
Właśnie o to mi chodziło jeśli ktoś będzie chciał sobie takie coś zrobić to będzie miał już przygotowane. Wydaje mi się że to jest odpowiednie miejsce o to chyba w tym chodzi aby dzielić się rozwiązaniami.
Skorzystałem z Flow autora, dziękuję za udostępnienie.
Proszę o informację którą encję należy wpisać w pierwszym (początkowym) nodzie - state node.
Do events state podstawiasz encję sensora utworzonego przez integrację, o której mowa.
Jest jednak mały problem, po odebraniu przesyłki encja pozostaje w systemie tylko jakiś czas , potem zostaje usunięta, więc ten flow przestaje mieć większy sens. Muszę to przemyśleć i sprawdzić czy mogę to jakoś przerobić.
Właśnie te encje tworzą się dopiero w momencie utworzenia przesyłki i jest w niej zawarty nr paczki.
Gdy w danej chwili nie ma żadnych przesyłek utworzonych integracja nie wystawia również encji, które można byłoby wykorzystać w nodzie events state.
Integracja jest w fazie wstępnego rozwoju i już autor z pomocą @Allon dodaje czujnik binarny, który będzie bardzo pomocny. Oczywiście flow będzie do przeróbki i trzeba się uzbroić w cierpliwość
Nie zdążyłem więc zasługa dodania dla autora, ale poprawiłem pare błędów które mogły by przeszkadzać.
Jasna sprawa, muszę przyznać, że w moim przypadku jest bardzo przydatna integracja ![]()
Przyznam że sam miałem robić nawet baze wszystkich integracji do śledzenia przesyłek a w szczególności inpostu, ale widzę że nie muszę
Panowie, podrzućcie proszę Flow umożliwiający wysyłanie wiadomości w momencie gdy przesyłka jest gotowa do odbioru.
Same powiadomienia zrobię za pomocą SMS, bo mam modem GSM zintegrowany z HA i tu sobie poradzę.
Ponieważ nie jestem w stanie wydobyć informacji do NR o paczkach z HA , ani przez get entites, ani events all, podszedłem do tematu trochę inaczej, może to się komuś nie podobać, ale nie jestem specem od NR i naprawdę mimo prób z czujnikiem “Aktywne przesyłki” czyli zmiana stanu na inny niż 0, potem opóźnienie kilka sekund i próby filtrowania z wszystkich encji nic nie wskórałem. Postanowiłem wykorzystać brokera mqtt do publikowania tablicy przesyłek i to robię automatyzacją w HA.
Automatyzacja to cykliczna co 5 min publikacja “sprawdzająca” po domenie ‘polish_shipment_tracking’.
Wszystkie informacje można podejrzeć w mqtt explorer, temat to paczki/aktualizacja.
W samym HA to już wszystko, a kod automatyzacji wstawiam poniżej.
Nie korzystam z czujnika stanu przesyłek, który zawsze jest dostępny w integracji.
alias: Paczki → MQTT (polling)
triggers:
- minutes: /5
trigger: time_pattern
actions:
- variables:
paczki: |
{{
states.sensor
| selectattr('attributes.integration_domain','eq','polish_shipment_tracking')
| map(attribute='attributes')
| list
}}
- data:
topic: paczki/aktualizacja
payload: "{{ paczki | tojson }}"
action: mqtt.publish
mode: single
W NR za pomocą noda mqtt-in subskrybuję jeden temat i dzięki temu mam informację o wszystkich przesyłkach lub ich braku.
Dalej flow “rozbija” tablicę na pojedyncze widomości rozróżniając paczki po numerze i aktualnym statusie, wysyła powiadomienie dla każdej paczki osobno tylko wtedy gdy jest gotowa do odbioru.
Dodatkowo jest przypominanie o nieodebranej przesyłce co 8h resetowane po odebraniu.
Tworzenie wiadomości jest typowo pod telegram bot, ostatnia funkcja.
Jak ktoś potrafi zrobić to bez udziału automatyzacji, to sam chętnie skorzystam.
Nie jestem w to dobry ale dodałem custom eventy. Może to pomoże?
Integracja publikuje zdarzenia na magistrali hass.bus:
polish_shipment_tracking_new_shipment - nowa przesyłka
polish_shipment_tracking_shipment_status_changed - przesyłka zmieniła stan
Przykładowy payload:
{
"courier": "inpost",
"shipment_id": "1234567890",
"entity_id": "sensor.inpost_paczka_1234567890",
"status_raw": "in_transit",
"status_key": "in_transport"
}
Dla polish_shipment_tracking_shipment_status_changed dodatkowo występują pola:
old_status_raw
old_status_key
new_status_raw
new_status_key
Witajcie, ja to zrobiłem w ten sposób
Pierwszy nod: “Paczka”
wybieramy encję jako regex: i wpisujemy ^sensor.paczka_.*, system sam wyszukuje wszystkie encje sensor.paczka… i reaguje na zmianę ich statusu.
Sprawdzałeś jak to się zachowa gdy jeszcze nie ma encji “sensor.paczka” ?
Czy pojawienie się encji uruchomi trigger ?
Tego nie wiem bo mam w aplikacji inpostu starą i nie aktywną już przesyłkę, która od razu wygenerowała encje. Nie wiem też jak zachowa się flow w wypadku multiskrytki, gdy będzie kilka przesyłek w jednej skrytce. W pojedynczych przesyłkach działa ale sprawdzone mam tylko z InPostu.
Mimo wszystko dzięki za pomysł, analizując teoretycznie samo pojawienie się sensora może jeszcze nie wywołać akcji, ale zmiana stanu z utworzona , na w transporcie, powinno już wyzwolić trigger ![]()
Będę to testował . Dzięki
Nie da się w NR nasłuchiwać na custom eventy? Specjalnie zrobiłem custom event na pojawienie się paczki jako sensora oraz zmianę jego statusu żeby nie trzeba było się męczyć z tym. Szybkie wyszukiwanie mówi że to może pomóc: First Automation | node-red-contrib-home-assistant-websocket
Działa wszystko w 100% mój flow poniżej jakby ktoś chciał skorzystać
[
{
"id": "7a244de00b607592",
"type": "switch",
"z": "a57403b63afbeda8",
"name": "Status",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "created",
"vt": "str"
},
{
"t": "eq",
"v": "in_transport",
"vt": "str"
},
{
"t": "eq",
"v": "handed_out_for_delivery",
"vt": "str"
},
{
"t": "eq",
"v": "waiting_for_pickup",
"vt": "str"
},
{
"t": "neq",
"v": "waiting_for_pickup",
"vt": "str"
}
],
"repair": false,
"outputs": 5,
"x": 310,
"y": 4100,
"wires": [
[
"ad42ce02d91bc9eb"
],
[
"34d81518c2434068"
],
[
"9d73f74b5459cc3a"
],
[
"d5e9daf6a25d95db",
"f92790e2943119ba"
],
[
"47efefa6d5cd8e9c"
]
]
},
{
"id": "d5e9daf6a25d95db",
"type": "function",
"z": "a57403b63afbeda8",
"name": "Wiadomość - waiting_for_pickup",
"func": "const attr = msg.data?.new_state?.attributes;\nif (!attr) return null;\n\n// --------- LOKALIZACJA ---------\nconst location = attr.location ?? \"W doręczeniu przez kuriera\";\n\n// --------- NADAWCA (dynamiczny) ---------\nlet sender = attr.sender;\n\n// jeśli brak sender, szukamy dowolnego klucza zaczynającego się od \"sender\"\nif (!sender) {\n const senderKey = Object.keys(attr).find(k =>\n k.toLowerCase().startsWith(\"sender\")\n );\n sender = senderKey ? attr[senderKey] : \"Nieznany nadawca\";\n}\n\n// --------- WIADOMOŚĆ ---------\nconst text = `📦 *Paczka gotowa do odbioru*\n🚚 Kurier: ${attr.courier ?? \"Brak danych\"}\n📨 Nadawca: ${sender}\n🔢 Numer: ${attr.tracking_number ?? \"Brak numeru\"}\n📍 Lokalizacja: ${location}\n🔓 * Kod odbioru:* ${ attr.open_code }`;\n\nflow.set(\"paczka_text_1\", text);\n\nmsg.payload = {\n type: \"message\",\n chatId: \"0000000000\",\n content: text,\n options: {\n parse_mode: \"Markdown\"\n }\n};\n\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 670,
"y": 4120,
"wires": [
[
"77a73a98d592374e"
]
]
},
{
"id": "f92790e2943119ba",
"type": "trigger",
"z": "a57403b63afbeda8",
"name": "Przypomnienie co 12h",
"op1": "",
"op2": "remind",
"op1type": "nul",
"op2type": "str",
"duration": "12",
"extend": true,
"overrideDelay": false,
"units": "hr",
"reset": "",
"bytopic": "all",
"topic": "paczka",
"outputs": 1,
"x": 640,
"y": 4160,
"wires": [
[
"9f7211778077fb4e"
]
]
},
{
"id": "9f7211778077fb4e",
"type": "function",
"z": "a57403b63afbeda8",
"name": "Przypomnienia",
"func": "const base = flow.get(\"paczka_text\");\nif (!base) return null;\n\nmsg.payload = {\n type: \"message\",\n \"chatId\": \"0000000000\", // tu podaj swój chatID\n content: `⏰ *Przypomnienie*\\n\\n${base}`,\n options: {\n parse_mode: \"Markdown\"\n }\n};\n\nreturn msg;\n",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 860,
"y": 4160,
"wires": [
[
"77a73a98d592374e"
]
]
},
{
"id": "47efefa6d5cd8e9c",
"type": "trigger",
"z": "a57403b63afbeda8",
"name": "Stop przypomnień",
"op1": "",
"op2": "",
"op1type": "nul",
"op2type": "nul",
"duration": "0",
"extend": false,
"overrideDelay": false,
"units": "second",
"reset": "true",
"bytopic": "all",
"topic": "paczka",
"outputs": 1,
"x": 630,
"y": 4200,
"wires": [
[]
]
},
{
"id": "77a73a98d592374e",
"type": "telegram sender",
"z": "a57403b63afbeda8",
"name": "Telegram",
"bot": "19ff4b39bf671e48",
"haserroroutput": false,
"outputs": 1,
"x": 1100,
"y": 4060,
"wires": [
[]
]
},
{
"id": "6d27e8b391623a90",
"type": "server-state-changed",
"z": "a57403b63afbeda8",
"name": "Paczka",
"server": "42e1a8c4.ec01f8",
"version": 6,
"outputs": 1,
"exposeAsEntityConfig": "",
"entities": {
"entity": [],
"substring": [],
"regex": [
"^sensor\\.paczka_.*",
"^sensor\\.inpost_.*",
"^sensor\\.pocztex_.*"
]
},
"outputInitially": true,
"stateType": "str",
"ifState": "",
"ifStateType": "str",
"ifStateOperator": "is",
"outputOnlyOnStateChange": true,
"for": "0",
"forType": "num",
"forUnits": "minutes",
"ignorePrevStateNull": false,
"ignorePrevStateUnknown": false,
"ignorePrevStateUnavailable": false,
"ignoreCurrentStateUnknown": false,
"ignoreCurrentStateUnavailable": false,
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "string",
"valueType": "entityState"
},
{
"property": "data",
"propertyType": "msg",
"value": "",
"valueType": "eventData"
},
{
"property": "topic",
"propertyType": "msg",
"value": "",
"valueType": "triggerId"
}
],
"x": 90,
"y": 4100,
"wires": [
[
"7a244de00b607592"
]
]
},
{
"id": "34d81518c2434068",
"type": "function",
"z": "a57403b63afbeda8",
"name": "Wiadomość - in_transport",
"func": "const attr = msg.data?.new_state?.attributes;\nif (!attr) return null;\n\n// --------- LOKALIZACJA ---------\nconst location = attr.location ?? \"W doręczeniu przez kuriera\";\n\n// --------- NADAWCA (dynamiczny) ---------\nlet sender = attr.sender;\n\n// jeśli brak sender, szukamy dowolnego klucza zaczynającego się od \"sender\"\nif (!sender) {\n const senderKey = Object.keys(attr).find(k =>\n k.toLowerCase().startsWith(\"sender\")\n );\n sender = senderKey ? attr[senderKey] : \"Nieznany nadawca\";\n}\n\n// --------- WIADOMOŚĆ ---------\nconst text = `📦 *Paczka już jedzie do Ciebie*\n🚚 Kurier: ${attr.courier ?? \"Brak danych\"}\n📨 Nadawca: ${sender}\n🔢 Numer: ${attr.tracking_number ?? \"Brak numeru\"}\n📍 Lokalizacja: ${location}`;\n\nflow.set(\"paczka_text_1\", text);\n\nmsg.payload = {\n type: \"message\",\n chatId: \"0000000000\",\n content: text,\n options: {\n parse_mode: \"Markdown\"\n }\n};\n\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 650,
"y": 4040,
"wires": [
[
"77a73a98d592374e"
]
]
},
{
"id": "9d73f74b5459cc3a",
"type": "function",
"z": "a57403b63afbeda8",
"name": "Wiadomość - handed_out_for_delivery",
"func": "const attr = msg.data?.new_state?.attributes;\nif (!attr) return null;\n\n// --------- LOKALIZACJA ---------\nconst location = attr.location ?? \"W doręczeniu przez kuriera\";\n\n// --------- NADAWCA (dynamiczny) ---------\nlet sender = attr.sender;\n\n// jeśli brak sender, szukamy dowolnego klucza zaczynającego się od \"sender\"\nif (!sender) {\n const senderKey = Object.keys(attr).find(k =>\n k.toLowerCase().startsWith(\"sender\")\n );\n sender = senderKey ? attr[senderKey] : \"Nieznany nadawca\";\n}\n\n// --------- WIADOMOŚĆ ---------\nconst text = `📦 *Paczka została wydana do doręczenia*\n🚚 Kurier: ${attr.courier ?? \"Brak danych\"}\n📨 Nadawca: ${sender}\n🔢 Numer: ${attr.tracking_number ?? \"Brak numeru\"}\n📍 Lokalizacja: ${location}`;\n\nflow.set(\"paczka_text_1\", text);\n\nmsg.payload = {\n type: \"message\",\n chatId: \"0000000000\",\n content: text,\n options: {\n parse_mode: \"Markdown\"\n }\n};\n\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 690,
"y": 4080,
"wires": [
[
"77a73a98d592374e"
]
]
},
{
"id": "ad42ce02d91bc9eb",
"type": "function",
"z": "a57403b63afbeda8",
"name": "Wiadomość - created",
"func": "const attr = msg.data?.new_state?.attributes;\nif (!attr) return null;\n\n// --------- LOKALIZACJA ---------\nconst location = attr.location ?? \"W doręczeniu przez kuriera\";\n\n// --------- NADAWCA (dynamiczny) ---------\nlet sender = attr.sender;\n\n// jeśli brak sender, szukamy dowolnego klucza zaczynającego się od \"sender\"\nif (!sender) {\n const senderKey = Object.keys(attr).find(k =>\n k.toLowerCase().startsWith(\"sender\")\n );\n sender = senderKey ? attr[senderKey] : \"Nieznany nadawca\";\n}\n\n// --------- WIADOMOŚĆ ---------\nconst text = `📦 *Sprzedawca wygenerował etykietę Twojej przesyłki*\n🚚 Kurier: ${attr.courier ?? \"Brak danych\"}\n📨 Nadawca: ${sender}\n🔢 Numer: ${attr.tracking_number ?? \"Brak numeru\"}\n📍 Lokalizacja: ${location}`;\n\nflow.set(\"paczka_text_1\", text);\n\nmsg.payload = {\n type: \"message\",\n chatId: \"0000000000\",\n content: text,\n options: {\n parse_mode: \"Markdown\"\n }\n};\n\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 640,
"y": 4000,
"wires": [
[
"77a73a98d592374e"
]
]
},
{
"id": "19ff4b39bf671e48",
"type": "telegram bot",
"botname": "@botname",
"usernames": "@usernames",
"chatids": "",
"baseapiurl": "",
"testenvironment": false,
"updatemode": "polling",
"pollinterval": 300,
"usesocks": false,
"sockshost": "",
"socksprotocol": "socks5",
"socksport": 6667,
"socksusername": "anonymous",
"sockspassword": "",
"bothost": "",
"botpath": "",
"localbothost": "0.0.0.0",
"localbotport": 8443,
"publicbotport": 8443,
"privatekey": "",
"certificate": "",
"useselfsignedcertificate": false,
"sslterminated": false,
"verboselogging": false
},
{
"id": "42e1a8c4.ec01f8",
"type": "server",
"name": "Home Assistant",
"version": 6,
"addon": true,
"rejectUnauthorizedCerts": true,
"ha_boolean": [
"y",
"yes",
"true",
"on",
"home",
"open"
],
"connectionDelay": true,
"cacheJson": true,
"heartbeat": false,
"heartbeatInterval": "30",
"areaSelector": "friendlyName",
"deviceSelector": "friendlyName",
"entitySelector": "friendlyName",
"statusSeparator": "at: ",
"statusYear": "hidden",
"statusMonth": "short",
"statusDay": "numeric",
"statusHourCycle": "h23",
"statusTimeFormat": "h:m",
"enableGlobalContextStore": true
},
{
"id": "0561779cf8b2693d",
"type": "global-config",
"env": [],
"modules": {
"node-red-contrib-telegrambot": "17.0.5",
"node-red-contrib-home-assistant-websocket": "0.80.3"
}
}
]