Float truncated in Transaction

Having an issue where a float timestamp is sent correctly to the card settings.db file but is truncated on the Transaction request in micropython running on an ESP32. The debug of the request in the REPL shows it correctly as:

,"start_time":1686158220.97,

but immediately after the Transaction it is stored as:
, 'start_time': 1.686158e+09,
losing a very significant amount of precision. I am guessing I can side step by converting to ms integer before sending to the db file but would like to know if I am just using the API incorrectly.

Hey @szygmunt thanks for the question and welcome to the Blues community, we’re glad you’re here!

I’ll take a look into this for you, but can you first provide an example code snippet that I can use to repro the issue?

Thanks. Test code is below. From the notehub interface I sent a test.qi containing:
{"start_time":1686158220.97}
Running the code in micropython on the ESP32 produces the following output:

>>> import bugtest
Opening Notecard...
{"inbound": 10, "outbound": 10, "sync": true, "duration": 60, "req": "hub.set", "body": {"os_family": "ESP32 module with ESP32", "os_platform": "esp32", "os_name": "micropython", "req_interface": "i2c", "agent": "note-python", "req_port": 0, "os_version": "3.4.0; MicroPython v1.20.0 on 2023-04-26"}, "mode": "continuous", "product": "####"}
{}
{"seconds": 600, "mode": "periodic", "req": "card.location.mode"}
{"seconds":600,"mode":"periodic"}
{"file": "test.qi", "req": "note.get"}
{"time":1686241193,"body":{"start_time":1686158220.97}}
+++++RESPONSE BODY+++++>{'time': 1686241193, 'body': {'start_time': 1.686158e+09}}
======>>>>{'start_time': 1.686158e+09}
Start Time: 1.686158e+09 as int 1686158208 as float 1.686158e+09


I was able to sidestep the issue in my code by converting to int first but am confused why the float is not converting correctly. Equipment is a Huzzah32 Feather running MicroPython v1.20.0. Python notecard library was pulled from github recently. Thank you for your help.

import sys, time
import notecard
from machine import I2C,Pin

def NotecardExceptionInfo(exception):
    """Construct a formatted Exception string.
    Args:
        exception (Exception): An exception object.
    Returns:
        string: a summary of the exception with line number and details.
    """
    name = exception.__class__.__name__
    return sys.platform + ": " + name \
        + ": " + ' '.join(map(str, exception.args))

#=========================ENTRY=====================================
productUID = "<<>>"
use_uart = False
try:
    i2c_port = I2C(0, scl=Pin(22), sda=Pin(23), freq=400000)
except Exception as exception:
    raise Exception("error opening port: "
                    + NotecardExceptionInfo(exception))
#===========================+++++===================================

def get_notecard():
    print("Opening Notecard...")
    try:
        card = notecard.OpenI2C(i2c_port, 0, 0, debug=True)
        configure_notecard(card)
        configure_notecard_gps(card)
        return card
    except Exception as exception:
        raise Exception("error opening notecard: "
                        + NotecardExceptionInfo(exception))


def configure_notecard(card):
    """Submit a simple JSON-based request to the Notecard.
    Args:
        card (object): An instance of the Notecard class
    """
    req = {"req": "hub.set"}
    req["product"] = productUID
    req["mode"] = "continuous"
    req["outbound"] = 10
    req["inbound"] = 10
    req["duration"] = 60
    req["sync"] = True
    try:
        card.Transaction(req)
    except Exception as exception:
        print("Configure Transaction error: " + NotecardExceptionInfo(exception))
        time.sleep(5)

def sync_notecard(card):
    """Submit a simple JSON-based request to the Notecard.
    Args:
        card (object): An instance of the Notecard class
    """
    req = {"req": "hub.sync"}

    try:
        card.Transaction(req)
    except Exception as exception:
        print("Sync Transaction error: " + NotecardExceptionInfo(exception))
        time.sleep(5)

def configure_notecard_gps(card):
    """Submit a simple JSON-based request to the Notecard.
    Args:
        card (object): An instance of the Notecard class
    """
    req = {"req": "card.location.mode"}
    req["mode"] = "periodic"
    req["seconds"] = 600

    try:
        card.Transaction(req)
    except Exception as exception:
        print("GPS Transaction error: " + NotecardExceptionInfo(exception))
        time.sleep(5)

def get_data(card):
    try:
        req = {"req":"note.get","file":"test.qi"}
        rsp = card.Transaction(req)
        print(f"+++++RESPONSE BODY+++++>{rsp}")
        config = rsp["body"]
        print(f"======>>>>{config}")
        print(f"Start Time: {config['start_time']} as int {int(config['start_time'])} as float {float(config['start_time'])}")
        return config
    except KeyError:
        print("No notes available")
        return None


ltecard = get_notecard()
ltecard = get_data(ltecard)