▷ Current status: 0% ███████████████████████████▒▒▒ 100% (= first running version)
Hi.
Welcome to healthcore.dev❗️
But wait: what the hell is healthcore.dev❓
healthcore.dev (or simply healthcore) is part of the open software and hardware architecture of bulp.io. With bulp, healthcare devices from any manufacturer can communicate with each other and any interface through a variety of protocols and APIs. In this way, bulp centrally captures a person's condition in many different ways, reacts automatically to changes in their environment, and optionally informs caregivers, nurses or family members. bulp.io follows the open-core approach: the software core is open source, while revenue is generated through hardware and services.
The software core is called "healthcore" (obviously!) and it standardizes the data from various devices, processes scenarios, and triggers actions. A simple API allows interfaces such as apps to visualize the device data.
Healthcore can run on any hardware — a Raspberry Pi, a PC, or any other device with a Linux system or Windows. The choice is yours.
Just imagine something like Home Assistant or OpenHAB, but specialized for healthcare. That’s exactly what this is.
Let’s democratize and de-monopolize the healthcare sector. Make healthcare devices and infrastructure affordable for everyone!
🤘HEALTHCORE!!!🤘
- 🏗️ Architecture
- 💻 Installation (software)
- 📁 Folder structure
- 🔧 Installation (hardware)
- 📈 Healthcheck - a monitor for healthcore
- 🧩 Own converters
- 🔌 API communication
Let’s take a look at the architecture of bulp.io:

In the middle — that’s the healthcore. The healthcore consists of several Node.js servers with different tasks. The Node.js servers communicate with each other via MQTT. The most important thing is that there is a separate bridge for each protocol, which standardizes the incoming and outgoing data of the devices. The healthcore supports the following protocols:
- Bluetooth
- ZigBee
- Thread
- LoRa P2P
- HTTP
And now the best part: you can add your own devices to the healthcore! Each bridge includes a list of classes for devices. So you can handle the data transformation with simple JavaScript in a class for your device (= very cool).
On the left, you can see how various interfaces communicate bi-directionally with the healthcore via a standardized API and visualize the data, for example. Just bring your own interface.
Prerequisites
- Node.js (v22 or higher) and npm
Project setup
- Clone/download the repository and
cdinto its root. - Create
.env.localto override defaults; fill in:- Adapter paths:
CONF_zigBeeAdapterPort,CONF_zigBeeAdapterName,CONF_loRaAdapterPath,
- Adapter paths:
- Install dependencies:
npm install
Start services (each in its own terminal or managed via a process manager):
# MQTT broker
node broker/app.js
# Server
node server/app.js
# Bridges
node "bridge - bluetooth/app.js"
node "bridge - zigbee/app.js"
node "bridge - lora/app.js"
node "bridge - http/app.js"If you want to use it for production, just run
.\production-start.shproduction-start.sh uses the process manager, so that a service is restarted if it crashes. The relevant logs can be found in the logs folder.
├── broker/ # MQTT broker
├── server/ # Server
│ ├── routes/ # Routes for communication Interface via SSE ↔ Server ↔ Interface via API
│ └── libs/ # Additionally libraries
├── bridge - bluetooth/ # Bluetooth ↔ MQTT bridge
│ └── converters/ # Common and own converters
├── bridge - zigbee/ # ZigBee ↔ MQTT bridge
│ └── converters/ # Common and own converters
├── bridge - lora/ # LoRa ↔ MQTT bridge
│ └── converters/ # Common and own converters
├── bridge - http/ # HTTP ↔ MQTT bridge
│ └── converters/ # Common and own converters
├── tests/ # Example device firmware (for Arduino) and other testing scripts
└── healthcheck/ # Healthcheck (see below)
- Host platform
- Raspberry Pi 4 or (or better) or any Linux/Windows PC with network access
- Adapters
- Bluetooth: Built-in BLE or USB dongle
- ZigBee: USB coordinator (e.g. CC2531, ConBee II, Sonoff Zigbee 3.0 USB stick)
- LoRa: USB or serial LoRa adapter (e.g. Dragino LA66 LoRaWAN USB Adapter)
- Connections
- Plug adapters into host; note device paths (e.g.
/dev/ttyUSB0orCOMx) and set in.env.local
- Plug adapters into host; note device paths (e.g.
Healthcore has an integrated interface (= healthcheck) to view the status of the individual bridges, brokers and servers and to start and stop them. All outputs are displayed in a console.
How to start healthcheck:
node healthcheck/app.jsThen open a browser und type:
http://localhost:9990(9990 is the standard port healthcheck and localhost the standard base URL, configured in .env)
The Own converters subsystem lets you transform raw device data (e.g., binary BLE characteristic values) into structured JSON properties that your interface (i.e. your app) can use. Each bridge (Bluetooth, ZigBee, LoRa, HTTP) has its own converters/ folder with individual converter classes extending a shared ConverterStandard base. Below is a detailed Bluetooth bridge example:
-
Create a new JS file in the bridge’s
converters/folder (e.g.Converter_MyConverter.js). -
Extend
ConverterStandard:In
Converter_MyConverter.js, import the base and declare your class:const { ConverterStandard } = require("./ConverterStandard.js"); class Converter_BulpAZ123 extends ConverterStandard { // always extend "ConverterStandard" static productName = "bulp-AZ-123"; // static property to identify the product name this converter is for constructor() { super(); // call the parent class constructor this.powerType = "wire"; // set the power type for this device ("wire" or "battery") // Define the properties supported by this device, using their Bluetooth UUIDs as keys. Each property object contains metadata used for conversion and access control. this.properties["19b10000e8f2537e4f6cd104768a1217"] = { name: "rotary_switch", // property name (easy to understand) notify: true, // notify healthcore if this value changes read: true, // read access write: false, // write access anyValue: 0, // pre-defined value standard: false, // is this a standard value? (https://www.bluetooth.com/wp-content/uploads/Files/Specification/Assigned_Numbers.html) valueType: "Integer" // Integer or String or Options }; this.properties["19b10000e8f2537e4f6cd104768a1218"] = { name: "speaker", notify: false, read: true, write: true, anyValue: ["on", "off"], valueType: "Options" }; // ... } // GET: Converts a raw value from the device into a higher-level representation, based on the property metadata. get(property, value) { if (property.read === false) { return undefined; // property is not readable, so return undefined } else { if (property.standard === true) { // if this is a standard property then use common converter return this.getStandard(property, value); } else { // device-specific conversion logic if (property.name === "rotary_switch") { const buf = Buffer.from(value); return buf[0]; } else if (property.name === "speaker") { if (value[0] === 1) { return "on"; } else { return "off"; } } // ... else { // unknown property name return undefined; } } } } // SET: Converts a higher-level value into a format suitable for writing to the device, based on the property metadata. set(property, value) { if (property.write === false) { return undefined; // if property is not writable, so return undefined } else { if (property.name === "speaker") { if (property.anyValue.includes(value)) { if (value === "on") { return Buffer.from([1]); } else { return Buffer.from([0]); } } else { return undefined; // invalid value for this property, then return undefined } } // ... else { return undefined; } } } } module.exports = { Converter_BulpAZ123 };
-
Auto-load:
Converters.jsdynamically requires all files inconverters/(excludingConverterStandard.js), detects the staticproductName, and registers your class.
Healthcore provides a comprehensive API that allows you to control all data and devices in a standardized way. Here is a complete example of connecting to a ZigBee device.
You can explore all APIs using Swagger:
http://localhost:9998/api-docs/(9998 is the standard server port and localhost the standard base URL, configured in .env)
Example for ZigBee:
Example coming soon.