UNPKG

ni-visa

Version:

Node.js bindings for NI-VISA

182 lines 6.46 kB
import os from 'node:os'; import koffi from 'koffi'; import { ViAChar, ViAccessMode, ViConstBuf, ViConstRsrc, ViConstString, ViObject, ViPBuf, ViPFindList, ViPSession, ViPUInt32, ViSession, ViStatus, ViUInt32, } from "./VisaTypes.js"; export const VisaAccessMode = { VI_NO_LOCK: 0, VI_EXCLUSIVE_LOCK: 1, VI_SHARED_LOCK: 2, VI_LOAD_CONFIG: 4, }; export class VisaResourceManager { visa; session; constructor(visaOrLib) { if (typeof visaOrLib === 'string' || visaOrLib === undefined) { this.visa = new Visa(visaOrLib); } else { this.visa = visaOrLib; } this.session = this.visa.openDefaultRM(); } listResources(query = '?*') { return this.visa.listResources(this.session, query); } open(resourceName, timeout = 5000) { return this.visa.open(this.session, resourceName, timeout); } close() { this.visa.close(this.session); } } export class VisaInstrument { visa; session; constructor(visa, session) { this.visa = visa; this.session = session; } query(command, bufferSize = 1024) { return this.visa.query(this.session, command, bufferSize); } queryBinary(command, bufferSize = 1024) { return this.visa.queryBinary(this.session, command, bufferSize); } write(data) { return this.visa.write(this.session, data); } close() { this.visa.close(this.session); } } export class Visa { visaLib; viOpenDefaultRM; viFindRsrc; viFindNext; viOpen; viRead; viWrite; viClose; constructor(libraryPath) { this.visaLib = koffi.load(libraryPath ?? this.getDefaultLibrary()); this.viOpenDefaultRM = this.visaLib.func('viOpenDefaultRM', ViStatus, [ViPSession]); this.viFindRsrc = this.visaLib.func('viFindRsrc', ViStatus, [ ViSession, ViConstString, ViPFindList, ViPUInt32, ViAChar, ]); this.viFindNext = this.visaLib.func('viFindNext', ViStatus, [ViPFindList, ViAChar]); this.viOpen = this.visaLib.func('viOpen', ViStatus, [ ViSession, ViConstRsrc, ViAccessMode, ViUInt32, ViPSession, ]); this.viRead = this.visaLib.func('viRead', ViStatus, [ViSession, ViPBuf, ViUInt32, ViPUInt32]); this.viWrite = this.visaLib.func('viWrite', ViStatus, [ ViSession, ViConstBuf, ViUInt32, ViPUInt32, ]); this.viClose = this.visaLib.func('viClose', ViStatus, [ViObject]); } getDefaultLibrary() { const platform = os.platform(); if (platform === 'win32') { return os.arch() === 'x64' ? 'visa64.dll' : 'visa32.dll'; } if (platform === 'darwin') { return '/Library/Frameworks/RsVisa.framework/Versions/A/RsVisa/librsvisa.dylib'; } if (platform === 'linux') { return 'librsvisa'; } throw new Error(`Unsupported platform: ${platform}`); } openDefaultRM() { const buffer = Buffer.alloc(4); const status = this.viOpenDefaultRM(buffer); if (status !== 0) { throw new Error(`viOpenDefaultRM failed with status: ${status}`); } const session = buffer.readUInt32LE(0); return session; } listResources(session, query = '?*') { const findListPtr = Buffer.alloc(4); const retCountPtr = Buffer.alloc(4); const resourceNameBuffer = Buffer.alloc(1024); const status = this.viFindRsrc(session, query, findListPtr, retCountPtr, resourceNameBuffer); if (status !== 0) { throw new Error(`viFindRsrc failed with status: ${status}`); } const findList = findListPtr.readUInt32LE(0); const numResources = retCountPtr.readUInt32LE(0); const resources = []; const resourceName = resourceNameBuffer.toString('utf8').split('\0').shift(); if (resourceName) { resources.push(resourceName); } for (let i = 1; i < numResources; i++) { resourceNameBuffer.fill(0); const nextStatus = this.viFindNext(findList, resourceNameBuffer); if (nextStatus !== 0) { throw new Error(`viFindNext failed with status: ${nextStatus}`); } const resourceName = resourceNameBuffer.toString('utf8').split('\0').shift(); if (resourceName) { resources.push(resourceName); } } return resources; } open(session, resourceName, timeout = 5000) { const vi = Buffer.alloc(4); const status = this.viOpen(session, resourceName, VisaAccessMode.VI_NO_LOCK, timeout, vi); if (status !== 0) { throw new Error(`viOpen failed with status: ${status}`); } return new VisaInstrument(this, vi.readUInt32LE(0)); } read(session, buffer) { const retCount = Buffer.alloc(4); const status = this.viRead(session, buffer, buffer.length, retCount); if (status !== 0) { throw new Error(`viRead failed with status: ${status}`); } return retCount.readUInt32LE(0); } write(session, data) { const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data); const retCount = Buffer.alloc(4); const status = this.viWrite(session, buffer, buffer.length, retCount); if (status !== 0) { throw new Error(`viWrite failed with status: ${status}`); } return retCount.readUInt32LE(0); } query(session, command, bufferSize = 1024) { const buffer = Buffer.alloc(bufferSize); this.write(session, Buffer.from(`${command}\n`)); const bytesRead = this.read(session, buffer); return buffer.toString('utf8', 0, bytesRead).trim(); } queryBinary(session, command, bufferSize = 1024) { const buffer = Buffer.alloc(bufferSize); this.write(session, Buffer.from(`${command}\n`)); const bytesRead = this.read(session, buffer); return buffer.slice(0, bytesRead); } close(vi) { const status = this.viClose(vi); if (status !== 0) { throw new Error(`viClose failed with status: ${status}`); } } } //# sourceMappingURL=Visa.js.map