npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

medcase-sdk

v2.1.0

Published

React Native Bluetooth SDK for MedCase medical device communication

Downloads

87

Readme

MedCase Bluetooth SDK

A React Native Bluetooth SDK for communicating with MedCase medical devices. Works with both Expo and standard React Native projects, with optional TypeScript support.

Features

  • 📱 Works with both Expo and React Native
  • 🔧 Automatic platform detection and adapter selection
  • 📦 Built-in connection management
  • 🔀 Data transformation and encoding (URL-encoded UTF-8 format)
  • 🎯 Manual connection mode for advanced users
  • 📝 Full TypeScript support (optional)
  • 🔄 Event-driven architecture
  • ⚡ Error handling and retry logic
  • 📊 Comprehensive logging
  • 🔄 Flutter-compatible data format

Installation

npm install medcase-sdk
# or
yarn add medcase-sdk

Dependencies

The SDK automatically detects your environment and uses the appropriate Bluetooth library:

  • Expo: react-native-ble-plx
  • React Native: react-native-ble-manager

Install the required dependency for your platform:

# For Expo
npm install react-native-ble-plx

# For React Native
npm install react-native-ble-manager

Platform Setup

Expo

Add the plugin to your app.json or app.config.js:

{
  "expo": {
    "plugins": [
      [
        "react-native-ble-plx",
        {
          "isBackgroundEnabled": true,
          "modes": ["bluetooth"]
        }
      ]
    ]
  }
}

React Native

iOS

Add to your Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs Bluetooth access to communicate with medical devices</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs Bluetooth access to communicate with medical devices</string>

Android

Add to your AndroidManifest.xml:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Quick Start

Recommended Usage (Auto-Connect and Discover)

The SDK now provides a streamlined auto-connect approach that eliminates the need for manual scanning and connection steps:

import { MedCaseBluetoothSDK } from 'medcase-sdk';

const sdk = new MedCaseBluetoothSDK({
  boxId: '2A:DC:C3:AF:B9:90', // Specific device to connect to
});

async function connectAndSendData() {
  try {
    // Initialize SDK and request permissions
    const initialized = await sdk.initialize();
    if(!initialized) return;

    // Auto-connect to device and discover services/characteristics
    const result = await sdk.autoConnectAndDiscover();
    
    // Send WiFi credentials with location data
    await sdk.sendData({
      ssid: 'MyWiFiNetwork',
      password: 'MyPassword123',
      time: '2023-12-01 10:30:00 123',
      lat: '40.7128',
      lng: '-74.0060'
    });
    
    await sdk.disconnectFromDevice();
  } catch (error) {
    console.error('Error:', error);
  }
}

API Reference

Configuration

The Configuration class provides utilities for generating and opening admin URLs for MedCase devices.

Constructor

const config = new Configuration(boxId: string, phoneNumber: string);

Parameters:

  • boxId (string): The Bluetooth device ID or MAC address
  • phoneNumber (string): The phone number associated with the device

Example:

import { Configuration } from 'medcase-sdk';

const config = new Configuration('C8:F0:9E:7A:79:70', '7908075918');

Methods

link(): string

Returns the admin URL as a string.

Returns: string - The complete admin URL

Example:

const config = new Configuration('C8:F0:9E:7A:79:70', '7908075918');
const url = config.link();
console.log(url); 
// Output: https://admin.medcase.in/admin/partner/C8:F0:9E:7A:79:70/7908075918
openInBrowser(): Promise<void>

Opens the admin URL in the device's default browser.

Throws: Error if the URL cannot be opened

Example:

const config = new Configuration('C8:F0:9E:7A:79:70', '7908075918');
try {
  await config.openInBrowser();
  console.log('Browser opened successfully');
} catch (error) {
  console.error('Failed to open browser:', error.message);
}
Getter Methods
  • getBoxId(): string - Returns the current box ID
  • getPhoneNumber(): string - Returns the current phone number
Setter Methods
  • updateBoxId(boxId: string): void - Updates the box ID
  • updatePhoneNumber(phoneNumber: string): void - Updates the phone number

Example:

const config = new Configuration('C8:F0:9E:7A:79:70', '7908075918');

// Get current values
console.log(config.getBoxId()); // 'C8:F0:9E:7A:79:70'
console.log(config.getPhoneNumber()); // '7908075918'

// Update values
config.updateBoxId('D1:E2:F3:G4:H5:76');
config.updatePhoneNumber('9876543210');

console.log(config.link()); 
// Output: https://admin.medcase.in/admin/partner/D1:E2:F3:G4:H5:76/9876543210

URL Format

The generated URLs follow this pattern:

https://admin.medcase.in/admin/partner/{boxId}/{phoneNumber}

Where:

  • {boxId} is the device ID/MAC address
  • {phoneNumber} is the associated phone number

MedCaseBluetoothSDK

Constructor Options

