Retrieve data from the OH2 snapDB based on specific parameters

Hello, Team,

I hope you’re all doing well.

We’re currently working on a Python API that includes a function designed to receive a list of PMUs, organized by PPAs, along with a specified time range. The purpose of this function is to retrieve the relevant data and subsequently save it locally within a DataFrame.

Here’s an example of how this part of the code looks:

time_filter = timestampSeekFilter.CreateFromRange(start_time, end_time)
point_filter = pointIDMatchFilter.CreateFromList(point_ids)

reader = instance.Read(time_filter, point_filter)
key = historianKey()
value = historianValue()

df = pd.DataFrame(columns=['Hora UTC', 'Valor', 'PPA'])

while reader.Read(key, value):
        match = re.search(r'@ (.+)', key.ToString(metadata))
        horario= match.group(1)
        #print(value.AsQuality)
        new_row = pd.DataFrame({'Hora UTC': [horario], 'Valor': [value.ToString()], 'PPA': [key.ToString().split('@')[0].strip()]})
        df = pd.concat([df, new_row], ignore_index=True)

As you can see, we’re using openHistorian.historianKey and openHistorian.historianValue to retrieve data from snapDB.

I have two requests for support:

  1. Decimal Precision:
    Is there a way to adjust the returned values to display with the maximum number of decimal places?
    To address this, I modified openHistorian.historianValue >> function ToString() to return more decimal places, and the same adjustment was made for openHistorian.historianKey >> function ToString(). However, I believe there may be a more optimized and less intrusive way to achieve this goal.

  2. Data Acquisition Rate:
    I would like to acquire data at lower rates (also specifying this parameter in the function mentioned above). For example, for PMUs that store data at 120fps, I would prefer to acquire only at 10fps. In this case, we have applications that do not necessarily require all 120 phasors to yield reliable results.

I would appreciate any suggestions you may have on both points mentioned above.

  1. I suspect you can adjust the printed precision of historianValue using a string format expression, for example:
value = historianValue()
value.AsSingle = 59.095468

print(f"Value with 4 decimals of precision = {value.AsSingle:.4f}")
  1. You can change the resolution of data retrieval by adjusting parameters on the timestampSeekFilter, for example:
def TestRead(instance: historianInstance, metadata: metadataCache, startTime: datetime, endTime: datetime, pointIDList: List[np.uint64]):
    # Set interval for 10 samples per second, i.e., 0.1 seconds plus window width of 0.001 seconds
    timeFilter = timestampSeekFilter.CreateFromRangeInterval(startTime, endTime, 0.1, 0.001)
    pointFilter = pointIDMatchFilter.CreateFromList(pointIDList)

    opStart = time()
    reader = instance.Read(timeFilter, pointFilter)
    count = 0
                
    key = historianKey()
    value = historianValue()

    while reader.Read(key, value):
        count += 1
        print(f"    Point {key.ToString(metadata)} = {value.ToString()}")

    print(f"\r\nRead complete for {count:,} points in {(time() - opStart):.2f} seconds.\r\n")
1 Like