@@ -27,20 +27,26 @@ export function crc16 (buffer) {
2727
2828/** DP100 Modbus Function IDs */
2929const FUNCTIONS = Object . freeze ( {
30- DEVICE_INFO : 0x10 ,
31- FIRM_INFO : 17 ,
32- START_TRANS : 18 ,
33- DATA_TRANS : 19 ,
34- END_TRANS : 20 ,
35- DEV_UPGRADE : 21 ,
36- BASIC_INFO : 48 ,
37- BASIC_SET : 53 ,
38- SYSTEM_INFO : 0x40 ,
39- SYSTEM_SET : 69 ,
40- SCAN_OUT : 80 ,
41- SERIAL_OUT : 85 ,
42- DISCONNECT : 0x80 ,
43- NONE : 0xFF ,
30+ DEVICE_INFO : 0x10 , // 16
31+ FIRM_INFO : 0x11 , // 17
32+ START_TRANS : 0x12 , // 18
33+ DATA_TRANS : 0x13 , // 19
34+ END_TRANS : 0x14 , // 20
35+ DEV_UPGRADE : 0x15 , // 21
36+ BASIC_INFO : 0x30 , // 48
37+ BASIC_SET : 0x35 , // 53
38+ SYSTEM_INFO : 0x40 , // 64
39+ SYSTEM_SET : 0x45 , // 69
40+ SCAN_OUT : 0x50 , // 80
41+ SERIAL_OUT : 0x55 , // 85
42+ DISCONNECT : 0x80 , // 128
43+ NONE : 0xFF // 255
44+ } )
45+
46+ const MAGIC_BYTES = Object . freeze ( {
47+ OUTPUT : 0x20 , // 32
48+ SETTING : 0x40 , // 64
49+ READ : 0x80 // 128
4450} )
4551
4652/** DP100 device class.
@@ -87,6 +93,8 @@ export function DP100 (Base) {
8793 this . device = null
8894 clearInterval ( this . updateLoop )
8995 } )
96+ this . sendReport ( FUNCTIONS . SYSTEM_INFO )
97+ this . sendReport ( FUNCTIONS . DEVICE_INFO )
9098 this . getBasicSettings ( ) . then ( ( ) => {
9199 this . updateLoop = setInterval ( ( ) => {
92100 this . sendReport ( FUNCTIONS . BASIC_INFO )
@@ -120,25 +128,39 @@ export function DP100 (Base) {
120128 }
121129
122130 async getBasicSettings ( ) {
123- await this . sendReport ( FUNCTIONS . BASIC_SET , new Uint8Array ( [ 0 | 0x80 ] ) , 0 )
131+ await this . sendReport ( FUNCTIONS . BASIC_SET , new Uint8Array ( [ MAGIC_BYTES . READ ] ) , 0 )
124132 }
125133
126- async setBasicSettings ( { state, vo_set, io_set, ovp_set , ocp_set } ) {
134+ async setBasicOutput ( { state, vo_set, io_set } ) {
127135 if ( this . settings === undefined ) {
128136 throw new Error ( 'Settings not loaded' )
129137 }
130- console . info ( 'setBasicSettings ' , { state, vo_set, io_set, ovp_set , ocp_set } )
138+ console . info ( 'setBasicOutput ' , { state, vo_set, io_set } )
131139 const basicSet = Object . assign ( { } , this . settings , Object . fromEntries ( Object . entries ( {
132- state, vo_set, io_set, ovp_set , ocp_set
140+ state, vo_set, io_set
133141 } ) . filter ( ( [ k , v ] ) => v !== undefined ) ) )
134- const index = this . settingsQueue . length
135- this . settingsQueue [ index ] = basicSet
142+ this . settingsQueue . push ( basicSet )
136143 const out = new Uint8Array ( 10 )
137144 const outDv = new DataView ( out . buffer , out . byteOffset , out . length )
138- outDv . setUint8 ( 0 , index | 0x20 )
145+ outDv . setUint8 ( 0 , MAGIC_BYTES . OUTPUT )
139146 outDv . setUint8 ( 1 , basicSet . state )
140147 outDv . setUint16 ( 2 , basicSet . vo_set * 1000 , true )
141148 outDv . setUint16 ( 4 , basicSet . io_set * 1000 , true )
149+ await this . sendReport ( FUNCTIONS . BASIC_SET , out , 0 )
150+ }
151+
152+ async setBasicSettings ( { ovp_set, ocp_set } ) {
153+ if ( this . settings === undefined ) {
154+ throw new Error ( 'Settings not loaded' )
155+ }
156+ console . info ( 'setBasicSettings' , { ovp_set, ocp_set } )
157+ const basicSet = Object . assign ( { } , this . settings , Object . fromEntries ( Object . entries ( {
158+ ovp_set, ocp_set
159+ } ) . filter ( ( [ k , v ] ) => v !== undefined ) ) )
160+ this . settingsQueue . push ( basicSet )
161+ const out = new Uint8Array ( 10 )
162+ const outDv = new DataView ( out . buffer , out . byteOffset , out . length )
163+ outDv . setUint8 ( 0 , MAGIC_BYTES . SETTING )
142164 outDv . setUint16 ( 6 , basicSet . ovp_set * 1000 , true )
143165 outDv . setUint16 ( 8 , basicSet . ocp_set * 1000 , true )
144166 await this . sendReport ( FUNCTIONS . BASIC_SET , out , 0 )
@@ -181,21 +203,44 @@ export function DP100 (Base) {
181203 } )
182204 break
183205 case FUNCTIONS . BASIC_SET :
184- if ( contentView . byteLength === 1 ) {
185- this . settings = this . settingsQueue . pop ( contentView . getUint8 ( 0 ) )
206+ if ( contentView . byteLength === 1 && contentView . getUint8 ( 0 ) ) {
207+ this . settings = this . settingsQueue . pop ( )
186208 break
187209 }
188210 this . receiveBasicSettings ( {
189- index : contentView . getUint8 ( 0 ) ,
211+ ack : contentView . getUint8 ( 0 ) ,
190212 state : contentView . getUint8 ( 1 ) ,
191213 vo_set : contentView . getUint16 ( 2 , true ) / 1000 ,
192214 io_set : contentView . getUint16 ( 4 , true ) / 1000 ,
193215 ovp_set : contentView . getUint16 ( 6 , true ) / 1000 ,
194216 ocp_set : contentView . getUint16 ( 8 , true ) / 1000 ,
195217 } )
196218 break
219+ case FUNCTIONS . SYSTEM_INFO :
220+ this . receiveSystemInfo ( {
221+ otp : contentView . getUint16 ( 0 , true ) ,
222+ opp : contentView . getUint16 ( 2 , true ) / 10.0 ,
223+ backlight : contentView . getUint8 ( 4 ) ,
224+ volume : contentView . getUint8 ( 5 ) ,
225+ reverse_protection : contentView . getUint8 ( 6 ) ,
226+ audio_out : contentView . getUint8 ( 7 ) ,
227+ } )
228+ break
229+ case FUNCTIONS . DEVICE_INFO :
230+ console . debug ( {
231+ deviceName : String . fromCharCode ( ...new Uint8Array ( contentView . buffer . slice ( 0 , 15 ) ) ) ,
232+ hardwareVersion : contentView . getUint16 ( 16 , true ) / 10 ,
233+ firmwareVersion : contentView . getUint16 ( 18 , true ) / 10 ,
234+ bootVersion : contentView . getUint16 ( 20 , true ) ,
235+ runVersion : contentView . getUint16 ( 22 , true ) ,
236+ serialNumber : new Uint8Array ( contentView . buffer . slice ( 24 , 24 + 11 ) ) . join ( '' ) ,
237+ year : contentView . getUint16 ( 36 , true ) ,
238+ month : contentView . getUint8 ( 38 ) ,
239+ day : contentView . getUint8 ( 39 ) ,
240+ } )
241+ break
197242 default :
198- console . warn ( 'Unhandled function' , header . functionType )
243+ console . warn ( 'Unhandled function' , header . functionType , contentView )
199244 }
200245 }
201246
@@ -218,16 +263,31 @@ export function DP100 (Base) {
218263
219264 /** Handle basic settings from the DP100
220265 * @param {Object } basicSettings
221- * @param {Number } basicSettings.index - Setting index .
222- * @param {Number } basicSettings.state - Setting state.
266+ * @param {boolean } basicSettings.ack - Acknowledgement .
267+ * @param {boolean } basicSettings.state - Setting state.
223268 * @param {Number } basicSettings.vo_set - Output voltage setting in V.
224269 * @param {Number } basicSettings.io_set - Output current setting in A.
225270 * @param {Number } basicSettings.ovp_set - Over-voltage protection setting in V.
226271 * @param {Number } basicSettings.ocp_set - Over-current protection setting in A.
227272 */
228- receiveBasicSettings ( { index , state, vo_set, io_set, ovp_set, ocp_set } ) {
229- console . info ( 'receiveBasicSettings' , { index , state, vo_set, io_set, ovp_set, ocp_set } )
273+ receiveBasicSettings ( { ack , state, vo_set, io_set, ovp_set, ocp_set } ) {
274+ console . info ( 'receiveBasicSettings' , { ack , state, vo_set, io_set, ovp_set, ocp_set } )
230275 this . settings = { state, vo_set, io_set, ovp_set, ocp_set }
231276 }
277+
278+ /** Handle system info from the DP100
279+ * @param {Object } system
280+ * @param {Number } system.backlight - Backlight setting between 0 and 4.
281+ * @param {Number } system.volume - Volume setting between 0 and 4.
282+ * @param {Number } system.opp - Over-power protection setting in W.
283+ * @param {Number } system.otp - Over-temperature protection setting in C (range: 50 – 80).
284+ * @param {boolean } system.reverse_protection - Reverse protection setting.
285+ * @param {boolean } system.audio_out - Audio output setting.
286+ */
287+ receiveSystemInfo ( { backlight, volume, opp, otp, reverse_protection, audio_out } ) {
288+ console . info ( 'receiveSystemInfo' , { backlight, volume, opp, otp, reverse_protection, audio_out } )
289+ this . system = { backlight, volume, opp, otp, reverse_protection, audio_out }
290+ }
291+
232292 }
233293}
0 commit comments