<!-- SPDX-FileCopyrightText: Copyright 2023 Jetperch LLC
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->

<a id="h-jsdrv"></a>

# JSDRV API

### *group* API

The Joulescope driver host application interface. 

This API is based upon a distributed publish-subscribe (PubSub) implementation. The system is arranged as a hierarchical set of topics which have values. Devices expose topics that control and configure operation. Devices also publish the measured data to topics for consumption by the host application.

The host code can set topic values using [jsdrv_publish()](#group__jsdrv__api_1ga97aefd212b9be44a44cac333810beb30). Host code can subscribe to topic value changes using [jsdrv_subscribe()](#group__jsdrv__api_1gadd7c24c1dd7531788fe5238901c8c3c9). This driver will then call the registered subscriber callback for each change on a matching topic. When the host code calls [jsdrv_subscribe()](#group__jsdrv__api_1gadd7c24c1dd7531788fe5238901c8c3c9) with flags (JSDRV_SFLAG_RETAIN | JSDRV_SFLAG_PUB), then the driver immediately provides the retained values to synchronize the host state.

This implementation provides several nice features:
* Multiple value data types including integers, floats, str, json, binary
* Retained values
* Topic metadata for automatically populating user interfaces.
* Thread-safe, in-order operation. The driver provides thread-safe synchronous publish with timeout. However, subscriber callbacks are always invoked from the internal PubSub thread, and the host code is responsible for resynchronization.
* Guaranteed in-order topic traversal for retained messages based upon creation order.
* Device connection options:
  * connect and restore default settings
  * connect and resume using existing device settings.

Topic names use a hierarchical naming convention. Topics associated with a device start with a prefix: {p} = {backend}/{model}/{serial_number}
* {backend}: 1 character backend identifier 0-9, a-z, A-Z.
* {model}: The device model number, such as js220.
* {serial_number}: The device serial number string.

The rest of the topic is also hierarchical, and the following characters are reserved: 
```default
/?#$'"`&@%
```

Topics that start with ‘_’ or ‘@’ are directed only to the central PubSub instance within the driver itself.

Topics are presumed to have retained values unless the subtopic starts with the character ‘!’.

Topics with the following suffix characters have special meanings:
* ’’: metadata request (value should be NULL)
* ’$’: metadata response
* ’&’: query request (value should be NULL)
* ’?’: query response
* ’#’: return code. Value is i32 return code. 0=success.

Note that the topic owner will respond to jsdrv_publish operations with a return code to allow for fully synchronous operation.

The metadata values are JSON-formatted strings with the following data structure:
* dtype: one of [str, json, bin, f32, f64, u8, u16, u32, u64, i8, i16, i32, i64]
* brief: A brief string description (recommended).
* detail: A more detailed string description (optional).
* default: The recommended default value (optional).
* options: A list of options, where each option is each a flat list of: [value [, alt1 [, …]]] The alternates must be given in preference order. The first value must be the value as dtype. The second value alt1 (when provided) is used to automatically populate user interfaces, and it can be the same as value. Additional values will be interpreted as equivalents.
* range: The list of [v_min, v_max] or [v_min, v_max, v_step]. Both v_min and v_max are *inclusive*. v_step defaults to 1 if omitted.
* format: Formatting hints string:
  * version: The u32 dtype should be interpreted as major8.minor8.patch16.
* flags: A list of flags for this topic. Options include:
  * ro: This topic cannot be updated.
  * hide: This topic should not appear in the user interface.
  * dev: Developer option that should not be used in production.

\*/

/ The maximum size for normal PubSub messages #define JSDRV_PAYLOAD_LENGTH_MAX

/ The header size of

[jsdrv_stream_signal_s](#structjsdrv__stream__signal__s)

before the data field. #define JSDRV_STREAM_HEADER_SIZE

/ The size of data in

[jsdrv_stream_signal_s](#structjsdrv__stream__signal__s). #define JSDRV_STREAM_DATA_SIZE // 256 kB max

/\*\* 

### Defines

### JSDRV_TIMEOUT_MS_ASYNC

Timeout value requesting asynchronous (non-blocking) operation. 

For [jsdrv_publish()](#group__jsdrv__api_1ga97aefd212b9be44a44cac333810beb30), [jsdrv_subscribe()](#group__jsdrv__api_1gadd7c24c1dd7531788fe5238901c8c3c9), [jsdrv_unsubscribe()](#group__jsdrv__api_1gacebc4601a7cf8f8fe7616690fc7aa4f5), [jsdrv_unsubscribe_all()](#group__jsdrv__api_1ga4f476dab77ffb75c121a1825e2e64640), [jsdrv_open()](#group__jsdrv__api_1ga7e39238d355b48ed6a182f2ece789a39), and [jsdrv_close()](#group__jsdrv__api_1ga422a63e079d6cd8ed5c6115ea4828158), passing timeout_ms == [JSDRV_TIMEOUT_MS_ASYNC](#group__jsdrv__api_1gac050278c5272768ccb971f3193926fd0) (0) makes the call return immediately without waiting for the operation to complete.

[jsdrv_initialize()](#group__jsdrv__api_1gafe05ec2e4128e409179cb2b5e2fa2808), [jsdrv_finalize()](#group__jsdrv__api_1ga4727efe4c5852f5ae8895077e1823aa0), and [jsdrv_query()](#group__jsdrv__api_1gad4562409cf7a80a76310061905932329) are always synchronous and interpret timeout_ms == 0 as a request to use the default timeout ([JSDRV_TIMEOUT_MS_DEFAULT](#group__jsdrv__api_1ga0f7b5d88b8b4fe48c40bddc4bab30dbe) or [JSDRV_TIMEOUT_MS_INIT](#group__jsdrv__api_1ga1e1f69fe5e293b54c8c94b89e67fd494) as appropriate).

The driver thread invokes subscriber callbacks and completes every command, so a callback that blocks on a command would deadlock. When any of these functions is called from the driver thread, the driver forces timeout_ms to [JSDRV_TIMEOUT_MS_ASYNC](#group__jsdrv__api_1gac050278c5272768ccb971f3193926fd0) and returns 0 at once. The command still runs, in order, but its result is only reported to the log. [jsdrv_query()](#group__jsdrv__api_1gad4562409cf7a80a76310061905932329) then returns a zeroed value. Callbacks can therefore call the driver with any timeout; use [jsdrv_is_driver_thread()](#group__jsdrv__api_1gacecbcd0ebbcddec10dad5616975515fc) to tell whether a call completed or was only queued. 

### JSDRV_TIMEOUT_MS_DEFAULT

The recommended default timeout. 

### JSDRV_TIMEOUT_MS_INIT

The recommended default [jsdrv_initialize()](#group__jsdrv__api_1gafe05ec2e4128e409179cb2b5e2fa2808) timeout. 

### JSDRV_TIMEOUT_MS_OPEN

The recommended device open timeout, which allows recovery from a host that exited without closing. 

### JSDRV_STATISTICS_I128_Q

The fractional bits of [jsdrv_statistics_s](#structjsdrv__statistics__s) charge_i128 and energy_i128. 

The accumulators are signed 128-bit two’s complement fixed-point values with this many fractional bits on every model, so the value in coulombs or joules is i128 \* 2\*\*-JSDRV_STATISTICS_I128_Q. 

### JSDRV_VARIABLE_LENGTH_ARRAY

### Typedefs

### typedef void (\*jsdrv_subscribe_fn)(void \*user_data, const char \*topic, const struct [jsdrv_union_s](https://docs.joulescope.com/en/software/joulescope_driver/h_union.md#_CPPv413jsdrv_union_s) \*value)

Function called on topic updates. 


This function will be called from the Joulescope driver frontend thread. The function is responsible for performing any resynchronization to an application target thread, if needed.

Lifetime: `topic`, `value`, and everything reachable through `value` are valid ONLY for the duration of this callback. This includes:
* string / JSON / raw binary payloads (copy the bytes with memcpy)
* union-typed values (use [jsdrv_union_copy](https://docs.joulescope.com/en/software/joulescope_driver/h_union.md#group__jsdrv__union_1gae1d75f8224637b1526459cdf6e7ade76))
* the pubsub-owned binary structs ([jsdrv_stream_signal_s](#structjsdrv__stream__signal__s), [jsdrv_statistics_s](#structjsdrv__statistics__s), [jsdrv_buffer_info_s](#structjsdrv__buffer__info__s), [jsdrv_buffer_response_s](#structjsdrv__buffer__response__s))
* pointer fields embedded in those structs, such as [jsdrv_buffer_info_s.tmap](#structjsdrv__buffer__info__s_1afa87a7c3331ed816834ff3a5442704f0) (use jsdrv_tmap_copy)

Storing any of these pointers for use after the callback returns is undefined behavior. Copy everything you need before returning. 

* **Param user_data:**
  The arbitrary user data. 
* **Param topic:**
  The topic for this update. 
* **Param value:**
  The value for this update.

### Enums

### enum jsdrv_payload_type_e

The payload type for [jsdrv_union_s.app](https://docs.joulescope.com/en/software/joulescope_driver/h_union.md#structjsdrv__union__s_1a48af9dab09413493219e3e375e54652b). 

*Values:*

### enumerator JSDRV_PAYLOAD_TYPE_UNION

### enumerator JSDRV_PAYLOAD_TYPE_STREAM

### enumerator JSDRV_PAYLOAD_TYPE_STATISTICS

### enumerator JSDRV_PAYLOAD_TYPE_BUFFER_INFO

### enumerator JSDRV_PAYLOAD_TYPE_BUFFER_REQ

### enumerator JSDRV_PAYLOAD_TYPE_BUFFER_RSP

### enum jsdrv_element_type_e

The element base type for streaming data. 

#### SEE ALSO
[jsdrv_stream_signal_s](#structjsdrv__stream__signal__s)

*Values:*

### enumerator JSDRV_DATA_TYPE_UNDEFINED

### enumerator JSDRV_DATA_TYPE_INT

### enumerator JSDRV_DATA_TYPE_UINT

### enumerator JSDRV_DATA_TYPE_FLOAT

### enum jsdrv_field_e

The signal field type for streaming data. 

#### SEE ALSO
[jsdrv_stream_signal_s](#structjsdrv__stream__signal__s)

*Values:*

### enumerator JSDRV_FIELD_UNDEFINED

### enumerator JSDRV_FIELD_CURRENT

### enumerator JSDRV_FIELD_VOLTAGE

### enumerator JSDRV_FIELD_POWER

### enumerator JSDRV_FIELD_RANGE

### enumerator JSDRV_FIELD_GPI

### enumerator JSDRV_FIELD_UART

### enumerator JSDRV_FIELD_RAW

### enum jsdrv_time_type_e

The time specification type. 

*Values:*

### enumerator JSDRV_TIME_UTC

Time in i64 34Q30 UTC. See jsdrv/time.h. 

### enumerator JSDRV_TIME_SAMPLES

Time in sample_ids for the corresponding channel. 

### enum jsdrv_buffer_response_type_e

The buffer response type. 

*Values:*

### enumerator JSDRV_BUFFER_RESPONSE_SAMPLES

Data contains samples. 

### enumerator JSDRV_BUFFER_RESPONSE_SUMMARY

Data contains summary statistics. 

### enum jsdrv_subscribe_flag_e

The subscriber flags for [jsdrv_subscribe()](#group__jsdrv__api_1gadd7c24c1dd7531788fe5238901c8c3c9). 

*Values:*

### enumerator JSDRV_SFLAG_NONE

No flags (always 0). 

### enumerator JSDRV_SFLAG_RETAIN

Immediately forward retained PUB and/or METADATA, depending upon JSDRV_SFLAG_PUB and JSDRV_SFLAG_METADATA_RSP. 

### enumerator JSDRV_SFLAG_PUB

Receive normal topic publish. 

### enumerator JSDRV_SFLAG_METADATA_REQ

Subscribe to receive metadata requests like “$” and “a/b/$”. 

### enumerator JSDRV_SFLAG_METADATA_RSP

Subscribe to receive metadata responses like “a/b/c$. 

### enumerator JSDRV_SFLAG_QUERY_REQ

Subscribe to receive query requests like “?” and “a/b/?”. 

### enumerator JSDRV_SFLAG_QUERY_RSP

Subscribe to receive query responses like “a/b/c?”. 

### enumerator JSDRV_SFLAG_RETURN_CODE

Subscribe to receive return code messages like “a/b/c#”. 

### enum jsdrv_device_open_mode_e

The driver mode for device open. 

*Values:*

### enumerator JSDRV_DEVICE_OPEN_MODE_DEFAULTS

Restore the device to its default, power-on state. 

### enumerator JSDRV_DEVICE_OPEN_MODE_RESUME

Update the driver with the device’s existing state. 

### enumerator JSDRV_DEVICE_OPEN_MODE_RAW

Low-level open only, for use by internal tools. 

### Functions

### int32_t jsdrv_initialize(struct jsdrv_context_s \*\*context, const struct [jsdrv_arg_s](#_CPPv411jsdrv_arg_s) \*args, uint32_t timeout_ms)

Initialize the Joulescope driver (synchronous). 

* **Parameters:**
  * **context** – **[out]** The Joulescope driver context for future API calls. 
  * **args** – Reserved for future use: pass NULL. No arguments are currently defined, and the driver ignores this parameter. When arguments are defined, the list will be terminated by an entry with an empty topic string. 
  * **timeout_ms** – This function is always blocking and waits for up to timeout_ms for the operation to complete. When 0, use the default timeout [recommended]. When nonzero, override the default timeout. 
* **Returns:**
  0 or error code. 

### void jsdrv_finalize(struct jsdrv_context_s \*context, uint32_t timeout_ms)

Finalize the Joulescope driver (synchronous). 


This function releases all Joulescope driver resources including memory and threads. On timeout or error the context is still invalidated; a nonzero status may indicate that some resources (threads, memory) could not be released cleanly and may have leaked.

This function must not be called from the driver frontend thread. Therefore, do not call this function directly from a subscriber callback. 

* **Parameters:**
  * **context** – The context from [jsdrv_initialize()](#group__jsdrv__api_1gafe05ec2e4128e409179cb2b5e2fa2808). The context is no longer usable after this call returns, regardless of return status. The caller must not invoke any other jsdrv API on the context after [jsdrv_finalize()](#group__jsdrv__api_1ga4727efe4c5852f5ae8895077e1823aa0). 
  * **timeout_ms** – This function is always blocking and waits for up to timeout_ms for the operation to complete. When 0, use the default timeout [recommended]. When nonzero, override the default timeout.

### int32_t jsdrv_publish(struct jsdrv_context_s \*context, const char \*topic, const struct [jsdrv_union_s](https://docs.joulescope.com/en/software/joulescope_driver/h_union.md#_CPPv413jsdrv_union_s) \*value, uint32_t timeout_ms)

Publish a new value. 

#### NOTE
The return code reflects synchronous processing only. In asynchronous mode the value is queued; no processing errors are reported. During development, prefer a non-zero timeout so failures surface immediately. 

* **Parameters:**
  * **context** – The Joulescope driver context. 
  * **topic** – The topic to publish. 
  * **value** – The new topic value. 
  * **timeout_ms** – Timeout in milliseconds. Pass [JSDRV_TIMEOUT_MS_ASYNC](#group__jsdrv__api_1gac050278c5272768ccb971f3193926fd0) (0) for asynchronous (non-blocking) operation: the publish is queued and this function returns immediately without reporting any processing result. Pass a positive value to wait for synchronous processing: the call blocks until the topic owner (if any) has processed the publish, and the return value reflects that processing. On timeout returns [JSDRV_ERROR_TIMED_OUT](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124a2419a8e3aa084fea15509a074a36a162). 
* **Returns:**
  0 or error code. All calls may return [JSDRV_ERROR_PARAMETER_INVALID](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124aef600eacd8a0257c02bac780011c5cee). Each topic may return other error codes.

### int32_t jsdrv_query(struct jsdrv_context_s \*context, const char \*topic, struct [jsdrv_union_s](https://docs.joulescope.com/en/software/joulescope_driver/h_union.md#_CPPv413jsdrv_union_s) \*value, uint32_t timeout_ms)

Query a retained value. 

* **Parameters:**
  * **context** – The Joulescope driver context. 
  * **topic** – The topic to query. 
  * **value** – **[inout]** The topic value. For string, JSON, and binary values, the provided value must be initialized with an allocated buffer. The value will be copied into this buffer or return [JSDRV_ERROR_TOO_SMALL](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124aef806f51d59aead5e00e8acf1fda0765). If provided, this buffer will be ignored for other value types. 
  * **timeout_ms** – This function is always blocking and waits for up to timeout_ms for the operation to complete. When 0, use the default timeout [recommended]. When nonzero, override the default timeout. 
* **Returns:**
  0 or error code. All calls may return [JSDRV_ERROR_PARAMETER_INVALID](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124aef600eacd8a0257c02bac780011c5cee) and [JSDRV_ERROR_TIMED_OUT](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124a2419a8e3aa084fea15509a074a36a162). 

### int32_t jsdrv_subscribe(struct jsdrv_context_s \*context, const char \*topic, uint8_t flags, [jsdrv_subscribe_fn](#_CPPv418jsdrv_subscribe_fn) cbk_fn, void \*cbk_user_data, uint32_t timeout_ms)

Subscribe to topic updates. 


Synchronous, blocking subscription is most useful when flags contains [JSDRV_SFLAG_RETAIN](#group__jsdrv__api_1gga2740382c8dd5128bbfc45a6c2625130dafd49c0605bc432ec7d12278ad885f675). The operation will not complete until cbk_fn() has been called with all retained values. 

* **Parameters:**
  * **context** – The Joulescope driver context. 
  * **topic** – The subscription topic. The cbk_fn will be called whenever this topic or a child is updated. 
  * **flags** – The [jsdrv_subscribe_flag_e](#group__jsdrv__api_1ga2740382c8dd5128bbfc45a6c2625130d) bitmap. As a convenience, a flags value of 0 is treated as ([JSDRV_SFLAG_PUB](#group__jsdrv__api_1gga2740382c8dd5128bbfc45a6c2625130da4ba46323f97e7069e54f9ece9d9b55ac) | [JSDRV_SFLAG_RETAIN](#group__jsdrv__api_1gga2740382c8dd5128bbfc45a6c2625130dafd49c0605bc432ec7d12278ad885f675)), which is the common default. Pass an explicit non-zero bitmap when you want a different combination. 
  * **cbk_fn** – The function to call with topic updates. When called, this function will be invoked from the Joulescope driver thread. The function must NOT call [jsdrv_finalize()](#group__jsdrv__api_1ga4727efe4c5852f5ae8895077e1823aa0). 
  * **cbk_user_data** – The arbitrary data provided to cbk_fn. 
  * **timeout_ms** – Timeout in milliseconds. Pass [JSDRV_TIMEOUT_MS_ASYNC](#group__jsdrv__api_1gac050278c5272768ccb971f3193926fd0) for asynchronous (non-blocking) operation. Pass a positive value to block until the subscribe operation completes; on timeout returns [JSDRV_ERROR_TIMED_OUT](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124a2419a8e3aa084fea15509a074a36a162). 
* **Returns:**
  0 or error code.

### int32_t jsdrv_unsubscribe(struct jsdrv_context_s \*context, const char \*topic, [jsdrv_subscribe_fn](#_CPPv418jsdrv_subscribe_fn) cbk_fn, void \*cbk_user_data, uint32_t timeout_ms)

Unsubscribe to topic updates. 


Most callers will want to use blocking, synchronous unsubscribe. Blocking unsubscribe ensures that cbk_fn() will not be called when this function returns. With asynchronous unsubscribe, cbk_fn() may be called for some indefinite number of times and duration until the unsubscribe request is handled internally.

#### SEE ALSO
[jsdrv_subscribe](#group__jsdrv__api_1gadd7c24c1dd7531788fe5238901c8c3c9)

#### SEE ALSO
[jsdrv_unsubscribe_all](#group__jsdrv__api_1ga4f476dab77ffb75c121a1825e2e64640)

Both cbk_fn AND cbk_user_data must match the values passed to [jsdrv_subscribe()](#group__jsdrv__api_1gadd7c24c1dd7531788fe5238901c8c3c9). A mismatch is not an error; the operation succeeds but the subscription remains active. Use the identical pointer values used at subscribe time. 

* **Parameters:**
  * **context** – The Joulescope driver context. 
  * **topic** – The subscription topic for unsubscription. 
  * **cbk_fn** – The previous subscribed function. 
  * **cbk_user_data** – The arbitrary data provided to cbk_fn which must match the value provided to [jsdrv_subscribe()](#group__jsdrv__api_1gadd7c24c1dd7531788fe5238901c8c3c9). 
  * **timeout_ms** – Timeout in milliseconds. Pass [JSDRV_TIMEOUT_MS_ASYNC](#group__jsdrv__api_1gac050278c5272768ccb971f3193926fd0) for asynchronous (non-blocking) operation. Pass a positive value to block until the unsubscribe operation completes; on timeout returns [JSDRV_ERROR_TIMED_OUT](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124a2419a8e3aa084fea15509a074a36a162). 
* **Returns:**
  0 or error code. 

### int32_t jsdrv_unsubscribe_all(struct jsdrv_context_s \*context, [jsdrv_subscribe_fn](#_CPPv418jsdrv_subscribe_fn) cbk_fn, void \*cbk_user_data, uint32_t timeout_ms)

Unsubscribe from all topic updates (asynchronous). 


Most callers will want to use blocking, synchronous unsubscribe. See [jsdrv_unsubscribe()](#group__jsdrv__api_1gacebc4601a7cf8f8fe7616690fc7aa4f5) for details. 

#### SEE ALSO
[jsdrv_unsubscribe](#group__jsdrv__api_1gacebc4601a7cf8f8fe7616690fc7aa4f5)

* **Parameters:**
  * **context** – The Joulescope driver context. 
  * **cbk_fn** – The previous subscribed function. 
  * **cbk_user_data** – The arbitrary data provided to cbk_fn which must match the value provided to [jsdrv_subscribe()](#group__jsdrv__api_1gadd7c24c1dd7531788fe5238901c8c3c9). 
  * **timeout_ms** – Timeout in milliseconds. Pass [JSDRV_TIMEOUT_MS_ASYNC](#group__jsdrv__api_1gac050278c5272768ccb971f3193926fd0) for asynchronous (non-blocking) operation. Pass a positive value to block until the unsubscribe operation completes; on timeout returns [JSDRV_ERROR_TIMED_OUT](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124a2419a8e3aa084fea15509a074a36a162). 
* **Returns:**
  0 or error code. 

### bool jsdrv_is_driver_thread(struct jsdrv_context_s \*context)

Check if the caller is the driver thread. 


The driver forces timeout_ms to [JSDRV_TIMEOUT_MS_ASYNC](#group__jsdrv__api_1gac050278c5272768ccb971f3193926fd0) for commands issued from the driver thread. See [JSDRV_TIMEOUT_MS_ASYNC](#group__jsdrv__api_1gac050278c5272768ccb971f3193926fd0). 

* **Parameters:**
  **context** – The Joulescope driver context. 
* **Returns:**
  true when called from the driver thread, which invokes the subscriber callbacks, and false otherwise, including for a NULL context.

### int32_t jsdrv_open(struct jsdrv_context_s \*context, const char \*device_prefix, int32_t mode, uint32_t timeout_ms)

Open a device. 


This is a convenience function that wraps a single call to [jsdrv_publish()](#group__jsdrv__api_1ga97aefd212b9be44a44cac333810beb30) with an i32 value. Language wrappers should not wrap this function and instead call [jsdrv_publish()](#group__jsdrv__api_1ga97aefd212b9be44a44cac333810beb30) directly. 

* **Parameters:**
  * **context** – The Joulescope driver context. 
  * **device_prefix** – The device prefix string. 
  * **mode** – The [jsdrv_device_open_mode_e](#group__jsdrv__api_1ga6f9aa66a911a7bb6370caa399d6f6f59). 
  * **timeout_ms** – Timeout in milliseconds. Pass [JSDRV_TIMEOUT_MS_ASYNC](#group__jsdrv__api_1gac050278c5272768ccb971f3193926fd0) for asynchronous (non-blocking) operation. Pass a positive value to block until the open operation completes; on timeout returns [JSDRV_ERROR_TIMED_OUT](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124a2419a8e3aa084fea15509a074a36a162). 
* **Returns:**
  0 or error code.

### int32_t jsdrv_close(struct jsdrv_context_s \*context, const char \*device_prefix, uint32_t timeout_ms)

Close a device. 


This is a convenience function that wraps a single call to [jsdrv_publish()](#group__jsdrv__api_1ga97aefd212b9be44a44cac333810beb30). Language wrappers should not wrap this function and instead call [jsdrv_publish()](#group__jsdrv__api_1ga97aefd212b9be44a44cac333810beb30) directly. 

* **Parameters:**
  * **context** – The Joulescope driver context. 
  * **device_prefix** – The device prefix string. 
  * **timeout_ms** – Timeout in milliseconds. Pass [JSDRV_TIMEOUT_MS_ASYNC](#group__jsdrv__api_1gac050278c5272768ccb971f3193926fd0) for asynchronous (non-blocking) operation. Pass a positive value to block until the close operation completes; on timeout returns [JSDRV_ERROR_TIMED_OUT](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124a2419a8e3aa084fea15509a074a36a162). 
* **Returns:**
  0 or error code.

### int32_t jsdrv_calibration_hash(const uint32_t \*msg, uint32_t length, uint32_t \*hash)

Compute the calibration hash. 

* **Parameters:**
  * **msg** – **[in]** The calibration message. Must not be NULL. 
  * **length** – **[in]** The length of message in bytes which must be nonzero and a multiple of 32 bytes. 
  * **hash** – **[out]** The u32[16] hash of the message. Must not be NULL. The total length is u32 x 16 = 64-byte = 512 bit. 
* **Returns:**
  0 on success or [JSDRV_ERROR_PARAMETER_INVALID](https://docs.joulescope.com/en/software/joulescope_driver/h_error_code.md#group__jsdrv__ec_1gga4bb10d6ebaa503f491a70539b49df124aef600eacd8a0257c02bac780011c5cee) if any parameter is NULL or length is 0 or not a multiple of 32 bytes. 

### struct jsdrv_stream_signal_s

 *#include <jsdrv.h>*

A contiguous, uncompressed sample block for a channel. 

Consumers MUST read `[version](#structjsdrv__stream__signal__s_1a2a8a9c4e6367cdd4b804f8f9735d914d)` before dereferencing any other field. If `[version](#structjsdrv__stream__signal__s_1a2a8a9c4e6367cdd4b804f8f9735d914d)` is greater than the value this consumer was compiled against, either degrade gracefully by reading only the v1 fields or reject the payload. Newer versions MUST NOT change the offset or meaning of any v1 field; they may only repurpose reserved fields or append. 

### Public Members

### uint8_t version

The response format version == 1. 

### uint8_t rsv1_u8

Reserved, set to 0. 

### uint8_t rsv2_u8

Reserved, set to 0. 

### uint8_t rsv3_u8

Reserved, set to 0. 

### uint32_t rsv4_u32

Reserved, set to 0. 

### uint64_t sample_id

the starting sample id, which increments by decimate_factor. 

### uint8_t field_id

[jsdrv_field_e](#group__jsdrv__api_1ga87596eb3009eb4484e9fc3f0031af622)

### uint8_t index

The channel index within the field. For JSDRV_FIELD_RANGE, 0=current, 1=voltage. 

### uint8_t element_type

[jsdrv_element_type_e](#group__jsdrv__api_1ga48546f02f15817df6dbe227fa3382eeb)

### uint8_t element_size_bits

The element size in bits. 

### uint32_t element_count

size of data in elements 

### uint32_t sample_rate

The frequency for sample_id. 

### uint32_t decimate_factor

The decimation factor from sample_id to data samples. 

### struct [jsdrv_time_map_s](https://docs.joulescope.com/en/software/joulescope_driver/h_time.md#_CPPv416jsdrv_time_map_s) time_map

The time map between sample_id (before decimate_factor) and UTC. 

### uint8_t data[JSDRV_STREAM_DATA_SIZE]

The channel data. 

### struct jsdrv_statistics_s

 *#include <jsdrv.h>*

The payload data structure for statistics updates. 

Consumers MUST read `[version](#structjsdrv__statistics__s_1a8bbe754acfed3638290016dd445b7870)` before dereferencing any other field. If `[version](#structjsdrv__statistics__s_1a8bbe754acfed3638290016dd445b7870)` is greater than the value this consumer was compiled against, either degrade gracefully by reading only the v1 fields or reject the payload. Newer versions MUST NOT change the offset or meaning of any v1 field; they may only repurpose reserved fields or append. 

### Public Members

### uint8_t version

The version, only 1 currently supported. 

### uint8_t rsv1_u8

Reserved = 0. 

### uint8_t rsv2_u8

Reserved = 0. 

### uint8_t decimate_factor

The decimate factor from sample_id to calculated samples, saturated at 255. Prefer decimate_factor32. 

### uint32_t block_sample_count

Samples used to compute this block, in decimated samples. 

### uint32_t sample_freq

The samples per second for \*_sample_id (undecimated). 

### uint32_t decimate_factor32

The decimate factor from sample_id to calculated samples (was reserved; 0 in payloads from older producers - fall back to decimate_factor). 

### uint64_t block_sample_id

First sample in this block’s statistics computation. 

### uint64_t accum_sample_id

First sample in the integration statistics computation. 

### double i_avg

The average current over the block. 

### double i_std

The standard deviation of current over the block. 

### double i_min

The minimum current value in the block. 

### double i_max

The maximum current value in the block. 

### double v_avg

The average voltage over the block. 

### double v_std

The standard deviation of voltage over the block. 

### double v_min

The minimum voltage value in the block. 

### double v_max

The maximum voltage value in the block. 

### double p_avg

The average power over the block. 

### double p_std

The standard deviation of power over the block. 

### double p_min

The minimum power value in the block. 

### double p_max

The maximum power value in the block. 

### double charge_f64

The charge (integral of current) from accum_sample_id as a 64-bit float. 

### double energy_f64

The energy (integral of power) from accum_sample_id as a 64-bit float. 

### uint64_t charge_i128[2]

The charge (integral of current) from accum_sample_id as a 128-bit signed integer, little-endian words, with 2\*\*-JSDRV_STATISTICS_I128_Q scale. 

### uint64_t energy_i128[2]

The energy (integral of power) from accum_sample_id as a 128-bit signed integer, little-endian words, with 2\*\*-JSDRV_STATISTICS_I128_Q scale. 

### struct [jsdrv_time_map_s](https://docs.joulescope.com/en/software/joulescope_driver/h_time.md#_CPPv416jsdrv_time_map_s) time_map

The time map between sample_id and UTC. 

### struct jsdrv_time_range_utc_s

 *#include <jsdrv.h>*

A UTC-defined time range. 

Times are int64 34Q30 in UTC from the epoch. See jsdrv/time.h. 

### Public Members

### int64_t start

The time for data[0] (inclusive). 

### int64_t end

The time for data[-1] (inclusive). 

### uint64_t length

The number of evenly-spaced entries. 

### struct jsdrv_time_range_samples_s

 *#include <jsdrv.h>*

A sample_id-defined time range. 

Times are in uint64_t sample_ids for the corresponding channel. 

### Public Members

### uint64_t start

The time for data[0] (inclusive). 

### uint64_t end

The time for data[-1] (inclusive). 

### uint64_t length

The number of evenly-spaced entries. 

### struct jsdrv_buffer_info_s

 *#include <jsdrv.h>*

The signal buffer information. 

This structure contains both the size and range. The size is populated immediately, even if the buffer is still empty. As the buffer contents grows, the buffer range will approach the buffer size. When the buffer is full, the range will be close to the size. The range when full is not required to be the entire size to allow for buffering optimizations.

Consumers MUST read `[version](#structjsdrv__buffer__info__s_1a14a317e379b292cfd95ca5391a170a98)` before dereferencing any other field. If `[version](#structjsdrv__buffer__info__s_1a14a317e379b292cfd95ca5391a170a98)` is greater than the value this consumer was compiled against, either degrade gracefully by reading only the v1 fields or reject the payload. Newer versions MUST NOT change the offset or meaning of any v1 field; they may only repurpose reserved fields or append. 

### Public Members

### uint8_t version

The response format version == 1. 

### uint8_t rsv1_u8

Reserved, set to 0. 

### uint8_t rsv2_u8

Reserved, set to 0. 

### uint8_t rsv3_u8

Reserved, set to 0. 

### uint8_t field_id

[jsdrv_field_e](#group__jsdrv__api_1ga87596eb3009eb4484e9fc3f0031af622)

### uint8_t index

The channel index within the field. 

### uint8_t element_type

[jsdrv_element_type_e](#group__jsdrv__api_1ga48546f02f15817df6dbe227fa3382eeb)

### uint8_t element_size_bits

The element size in bits. 

### char topic[JSDRV_TOPIC_LENGTH_MAX]

The source topic that provides [jsdrv_stream_signal_s](#structjsdrv__stream__signal__s). 

### int64_t size_in_utc

The total buffer size in UTC time based on nominal sample rate. 

### uint64_t size_in_samples

The total buffer size in samples. 

### struct [jsdrv_time_range_utc_s](#_CPPv422jsdrv_time_range_utc_s) time_range_utc

In UTC time, derived from the invariant tmap. 

### struct [jsdrv_time_range_samples_s](#_CPPv426jsdrv_time_range_samples_s) time_range_samples

In sample time. 

### struct [jsdrv_time_map_s](https://docs.joulescope.com/en/software/joulescope_driver/h_time.md#_CPPv416jsdrv_time_map_s) time_map

The simple time map for the response. 


This field contains the most recent time map between sample ids and UTC wall-clock time. It does not preserve past history and will adjust the UTC time for old samples. For an invariant time map, use tmap. 

#### SEE ALSO
[tmap](#structjsdrv__buffer__info__s_1afa87a7c3331ed816834ff3a5442704f0)

### uint32_t decimate_factor

The decimation factor from source sample_id. 

The time_range_samples has already been decimated by this amount. You can reconstruct the source sample id by multiplying by this factor which can allow comparison across different signals from the same source that operate with different decimate_factor values. 

### struct jsdrv_tmap_s \*tmap

The time map for the response. 


This instance is a snapshot owned by the consumer. Call jsdrv_tmap_free() when done. No locking is required; the snapshot is independent of the writer’s tmap. The time map for the response. 

#### SEE ALSO
[time_map](#structjsdrv__buffer__info__s_1a39052ec6bd7f606f760a89acd28d7190)

### union jsdrv_buffer_request_time_range_u

 *#include <jsdrv.h>*

The time range union for buffer requests. 

### Public Members

### struct [jsdrv_time_range_utc_s](#_CPPv422jsdrv_time_range_utc_s) utc

### struct [jsdrv_time_range_samples_s](#_CPPv426jsdrv_time_range_samples_s) samples

### struct jsdrv_buffer_request_s

 *#include <jsdrv.h>*

Request data from the streaming sample buffer. 

To make a sample request that returns jsdrv_buffer_sample_response_s, only specify end or length. Set the unused value to zero.

If both end and length are specified, then the request may return jsdrv_buffer_summary_response_s. However, if the specified increment is less than or equal to one sample duration, then the request will return jsdrv_buffer_sample_response_s.

For JSDRV_TIME_UTC with end and length > 1, the time increment between samples is: time_incr = (time_end - time_start) / (length - 1)

Using python, the x-axis time is then: x = np.linspace(time_start, time_end, length, dtype=np.int64)

For JSDRV_TIME_SAMPLES with end and length > 1, the sample increment between samples is: sample_id_incr = (sample_id_end - sample_id_start) / (length - 1)

The buffer implementation may deduplicate requests using the combination rsp_topic and rsp_id.

Consumers MUST populate `[version](#structjsdrv__buffer__request__s_1a69c4c24b40bfce7ca59e4bbade8bd137)` with the maximum version they understand. Producers MAY examine `[version](#structjsdrv__buffer__request__s_1a69c4c24b40bfce7ca59e4bbade8bd137)` to stay within the consumer’s capabilities. Newer versions MUST NOT change the offset or meaning of any v1 field; they may only repurpose reserved fields or append. 

### Public Members

### uint8_t version

The request format version == 1. 

### int8_t time_type

[jsdrv_time_type_e](#group__jsdrv__api_1ga8ac2ca62a6ee9a9af94bf3dd13f0e01c)

### uint8_t rsv1_u8

Reserved, set to 0. 

### uint8_t rsv2_u8

Reserved, set to 0. 

### uint32_t rsv3_u32

Reserved, set to 0. 

### char rsp_topic[JSDRV_TOPIC_LENGTH_MAX]

The topic for this response. 

### int64_t rsp_id

The additional identifier to include in the response. 

### struct jsdrv_summary_entry_s

 *#include <jsdrv.h>*

A single summary statistics entry. 

### Public Members

### float avg

The average (mean) over the window. 

### float std

The standard deviation over the window. 

### float min

The minimum value over the window. 

### float max

The maximum value over the window. 

### struct jsdrv_buffer_response_s

 *#include <jsdrv.h>*

The response to [jsdrv_buffer_request_s](#structjsdrv__buffer__request__s) produced by the memory buffer. 

The response populates both info.time_range_utc and info.time_range_samples. Both length values are equal, and specify the number of returned data samples. For response_type JSDRV_BUFFER_RESPONSE_SUMMARY, the data is [jsdrv_summary_entry_s](#structjsdrv__summary__entry__s)[info.time_range_utc.length]. info.element_type is JSDRV_DATA_TYPE_UNDEFINED and info.element_size_bits is sizeof(jsdrv_summary_entry_s) \* 8.

For response_type JSDRV_BUFFER_RESPONSE_SAMPLES, the data type depends upon info.element_type and info.element_size_bits.

Consumers MUST read `[version](#structjsdrv__buffer__response__s_1a5a32cb450218da942d29c773d87d0282)` before dereferencing any other field. If `[version](#structjsdrv__buffer__response__s_1a5a32cb450218da942d29c773d87d0282)` is greater than the value this consumer was compiled against, either degrade gracefully by reading only the v1 fields or reject the payload. Newer versions MUST NOT change the offset or meaning of any v1 field; they may only repurpose reserved fields or append. 

### Public Members

### uint8_t version

The response format version == 1. 

### uint8_t response_type

[jsdrv_buffer_response_type_e](#group__jsdrv__api_1ga4839c5c7310a577b5084f25976b2fe00)

### uint8_t rsv1_u8

Reserved, set to 0. 

### uint8_t rsv2_u8

Reserved, set to 0. 

### uint32_t rsv3_u32

Reserved, set to 0. 

### int64_t rsp_id

The value provided to [jsdrv_buffer_request_s](#structjsdrv__buffer__request__s). 

### struct [jsdrv_buffer_info_s](#_CPPv419jsdrv_buffer_info_s) info

The response information. 

### uint64_t data[JSDRV_VARIABLE_LENGTH_ARRAY]

The response data. 

The data type for the response varies. Unfortunately, C does not support flexible arrays in union types. Your code should cast the data to the appropriate type. Use info.time_range_samples.length for the number of data elements in this response data.

For response_type JSDRV_BUFFER_RESPONSE_SUMMARY, the data is [jsdrv_summary_entry_s](#structjsdrv__summary__entry__s)[info.time_range_samples.length].

For response_type JSDRV_BUFFER_RESPONSE_SAMPLES, the data is defined by info.element_type and info.element_size_bits. 

### struct jsdrv_arg_s

 *#include <jsdrv.h>*

The initialization argument structure. 

Reserved for future use. No arguments are currently defined. See [jsdrv_initialize()](#group__jsdrv__api_1gafe05ec2e4128e409179cb2b5e2fa2808). 

### Public Members

### const char \*topic

The argument name. 

### struct [jsdrv_union_s](https://docs.joulescope.com/en/software/joulescope_driver/h_union.md#_CPPv413jsdrv_union_s) value

The argument value.
