bt-seneca-msc
Version:
A pure Javascript API for the Seneca Multi Smart Calibrator (MSC) device, using web bluetooth.
531 lines (409 loc) โข 16.4 kB
Markdown
# bt-seneca-msc
[](https://badge.fury.io/js/bt-seneca-msc)
[](https://opensource.org/licenses/MIT)
[](https://github.com/schneiderelectricsystemsitaly/bt-seneca-msc/actions)
[](https://coveralls.io/github/schneiderelectricsystemsitaly/bt-seneca-msc?branch=main)
> A pure JavaScript API for the Seneca Multi Smart Calibrator (MSC) device, using Web Bluetooth from modern browsers.
**๐ [Live Demo](https://schneiderelectricsystemsitaly.github.io/bt-seneca-msc/)** | **๐ [Documentation](#api-reference)** | **๐ ๏ธ [Getting Started](#quick-start)**
---
## Table of Contents
- [Overview](#overview)
- [Prerequisites](#prerequisites)
- [Quick Start](#quick-start)
- [Installation](#installation)
- [API Reference](#api-reference)
- [Usage Examples](#usage-examples)
- [Device Features](#device-features)
- [Performance](#performance)
- [Development](#development)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
## Overview
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.
### โจ Key Features
- ๐ **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)
### ๐งช Tested Environments
| Platform | Browser | Device | Status |
|----------|---------|---------|---------|
| Windows PC | Chrome/Edge | MSC firmware 1.0.44 | โ
Tested |
| Android | Chrome | Samsung S10 | โ
Tested |
| iOS | Safari | - | โ Not supported |
## ๐ Prerequisites
### Browser Requirements
| 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
### Hardware Requirements
- โ
Seneca Multi Smart Calibrator device ([MSC series](https://www.seneca.it/msc/))
- โ
Bluetooth-enabled device
- โ ๏ธ User gesture required for initial pairing (browser security requirement)
### Quick Compatibility Check
```javascript
if (!navigator.bluetooth) {
console.error('Web Bluetooth is not supported in this browser');
} else {
console.log('Web Bluetooth is available');
}
```
## ๐ Quick Start
### 1. Include the Library
<details>
<summary><strong>๐ฆ CDN (Recommended)</strong></summary>
```html
<script src="https://cdn.jsdelivr.net/npm/bt-seneca-msc@latest/dist/bt-seneca-msc.min.js"></script>
```
</details>
<details>
<summary><strong>๐ฅ NPM</strong></summary>
```bash
npm install bt-seneca-msc
```
```javascript
import MSC from 'bt-seneca-msc';
// or
const MSC = require('bt-seneca-msc');
```
</details>
### 2. Pair and Connect
```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);
}
});
```
### 3. Take a Measurement
```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`);
}
}
}
```
## ๐ฆ Installation
<details>
<summary><strong>NPM (Node.js/Webpack/Bundlers)</strong></summary>
```bash
npm install bt-seneca-msc
```
```javascript
import MSC from 'bt-seneca-msc';
// or
const MSC = require('bt-seneca-msc');
```
</details>
<details>
<summary><strong>CDN (Browser)</strong></summary>
```html
<script src="https://cdn.jsdelivr.net/npm/bt-seneca-msc@latest/dist/bt-seneca-msc.min.js"></script>
```
</details>
<details>
<summary><strong>LibMan (ASP.NET Core)</strong></summary>
```powershell
libman install bt-seneca-msc --provider jsdelivr
```
</details>
<details>
<summary><strong>Manual Download</strong></summary>
Download from the [releases page](https://github.com/schneiderelectricsystemsitaly/bt-seneca-msc/releases) and include the `dist/bt-seneca-msc.min.js` file.
</details>
## ๐ API Reference
### Core Methods
#### `MSC.Pair(force: boolean): Promise<boolean>`
Pairs with a Bluetooth MSC device.
- `force`: 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<boolean>`
Disconnects Bluetooth and stops polling.
- **Returns:** Promise resolving to disconnection success
#### `MSC.Execute(command: Command): Promise<Command>`
Executes a command and returns updated command object.
- `command`: Command object created with `MSC.Command.CreateXXX()` methods
- **Returns:** Promise resolving to updated command with results
#### `MSC.SimpleExecute(command: Command): Promise<CommandResult>`
Executes command and returns simple result value.
- **Returns:** Promise resolving to `{error: boolean, value: any, message: string}`
#### `MSC.GetState(): Promise<MeterState>`
Gets current device state and measurements.
- **Returns:** Promise resolving to complete device state
### JSON API (ASP.NET Core Interop)
#### `MSC.SimpleExecuteJSON(jsonCommand: string): Promise<string>`
JSON version of SimpleExecute.
#### `MSC.ExecuteJSON(jsonCommand: string): Promise<string>`
JSON version of Execute.
#### `MSC.GetStateJSON(): Promise<string>`
JSON version of GetState.
### Command Creation
#### `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).
### State Properties
```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
```
### Device States
| 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 | - |
## ๐ก Usage Examples
### Basic Voltage Measurement
```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);
}
}
```
### Voltage Generation
```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);
}
}
```
### Pulse Generation
```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);
}
}
```
### Continuous Monitoring
```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
### Measurements
| 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 |
### Generation
| 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 |
### Configuration Settings
| 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 |
### Not Implemented Features
- 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
### Building
```bash
# Install dependencies
npm install
# Development build (unminified)
npm run dev
# Production build (minified)
npm run dist
```
### Testing
```bash
# Run tests with coverage
npm test
# Verbose test output
npm test -- --verbose
```
**Note:** Tests use captured Modbus RTU packet traces in hex format for simulation, allowing comprehensive testing without physical hardware.
### Project Structure
```
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
```
### CI/CD
- **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
### Common Issues
#### "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
### Debug Information
Enable debug logging:
```javascript
const state = await MSC.GetState();
console.log('Debug stats:', state.stats);
```
### Getting Help
- Check the [live demo](https://schneiderelectricsystemsitaly.github.io/bt-seneca-msc/) 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
### Development Workflow
- Use `development` branch for features
- PR to `main` when ready for release
- Tests must pass and maintain coverage
- Follow existing code style and patterns
## License
MIT License - see LICENSE file for details.
---
**Seneca MSC Device Information:** https://www.seneca.it/msc/