Hi @Anko - Only charge and energy accumulate, and !clear only affects those two quantities. The average, standard deviation, min, and max are only computed over that window of statistics from the full 1 MSPS samples.
I modified the code above to print current min and max, and you can see that max definitely is not held:
PS C:\project\Joulescope\support\2026\02\20260213> python stats_clear.py
#sampled_id,i,i_min,i_max,v,p,charge,energy
143189524997,0.023,-0.008,0.105,0.991,0.023,0.012,0.012
143190524997,0.008,-0.006,0.053,0.991,0.008,0.016,0.015
143191524997,0.004,0.000,0.011,0.991,0.004,0.018,0.017
143192524997,0.000,-0.002,0.001,0.991,0.000,0.018,0.018
143193524997,0.000,-0.002,0.000,0.991,0.000,0.018,0.018
143194524997,0.000,0.000,0.000,0.991,0.000,0.018,0.018
143195524997,0.000,0.000,0.000,0.991,0.000,0.018,0.018
143196524997,0.062,-0.006,0.139,0.990,0.061,0.049,0.048
143197524997,0.046,-0.009,0.105,0.991,0.046,0.072,0.071
143198524997,0.005,-0.004,0.057,0.991,0.005,0.075,0.074
143199524997,0.006,-0.000,0.011,0.991,0.006,0.078,0.077
143200524997,0.001,-0.001,0.001,0.991,0.001,0.078,0.077
Here is the updated code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2026 Jetperch LLC
#
# 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.
from pyjoulescope_driver import Driver, time64
import sys
import queue
def _print_statistics_value(topic, value):
sample_id = value['time']['samples']['value'][0]
i_avg = value['signals']['current']['avg']['value']
i_min = value['signals']['current']['min']['value']
i_max = value['signals']['current']['max']['value']
v_avg = value['signals']['voltage']['avg']['value']
p_avg = value['signals']['power']['avg']['value']
charge = value['accumulators']['charge']['value']
energy = value['accumulators']['energy']['value']
print(f'{sample_id},{i_avg:.3f},{i_min:.3f},{i_max:.3f},{v_avg:.3f},{p_avg:.3f},{charge:.3f},{energy:.3f}')
def run():
# Use a queue to synchronize statistics to the main thread
q = queue.Queue()
def _on_statistics_value(topic, value):
q.put((topic, value), block=False)
with Driver() as d:
# JS220 only, one at a time
devices = d.device_paths()
devices = [device for device in devices if 'js220' in device]
if len(devices) != 1:
print(f'Only support one device at a time, found {devices}')
return 1
device = devices[0]
# display the column header
print("#sampled_id,i,i_min,i_max,v,p,charge,energy")
d.open(device)
try:
d.publish(device + '/s/i/range/mode', 'auto')
d.subscribe(device + '/s/stats/value', 'pub', _on_statistics_value)
d.publish(device + '/s/stats/ctrl', 1)
d.publish(device + '/s/stats/!clear', 0)
d.publish(device + '/s/stats/!clear', 1)
while True:
topic, value = q.get(block=True, timeout=1.0)
_print_statistics_value(topic, value)
except KeyboardInterrupt:
sys.stdout.flush()
finally:
d.publish(device + '/s/stats/ctrl', 0)
d.close(device)
return 0
if __name__ == '__main__':
sys.exit(run())
If you want to better understand min and max with your circuit, you can use the Oscilloscope view (Waveform widget) in the Joulescope UI.