{"_id":"@coremarine/thelmabiotel-tblive-nodered","_rev":"7-99813f80743db52c1fae16c59f99823a","name":"@coremarine/thelmabiotel-tblive-nodered","dist-tags":{"latest":"3.0.0"},"versions":{"0.0.1":{"name":"@coremarine/thelmabiotel-tblive-nodered","version":"0.0.1","keywords":["node-red","iot","hydrophone","thelma","thelmabiotel","accoustic","inclinometer"],"author":{"name":"CoreMarine"},"license":"MIT","_id":"@coremarine/thelmabiotel-tblive-nodered@0.0.1","maintainers":[{"name":"valentina-rubane","email":"vru@core-marine.com"},{"name":"crisconru","email":"crisconru@gmail.com"},{"name":"coremarinedev","email":"dev@core-marine.com"}],"homepage":"https://github.com/core-marine-dev/devices/tree/main/packages/thelmabiotel-tblive-nodered","bugs":{"url":"https://github.com/core-marine-dev/devices/issues"},"dist":{"shasum":"dcc68c4536910a8b4936c3f8ac39d47634ba71c9","tarball":"https://registry.npmjs.org/@coremarine/thelmabiotel-tblive-nodered/-/thelmabiotel-tblive-nodered-0.0.1.tgz","fileCount":10,"integrity":"sha512-v3KqhLgPCy/RcwrWCZT8JWqF3mzSTxu6K/GLV89IVS5ROwgjycUcem46yhB5+IWqHKQMpsIBkc+1ZYhBNv4EUg==","signatures":[{"sig":"MEQCICnPw2c1EI312H6l5k+egcIDksNzmwM98GftZ6OHMLfxAiBd8HPcjWUKdk6xaLNyTqrg5moEX5cNK0fIe6VSrfaYdQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":53349},"main":"index.js","engines":{"node":">=18.0.0"},"gitHead":"da7cbaeedb05614866901c73597caaf5fb8c401c","scripts":{"test":"mocha \"tests/**/*.test.js\"","docker":"sh manual_tests.sh","test:vitest":"vitest"},"_npmUser":{"name":"coremarinedev","email":"dev@core-marine.com"},"node-red":{"nodes":{"cma-thelmabiotel-tblive":"src/parser.js"},"version":">=3.0.0"},"repository":{"url":"git+https://github.com/core-marine-dev/devices.git","type":"git"},"_npmVersion":"10.7.0","description":"Node-Red component to work with Thelma Biotel hydrophones TB-Live","directories":{},"_nodeVersion":"20.15.0","dependencies":{"@coremarine/thelmabiotel-tblive":">=0.0.6"},"_hasShrinkwrap":false,"peerDependencies":{"valibot":">=0.30.0"},"_npmOperationalInternal":{"tmp":"tmp/thelmabiotel-tblive-nodered_0.0.1_1720177686062_0.3184211256075766","host":"s3://npm-registry-packages"}},"0.0.2":{"name":"@coremarine/thelmabiotel-tblive-nodered","version":"0.0.2","keywords":["node-red","iot","hydrophone","thelma","thelmabiotel","accoustic","inclinometer"],"author":{"name":"CoreMarine"},"license":"MIT","_id":"@coremarine/thelmabiotel-tblive-nodered@0.0.2","maintainers":[{"name":"valentina-rubane","email":"vru@core-marine.com"},{"name":"coremarinedev","email":"dev@core-marine.com"},{"name":"crisconru","email":"crisconru@gmail.com"}],"homepage":"https://github.com/core-marine-dev/devices/tree/main/packages/thelmabiotel-tblive-nodered","bugs":{"url":"https://github.com/core-marine-dev/devices/issues"},"dist":{"shasum":"33798ba24519fd29a07c92c7f13911b915870cfc","tarball":"https://registry.npmjs.org/@coremarine/thelmabiotel-tblive-nodered/-/thelmabiotel-tblive-nodered-0.0.2.tgz","fileCount":10,"integrity":"sha512-VH2QVxRPFQDRzyZB2b8Ve8i7pLvr74Ng2H1rKFvhBNy1ol6owTELDflgbcVQEEeIMD5QZbH/dy/o1d7emBUTUQ==","signatures":[{"sig":"MEYCIQDFS4Q86Bqc6vi3qOKc0sL/u08Tl3nRyj0fP2gi4tigtAIhANiO1p+Bi2Wlz5a1+8uo6Wd4wwo+O3KVrZYJHkaWhn4b","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53348},"main":"index.js","engines":{"node":">=18.0.0"},"gitHead":"1dec380d1f11f27487fec214e5b4aa7e18e112db","scripts":{"test":"mocha \"tests/**/*.test.js\"","docker":"sh manual_tests.sh","test:vitest":"vitest"},"_npmUser":{"name":"coremarinedev","email":"dev@core-marine.com"},"node-red":{"nodes":{"cma-thelmabiotel-tblive":"src/parser.js"},"version":">=3.0.0"},"repository":{"url":"git+https://github.com/core-marine-dev/devices.git","type":"git"},"_npmVersion":"10.8.2","description":"Node-Red component to work with Thelma Biotel hydrophones TB-Live","directories":{},"_nodeVersion":"20.19.0","dependencies":{"@coremarine/thelmabiotel-tblive":">=0.0.7"},"_hasShrinkwrap":false,"peerDependencies":{"valibot":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/thelmabiotel-tblive-nodered_0.0.2_1743676800141_0.7409880008920624","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@coremarine/thelmabiotel-tblive-nodered","version":"1.0.0","keywords":["node-red","iot","hydrophone","thelma","thelmabiotel","accoustic","inclinometer"],"author":{"name":"CoreMarine"},"license":"MIT","_id":"@coremarine/thelmabiotel-tblive-nodered@1.0.0","maintainers":[{"name":"valentina-rubane","email":"vru@core-marine.com"},{"name":"coremarinedev","email":"dev@core-marine.com"},{"name":"crisconru","email":"crisconru@gmail.com"}],"homepage":"https://github.com/core-marine-dev/devices/tree/main/packages/thelmabiotel-tblive-nodered","bugs":{"url":"https://github.com/core-marine-dev/devices/issues"},"dist":{"shasum":"34e829d058fc75eb70943c8d22976d8597839b40","tarball":"https://registry.npmjs.org/@coremarine/thelmabiotel-tblive-nodered/-/thelmabiotel-tblive-nodered-1.0.0.tgz","fileCount":8,"integrity":"sha512-KHpsM74ULB23IHHvQglhIj785nqZDevEPg4Vsm3zAJEQKTB40e2vhcI0xiQo8nkK+3W5H7SYvVTehh5d2+b/4Q==","signatures":[{"sig":"MEQCICskO3FXSfshR8JHTKKPJeJKqnI1yjeXIp6B4i797yNwAiB9ky9QUlV0Pb5jiKhawn65HxE9MgiMYkGrh9Ecnh4S3A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48261},"main":"index.js","engines":{"node":">=18.0.0"},"gitHead":"1c05607c36b2d87d2b71ab7772136ac1945ea624","scripts":{"test":"mocha \"tests/**/*.test.js\"","docker":"sh manual_tests.sh","test:vitest":"vitest"},"_npmUser":{"name":"coremarinedev","email":"dev@core-marine.com"},"node-red":{"nodes":{"cma-thelmabiotel-tblive":"src/parser.js"},"version":">=3.0.0"},"repository":{"url":"git+https://github.com/core-marine-dev/devices.git","type":"git"},"_npmVersion":"10.8.2","description":"Node-Red component to work with Thelma Biotel hydrophones TB-Live","directories":{},"_nodeVersion":"20.19.2","dependencies":{"@coremarine/thelmabiotel-tblive":">=1.0.2"},"_hasShrinkwrap":false,"peerDependencies":{"valibot":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/thelmabiotel-tblive-nodered_1.0.0_1749823169468_0.05064842508997014","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@coremarine/thelmabiotel-tblive-nodered","version":"2.0.0","keywords":["node-red","iot","cma","hydrophone","thelma","thelmabiotel","tb-live","acoustic","inclinometer","parser","protocol"],"author":"CoreMarine","license":"MIT","_id":"@coremarine/thelmabiotel-tblive-nodered@2.0.0","maintainers":[{"name":"coremarinedev","email":"dev@core-marine.com"},{"name":"crisconru","email":"crisconru@gmail.com"},{"name":"egr666","email":"egr@core-marine.com"}],"homepage":"https://github.com/core-marine-dev/devices/tree/main/packages/thelmabiotel-tblive-nodered","bugs":{"url":"https://github.com/core-marine-dev/devices/issues"},"dist":{"shasum":"de786e4241e4170f3789219459a6f8b2816c3343","tarball":"https://registry.npmjs.org/@coremarine/thelmabiotel-tblive-nodered/-/thelmabiotel-tblive-nodered-2.0.0.tgz","fileCount":8,"integrity":"sha512-yGcKUfE7WN3F4+Imd+FTIIj50HYYqvuGWB8tPeafytGMlMtRWKgi2aw4F8VnvOLjA6UE1EGIZrli6/uhdNs4qg==","signatures":[{"sig":"MEQCIC9J/4rbgqpcSST05wec71PxvSdjkV3Y2LO8d/9KKHuGAiBZXqAaayJAXWBONoaaK8I4dDLwOTM4hTf9mIdbvvc04Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@coremarine%2fthelmabiotel-tblive-nodered@2.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":88221},"main":"dist/parser.js","engines":{"node":">=22"},"scripts":{"dev":"pnpm run build && node dev-server.mjs dev","lint":"eslint","test":"node --import tsx --test \"tests/**/*.test.ts\"","build":"pnpm run format && tsup && node copy-assets.mjs","format":"eslint --fix","examples":"pnpm run build && node dev-server.mjs examples","test:unit":"node --import tsx --test \"tests/*.unit.test.ts\"","test:integration":"node --import tsx --test \"tests/*.integration.test.ts\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7a953d4a-5689-48c4-a4c5-833406fcb04a"}},"node-red":{"nodes":{"cma-thelmabiotel-tblive":"dist/parser.js"},"version":">=4.0.0"},"repository":{"url":"git+https://github.com/core-marine-dev/devices.git","type":"git","directory":"packages/thelmabiotel-tblive-nodered"},"description":"Node-RED component to read Thelma Biotel TB Live receiver output as CMA","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@coremarine/thelmabiotel-tblive":"^2.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.23.1","@types/node-red":"1.3.5"},"_npmOperationalInternal":{"tmp":"tmp/thelmabiotel-tblive-nodered_2.0.0_1785414279273_0.8541353163921679","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"@coremarine/thelmabiotel-tblive-nodered","version":"3.0.0","author":"CoreMarine","license":"MIT","description":"Node-RED component to read Thelma Biotel TB Live receiver output as CMA","homepage":"https://github.com/core-marine-dev/devices/tree/main/packages/thelmabiotel-tblive-nodered","repository":{"type":"git","url":"git+https://github.com/core-marine-dev/devices.git","directory":"packages/thelmabiotel-tblive-nodered"},"bugs":{"url":"https://github.com/core-marine-dev/devices/issues"},"keywords":["node-red","iot","cma","hydrophone","thelma","thelmabiotel","tb-live","acoustic","inclinometer","parser","protocol"],"engines":{"node":">=22"},"node-red":{"version":">=4.0.0","nodes":{"cma-thelmabiotel-tblive":"dist/parser.js"}},"main":"dist/parser.js","dependencies":{"@coremarine/thelmabiotel-tblive":"^3.0.0"},"devDependencies":{"@types/node-red":"1.3.5","tsx":"4.23.1"},"scripts":{"build":"pnpm run format && tsup && node copy-assets.mjs","lint":"eslint","format":"eslint --fix","test":"node --import tsx --test \"tests/**/*.test.ts\"","test:coverage":"node --import tsx --test --experimental-test-coverage --test-coverage-include=\"src/**\" \"tests/**/*.test.ts\"","test:unit":"node --import tsx --test \"tests/*.unit.test.ts\"","test:integration":"node --import tsx --test \"tests/*.integration.test.ts\"","dev":"pnpm run build && node dev-server.mjs dev","examples":"pnpm run build && node dev-server.mjs examples"},"_nodeVersion":"24.18.0","_id":"@coremarine/thelmabiotel-tblive-nodered@3.0.0","dist":{"integrity":"sha512-K/otrjquUnDqfDsX2DWQErs3mmYJJV1vIVbcdungu/h1F3W53+nsr4tNHEBnzkbkhFK/9X7ZPFBhasqh1jXVtg==","shasum":"631cb96c04cb70513a7844224e107d1209aaa5d9","tarball":"https://registry.npmjs.org/@coremarine/thelmabiotel-tblive-nodered/-/thelmabiotel-tblive-nodered-3.0.0.tgz","fileCount":8,"unpackedSize":89480,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@coremarine%2fthelmabiotel-tblive-nodered@3.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGHfmFGT2JDPe5Sje/VDkfzmRYKcfUh9RJPnRdmJwOs9AiEA5FZ2Fh/p86gacr5Df/pEcj3CF29qmruUDv+F72LB/DM="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7a953d4a-5689-48c4-a4c5-833406fcb04a"}},"directories":{},"maintainers":[{"name":"coremarinedev","email":"dev@core-marine.com"},{"name":"crisconru","email":"crisconru@gmail.com"},{"name":"egr666","email":"egr@core-marine.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/thelmabiotel-tblive-nodered_3.0.0_1785601906889_0.5500569669318793"},"_hasShrinkwrap":false}},"time":{"created":"2024-07-05T11:08:05.949Z","modified":"2026-08-01T16:31:47.428Z","0.0.1":"2024-07-05T11:08:06.246Z","0.0.2":"2025-04-03T10:40:00.318Z","1.0.0":"2025-06-13T13:59:29.621Z","2.0.0":"2026-07-30T12:24:39.463Z","3.0.0":"2026-08-01T16:31:47.019Z"},"bugs":{"url":"https://github.com/core-marine-dev/devices/issues"},"author":"CoreMarine","license":"MIT","homepage":"https://github.com/core-marine-dev/devices/tree/main/packages/thelmabiotel-tblive-nodered","keywords":["node-red","iot","cma","hydrophone","thelma","thelmabiotel","tb-live","acoustic","inclinometer","parser","protocol"],"repository":{"type":"git","url":"git+https://github.com/core-marine-dev/devices.git","directory":"packages/thelmabiotel-tblive-nodered"},"description":"Node-RED component to read Thelma Biotel TB Live receiver output as CMA","maintainers":[{"name":"coremarinedev","email":"dev@core-marine.com"},{"name":"crisconru","email":"crisconru@gmail.com"},{"name":"egr666","email":"egr@core-marine.com"}],"readme":"# @coremarine/thelmabiotel-tblive-nodered\n\n[![npm version](https://img.shields.io/npm/v/@coremarine/thelmabiotel-tblive-nodered.svg)](https://www.npmjs.com/package/@coremarine/thelmabiotel-tblive-nodered)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nNode-RED node for the **Thelma Biotel TB Live** acoustic receiver (hydrophone). It turns the\nreceiver's serial output into **CMA**, the same JSON shape every CoreMarine device parser emits.\n\nWrapper of [@coremarine/thelmabiotel-tblive](https://www.npmjs.com/package/@coremarine/thelmabiotel-tblive).\nNode >= 22, Node-RED >= 4.\n\n## Install\n\nFrom the Node-RED palette manager, or:\n\n```bash\nnpm install @coremarine/thelmabiotel-tblive-nodered\n```\n\nThe node appears in the **CoreMarine** palette category as **TB Live parser**.\n\n## Configuration\n\n| Field | Meaning |\n| --- | --- |\n| **Name** | Optional node label |\n| **Firmware** | `Learn from the stream` (default), `1.0.1` or `1.0.2` |\n| **Memory** | On by default — append each input to the buffer instead of replacing it |\n\nThe firmware **is** the protocol version: 1.0.1 detections carry 9 fields and logs 8, while 1.0.2\ncarries 8 and 7. Left on *learn*, the parser works it out from the stream (an `FV=` response, or\nwhether the receiver entered command mode with `LIVECM` or `TBRC`) and reports `unknown` until\nsomething proves it. Pin it when your deployment knows better than the wire does.\n\n## msg API\n\nSend `payload` to parse. Every other key is optional; **a key you do not send is absent from the\noutput too**, and on a bad request the corresponding output key holds an error **string**.\n\n| Key | In | Out |\n| --- | --- | --- |\n| `payload` | TB Live ASCII string | `CMA[]` |\n| `memory` | `{ command: 'get' }` / `{ command: 'set', payload: boolean }` | `{ memory, characters }` |\n| `firmware` | `{ command: 'get' }` / `{ command: 'set', payload: '1.0.1' \\| '1.0.2' }` | `{ firmware, firmwares }` |\n| `ids` | any truthy value | `string[]` — every sentence id it knows |\n| `definition` | `'emitter'` or `{ id, protocol? }` | `SentenceDefinition[]` |\n| `fake` | `{ id, protocol, options? }` | a wire sentence `string` |\n\nFull details, tables and warnings are in the node's **help panel** inside Node-RED.\n\n### Diagnostics\n\n`ids` and `definition` let a flow ask the running node what it expects — field names, types, units,\ndescriptions, which of the device's two APIs a sentence belongs to, and prose saying how it is\nrecognised on the wire. Omit `protocol` to get every firmware version, which is how you see what\nthe firmware changes.\n\nThat matters because these receivers sit on remote installations with restricted internet access\nfor years: asking the deployed node settles a question that would otherwise need the datasheets.\n\n### Fake sentences\n\n`fake` generates a valid sample sentence. `protocol` is required (the output genuinely differs by\nfirmware), it is **deterministic**, and with no `options` it reproduces the datasheets' own\nexamples:\n\n```javascript\nmsg.fake = { id: 'emitter', protocol: '1.0.1' }\n// -> '$1000042,1589557202,615,S64K,1285,0,24,69,11\\r'\n```\n\n## Two things a flow must handle\n\n**A field can be `null`** — present but empty. The emitter `data` field is empty for ID-only\ntransmit protocols (`R256`, `R04K`, `R64K`, `R01M`, `OPi`). **`null` means \"no measurement\" and\nmust never be read as zero.** Version 1.x reported `0` there, which made a missing reading\nindistinguishable from a perfectly vertical mooring line.\n\n**Sentences can carry `errors`.** Nothing the parser receives is dropped silently any more:\nmalformed input, line noise and interference-wrecked sentences all arrive, flagged. Check `errors`\nand `id === 'unknown'` before trusting a reading. The shipped example flow demonstrates this with a\nsplitter routing clean and flagged sentences to separate debug nodes.\n\n**The emitter `data` field is not decoded.** Those 16 bits carry whatever the *emitter's* firmware\nencodes — an inclinometer, or tilt plus depth — which is not part of the TB Live protocol, so\ndecoding it is your flow's job.\n\n## Examples\n\nImport `examples/thelmabiotel-tblive-examples.json` from the Node-RED menu → Import → Examples, or\nopen it directly:\n\n```bash\npnpm run thelmabiotel-tblive:nodered:examples\n```\n\nNine groups, every payload taken from the datasheets: listening data, the empty-`data` case,\nfailed and garbage sentences (line noise, half-duplex interference, bad field counts), memory and\nsplit sentences, firmware learning versus pinning, command-mode responses, diagnostics, and fake\nsentences. It uses **only built-in node types**, so it imports cleanly with no extra contrib nodes.\n\n## Development\n\n```bash\npnpm run thelmabiotel-tblive:nodered:build    # tsup -> CJS + copy html/icons\npnpm run thelmabiotel-tblive:nodered:test     # node:test — unit + real headless node-red\npnpm run thelmabiotel-tblive:nodered:dev      # local Node-RED on a scratch flow\n```\n\n## Upgrading from 1.x\n\nThe output is now **CMA** rather than the old `ParsedSentence`. The node type is **unchanged**\n(`cma-thelmabiotel-tblive`), so existing flows keep their node — but the data changed:\n\n- **`msg.firmwares`** (a bare array, emitted on every message) is gone. Use `msg.firmware` with\n  `{ command: 'get' }`, which reports the current firmware *and* the available ones.\n- **`msg.memory`** was a bare boolean in and out; it is now `{ command, payload }` in and a\n  `{ memory, characters }` report out.\n- **No top-level `mode` or `firmware`** on the output: `mode` moved to `metadata.mode`, and the\n  firmware is now `protocol.version`.\n- **`protocol` is new and required** on every CMA — `{ name: 'TBLive', version }`.\n- **Serial numbers are strings**, so the receiver's inconsistent zero-padding survives (`'001129'`\n  used to become `1129`). Match on the last digits with a string comparison.\n- **Values can be `null`**, and sentences that used to vanish now arrive with `errors`.\n- **`metadata.angle` is gone** — the inclination decode was removed from the library, so a flow\n  that relied on it must decode the `data` field itself.\n- **Node >= 22** (was >= 18) and **Node-RED >= 4** (was >= 3).\n\n## License\n\nMIT\n","readmeFilename":""}