UNPKG

weblab-instrument

Version:
927 lines (831 loc) 30 kB
/* eslint no-restricted-syntax: 0 */ /* eslint no-await-in-loop: 0 */ /** * Module use to communicate with GWINSTEK's DSO through Ethernet or USB * * @module instrument-com */ import cmdObj from './sys/pwr-command.json'; const EventEmitter = require('events').EventEmitter; const debug = require('debug'); const log = debug('pwr:log'); const sysConstant = require('./sys/sysConstant.js'); const syscmd = require('./pwr/system.js'); const channel = require('./pwr/channel.js'); const usbDev = require('./dev/devUsb.js'); const base = require('./dev/base.js'); const DELAY_CNT = 150; /** * Create all needed private properties and method * * @private * @constructor PwrObject * * @return {Object} Private method used to control DSO */ const PwrObject = function PwrObject() { this.dev = new base.Dev(); this.sys = syscmd.initPwrSysObj.call(this, 'sys'); this.ch1 = channel.initPwrChanObj.call(this, 'ch1'); this.ch2 = channel.initPwrChanObj.call(this, 'ch2'); this.ch3 = channel.initPwrChanObj.call(this, 'ch3'); this.ch4 = channel.initPwrChanObj.call(this, 'ch4'); this.cmdEvent = new EventEmitter(); this.commandObj = cmdObj; this.dev.commandObj = this.commandObj; return this; }; /** * The class define all needed public properties and methods * * @class pwrctrl * * */ const PwrControl = function PwrControl(pwrObj) { const pwrctrl = {}; /** * The method belong to pwrctrl class used to release device's resource. * * @method closeDev * @return {null} null * */ pwrctrl.closeDev = (function closeDev() { log('closeDev'); return new Promise(((resolve, reject) => { pwrctrl.disconnect() .then(resolve) .catch((e) => { reject(e); }); })); }); // var all_the_types = mdns.browseThemAll(); /** * The method belong to pwrctrl class used to connect to device, * connect method must be called and wait to complete before any pwrctrl method. * * @method connect * * */ pwrctrl.connect = (function connect(dontCheckdev) { const self = this; return new Promise(((resolve, reject) => { function conn(e) { if (e) { reject(e); } else { resolve(); } } self.dev.usbConnect(conn, dontCheckdev); /* if (self.dev.interf === 'usb') { self.dev.usbConnect(conn); }else if (self.dev.interf === 'net') { self.dev.tcpConnect(conn); } else{ reject(Error('Not supported interface')); } */ })); }).bind(pwrObj); /** * The method belong to pwrctrl class used to disconnect from device. * * @method disconnect * * */ pwrctrl.disconnect = (function disconnect() { log('disconnect'); const self = this; return new Promise(((resolve, reject) => { function disconnectDone(e) { if (e) { log('disconnect return'); log(e); reject(e); } else { resolve(); } } self.dev.asyncWrite = 'done'; self.dev.queryBlock = false; self.dev.state.setTimeout = false; if (self.dev.state.conn !== 'disconnected') { self.dev.cmdSequence = []; if (self.dev.writeTimeoutObj !== null) { clearTimeout(self.dev.writeTimeoutObj); } self.dev.usbDisconnect(disconnectDone); } else { resolve(); } })); }).bind(pwrObj); pwrctrl.setDelay = (function setDelay(val) { const self = this; return new Promise(((resolve, reject) => { function setDone(e) { if (e) { reject(e); } else { resolve(self.sys.status); } } const sysCmd = [ { id: 'sys', prop: 'delay_for_a_while', arg: parseInt(val, 10), cb: setDone, method: 'set' }, ]; self.dev.cmdSequence = self.dev.cmdSequence.concat(sysCmd); self.cmdEvent.emit('cmdWrite', sysCmd); })); }).bind(pwrObj); /** * */ pwrctrl.getSetup = (function getSetup() { // this.GetSnapshot(callback); const self = this; return new Promise(((resolve, reject) => { function getDone(e) { if (e) { reject(e); } else { resolve({ status: self.sys.status, chProps: { ch1: { iset: self.ch1.iset, vset: self.ch1.vset, }, ch2: { iset: self.ch2.iset, vset: self.ch2.vset, }, ch3: { iset: self.ch3.iset, vset: self.ch3.vset, }, ch4: { iset: self.ch4.iset, vset: self.ch4.vset, }, }, }); } } const cmd = []; let i; const chID = ['ch1', 'ch2', 'ch3', 'ch4']; log('pwr getSetup'); cmd.push({ id: 'sys', prop: 'SysRemote', arg: '1', cb: null, method: 'set' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); for (i = 0; i < self.dev.maxChNum; i += 1) { cmd.push({ id: chID[i], prop: 'ISET', arg: '', cb: null, method: 'get' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); cmd.push({ id: chID[i], prop: 'VSET', arg: '', cb: null, method: 'get' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } cmd.push({ id: 'sys', prop: 'STATUS', arg: '', cb: getDone, method: 'get' }); self.dev.cmdSequence = self.dev.cmdSequence.concat(cmd); // log(self.dev.cmdSequence); self.cmdEvent.emit('cmdWrite', cmd); })); }).bind(pwrObj); /** * */ pwrctrl.setSetup = (function setSetup(setup) { const self = this; return new Promise(((resolve, reject) => { function setDone(e) { if (e) { log('pwr.setSetup error'); log(e); reject(e); } else { resolve(); } } const cmd = []; let i; const chID = ['ch1', 'ch2', 'ch3', 'ch4']; let track; log('pwr setSetup'); log(setup); cmd.push({ id: 'sys', prop: 'SysRemote', arg: '1', cb: null, method: 'set' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); cmd.push({ id: 'sys', prop: 'TRACK', arg: '0', cb: null, method: 'set' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); for (i = 0; i < self.dev.maxChNum; i += 1) { cmd.push({ id: chID[i], prop: 'ISET', arg: setup.chProps[chID[i]].iset.slice(0, -2), cb: null, method: 'set' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); cmd.push({ id: chID[i], prop: 'VSET', arg: setup.chProps[chID[i]].vset.slice(0, -2), cb: null, method: 'set' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } if ((setup.status[2] === '1') && (setup.status[3] === '0')) { track = '2';// PARA } else if ((setup.status[2] === '1') && (setup.status[3] === '1')) { track = '1';// SER } else { track = '0'; } cmd.push({ id: 'sys', prop: 'TRACK', arg: track, cb: setDone, method: 'set' }); self.dev.cmdSequence = self.dev.cmdSequence.concat(cmd); // log(self.dev.cmdSequence); self.cmdEvent.emit('cmdWrite', cmd); })); }).bind(pwrObj); /** * The method belong to pwrctrl class used to set the device into local state * * @method status * */ pwrctrl.status = (function status() { const self = this; return new Promise(((resolve, reject) => { function getDone(e) { if (e) { reject(e); } else { resolve(self.sys.status); } } const sysCmd = [ { id: 'sys', prop: 'STATUS', arg: '', cb: null, method: 'get' }, { id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: getDone, method: 'set' }, ]; self.dev.cmdSequence = self.dev.cmdSequence.concat(sysCmd); self.cmdEvent.emit('cmdWrite', sysCmd); })); }).bind(pwrObj); /** * The method belong to pwrctrl class used to set the device into local state * * @method force * */ pwrctrl.track = (function track(arg) { const self = this; return new Promise(((resolve, reject) => { function setDone(e) { if (e) { reject(e); } else { resolve(); } } const sysCmd = [ { id: 'sys', prop: 'TRACK', arg, cb: null, method: 'set' }, { id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: setDone, method: 'set' }, ]; self.dev.cmdSequence = self.dev.cmdSequence.concat(sysCmd); self.cmdEvent.emit('cmdWrite', sysCmd); })); }).bind(pwrObj); /** * The method belong to pwrctrl class used to set the device into local state * * @method force * */ pwrctrl.beep = (function beep(arg) { const self = this; return new Promise(((resolve, reject) => { function setDone(e) { if (e) { reject(e); } else { resolve(); } } const sysCmd = [ { id: 'sys', prop: 'BEEP', arg, cb: null, method: 'set' }, { id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: setDone, method: 'set' }, ]; self.dev.cmdSequence = self.dev.cmdSequence.concat(sysCmd); self.cmdEvent.emit('cmdWrite', sysCmd); })); }).bind(pwrObj); /** * The method belong to pwrctrl class used to set the device into local state * * @method force * */ pwrctrl.out = (function out(arg) { const self = this; return new Promise(((resolve, reject) => { function setDone(e) { if (e) { reject(e); } else { resolve(); } } const sysCmd = [ { id: 'sys', prop: 'OUT', arg, cb: null, method: 'set' }, { id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: setDone, method: 'set' }, ]; self.dev.cmdSequence = self.dev.cmdSequence.concat(sysCmd); self.cmdEvent.emit('cmdWrite', sysCmd); })); }).bind(pwrObj); /** * Channel property of device. * * @property funcProp * @type Object * @param {String} Sets the function for the display */ pwrctrl.setSysProp = (function setSysProp(sysProp) { // this.GetSnapshot(callback); const self = this; return new Promise(((resolve, reject) => { function setDone(e) { if (e) { reject(e); } else { resolve(); } } const cmd = []; if (sysProp.track !== undefined) { cmd.push({ id: 'sys', prop: 'TRACK', arg: sysProp.track, cb: null, method: 'set' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } if (sysProp.out !== undefined) { cmd.push({ id: 'sys', prop: 'OUT', arg: sysProp.out, cb: null, method: 'set' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } if (cmd.length > 0) { cmd[cmd.length - 1].cb = setDone; self.dev.cmdSequence = self.dev.cmdSequence.concat(cmd); // log(self.dev.cmdSequence); self.cmdEvent.emit('cmdWrite', cmd); } else { log('setSysProp do nothing'); reject(['DELAY_CNT', 'Parameter Error']); } })); }).bind(pwrObj); /** * Channel property * * @property chProperty * @type Object * @param {String} coupling Specify coupling on AC,DC or GND * @param {String} impedance Specify the impedance of the analog channel * @param {String} invert * @param {String} bandwidth * @param {String} expand * @param {String} state * @param {String} scale * @param {String} position * @param {String} deskew * @param {String} rawdata * @param {String} probe.unit * @param {String} probe.atten */ pwrctrl.getChannel = (function getChannel(chProp) { // this.GetSnapshot(callback); const self = this; const chNum = sysConstant.chID[chProp.ch]; return new Promise(((resolve, reject) => { function getDone(e) { if (e) { reject(e); } else { resolve(self[chProp.ch]); } } const cmd = []; log(`chNum =${chNum}`); log(`maxChNum =${self.dev.maxChNum}`); if (chNum === undefined) { reject(['DELAY_CNT', 'Parameter Error']); return; } if (chNum >= self.dev.maxChNum) { reject(['DELAY_CNT', 'Parameter Error']); return; } // if(chNum < self.dev.maxChNum) { // chCmd = chanLoadCmd[chNum].slice(0); // chCmd[chCmd.length-1].cb = vetical; // self.dev.cmdSequence = self.dev.cmdSequence.concat(chCmd); // self.cmdEvent.emit('cmdWrite', self.dev.cmdSequence); // } if (chProp.iout !== undefined) { cmd.push({ id: chProp.ch, prop: 'IOUT', arg: '', cb: null, method: 'get' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } if (chProp.vout !== undefined) { cmd.push({ id: chProp.ch, prop: 'VOUT', arg: '', cb: null, method: 'get' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } if (chProp.iset !== undefined) { cmd.push({ id: chProp.ch, prop: 'ISET', arg: '', cb: null, method: 'get' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } if (chProp.vset !== undefined) { cmd.push({ id: chProp.ch, prop: 'VSET', arg: '', cb: null, method: 'get' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } if (cmd.length > 0) { cmd[cmd.length - 1].cb = getDone; self.dev.cmdSequence = self.dev.cmdSequence.concat(cmd); // log(self.dev.cmdSequence); self.cmdEvent.emit('cmdWrite', cmd); } else { log('setSysProp do nothing'); reject(['DELAY_CNT', 'Parameter Error']); } })); }).bind(pwrObj); /** * Channel property * * @property chProperty * @type Object * @param {String} coupling Specify coupling on AC,DC or GND * @param {String} impedance Specify the impedance of the analog channel */ pwrctrl.setChannel = (function setChannel(chProp) { // this.GetSnapshot(callback); const self = this; const chNum = sysConstant.chID[chProp.ch]; const cmd = []; return new Promise(((resolve, reject) => { function setDone(e) { if (e) { reject(e); } else { resolve(self[chProp.ch]); } } log(`chNum =${chNum}`); log(`maxChNum =${self.dev.maxChNum}`); log(chProp); if (chNum === undefined) { reject(['DELAY_CNT', 'Parameter Error']); return; } if (chNum >= self.dev.maxChNum) { reject(['DELAY_CNT', 'Parameter Error']); return; } if (chProp.iset !== undefined) { cmd.push({ id: chProp.ch, prop: 'ISET', arg: chProp.iset, cb: null, method: 'set' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } if (chProp.vset !== undefined) { cmd.push({ id: chProp.ch, prop: 'VSET', arg: chProp.vset, cb: null, method: 'set' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } if (cmd.length > 0) { cmd[cmd.length - 1].cb = setDone; self.dev.cmdSequence = self.dev.cmdSequence.concat(cmd); // log(self.dev.cmdSequence); self.cmdEvent.emit('cmdWrite', cmd); } else { log('setVertical do nothing'); resolve(); } })); }).bind(pwrObj); // ////////////////////////// // pwrctrl.onError = (function(callback) { // this.errHandler = callback; // }).bind(pwrObj); // ///////////////////////////// /** * The method belong to pwrctrl class used to set the device into local state * * @method force * */ pwrctrl.local = (function local() { const self = this; return new Promise(((resolve, reject) => { function sysLocal(e) { if (e) { reject(e); } else { resolve(); } } const sysCmd = [ { id: 'sys', prop: 'SysLocal', arg: '', cb: null, method: 'set' }, { id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: sysLocal, method: 'set' }, ]; self.dev.cmdSequence = self.dev.cmdSequence.concat(sysCmd); self.cmdEvent.emit('cmdWrite', sysCmd); })); }).bind(pwrObj); /** * The method belong to pwrctrl class used to set the device into remote state * * @method force * */ pwrctrl.remote = (function remote() { const self = this; return new Promise(((resolve, reject) => { function sysRemote(e) { if (e) { reject(e); } else { resolve(); } } const sysCmd = [ { id: 'sys', prop: 'SysRemote', arg: '', cb: null, method: 'set' }, { id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: sysRemote, method: 'set' }, ]; self.dev.cmdSequence = self.dev.cmdSequence.concat(sysCmd); self.cmdEvent.emit('cmdWrite', sysCmd); })); }).bind(pwrObj); /** * The method belong to afgctrl class used * to setup a periodical measure channel with specify measure type * and source channel * * @method setMeas * @param {Object} measConf Config to setup a measure channel * * */ /** * * Object used to get a specify data * * @property conf * @type Object * @param {String} src1 Specify source channel * @param {String} type Specify channel data */ pwrctrl.getMeas = (function getMeas(conf) { // this.GetSnapshot(callback); const self = this; const chNum = sysConstant.chID[conf.src1]; return new Promise(((resolve, reject) => { function getDone(e) { if (e) { reject(e); } else { let val; if (conf.type === 'iout') { val = self[conf.src1].iout; } else if (conf.type === 'iset') { val = self[conf.src1].iset; } else if (conf.type === 'vset') { val = self[conf.src1].vset; } else if (conf.type === 'vout') { val = self[conf.src1].vout; } resolve(val); } } const cmd = []; log(`chNum =${chNum}`); log(`maxChNum =${self.dev.maxChNum}`); if (chNum === undefined) { reject(['DELAY_CNT', 'Parameter Error']); return; } if (chNum >= self.dev.maxChNum) { reject(['DELAY_CNT', 'Parameter Error']); return; } // if(chNum < self.dev.maxChNum) { // chCmd = chanLoadCmd[chNum].slice(0); // chCmd[chCmd.length-1].cb = vetical; // self.dev.cmdSequence = self.dev.cmdSequence.concat(chCmd); // self.cmdEvent.emit('cmdWrite', self.dev.cmdSequence); // } if (conf.type === 'iout') { cmd.push({ id: conf.src1, prop: 'IOUT', arg: '', cb: null, method: 'get' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } else if (conf.type === 'iset') { cmd.push({ id: conf.src1, prop: 'ISET', arg: '', cb: null, method: 'get' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } else if (conf.type === 'vset') { cmd.push({ id: conf.src1, prop: 'VSET', arg: '', cb: null, method: 'get' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } else if (conf.type === 'vout') { cmd.push({ id: conf.src1, prop: 'VOUT', arg: '', cb: null, method: 'get' }); cmd.push({ id: 'sys', prop: 'delay_for_a_while', arg: DELAY_CNT, cb: null, method: 'set' }); } if (cmd.length > 0) { cmd[cmd.length - 1].cb = getDone; self.dev.cmdSequence = self.dev.cmdSequence.concat(cmd); // log(self.dev.cmdSequence); self.cmdEvent.emit('cmdWrite', cmd); } else { log('setSysProp do nothing'); reject(['DELAY_CNT', 'Parameter Error']); } })); }).bind(pwrObj); /** * */ pwrctrl.model = (function model() { const self = this; return new Promise(((resolve) => { const serialNumber = self.dev.usb.serialNumber; const devModel = self.dev.gdsModel; resolve({ devModel, serialNumber }); })); }).bind(pwrObj); /** * */ pwrctrl.clearEvent = (function clearEvent() { const self = this; return new Promise(((resolve) => { if (self.dev.writeTimeoutObj) { clearTimeout(self.dev.writeTimeoutObj); } self.dev.asyncWrite = 'done'; self.dev.queryBlock = false; self.dev.state.setTimeout = false; if (self.dev.state.timeoutObj) { clearTimeout(self.dev.state.timeoutObj); } resolve(); })); }).bind(pwrObj); /** * * * @method maxChNum * */ pwrctrl.maxch = (function maxch() { const self = this; return new Promise(((resolve) => { resolve(self.dev.maxChNum.toString()); })); }).bind(pwrObj); return pwrctrl; }; async function cmdWrite() { const self = this; let cb = null; const cmd = []; async function sendCmd(cmdItem) { return new Promise(((resolve, reject) => { if (cmdItem.method === 'set') { // log(self['sys']); self[cmdItem.id].prop.set(cmdItem.prop, cmdItem.arg, (err) => { if (err) { reject(err); return; } resolve(); }); } else { self[cmdItem.id].prop.get(cmdItem.prop, cmdItem.arg, (err) => { if (err) { reject(err); return; } resolve(); }); } })); } log(this.dev.cmdSequence); if (this.dev.asyncWrite === 'busy') { log('async write busy'); log(this.dev.cmdSequence); // if (this.dev.writeTimeoutObj === null) { // log('set timeout retry cmdWrite'); // this.dev.writeTimeoutObj = setTimeout(function() { // log('cmdWrite reissue'); // self.dev.writeTimeoutObj = null; // //cmdWrite.call(self); // self.cmdEvent.emit('cmdWrite', self.dev.cmdSequence); // },400); // } return; } for (let i = 0, len = this.dev.cmdSequence.length; i < len; i += 1) { cmd[i] = this.dev.cmdSequence.shift(); // avoid missing async callback, flush command buffer when find cb exist if (cmd[i].cb !== null) { cb = cmd[i].cb; break; } } if (self.dev.state.conn === 'disconnected') { if (cb) { cb('device disconnect'); } self.dev.asyncWrite = 'done'; return; } if (cmd.length === 0) { self.dev.asyncWrite = 'done'; return; } self.dev.asyncWrite = 'busy'; for (const cmdItem of cmd) { try { await sendCmd(cmdItem); } catch (err) { log(`send cmd ${cmdItem} error: ${err}`); self.dev.usbDisconnect(() => { self.dev.usbConnect(() => { self.dev.cmdSequence = []; self.dev.asyncWrite = 'done'; if (cb) { cb(err); } }); }); return; } } log('async/await write done'); if (self.dev.writeTimeoutObj) { clearTimeout(self.dev.writeTimeoutObj); } self.dev.asyncWrite = 'done'; self.dev.state.conn = 'connected'; if (self.dev.cmdSequence.length !== 0) { self.cmdEvent.emit('cmdWrite', self.dev.cmdSequence); } if (cb) { cb(); } // async.eachSeries(cmd, // function(item,done) { // log(item); // if(item.method === 'set') { // log(self['sys']); // log("-------------------") // self[item.id].prop.set(item.prop, item.arg, done); // }else { // try{ // self[item.id].prop.get(item.prop, item.arg, done); // } // catch(e){ // console.log(e); // } // } // },function(err, results) { // log('err: '+err); // log('async write done'); // if(self.dev.writeTimeoutObj) // clearTimeout(self.dev.writeTimeoutObj); // if(err){ // self.dev.usbDisconnect( function(){ // self.dev.usbConnect( function(){ // self.dev.cmdSequence = []; // self.dev.asyncWrite = 'done'; // if(cb) // cb(err); // }); // }); // return; // } // else{ // self.dev.asyncWrite = 'done'; // self.dev.state.conn = 'connected'; // if(self.dev.cmdSequence.length !== 0) { // self.cmdEvent.emit('cmdWrite', self.dev.cmdSequence); // } // } // if (cb) // cb(err); // } // ); } /** * Create new instance that used to communicate with instrument through USB * * @class PwrUSB * @constructor * @extends pwrctrl * @param {string} vid Vender ID bind to USB device * @param {string} pid Product ID bind to USB device * * @return {Object} Return pwrctrl object */ exports.PwrUSB = function PwrUSB(device) { const pwrObj = new PwrObject(); // log(pwrObj); // log('PwrUSB:'); // log(pwrObj); // if(pwrObj.dev.usbConnect) // log('we have usbConnect'); // else // log('we dont have usbConnect'); pwrObj.cmdEvent.on('cmdWrite', () => { log('trigger cmdEvent'); cmdWrite.call(pwrObj); }); usbDev.BindUsbObj(pwrObj.dev, device); return PwrControl(pwrObj); };