---
name: modbus-serial
description: 'Modbus-Serial kütüphanesini (modbus-serial) kullanırken yardımcı kısa rehber: bağlantı yöntemleri (RTU/TCP/ASCII/UDP), yaygın API çağrıları, örnek kodlar, test ve hata ayıklama ipuçları. Anahtar kelimeler: modbus, RTU, TCP, serialport, connectRTU, connectTCP, readHoldingRegisters, ServerTCP'
license: Complete terms in LICENSE
---

# Modbus-Serial Yardımcı
Bu skill, proje içinde yer alan `modbus-serial` kütüphanesini kullanırken sık yapılan görevleri, örnekleri ve hata ayıklama ipuçlarını hızlıca bulmanızı sağlar.

## When to Use This Skill
- Yeni bir Modbus client veya server örneği oluştururken
- Seri (RTU/ASCII) veya TCP üzerinden Modbus cihazlarına bağlanma kodu gerektiğinde
- Test, hata ayıklama veya CI yapılandırması yaparken
- TypeScript tipleri, `serialport` opsiyoneli veya performans sorunlarıyla uğraşırken

## Prerequisites
- Node.js ve npm: repo testleri için `npm ci` ve `npm test` çalıştırılabilir. Not: `serialport` 13.x kullanacaksanız Node.js 20+ gereklidir.
- Opsiyonel: seri port desteği için `serialport` (opsiyonel dependency). CI ortamında native derlemeyi atlamak için `--no-optional` kullanabilirsiniz.

## Quick Commands
```bash
npm ci
npm test
npm run lint
npm run build
# Eğer seri port istemiyorsanız:
npm install --no-optional
```

## Hızlı Örnekler

### TCP Client (async/await)
```javascript
const ModbusRTU = require("modbus-serial");
const client = new ModbusRTU();

async function run() {
  await client.connectTCP("127.0.0.1", { port: 8502 });
  client.setID(1);
  const res = await client.readHoldingRegisters(0, 2);
  console.log(res.data);
  client.close();
}
run().catch(console.error);
```

### RTU (seri) - Buffered
```javascript
const ModbusRTU = require("modbus-serial");
const client = new ModbusRTU();

async function runSerial() {
  await client.connectRTUBuffered("/dev/ttyUSB0", { baudRate: 9600 });
  client.setID(1);
  await client.writeRegisters(5, [0, 0xffff]);
  const res = await client.readHoldingRegisters(5, 2);
  console.log(res.data);
  client.close();
}
runSerial().catch(console.error);
```

### ModbusTCP Sunucu (basit)
```javascript
const ModbusRTU = require("modbus-serial");
const vector = {
  getInputRegister: (addr) => addr,
  getHoldingRegister: (addr, unitID, cb) => cb(null, addr + 8000),
  getCoil: async (addr) => (addr % 2) === 0
};
const server = new ModbusRTU.ServerTCP(vector, { host: "0.0.0.0", port: 8502 });
```

### TestPort (unit-test için)
```javascript
const ModbusRTU = require("modbus-serial");
const TestPort = ModbusRTU.TestPort;
const testPort = new TestPort();
const client = new ModbusRTU(testPort);

async function test() {
  await client.open();
  const data = await client.readHoldingRegisters(8, 3); // test port'ta simülasyon kayıtları var
  console.log(data.data);
  client.close();
}
test().catch(console.error);
```

## PLC & Ethernet (Modbus TCP): PLC'ye Ethernet ile bağlanma

### Hızlı bağlantı örneği
```javascript
const ModbusRTU = require("modbus-serial");
const client = new ModbusRTU();
async function connectPLC() {
  await client.connectTCP("192.168.0.10", { port: 502, timeout: 2000 });
  client.setID(1); // PLC'nin Unit ID'si
  const res = await client.readHoldingRegisters(0, 10);
  console.log(res.data);
  client.close();
}
connectPLC().catch(console.error);
```

### Önemli noktalar
- Modbus TCP kullanan PLC'lerde port genelde `502`'dir; cihazın dökümantasyonunu kontrol edin.
- `connectTCP` MBAP (Modbus TCP) framing kullanır — TCP üzerinde CRC eklemeyin; `modbus-serial` bunu `TcpPort` içinde yönetir.
- Bazı cihazlar RTU-over-TCP (seri çerçevesini TCP paketine sarma) kullanır; bu durumda `connectTcpRTUBuffered` veya `linkTcpRTUBuffered` gerekebilir.
- PLC register adresleme üreticiden üreticiye 1-based veya 0-based olabilir. Örneğin dokümanda `40001` görürseniz genelde `readHoldingRegisters(0, ...)` kullanmanız gerekir — adresleme kaydırmasını doğrulayın.
- Birden fazla sorgu gönderirken PLC'yi aşırı yüklemeyin; `worker`/polling ayarlarında `maxConcurrentRequests` ve `maxChunkSize` ayarlarını kullanın.

