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 🙏

© 2025 – Pkg Stats / Ryan Hefner

je_nfc_sdk

v2.0.15

Published

A comprehensive React Native SDK for NFC-based device control and communication

Readme

JE NFC SDK

A comprehensive React Native SDK for NFC-based device control and communication, specifically designed for irrigation control systems and IoT devices.

Features

  • Complete NFC Control Interface: Full-featured control screen with solenoid management, scheduling, time synchronization, and sensor data
  • Modular Components: Reusable NFC operation cards and UI components
  • Custom Hooks: React hooks for NFC operations management
  • Frame Server: Advanced NFC frame handling with ISO 7816 support
  • Operation State Management: Comprehensive state machine for NFC operations
  • Customizable UI: Theme support, custom icons, and configurable categories
  • TypeScript Support: Full TypeScript definitions for type safety
  • Logging Service: Built-in logging and debugging capabilities

Installation

Since this is a local SDK, you can import it directly in your React Native project:

import { 
  ControlScreen, 
  NfcOperationCard, 
  useNfcOperations, 
  LoggerService, 
  FrameServer 
} from './je_nfc_sdk';

Dependencies

Make sure your project has these peer dependencies installed:

{
  "react": ">=18.0.0",
  "react-native": ">=0.71.0",
  "react-native-nfc-manager": ">=3.11.0",
  "react-native-safe-area-context": ">=5.4.0",
  "react-native-screens": ">=4.10.0",
  "react-native-linear-gradient": ">=2.8.0",
  "react-native-vector-icons": ">=10.0.0",
  "@react-native-picker/picker": ">=2.11.0",
  "@react-native-community/datetimepicker": ">=8.3.0"
}

Quick Start

Basic Usage with ControlScreen

import React from 'react';
import { ControlScreen } from './je_nfc_sdk';

const MyApp = () => {
  const translate = (key: string) => {
    // Your translation logic here
    return key;
  };

  const handleTagConnected = (tagInfo: any) => {
    console.log('Tag connected:', tagInfo);
  };

  const handleOperationComplete = (operationType: string, result: any) => {
    console.log('Operation completed:', operationType, result);
  };

  const handleError = (error: string) => {
    console.error('NFC Error:', error);
  };

  return (
    <ControlScreen
      translate={translate}
      onTagConnected={handleTagConnected}
      onOperationComplete={handleOperationComplete}
      onError={handleError}
      showMenu={true}
      categories={['connection', 'solenoid', 'time', 'pressure']}
      theme="light"
      enableScheduling={true}
      enableSensorData={true}
    />
  );
};

export default MyApp;

Using Individual Components

import React from 'react';
import { View } from 'react-native';
import { NfcOperationCard, useNfcOperations } from './je_nfc_sdk';

const MyCustomScreen = () => {
  const operationConfigs = {
    solenoid_1: {
      writeCmd: 0x13,
      writeSubCmd: 0x10,
      readCmd: 0x12,
      writeApdu: [0x11],
      readApdu: [0x00],
      displayName: 'Solenoid 1',
      processingMessage: 'Processing solenoid operation...',
      icon: '🎚️'
    }
  };

  const {
    operations,
    handleOperation,
    isScanning,
    connectToTag
  } = useNfcOperations({
    operationConfigs,
    onOperationComplete: (type, result) => console.log(type, result),
    onError: (error) => console.error(error)
  });

  return (
    <View>
      <NfcOperationCard
        operationType="solenoid_1"
        config={operationConfigs.solenoid_1}
        operation={operations.solenoid_1}
        onPress={() => handleOperation('solenoid_1')}
        disabled={isScanning}
      />
    </View>
  );
};

Using the Frame Server Directly

import { FrameServer, LoggerService } from './je_nfc_sdk';

const performCustomOperation = async () => {
  try {
    // Write data to device
    const writeResult = await FrameServer.writeData(0x13, 0x10, [0x11]);
    
    if (writeResult.success) {
      LoggerService.success('Write operation successful');
      
      // Read data from device
      const readResult = await FrameServer.readReq(0x12, 0x10, [0x00]);
      
      if (readResult.success && readResult.data) {
        LoggerService.success('Read operation successful');
        console.log('Device response:', readResult.data);
      }
    }
  } catch (error) {
    LoggerService.error(`Operation failed: ${error}`);
  }
};

API Reference

ControlScreen Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | translate | (key: string) => string | (key) => key | Translation function for internationalization | | operationConfigs | Record<string, OperationConfig> | {} | Custom operation configurations | | icons | Record<string, any> | {} | Custom icons for categories | | onTagConnected | (tagInfo: any) => void | undefined | Callback when NFC tag is connected | | onOperationComplete | (operationType: string, result: any) => void | undefined | Callback when operation completes | | onError | (error: string) => void | undefined | Error callback | | initialSolenoidStates | Record<number, boolean> | {1: false, 2: false, 3: false, 4: false} | Initial solenoid states | | initialSchedules | Schedule[] | [] | Initial schedules | | showMenu | boolean | true | Whether to show the side menu | | categories | string[] | ['connection', 'solenoid', 'schedule', 'time', 'pressure', 'waterflow'] | Available categories | | theme | 'light' \| 'dark' | 'light' | UI theme | | enableScheduling | boolean | true | Enable scheduling features | | enableSensorData | boolean | true | Enable sensor data features | | enableTesting | boolean | false | Enable testing features |

OperationConfig Interface