interface MedCaseSDKConfig {
  autoManageConnection?: boolean;        // Default: true
  serviceUUID?: string;                  // Default: '1800'
  characteristicUUID?: string;           // Default: '2A00'
  enableLogging?: boolean;               // Default: false
  connectionTimeout?: number;             // Default: 30000 (ms)
  boxId?: string;                        // Optional: for device name filtering
  deviceNamePrefix?: string;             // Default: 'MedCase'
  dataTransformation?: {
    encoding?: 'utf8' | 'base64' | 'hex'; // Default: 'utf8'
    delimiter?: string;                   // Default: '|'
    prefix?: string;
    suffix?: string;
  };
}

Methods

Connection Management
  • initialize(): Promise<boolean> - Initialize SDK and request permissions
  • autoConnectAndDiscover(): Promise<{connection, services, characteristics}> - Auto-connect and discover services/characteristics (Recommended)
  • scanForDevices(serviceUUIDs?, timeoutMs?): Promise<MedCaseDevice[]> - Scan for devices (Manual approach)
  • connectToDevice(deviceId, options?): Promise<BluetoothConnection> - Connect to specific device
  • disconnectFromDevice(deviceId?): Promise<void> - Disconnect from device
  • getCurrentConnection(): BluetoothConnection | null - Get current connection
  • isConnected(): boolean - Check if connected
Data Transmission
  • sendData(values, deviceId?): Promise<void> - Send data with automatic connection
  • sendDataToCharacteristic(connection, serviceUUID, characteristicUUID, values): Promise<void> - Send to specific characteristic
Configuration
  • updateConfig(newConfig): void - Update configuration
  • getConfig(): MedCaseSDKConfig - Get current configuration
  • cleanup(): Promise<void> - Clean up resources
Events
  • on(event, listener): void - Add event listener
  • off(event, listener): void - Remove event listener

Events

  • device-discovered - When a matching device is found during scanning
  • device-connected - When a device is connected
  • device-disconnected - When a device is disconnected
  • error - When an error occurs

Note: The data-received event and notification listening methods are kept for internal use only and are not exposed in the public API.

Data Format

The SDK uses URL-encoded UTF-8 format that's fully compatible with Flutter apps. When you send data:

// Input data
{
  ssid: 'MyWiFiNetwork',
  password: 'MyPassword123',
  time: '2023-12-01 10:30:00 123',
  lat: '40.7128',
  lng: '-74.0060'
}

It gets transformed to: MyWiFiNetwork/MyPassword123/CT:2023-12-01%2010%3A30%3A00%20123/LT:40.7128/LG:-74.0060

This matches the Flutter Uri.encodeComponent() behavior exactly, ensuring seamless communication between React Native and Flutter MedCase apps.

Data Structure

The SDK expects data with these fields:

  • ssid: WiFi network name
  • password: WiFi password
  • time: Timestamp with milliseconds
  • lat: Latitude coordinate
  • lng: Longitude coordinate

Format Details

The transmitted format follows this pattern:

{encodedSSID}/{encodedPassword}/CT:{encodedTime}/LT:{encodedLat}/LG:{encodedLng}

Where:

  • All values are URL-encoded using encodeURIComponent()
  • CT: prefix for Current Time
  • LT: prefix for Latitude
  • LG: prefix for Longitude
  • Separated by / and : characters

Format Explanation:

  • $encodedSSID/$encodedPassword/CT:$encodedTime/LT:$encodedLat/LG:$encodedLng
  • All values are URL encoded to handle special characters
  • CT: Current Time, LT: Latitude, LG: Longitude
  • Time format should be: yyyy-MM-dd HH:mm:ss SSS

Device Name Filtering

The SDK can automatically filter devices by name during scanning:

// Default behavior - searches for devices starting with 'MedCase'
const sdk = new MedCaseBluetoothSDK();

// Custom prefix
const sdk = new MedCaseBluetoothSDK({
  deviceNamePrefix: 'CustomDevice'
});

// Exact match with boxId
const sdk = new MedCaseBluetoothSDK({
  deviceNamePrefix: 'MedCase',
  boxId: '12345' // Will search for exact name 'MedCase12345'
});

Usage Workflow

Recommended Workflow (Auto-Connect)

  1. Initialize SDK - Request permissions and set up Bluetooth
  2. Auto-Connect - Use autoConnectAndDiscover() to automatically find, connect to, and discover services/characteristics
  3. Send Data - Use sendData() to transmit information to the device
  4. Cleanup - Call cleanup() when done

Manual Workflow (Legacy)

  1. Initialize SDK - Request permissions and set up Bluetooth
  2. Scan - Use scanForDevices() to find available devices
  3. Connect - Use connectToDevice() to establish connection
  4. Discover Services (Optional) - Use discoverServices() and discoverCharacteristics()
  5. Send Data - Use sendData() to transmit information
  6. Disconnect - Use disconnectFromDevice() when done

Examples

Configuration Usage

import { Configuration } from 'medcase-sdk';

