UNPKG

soem-node

Version:

Bindings Node-API pour SOEM (Simple Open EtherCAT Master)

159 lines (158 loc) 7.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SoemMaster = void 0; // Utilise 'bindings' pour résoudre le chemin du binaire natif de façon robuste // (compatible avec Electron, asarUnpack, et différentes dispositions de build) // Voir: https://www.electronjs.org/docs/latest/tutorial/native-code-and-electron // et https://github.com/TooTallNate/node-bindings // NB: le nom doit correspondre au nom du module natif généré par node-gyp (target_name dans binding.gyp: soem_addon) // ainsi qu'au nom du module exporté via NODE_API_MODULE. // Fallback vers le chemin direct si nécessaire (en dev rare) let native; try { // eslint-disable-next-line @typescript-eslint/no-var-requires native = require('bindings')('soem_addon'); } catch (e) { // eslint-disable-next-line @typescript-eslint/no-var-requires native = require('../build/Release/soem_addon.node'); } /** * Wrapper TypeScript autour du binding natif SOEM (N-API). * * Contrat (résumé): * - Entrées: nom d'interface réseau (string) optionnel dans le constructeur. * - Sorties: méthodes renvoyant des types JS primitifs ou Buffers. * - Modes d'erreur: la plupart des méthodes renvoient un booléen ou un code; le binding natif * peut jeter pour les erreurs fatales (ex: problème d'initialisation). * * Usage typique: * const m = new SoemMaster('eth0'); * if (m.init()) { * const slaves = m.configInit(); * ... * m.close(); * } */ class SoemMaster { /** * Crée une instance du Master SOEM en se liant à une interface réseau. * @param ifname Le nom de l'interface réseau à utiliser. Défaut: 'eth0' (modifiable pour Windows). */ constructor(ifname = 'eth0') { this._m = new native.Master(ifname); } /** * Initialise le master (ouvre l'interface, prépare SOEM). * @returns true si l'initialisation a réussi, false sinon. */ init() { return this._m.init(); } /** * Lance la découverte et la configuration des esclaves EtherCAT sur le bus. * @returns nombre d'esclaves détectés (0 si aucun). */ configInit() { return this._m.configInit(); } /** * Configure la map des PDOs après `configInit()`. * Ne renvoie rien; l'appel peut lever une erreur côté natif si mal utilisé. */ configMapPDO() { this._m.configMapPDO(); } /** * Retourne l'état courant du master / bus (valeur numérique dépendant du binding). * Voir la documentation SOEM pour l'interprétation des codes d'état. */ state() { return this._m.state(); } /** * Force la lecture de l'état (rafraîchit la représentation interne) et renvoie le code d'état. */ readState() { return this._m.readState(); } /** * Lit un SDO d'un esclave. * @param slave Index (1-based) de l'esclave sur le bus. * @param index Index de l'objet SDO (ex: 0x1000). * @param sub Sous-index de l'objet SDO (ex: 0). * @param ca optional Complete Access flag (true = Complete Access) * @returns Buffer contenant les octets lus, ou null/undefined si la lecture a échoué. */ sdoRead(slave, index, sub, ca) { return this._m.sdoRead(slave, index, sub, ca); } /** * Écrit un SDO sur un esclave. * @param slave Index (1-based) de l'esclave. * @param index Index de l'objet SDO. * @param sub Sous-index de l'objet SDO. * @param data Buffer contenant les octets à écrire. * @param data Buffer contenant les octets à écrire. * @param ca optional Complete Access flag (true = Complete Access) * @returns true si l'écriture a réussi, false sinon. */ sdoWrite(slave, index, sub, data, ca) { return this._m.sdoWrite(slave, index, sub, data, ca); } /** * Envoie les données process (processdata) au réseau EtherCAT pour le cycle courant. * @returns nombre d'octets envoyés ou un code WKC selon l'implémentation. */ sendProcessdata() { return this._m.sendProcessdata(); } /** * Reçoit les données process (processdata) depuis le réseau EtherCAT pour le cycle courant. * @returns code WKC (working counter) ou nombre d'octets reçus selon le binding. */ receiveProcessdata() { return this._m.receiveProcessdata(); } /** * Ferme le master et libère les ressources (sockets/bruts, handles natifs). */ close() { this._m.close(); } /** * Écrit l'état demandé sur un esclave (ou master si slave=0). * @returns workcounter ou code d'erreur. */ writeState(slave, state) { return this._m.writeState(slave, state); } /** * Vérifie l'état d'un esclave (blocking). * @param timeout en ms (optionnel) */ stateCheck(slave, reqstate, timeout) { return this._m.stateCheck(slave, reqstate, timeout); } /** * Reconfigure un esclave (blocking). Retourne l'état final. */ reconfigSlave(slave, timeout) { return this._m.reconfigSlave(slave, timeout); } /** * Récupère un esclave (blocking). Retourne >0 si successful. */ recoverSlave(slave, timeout) { return this._m.recoverSlave(slave, timeout); } /** * Active la mailbox cyclique pour un esclave. */ slaveMbxCyclic(slave) { return this._m.slaveMbxCyclic(slave); } /** * Configure et active Distributed Clocks (DC). */ configDC() { return this._m.configDC(); } /** * Retourne un tableau décrivant les esclaves détectés (name, state, outputs, inputs, ...). */ getSlaves() { return this._m.getSlaves(); } initRedundant(if1, if2) { return this._m.initRedundant(if1, if2); } configMapGroup(group) { return this._m.configMapGroup(group); } sendProcessdataGroup(group) { return this._m.sendProcessdataGroup(group); } receiveProcessdataGroup(group, timeout) { return this._m.receiveProcessdataGroup(group, timeout); } mbxHandler(group, limit) { return this._m.mbxHandler(group, limit); } elist2string() { return this._m.elist2string(); } SoEread(slave, driveNo, elementflags, idn) { return this._m.SoEread(slave, driveNo, elementflags, idn); } SoEwrite(slave, driveNo, elementflags, idn, data) { return this._m.SoEwrite(slave, driveNo, elementflags, idn, data); } readeeprom(slave, eeproma, timeout) { return this._m.readeeprom(slave, eeproma, timeout); } writeeeprom(slave, eeproma, data, timeout) { return this._m.writeeeprom(slave, eeproma, data, timeout); } APRD(ADP, ADO, length, timeout) { return this._m.APRD(ADP, ADO, length, timeout); } APWR(ADP, ADO, data, timeout) { return this._m.APWR(ADP, ADO, data, timeout); } LRW(LogAdr, length, buf, timeout) { return this._m.LRW(LogAdr, length, buf, timeout); } LRD(LogAdr, length, timeout) { return this._m.LRD(LogAdr, length, timeout); } LWR(LogAdr, data, timeout) { return this._m.LWR(LogAdr, data, timeout); } dcsync0(slave, act, CyclTime, CyclShift) { return this._m.dcsync0(slave, act, CyclTime, CyclShift); } dcsync01(slave, act, CyclTime0, CyclTime1, CyclShift) { return this._m.dcsync01(slave, act, CyclTime0, CyclTime1, CyclShift); } /** * Liste les interfaces réseau disponibles pour l'usage EtherCAT. * @returns tableau d'objets `{ name, description }`. */ static listInterfaces() { return native.Master.listInterfaces(); } } exports.SoemMaster = SoemMaster;