ni-visa
Version:
Node.js bindings for NI-VISA
182 lines • 6.46 kB
JavaScript
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