je_nfc_sdk
Version:
A comprehensive React Native SDK for NFC-based device control and communication
408 lines (326 loc) • 11.9 kB
Markdown
# 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:
```typescript
import {
ControlScreen,
NfcOperationCard,
useNfcOperations,
LoggerService,
FrameServer
} from './je_nfc_sdk';
```
## Dependencies
Make sure your project has these peer dependencies installed:
```json
{
"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
```typescript
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
```typescript
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
```typescript
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
```typescript
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
```typescript
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:
```typescript
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
```typescript
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
```typescript
const customIcons = {
connection: require('./assets/my-connection-icon.png'),
solenoid: require('./assets/my-solenoid-icon.png'),
};
<ControlScreen icons={customIcons} />
```
### Custom Theme
```typescript
<ControlScreen
theme="dark"
// ... other props
/>
```
## Error Handling
The SDK provides comprehensive error handling:
```typescript
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:
```typescript
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:
```typescript
// 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.