UNPKG

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
# bt-seneca-msc [![npm version](https://badge.fury.io/js/bt-seneca-msc.svg)](https://badge.fury.io/js/bt-seneca-msc) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Build Status](https://github.com/schneiderelectricsystemsitaly/bt-seneca-msc/actions/workflows/publish.yml/badge.svg)](https://github.com/schneiderelectricsystemsitaly/bt-seneca-msc/actions) [![Coverage Status](https://coveralls.io/repos/github/schneiderelectricsystemsitaly/bt-seneca-msc/badge.svg?branch=main)](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/