Hi all!
In my team, we are trying to automate power consumption measurements of battery powered embedded device with Joulescope JS110 and Python.
Short problem description
I do not know how to add recording start time to .jls file.
Detailed problem description
Problem occurs when I want to open JLS file (that was recorded with example.py script) with my other script (JLSReader.py) and read UTC timestamp of given sample.
This is the output that I have got:
Sources:
source_id=0, source.name='global_annotation_source'
source_id=1, source.name='JS110-003901'
Signals:
signal_id=0, signal.name='global_annotation_signal', signal.signal_type=1, signal.sample_rate=0
signal_id=1, signal.name='current', signal.signal_type=0, signal.sample_rate=2000000
signal_id=2, signal.name='voltage', signal.signal_type=0, signal.sample_rate=2000000
Data for Signal ID 1: [-4.09781933e-08 -1.67638063e-08 2.14204192e-08 1.76951289e-08
-1.95577741e-08 -5.30853868e-08 -1.11758709e-08 2.98023224e-08
6.51925802e-09 -4.37721610e-08 -4.09781933e-08 0.00000000e+00
3.25962901e-08 2.42143869e-08 -2.88709998e-08 -5.86733222e-08
-2.32830644e-08 1.76951289e-08 1.49011612e-08 -1.67638063e-08
-5.86733222e-08 -3.81842256e-08 0.00000000e+00 1.49011612e-08
-4.65661287e-09 -2.60770321e-08 -2.32830644e-08 1.21071935e-08
6.51925802e-09 -1.39698386e-08 0.00000000e+00 1.21071935e-08
2.98023224e-08 1.49011612e-08 -2.88709998e-08 -3.53902578e-08
-1.86264515e-09 3.25962901e-08 -1.86264515e-09 -4.09781933e-08
-4.37721610e-08 -1.86264515e-09 1.76951289e-08 -1.86264515e-09
-2.32830644e-08 1.76951289e-08 5.12227416e-08 4.84287739e-08
6.51925802e-09 -2.32830644e-08 -1.11758709e-08 2.98023224e-08
3.63215804e-08 1.49011612e-08 -1.95577741e-08 -2.32830644e-08
1.21071935e-08 1.76951289e-08 -1.95577741e-08 -3.53902578e-08
-1.39698386e-08 1.76951289e-08 0.00000000e+00 -5.30853868e-08
-7.07805157e-08 -2.32830644e-08 4.47034836e-08 3.25962901e-08
-1.86264515e-09 -1.39698386e-08 -1.11758709e-08 2.98023224e-08
1.21071935e-08 -3.16649675e-08 -3.53902578e-08 -1.39698386e-08
0.00000000e+00 9.31322575e-09 6.51925802e-09 -1.11758709e-08
-8.38190317e-09 1.76951289e-08 1.76951289e-08 6.51925802e-09
-1.67638063e-08 -1.95577741e-08 1.21071935e-08 2.42143869e-08
-4.65661287e-09 -2.32830644e-08 -4.65661287e-09 2.98023224e-08
2.70083547e-08 -1.39698386e-08 -4.09781933e-08 -2.88709998e-08
2.79396772e-09 3.63215804e-08 2.14204192e-08 -1.39698386e-08]
fsr_stats=array([[-4.65661287e-09, 2.96954166e-08, -4.09781933e-08,
2.14204192e-08],
[-1.35041773e-08, 3.40792806e-08, -5.30853868e-08,
2.98023224e-08],
[-1.95577741e-08, 2.65059051e-08, -4.37721610e-08,
6.51925802e-09],
...,
[-1.83936208e-08, 3.43906966e-08, -5.58793545e-08,
1.76951289e-08],
[-2.46800482e-08, 1.45377833e-08, -4.37721610e-08,
-8.38190317e-09],
[-2.51457095e-08, 1.38346602e-08, -4.37721610e-08,
-1.11758709e-08]])
signal.signal_type=0
Traceback (most recent call last):
File "######\JLSReader.py", line 32, in <module>
jls_ts = reader.sample_id_to_timestamp(1, sample_id)
File "pyjls/binding.pyx", line 812, in pyjls.binding.Reader.sample_id_to_timestamp
File "pyjls/binding.pyx", line 269, in pyjls.binding._handle_rc
RuntimeError: sample_id_to_timestamp UNAVAILABLE[20]: The requested resource is currently unavailable.
Process finished with exit code 1
To investigate it I have run the same script with JLS file that was recorded using official Joulescope GUI and the output looked like this:
Sources:
source_id=0, source.name='global_annotation_source'
source_id=1, source.name='JS110-003901'
Signals:
signal_id=0, signal.name='global_annotation_signal', signal.signal_type=1, signal.sample_rate=0
signal_id=1, signal.name='voltage', signal.signal_type=0, signal.sample_rate=2000000
signal_id=2, signal.name='power', signal.signal_type=0, signal.sample_rate=2000000
signal_id=3, signal.name='current', signal.signal_type=0, signal.sample_rate=2000000
signal_id=4, signal.name='current_range', signal.signal_type=0, signal.sample_rate=2000000
signal_id=5, signal.name='gpi[0]', signal.signal_type=0, signal.sample_rate=2000000
signal_id=6, signal.name='gpi[1]', signal.signal_type=0, signal.sample_rate=2000000
Data for Signal ID 1: [4.8694386 4.871708 4.8785157 4.8762465 4.871708 4.8694386 4.871708
4.880785 4.8762465 4.871708 4.8671694 4.8694386 4.873977 4.873977
4.8671694 4.8671694 4.8671694 4.8762465 4.873977 4.8671694 4.8671694
4.8671694 4.8785157 4.880785 4.8762465 4.871708 4.873977 4.8785157
4.880785 4.8785157 4.8762465 4.873977 4.8785157 4.880785 4.880785
4.873977 4.871708 4.8785157 4.8762465 4.8785157 4.8694386 4.8671694
4.8762465 4.873977 4.8762465 4.8694386 4.8671694 4.873977 4.873977
4.873977 4.8671694 4.8671694 4.8762465 4.8762465 4.873977 4.8694386
4.871708 4.8762465 4.880785 4.871708 4.871708 4.871708 4.8785157
4.880785 4.871708 4.8694386 4.873977 4.8762465 4.8762465 4.8671694
4.8649006 4.871708 4.873977 4.871708 4.8649006 4.8649006 4.8694386
4.873977 4.8694386 4.8694386 4.8694386 4.8762465 4.8785157 4.880785
4.873977 4.8762465 4.883054 4.883054 4.880785 4.8785157 4.8785157
4.880785 4.883054 4.880785 4.8762465 4.873977 4.8785157 4.8785157
4.8785157 4.8694386]
fsr_stats=array([[4.87397718e+00, 4.14309764e-03, 4.86943865e+00, 4.87851572e+00],
[4.87340987e+00, 5.03177460e-03, 4.86943865e+00, 4.88078499e+00],
[4.87114060e+00, 3.87551297e-03, 4.86716938e+00, 4.87624645e+00],
...,
[5.28300083e+00, 2.17265873e-03, 5.28016424e+00, 5.28470278e+00],
[5.28356814e+00, 4.34531746e-03, 5.28016424e+00, 5.28924131e+00],
[5.28186619e+00, 5.03177460e-03, 5.27789497e+00, 5.28924131e+00]])
signal.signal_type=0
jls_ts=234197732024271628
utc_ts=1732878434.7579505
human_datetime='2024-11-29 12:07:14'
Process finished with exit code 0
And for this file everything worked smoothly.
During mine investigation I have noticed a difference between JLS files that were created using Joulescope GUI and my Python script.
gui_example.jls:
my_example.jls:
Check upper left corner - my_example.jls has default value:
2018-01-01T00:00:00+00:00
So I guess my script lacks an explicit definition of the time when my recording starts, but unofrtunately I have not seen (or just missed) explanation in docs/examples how this operation can be done.
Thanks in advance for your support!
============================
Source code
example.py
import time
import joulescope
device = joulescope.scan_require_one(config='auto')
device.open()
filename = r'########\my_example.jls'
jls_writer = joulescope.JlsWriter(device, filename)
jls_writer.open()
device.stream_process_register(jls_writer)
device.start()
time.sleep(3) # Device under test does something
device.stop()
device.stream_process_unregister(jls_writer)
jls_writer.close()
device.close()
JLSReader.py
from time import strftime, localtime
from pyjls.binding import Reader, jls_to_utc
with Reader(r'###########\gui_example.jls') as reader:
print("Sources:")
for source_id, source in reader.sources.items():
print(f" {source_id=}, {source.name=}")
print("\nSignals:")
for signal_id, signal in reader.signals.items():
print(
f" {signal_id=}, {signal.name=}, {signal.signal_type=}, {signal.sample_rate=}")
# Example: Read data from an FSR signal for 100 samples
signal_id = 1
start_sample_id = 0
length = 100
data = reader.fsr(signal_id, start_sample_id, length)
print(f"\nData for Signal ID {signal_id}: {data}")
# Example: Read FSR statistics for data
increment = 4
max_length = reader.signals[1].length
stat_length = int(max_length / increment)
fsr_stats = reader.fsr_statistics(signal_id, start_sample_id, increment, stat_length)
print(f'\n{fsr_stats=}')
# Example: Convert sample ID to timestamp
signal = reader.signals[1]
print(f'{signal.signal_type=}')
sample_id = 1000
jls_ts = reader.sample_id_to_timestamp(1, sample_id)
print(f'{jls_ts=}')
utc_ts = jls_to_utc(jls_ts)
print(f'{utc_ts=}')
human_datetime = strftime('%Y-%m-%d %H:%M:%S', localtime(utc_ts))
print(f'\n{human_datetime=}')
What I use
- OS: Win-11
- Joulescope: JS110
- Joulescope App:
- UI: 1.2.2
- driver: 1.7.1
- JLS: 0.11.0
- Python 3.11.9
- Platform: Windows-10-10.0.22631-SP0
- Python: 3.13.0
- Python Packages:
- joulescope: 1.2.0
- pyjoulescope_driver: 1.7.0
- pyjls: 0.11.0