// Create configuration instance
const config = new Configuration('C8:F0:9E:7A:79:70', '7908075918');

// Generate URL link
const adminUrl = config.link();
console.log(adminUrl); 
// https://admin.medcase.in/admin/partner/C8:F0:9E:7A:79:70/7908075918

// Open in browser
await config.openInBrowser();

// Update configuration
config.updateBoxId('D1:E2:F3:G4:H5:76');
config.updatePhoneNumber('9876543210');

React Native Integration

import React, { useState } from 'react';
import { View, TextInput, Button, Alert } from 'react-native';
import { Configuration } from 'medcase-sdk';

const ConfigScreen = () => {
  const [boxId, setBoxId] = useState('C8:F0:9E:7A:79:70');
  const [phoneNumber, setPhoneNumber] = useState('7908075918');

  const handleOpenAdmin = async () => {
    try {
      const config = new Configuration(boxId, phoneNumber);
      await config.openInBrowser();
    } catch (error) {
      Alert.alert('Error', error.message);
    }
  };

  const handleGenerateLink = () => {
    try {
      const config = new Configuration(boxId, phoneNumber);
      const url = config.link();
      Alert.alert('Generated URL', url);
    } catch (error) {
      Alert.alert('Error', error.message);
    }
  };

  return (
    <View>
      <TextInput
        value={boxId}
        onChangeText={setBoxId}
        placeholder="Box ID"
      />
      <TextInput
        value={phoneNumber}
        onChangeText={setPhoneNumber}
        placeholder="Phone Number"
        keyboardType="phone-pad"
      />
      <Button title="Generate Link" onPress={handleGenerateLink} />
      <Button title="Open in Browser" onPress={handleOpenAdmin} />
    </View>
  );
};

See the example/ directory for a complete working example app that demonstrates both the auto-connect and manual connection approaches, plus the Configuration class usage.

TypeScript Support

The SDK includes full TypeScript definitions. Import types as needed:

import { 
  MedCaseBluetoothSDK, 
  MedCaseDevice, 
  BluetoothConnection,
  MedCaseData,
  Configuration 
} from 'medcase-sdk';

Error Handling

The SDK provides comprehensive error handling:

sdk.on('error', (error) => {
  console.error('SDK Error:', error.message);
  
  // Handle specific errors
  if (error.message.includes('Connection timeout')) {
    // Handle timeout
  } else if (error.message.includes('Bluetooth permissions')) {
    // Handle permission issues
  }
});

Troubleshooting

Common Issues and Solutions

"Cannot read property 'createClient' of null"

Cause: This error occurs when the Bluetooth library is not properly installed or linked.

Solutions:

  1. Ensure correct library is installed:

    # For Expo projects
    npm install react-native-ble-plx expo-constants
       
    # For React Native projects
    npm install react-native-ble-manager
  2. For React Native - Link the library:

    cd ios && pod install && cd ..
  3. For Expo - Configure plugin in app.json:

    {
      "expo": {
        "plugins": [
          ["react-native-ble-plx", {
            "isBackgroundEnabled": true,
            "modes": ["bluetooth"]
          }]
        ]
      }
    }
  4. Clean and rebuild:

    # Expo
    expo start -c
       
    # React Native
    npx react-native run-android --reset-cache
    npx react-native run-ios --reset-cache

Bluetooth Support Check Failed

Cause: The Bluetooth library failed to initialize properly.

Solutions:

  1. Check platform compatibility:

    • iOS: Ensure iOS 10+ device
    • Android: Ensure Bluetooth Low Energy support
  2. Verify permissions:

    • iOS: Check Info.plist has Bluetooth permissions
    • Android: Check AndroidManifest.xml has all required permissions
  3. Restart Bluetooth:

    • Toggle device Bluetooth off/on
    • Restart the app

Library Version Mismatches

Cause: Using incompatible versions of Bluetooth libraries.

Solution: Use the recommended versions:

{
  "dependencies": {
    "react-native-ble-manager": "^12.4.1",
    "react-native-ble-plx": "^3.5.0",
    "expo-constants": "^16.0.2"
  }
}

Debug Mode

Enable detailed logging to troubleshoot issues:

const sdk = new MedCaseBluetoothSDK({
  enableLogging: true  // Enables detailed console logs
});

Platform Detection Issues

If the SDK detects the wrong platform, you can manually check:

import { getPlatformInfo } from 'medcase-sdk';

const platformInfo = getPlatformInfo();
console.log('Platform:', platformInfo);
// Output: { isExpo: boolean, isReactNative: boolean, platform: 'ios'|'android'|'web' }

Platform Differences

| Feature | Expo | React Native | |---------|------|--------------| | Library | react-native-ble-plx | react-native-ble-manager | | Permissions | Automatic | Manual setup required | | iOS Setup | Automatic | Info.plist required | | Android Setup | Plugin configuration | Manifest permissions required |

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For support, please open an issue on GitHub or contact the MedCase team.