### Ağ, güvenlik ve sorun giderme
- Firewall: cihazın TCP 502'yi kabul ettiğinden emin olun (sunucu tarafında açık).
- Switch/Router: ARP, VLAN, veya NAT sorunları Modbus iletişimini bozabilir; doğrudan ağ erişimi veya uygun NAT kuralları kullanın.
- Güvenlik: Modbus şifrelemesiz ve kimlik doğrulamasızdır — PLC'lerinizi ağ segmentasyonuyla, ACL ve VPN ile koruyun.
- Zaman aşımları: düşük timeout değerleri (`timeout: 2000`) kullanarak hızlı hata tespiti yapın, ancak çok agresif ayarlardan kaçının.

### Örnek: hataya karşı tekrar deneme (retry)
```javascript
async function readWithRetry(client, addr, len, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      return await client.readHoldingRegisters(addr, len);
    } catch (err) {
      if (i === retries - 1) throw err;
      await new Promise(r => setTimeout(r, 200));
    }
  }
}
```

### Donanım/spesifik PLC notları
- PLC üreticisi ve modeli varsa dokümantasyonunda `Modbus TCP` desteğini, kullanılan portu ve Unit ID varsayımlarını kontrol edin. Bazı cihazlar Unit ID'yi köprüleme/çevirme amaçlı kullanır.

## Gotchas (Dikkat Edilmesi Gerekenler)
- **`serialport` opsiyoneldir**: TCP-only kullanımda opsiyoneli yüklemek zorunda değilsiniz; ama RTU/ASCII için `serialport` gerekir ve 13.x sürümü Node 20+ gerektirir.
- **TypeScript tipleri**: `ServerSerial.d.ts` gibi dosyalar `serialport` tiplerini import edebilir. `--no-optional` kullanıyorsanız `skipLibCheck` veya `serialport`'u devDependency olarak ekleyin.
- **RTU vs TCP framing**: TCP (MBAP) ile RTU (CRC) arasındaki farklar nedeniyle yanlış paketleme CRC hatalarına yol açabilir — doğru port tipini kullanın (`connectTCP` vs `connectRTUBuffered`).
- **Bağlantıları kapatma**: Uzun süreli çalışan testlerde `.close()`/`.destroy()` çağrılarını unutmayın.

## Troubleshooting (Hızlı Çözümler)
- Port Not Open / ECONNREFUSED: Bağlantıyı açmadan önce `connectXXX` çağrısını await/ callback ile tamamlayın.
- CRC error: Yanlış framing veya hatalı seri ayar (baudrate/parity) kontrol edin.
- serialport derleme hatası (CI): `npm install --no-optional` veya uygun `serialport` major'ını manuel kurun.
- Tests failing locally: `npm ci` çalıştırıp sonra `npm test` ile tekrar deneyin; testler mock port kullanacak şekilde yazılmıştır (`test/mocks`, `ports/testport.js`).

## References (External)
- GitHub repository: https://github.com/yaacov/node-modbus-serial
- npm package: https://www.npmjs.com/package/modbus-serial
- Modbus specifications: https://modbus.org/specs.php
- serialport docs: https://serialport.io/
- Node.js: https://nodejs.org/

Note: This `SKILL.md` is written to be portable and self-contained. Do not reference files in other repositories. To use this skill in another project, add this file under `.github/skills/modbus-serial/SKILL.md` and include a `LICENSE` file (for example `LICENSE` or `LICENSE.txt`) alongside it.

## Hızlı Sorular (Copilot'a sorabileceğiniz örnekler)
- "modbus-serial ile TCP'ye bağlanıp holding register oku"
- "connectRTUBuffered örneği ve seri ayarları nasıl olmalı?"
- "ModbusTCP sunucusu nasıl oluşturulur ve getHoldingRegister nasıl implement edilir?"
- "TestPort kullanarak birim testleri nasıl yazılır?"
- "serialport derleme hatası CI'da nasıl atlanır?"

## Sonraki Adımlar
- İsterseniz bu örneklerden birini doğrudan `examples/` içine ekleyip README'ye özetle ekleyebilirim. Hangi örneği istersiniz?