interface OperationConfig {
  writeCmd: number;          // Write command ID
  writeSubCmd: number;       // Write sub-command ID
  readCmd: number;           // Read command ID
  writeApdu: number[];       // Write APDU data
  readApdu: number[];        // Read APDU data
  displayName: string;       // Human-readable name
  processingMessage: string; // Message shown during processing
  icon: string;             // Icon or emoji
}

OperationStatus Interface

interface OperationStatus {
  state: OperationState;
  lastOperation: {
    type: 'WRITE' | 'READ' | null;
    status: 'SUCCESS' | 'FAILED' | 'COMPLETED' | null;
    timestamp: number | null;
  };
  processingBit: number;
  data?: string;
  resetRequested?: boolean;
  processingStartTime?: number;
  timer?: {
    startTime: number;
    currentValue: number;
    isRunning: boolean;
  };
}

useNfcOperations Hook

The useNfcOperations hook provides a complete interface for managing NFC operations:

const {
  operations,           // Current operation states
  isScanning,          // Whether NFC is currently scanning
  isTagConnected,      // Whether NFC tag is connected
  handleOperation,     // Execute an operation
  connectToTag,        // Connect to NFC tag
  resetOperation,      // Reset an operation state
  updateOperationStatus, // Update operation status
  getOperationButtonText, // Get button text for operation
  getStatusColor,      // Get status color for operation
  transceiveWithTimeout // Send APDU with timeout
} = useNfcOperations({
  operationConfigs,
  onOperationComplete,
  onError,
  translate
});

FrameServer Methods

The FrameServer provides low-level NFC communication:

  • writeData(commandId, idIndex, data) - Write data to NFC device
  • readReq(commandId, idIndex, parameters) - Read data from NFC device
  • createSendFrame(commandId, idIndex, data, instruction) - Create NFC frame
  • parseFrame(frameData) - Parse received NFC frame
  • transceiveWithTimeout(apduCommand, timeout) - Send APDU with timeout
  • hexFrameToDecimal(hexFrame, dataLength) - Convert hex frame to decimal

LoggerService Methods

The LoggerService provides logging capabilities:

  • log(message, level, category) - Log a message
  • info(message, category) - Log info message
  • warning(message, category) - Log warning message
  • error(message, category) - Log error message
  • success(message, category) - Log success message
  • getLogs() - Get all logs
  • clearLogs() - Clear all logs
  • subscribe(callback) - Subscribe to log updates

Operation States

The SDK uses a state machine for operation management:

  • IDLE - Operation is ready to start
  • WRITE_PENDING - Write operation in progress
  • READ_READY - Ready to read after successful write
  • READ_PENDING - Read operation in progress
  • PROCESSING - Device is processing the operation
  • ERROR - Operation failed
  • READ_READY_WRITE - Ready for next write operation
  • READ_READY_READ - Ready for status read

Customization

Custom Operation Configurations

const customOperations = {
  my_custom_operation: {
    writeCmd: 0x20,
    writeSubCmd: 0x01,
    readCmd: 0x21,
    writeApdu: [0x01, 0x02, 0x03],
    readApdu: [0x00],
    displayName: 'My Custom Operation',
    processingMessage: 'Processing custom operation...',
    icon: '⚙️'
  }
};

<ControlScreen operationConfigs={customOperations} />

Custom Icons

const customIcons = {
  connection: require('./assets/my-connection-icon.png'),
  solenoid: require('./assets/my-solenoid-icon.png'),
};

<ControlScreen icons={customIcons} />

Custom Theme

<ControlScreen 
  theme="dark"
  // ... other props
/>

Error Handling

The SDK provides comprehensive error handling:

const handleError = (error: string) => {
  // Log error
  LoggerService.error(error);
  
  // Show user-friendly message
  Alert.alert('Operation Failed', error);
  
  // Send to crash reporting service
  crashlytics().recordError(new Error(error));
};

<ControlScreen onError={handleError} />

Debugging

Enable detailed logging for debugging:

import { LoggerService } from './je_nfc_sdk';

// Subscribe to all logs
const unsubscribe = LoggerService.subscribe((logs) => {
  console.log('All logs:', logs);
});

// Log custom messages
LoggerService.info('Custom debug message', 'system');
LoggerService.error('Custom error message', 'connection');

// Clean up
unsubscribe();

Best Practices

  1. Always handle errors: Provide error callbacks to handle NFC communication failures
  2. Use translations: Implement proper internationalization with the translate prop
  3. Customize operations: Define your own operation configurations for specific device protocols
  4. Monitor state: Subscribe to operation state changes for UI updates
  5. Clean up resources: Ensure NFC resources are properly cleaned up when components unmount
  6. Test thoroughly: Test NFC operations on real devices with actual NFC tags

Troubleshooting

Common Issues

  1. NFC not working: Ensure NFC is enabled on the device and proper permissions are granted
  2. Connection timeouts: Adjust timeout values in transceiveWithTimeout calls
  3. Frame parsing errors: Check that your operation configurations match the device protocol
  4. State management issues: Use the provided hooks and don't modify operation states directly

Debug Mode

Enable debug mode for detailed logging:

// Enable verbose logging
LoggerService.log('Debug mode enabled', 'info', 'system');

// Monitor all NFC operations
const { operations } = useNfcOperations({
  operationConfigs,
  onOperationComplete: (type, result) => {
    LoggerService.success(`Operation ${type} completed: ${JSON.stringify(result)}`);
  },
  onError: (error) => {
    LoggerService.error(`Operation failed: ${error}`);
  }
});

License

MIT License - see LICENSE file for details.

Support

For support and questions, please refer to the project documentation or create an issue in the project repository.