Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Portflow Laravel Package

hamzi/portflow

PortFlow connects serial hardware (thermal printers, barcode/RFID scanners, scales, IoT boards) to Laravel via a driver-based architecture. Parse raw bytes into typed events, queue routes, and printing workflows, with Web Serial API support for browser integration.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:
    composer require hamzi/portflow
    php artisan vendor:publish --tag=portflow-config
    php artisan vendor:publish --tag=portflow-assets
    
  2. Add JS Bridge to Layout:
    <script src="{{ asset('vendor/portflow/portflow-serial.js') }}"></script>
    
  3. Initialize Livewire Connector:
    <livewire:portflow-connector :baud-rate="115200" />
    
  4. Listen for Hardware Events:
    use Hamzi\PortFlow\Domain\Events\ProductScanned;
    
    Event::listen(ProductScanned::class, fn(ProductScanned $event) => {
        // Handle event
    });
    

First Use Case

Thermal Printer Integration:

// Print a receipt
$bytes = PortFlow::print('receipts.order', ['order' => $order]);
PortFlow::encode('escpos', $bytes)->sendToPrinter();

Implementation Patterns

Driver-Based Workflows

  1. Inbound Data Flow:
    • Browser → Web Serial API → portflow-serial.jsPOST /portflow/ingest
    • Laravel parses via SerialDriverSerialFrame → Event/Queue → Eloquent
  2. Outbound Data Flow:
    // Encode and send to hardware
    PortFlow::encode('escpos', ['text' => 'Hello'])
            ->withDriver('thermal-printer')
            ->send();
    

Common Patterns

  • Event Mapping: Define payload-to-event rules in config/portflow.php:
    'mappings' => [
        [
            'driver' => 'raw-json',
            'payload_field' => 'type',
            'equals' => 'barcode.scan',
            'event' => ProductScanned::class,
        ],
    ],
    
  • Livewire Integration:
    <livewire:portflow-status :device="device" />
    
  • Queue-Based Routing: Offload heavy processing:
    PortFlow::routeToQueue(ProductScanned::class, $frame);
    

Integration Tips

  1. Hardware Discovery:
    PortFlow::discoverDevices(['usbVendorId' => 6790]);
    
  2. Contextual Processing:
    PortFlow::parse('raw-json', $chunk, ['device' => 'scale-a']);
    
  3. Blade Rendering:
    $bytes = PortFlow::print('receipts.order', compact('order'));
    

Gotchas and Tips

Pitfalls

  1. Web Serial API Limitations:

    • No Firefox/Safari support (Chrome/Edge only).
    • Requires user permission for each device connection.
    • Fix: Use autoConnectOnLoad with navigator.serial.getPorts() for remembered devices.
  2. Driver Configuration:

    • Forgetting to publish config (portflow-config) causes silent failures.
    • Fix: Run php artisan vendor:publish --tag=portflow-config after install.
  3. Event Type Safety:

    • Events not implementing SerialEvent trigger warnings.
    • Fix: Extend SerialEvent for all custom events:
      class WeightReceived implements SerialEvent { ... }
      
  4. Buffer Overflows:

    • IoTFrameBuffer has a max_bytes limit (default: 16KB).
    • Fix: Adjust in config or handle partial frames in custom drivers.

Debugging

  1. Log SerialFrames:
    PortFlow::setDebug(true); // Logs all frames to Laravel logs
    
  2. Inspect Raw Bytes:
    PortFlow::parse('raw-json', $chunk)->dump();
    
  3. Livewire Debugging:
    @livewireScripts
    <script>
      window.addEventListener('esp32-browser-frame', (e) => {
        console.log('Raw chunk:', e.detail);
      });
    </script>
    

Extension Points

  1. Custom Drivers:

    • Use php artisan portflow:make-driver for scaffolding.
    • Implement SerialDriver for new protocols (e.g., Modbus).
  2. Blade Extensions:

    // Add to AppServiceProvider
    Blade::directive('escpos', function ($expr) {
        return "<?php echo app('portflow')->print($expr); ?>";
    });
    

    Usage:

    @escpos('receipts.order', ['order' => $order])
    
  3. Queue Workers:

    • Monitor RouteSerialFrameJob for stuck frames:
      php artisan queue:work --queue=portflow
      

Configuration Quirks

  1. Default Driver:
    • Override globally in config/portflow.php or per-request:
      PortFlow::setDriver('rfid-ascii');
      
  2. Auto-Reconnect:
    • Requires autoConnectOnLoad: true and filters to match remembered devices.
  3. CSRF Protection:
    • Ensure csrfToken is passed to PortFlowBridge in JavaScript.

Performance Tips

  1. Batch Processing:
    PortFlow::batchFrames($frames)->routeToQueue(ProductScanned::class);
    
  2. Memory Management:
    • Clear buffers after processing:
      PortFlow::clearBuffer('raw-json');
      
  3. Livewire Optimization:
    • Use wire:ignore for high-frequency updates:
      <div wire:ignore>
        <livewire:portflow-status />
      </div>
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle