Controlling the GUI programmatically -- can/cannot

So, I just thought of something. The use of a map prevents multiple assignments. While not a big deal for settings, it prevents the JLS file from issuing multiple !x_markers actions. Fixed!

Here is the updated jls_create.py script along with a generated JLS file.

# Copyright 2025 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 pyjls import Writer, SignalType, DataType, time64
import argparse
import numpy as np


def parser():
    p = argparse.ArgumentParser(description='JLS generator.')
    p.add_argument('filename',
                   help='The output JLS file path')
    return p


def run():
    args = parser().parse_args()
    with Writer(args.filename) as wr:
        wr.source_def(source_id=1)
        wr.signal_def(
            signal_id=1,
            source_id=1,
            signal_type=SignalType.FSR,
            data_type=DataType.F32,
            sample_rate=1_000_000,
            name='current',
            units='A')
        s = np.zeros(1_000_000, dtype=np.float32)
        s[250_000:750_000] = 0.008
        s[250_000:300_000] = 0.012
        for idx in range(500_000, 750_000, 50_000):
            s[idx:(idx+25_000)] += 0.002
        r = np.random.default_rng().standard_normal(len(s), dtype=np.float64) * 0.05
        r += 1.0
        s *= r
        wr.fsr(1, 0, s)
        t = time64.now()
        second = time64.SECOND
        wr.utc(1, 0, t)
        metadata = {
          "id": "joulescope.ui.waveform_widget",
          "version": "1.0",
          "plots": {
            "i": {
              "range_mode": "manual",
              "range": [-0.002, 0.015],
            },
            "v": {
              "enabled": False,
            },
          },
          "settings": [
            ["show_min_max", "off"],
            ["show_statistics", False],
            ["control_location", "off"],
          ],
          "actions": [
            # adjust the x-axis range for fun
            ["!x_zoom_to", [t + int(second * 0.1), t + int(second * 0.9)]],
            # add a dual markers for fun
            ["!x_markers", ["add_dual", t + int(second * 0.245), t + int(second * 0.755)]],
            ["!x_markers", ["add_dual", t + int(second * 0.55), t + int(second * 0.575)]],
          ],
        }
        wr.user_data(0x400, metadata)


if __name__ == '__main__':
    run()

out.jls (4.0 MB)

And here is how it looks when opened with the Joulescope UI: