je_nfc_sdk
v2.0.15
Published
A comprehensive React Native SDK for NFC-based device control and communication
Maintainers
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 devicereadReq(commandId, idIndex, parameters)- Read data from NFC devicecreateSendFrame(commandId, idIndex, data, instruction)- Create NFC frameparseFrame(frameData)- Parse received NFC frametransceiveWithTimeout(apduCommand, timeout)- Send APDU with timeouthexFrameToDecimal(hexFrame, dataLength)- Convert hex frame to decimal
LoggerService Methods
The LoggerService provides logging capabilities:
log(message, level, category)- Log a messageinfo(message, category)- Log info messagewarning(message, category)- Log warning messageerror(message, category)- Log error messagesuccess(message, category)- Log success messagegetLogs()- Get all logsclearLogs()- Clear all logssubscribe(callback)- Subscribe to log updates
Operation States
The SDK uses a state machine for operation management:
IDLE- Operation is ready to startWRITE_PENDING- Write operation in progressREAD_READY- Ready to read after successful writeREAD_PENDING- Read operation in progressPROCESSING- Device is processing the operationERROR- Operation failedREAD_READY_WRITE- Ready for next write operationREAD_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
- Always handle errors: Provide error callbacks to handle NFC communication failures
- Use translations: Implement proper internationalization with the translate prop
- Customize operations: Define your own operation configurations for specific device protocols
- Monitor state: Subscribe to operation state changes for UI updates
- Clean up resources: Ensure NFC resources are properly cleaned up when components unmount
- Test thoroughly: Test NFC operations on real devices with actual NFC tags
Troubleshooting
Common Issues
- NFC not working: Ensure NFC is enabled on the device and proper permissions are granted
- Connection timeouts: Adjust timeout values in transceiveWithTimeout calls
- Frame parsing errors: Check that your operation configurations match the device protocol
- 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.
