A pure Javascript API for the Seneca Multi Smart Calibrator (MSC) device, using web bluetooth.
npm install bt-seneca-msc



> A pure JavaScript API for the Seneca Multi Smart Calibrator (MSC) device, using Web Bluetooth from modern browsers.
๐ Live Demo | ๐ Documentation | ๐ ๏ธ Getting Started
---
- Overview
- Prerequisites
- Quick Start
- Installation
- API Reference
- Usage Examples
- Device Features
- Performance
- Development
- Troubleshooting
- Contributing
This package provides a complete JavaScript interface for the Seneca Multi Smart Calibrator device via Web Bluetooth. It implements Modbus RTU FC3/FC16 functions specifically designed to run in pure browser environments without Node.js dependencies.
- ๐ Pure browser implementation using Web Bluetooth API
- ๐ Modbus RTU protocol over Bluetooth
- โก Real-time measurement and generation capabilities
- ๐ Automatic device state management
- ๐ก๏ธ Comprehensive error handling and recovery
- ๐ฑ Cross-platform support (Desktop & Mobile browsers)
| Platform | Browser | Device | Status |
|----------|---------|---------|---------|
| Windows PC | Chrome/Edge | MSC firmware 1.0.44 | โ
Tested |
| Android | Chrome | Samsung S10 | โ
Tested |
| iOS | Safari | - | โ Not supported |
| Browser | Minimum Version | Notes |
|---------|----------------|-------|
| Chrome | 56+ | โ
Full support |
| Edge | 79+ | โ
Full support |
| Firefox | - | โ No Web Bluetooth support |
| Safari | - | โ No Web Bluetooth support |
> Note: "Experimental Web Platform Features" may need to be enabled in Chrome flags
- โ
Seneca Multi Smart Calibrator device (MSC series)
- โ
Bluetooth-enabled device
- โ ๏ธ User gesture required for initial pairing (browser security requirement)
``javascript`
if (!navigator.bluetooth) {
console.error('Web Bluetooth is not supported in this browser');
} else {
console.log('Web Bluetooth is available');
}
๐ฆ CDN (Recommended)
`html`
๐ฅ NPM
`bash`
npm install bt-seneca-msc
`javascript`
import MSC from 'bt-seneca-msc';
// or
const MSC = require('bt-seneca-msc');
`javascript`
// โ ๏ธ Must be called from a user gesture (button click, etc.)
document.getElementById('connectBtn').addEventListener('click', async () => {
try {
const paired = await MSC.Pair(true);
if (paired) {
console.log('Device connected successfully!');
}
} catch (error) {
console.error('Pairing failed:', error);
}
});
`javascript
async function measureVoltage() {
const state = await MSC.GetState();
if (state.ready) {
const command = MSC.Command.CreateNoSP(MSC.CommandType.V);
const result = await MSC.SimpleExecute(command);
if (!result.error) {
console.log(Voltage: ${result.value} V);`
}
}
}
NPM (Node.js/Webpack/Bundlers)
`bash`
npm install bt-seneca-msc
`javascript`
import MSC from 'bt-seneca-msc';
// or
const MSC = require('bt-seneca-msc');
CDN (Browser)
`html`
LibMan (ASP.NET Core)
`powershell`
libman install bt-seneca-msc --provider jsdelivr
Manual Download
Download from the releases page and include the dist/bt-seneca-msc.min.js file.
#### MSC.Pair(force: boolean): Promiseforce
Pairs with a Bluetooth MSC device.
- : If true, always shows device picker; if false, reconnects to last device
- Returns: Promise resolving to connection success
- Note: Must be called from user gesture
#### MSC.Stop(): Promise
Disconnects Bluetooth and stops polling.
- Returns: Promise resolving to disconnection success
#### MSC.Execute(command: Command): Promisecommand
Executes a command and returns updated command object.
- : Command object created with MSC.Command.CreateXXX() methods
- Returns: Promise resolving to updated command with results
#### MSC.SimpleExecute(command: Command): Promise{error: boolean, value: any, message: string}
Executes command and returns simple result value.
- Returns: Promise resolving to
#### MSC.GetState(): Promise
Gets current device state and measurements.
- Returns: Promise resolving to complete device state
#### MSC.SimpleExecuteJSON(jsonCommand: string): Promise
JSON version of SimpleExecute.
#### MSC.ExecuteJSON(jsonCommand: string): Promise
JSON version of Execute.
#### MSC.GetStateJSON(): Promise
JSON version of GetState.
#### MSC.Command.CreateNoSP(type: CommandType): Command
Creates command with no setpoints (measurements).
#### MSC.Command.CreateOneSP(type: CommandType, setpoint: number): Command
Creates command with one setpoint (single value generation).
#### MSC.Command.CreateTwoSP(type: CommandType, setpoint1: number, setpoint2: number): Command
Creates command with two setpoints (dual value generation).
`javascript
const state = await MSC.GetState();
// Connection status
state.ready // boolean: Device ready for commands
state.initializing // boolean: Device initializing
state.status // string: Current state machine status
// Data
state.lastMeasure // array: Latest measurement data
state.lastSetpoint // array: Latest generation setpoint data
// Device info
state.deviceName // string: Bluetooth device name
state.deviceSerial // string: MSC device serial number
state.deviceMode // string: Current device mode
state.batteryLevel // number: Battery voltage
state.stats // object: Debug statistics
`
| State | Description | Next State |
|-------|-------------|------------|
| NOT_CONNECTED | Initial state before pairing | CONNECTING |CONNECTING
| | Waiting for pairing to complete | DEVICE_PAIRED |DEVICE_PAIRED
| | Pairing completed, no BT interface | SUBSCRIBING |SUBSCRIBING
| | Waiting for BT interfaces | METER_INIT |METER_INIT
| | Connected, initializing meter | METER_INITIALIZING |METER_INITIALIZING
| | Reading initial meter state | IDLE |IDLE
| | Ready to execute commands | BUSY |BUSY
| | Executing command or refreshing data | IDLE, ERROR |ERROR
| | Exception occurred | METER_INIT |STOPPING
| | Processing stop request | STOPPED |STOPPED
| | Everything stopped | - |
javascript
async function measureVoltage() {
try {
// Check if device is ready
const state = await MSC.GetState();
if (!state.ready) {
throw new Error('Device not ready');
} // Create measurement command
const command = MSC.Command.CreateNoSP(MSC.CommandType.V);
const result = await MSC.SimpleExecute(command);
if (result.error) {
console.error('Measurement failed:', result.message);
} else {
console.log(
Voltage: ${result.value} V);
}
} catch (error) {
console.error('Error:', error);
}
}
`$3
`javascript
async function generateVoltage(voltage) {
try {
const state = await MSC.GetState();
if (!state.ready) {
throw new Error('Device not ready');
} // Create generation command
const command = MSC.Command.CreateOneSP(MSC.CommandType.GEN_V, voltage);
const result = await MSC.Execute(command);
if (result.error) {
console.error('Generation failed');
} else {
console.log(
Generating ${voltage}V);
// Monitor generation status
const newState = await MSC.GetState();
if (newState.lastSetpoint.error) {
console.error('Generation error detected');
}
}
} catch (error) {
console.error('Error:', error);
}
}
`$3
`javascript
async function generatePulses(count, frequency) {
try {
// Set voltage levels first
await MSC.Execute(MSC.Command.CreateOneSP(MSC.CommandType.SET_Ulow, 0.0));
await MSC.Execute(MSC.Command.CreateOneSP(MSC.CommandType.SET_Uhigh, 5.0));
// Generate pulses (count, frequency in Hz)
const command = MSC.Command.CreateTwoSP(MSC.CommandType.GEN_PulseTrain, count, frequency);
const result = await MSC.Execute(command);
if (!result.error) {
console.log(Generating ${count} pulses at ${frequency} Hz);
}
} catch (error) {
console.error('Pulse generation failed:', error);
}
}
`$3
`javascript
async function startMonitoring() {
setInterval(async () => {
try {
const state = await MSC.GetState();
if (state.ready && state.lastMeasure && !state.lastMeasure.error) {
console.log('Current measurement:', state.lastMeasure[0]);
}
if (state.lastSetpoint && !state.lastSetpoint.error) {
console.log('Current setpoint:', state.lastSetpoint[0]);
}
} catch (error) {
console.error('Monitoring error:', error);
}
}, 1000);
}
`๐ง Device Features
$3
| Function | Status | Data Returned |
|----------|--------|---------------|
| V, mV readings | โ
Tested | Instantaneous, min, max values |
| mA active/passive | โ
Tested | Instantaneous, min, max values |
| RTD 2W readings | โ
Tested | Temperature (ยฐC) and resistance (ฮฉ) |
| Thermocouples 2W/3W/4W | โ
Not tested | Temperature (ยฐC) |
| Frequency reading | โ
Tested | Leading/falling edge frequency |
| Pulse counting | โ
Tested 0-10kHz | Leading/falling edge counts |
| Load cell | โ
Not tested | Imbalance mV/V |
$3
| Function | Status | Setpoint |
|----------|--------|----------|
| V, mV generation | โ
Tested | Voltage (mV/V) |
| mA active/passive | โ ๏ธ Basic testing | Current (mA) |
| RTD 2W simulation | โ
Not tested | Temperature (ยฐC) |
| Thermocouple simulation | โ
Not tested | Temperature (ยฐC) |
| Frequency generation | โ
Tested 0-10kHz | LE and FE frequency (Hz) |
| Pulse generation | โ
Tested 1kHz | LE and FE frequency (Hz) |
| Load cell simulation | โ
Not tested | Imbalance mV/V |
$3
| Setting | Command | Range | Status |
|---------|---------|-------|--------|
| Low level voltage |
SET_Ulow | 0-27V | โ
Tested |
| High level voltage | SET_Uhigh | 0-27V | โ
Tested |
| Pulse width threshold | SET_Sensitivity_uS | 1-โ ฮผs | โ ๏ธ Not tested |
| Voltage threshold | SET_UThreshold_F | 0-27V | โ ๏ธ Not tested |
| Cold junction compensation | SET_ColdJunction | Various | โ ๏ธ Not tested |$3
- Ramps editing and application
- Data logging start/stop
- Logged data retrieval
- Clock read/sync
- Firmware version read
- mV/V to kg conversion
- Automatic switch off delay
Performance
| Operation | Typical Time | Notes |
|-----------|--------------|-------|
| Device pairing | 20-40s | Multiple attempts to establish characteristics |
| Command execution | 2-3s | From command to device response |
| Measurement refresh | ~1s | Updated min/max/current values |
| Generation refresh | ~1s | Updated setpoint and error status |
| Modbus roundtrip | ~150ms | Single command/response cycle |
Polling Frequency: 750ms automatic state refresh when idle
Development
$3
`bash
Install dependencies
npm installDevelopment build (unminified)
npm run devProduction build (minified)
npm run dist
`$3
`bash
Run tests with coverage
npm testVerbose test output
npm test -- --verbose
`Note: Tests use captured Modbus RTU packet traces in hex format for simulation, allowing comprehensive testing without physical hardware.
$3
`
src/
โโโ classes/ # Core classes
โ โโโ SenecaMSC.js # Main Bluetooth/Modbus operations
โ โโโ APIState.js # State management
โ โโโ Command.js # Command structure
โ โโโ ...
โโโ bluetooth.js # Web Bluetooth wrapper
โโโ modbusRtu.js # Modbus RTU protocol
โโโ senecaModbus.js # Seneca-specific commands
โโโ constants.js # Enums and constants
`$3
- Main branch: Triggers GitHub Actions for CI and NPM publishing
- Development branch: Use for feature development, PR to main when ready
- GitHub Pages: Sample application updates on main branch pushes
- NPM: Automatic publishing when package.json version changes
Troubleshooting
$3
#### "Web Bluetooth is not available"
- Ensure you're using a supported browser (Chrome 56+, Edge 79+)
- Check that Bluetooth is enabled on your device
- Try enabling "Experimental Web Platform Features" in Chrome flags
#### "User cancelled the requestDevice() chooser"
- User must manually select device from browser dialog
- Ensure MSC device is powered on and discoverable
- Device name should start with "MSC"
#### "Device pairing takes too long"
- This is normal (20-40s typical)
- Ensure MSC device remains powered during pairing
- Try moving closer to the device
#### "Commands fail after successful pairing"
- Check device battery level (
state.batteryLevel)
- Verify device is not in error state
- Try disconnecting and reconnecting#### "Measurements show error flag"
- Check device connections and probes
- Verify measurement range is appropriate
- Check for overcurrent/overvoltage conditions
$3
Enable debug logging:
`javascript
const state = await MSC.GetState();
console.log('Debug stats:', state.stats);
`$3
- Check the live demo for working examples
- Review browser console for error messages
- Ensure proper user gesture handling for pairing
- Verify device compatibility and firmware version
Contributing
1. Fork the repository
2. Create a feature branch from
development
3. Make your changes with tests
4. Submit a pull request to development branch$3
- Use
development branch for features
- PR to main` when ready for releaseMIT License - see LICENSE file for details.
---
Seneca MSC Device Information: https://www.seneca.it/msc/