From aa4e713c8e788e7ac037b01bffd308546efb812d Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 12 Mar 2024 22:09:23 +0100 Subject: [PATCH 1/3] not working --- rowers/rowing-workout-metrics.proto | 49 +++++++++++++++++++++++++++++ rowers/rowing_workout_metrics.proto | 49 +++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 rowers/rowing-workout-metrics.proto create mode 100644 rowers/rowing_workout_metrics.proto diff --git a/rowers/rowing-workout-metrics.proto b/rowers/rowing-workout-metrics.proto new file mode 100644 index 00000000..2992b397 --- /dev/null +++ b/rowers/rowing-workout-metrics.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; + +package rowing_workout_metrics; +option go_package = "./rowing-workout-metrics"; + +// OTW-metrics service definition +service Metrics { + rpc CalcMetrics (WorkoutMetricsRequest) returns (WorkoutMetricsResponse); +}; + +// GetCP service definition +service CP { + rpc GetCP (CPRequest) returns (CPResponse); +} + +// WorkoutMetricsRequest message +message WorkoutMetricsRequest { + string filename = 1; + string sex = 2; + double ftp = 3; + double hrftp = 4; + double hrmax = 5; + double hrmin = 6; + +}; + +// WorkoutMetricsReponse message +message WorkoutMetricsResponse { + double tss = 1; + double normp = 2; + double trimp = 3; + double hrtss = 4; + double normv = 5; + double normw = 6; +}; + +// CPRequest message +message CPRequest { + string filename = 1; + string filetype = 2; // CSV or Parquet + repeated double tarr = 3; +} + +message CPResponse { + repeated double delta = 1; + repeated double power = 2; + double avgpower = 3; + +} \ No newline at end of file diff --git a/rowers/rowing_workout_metrics.proto b/rowers/rowing_workout_metrics.proto new file mode 100644 index 00000000..2992b397 --- /dev/null +++ b/rowers/rowing_workout_metrics.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; + +package rowing_workout_metrics; +option go_package = "./rowing-workout-metrics"; + +// OTW-metrics service definition +service Metrics { + rpc CalcMetrics (WorkoutMetricsRequest) returns (WorkoutMetricsResponse); +}; + +// GetCP service definition +service CP { + rpc GetCP (CPRequest) returns (CPResponse); +} + +// WorkoutMetricsRequest message +message WorkoutMetricsRequest { + string filename = 1; + string sex = 2; + double ftp = 3; + double hrftp = 4; + double hrmax = 5; + double hrmin = 6; + +}; + +// WorkoutMetricsReponse message +message WorkoutMetricsResponse { + double tss = 1; + double normp = 2; + double trimp = 3; + double hrtss = 4; + double normv = 5; + double normw = 6; +}; + +// CPRequest message +message CPRequest { + string filename = 1; + string filetype = 2; // CSV or Parquet + repeated double tarr = 3; +} + +message CPResponse { + repeated double delta = 1; + repeated double power = 2; + double avgpower = 3; + +} \ No newline at end of file From 4b83a251db8de8f31cc0ae351b651d719f9b4a05 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 12 Mar 2024 22:09:33 +0100 Subject: [PATCH 2/3] not working 2 --- rowers/dataprep.py | 45 +++++ rowers/datautils.py | 1 - rowers/otw_power_calculator_pb2.py | 190 ++----------------- rowers/otw_power_calculator_pb2_grpc.py | 62 ++++-- rowers/rowing_workout_metrics_pb2.py | 221 +++------------------- rowers/rowing_workout_metrics_pb2_grpc.py | 122 ++++++++++-- rowers/tasks.py | 1 - rowers/tests/testdata/testdata.tcx.gz | Bin 4000 -> 4000 bytes 8 files changed, 233 insertions(+), 409 deletions(-) diff --git a/rowers/dataprep.py b/rowers/dataprep.py index f206a457..d05ec634 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -31,6 +31,11 @@ from zipfile import BadZipFile import zipfile import os from rowers.models import strokedatafields +import grpc +import grpc.experimental +import rowers.rowing_workout_metrics_pb2 as metrics_pb2 +import rowers.rowing_workout_metrics_pb2_grpc as metrics_pb2_grpc +import traceback from rowingdata import ( KinoMapParser, @@ -499,9 +504,48 @@ def calculate_goldmedalstandard(rower, workout, recurrance=True): def setcp(workout, background=False, recurrance=True): filename = 'media/cpdata_{id}.parquet.gz'.format(id=workout.id) + csvfilename = workout.csvfilename + # check what the real file name is + if os.path.exists(csvfilename): + csvfile = csvfilename + elif os.path.exists(csvfilename+'.csv'): # pragma: no cover + csvfile = csvfilename+'.csv' + elif os.path.exists(csvfilename+'.gz'): # pragma: no cover + csvfile = csvfilename+'.gz' + else: # pragma: no cover + return pd.DataFrame({'delta': [], 'cp': []}), pd.Series(dtype='float'), pd.Series(dtype='float') + strokesdf = getsmallrowdata_db( ['power', 'workoutid', 'time'], ids=[workout.id]) + protos = grpc.protos("rowing_workout_metrics.proto") + services = grpc.services("rowing_workout_metrics.proto") + req = protos.CPRequest( + filename = csvfile, + filetype = "CSV", + tarr = datautils.getlogarr(1.05*strokesdf['time'].max()) + ) + response = services.GetCP(req, "localhost:50052", insecure=True) + delta = response.delta + cpvalues = response.power + powermean = response.avgpower + + df = pd.DataFrame({ + 'delta': delta, + 'cp': cpvalues, + 'id': workout.id, + }) + df.to_parquet(filename, engine='fastparquet', compression='GZIP') + if recurrance: + goldmedalstandard, goldmedalduration = calculate_goldmedalstandard( + workout.user, workout) + workout.goldmedalstandard = goldmedalstandard + workout.goldmedalduration = goldmedalduration + workout.save() + return df, delta, cpvalues + + + try: if strokesdf['power'].std() == 0: return pd.DataFrame(), pd.Series(dtype='float'), pd.Series(dtype='float') @@ -682,6 +726,7 @@ def fetchcp_new(rower, workouts): for workout in workouts: cpfile = 'media/cpdata_{id}.parquet.gz'.format(id=workout.id) try: + df, delta, cpvalues = setcp(workout) df = pd.read_parquet(cpfile) df['workout'] = str(workout) df['url'] = workout.url() diff --git a/rowers/datautils.py b/rowers/datautils.py index 029de2f3..fcebd334 100644 --- a/rowers/datautils.py +++ b/rowers/datautils.py @@ -1,4 +1,3 @@ - import pandas as pd import numpy as np from scipy.interpolate import griddata diff --git a/rowers/otw_power_calculator_pb2.py b/rowers/otw_power_calculator_pb2.py index f0c2091c..d099031d 100644 --- a/rowers/otw_power_calculator_pb2.py +++ b/rowers/otw_power_calculator_pb2.py @@ -1,185 +1,31 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: otw-power-calculator.proto - -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import reflection as _reflection -from google.protobuf import message as _message +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor -import sys -_b = sys.version_info[0] < 3 and ( - lambda x: x) or (lambda x: x.encode('latin1')) +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor.FileDescriptor( - name='otw-power-calculator.proto', - package='otw_power_calculator', - syntax='proto3', - serialized_options=None, - serialized_pb=_b('\n\x1aotw-power-calculator.proto\x12\x14otw_power_calculator\"\xc0\x01\n\x13WorkoutPowerRequest\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x10\n\x08\x62oattype\x18\x02 \x01(\t\x12\x10\n\x08\x63rewmass\x18\x03 \x01(\x01\x12\x15\n\rpowermeasured\x18\x04 \x01(\x08\x12\x13\n\x0bprogressurl\x18\x05 \x01(\t\x12\x0e\n\x06secret\x18\x06 \x01(\t\x12\x0e\n\x06silent\x18\x07 \x01(\x08\x12\x11\n\tboatclass\x18\x08 \x01(\t\x12\x14\n\x0c\x63oastalbrand\x18\t \x01(\t\"#\n\x11\x43\x61lculationResult\x12\x0e\n\x06result\x18\x01 \x01(\x05\x32j\n\x05Power\x12\x61\n\tCalcPower\x12).otw_power_calculator.WorkoutPowerRequest\x1a\'.otw_power_calculator.CalculationResult\"\x00\x62\x06proto3') -) -_WORKOUTPOWERREQUEST = _descriptor.Descriptor( - name='WorkoutPowerRequest', - full_name='otw_power_calculator.WorkoutPowerRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='filename', full_name='otw_power_calculator.WorkoutPowerRequest.filename', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='boattype', full_name='otw_power_calculator.WorkoutPowerRequest.boattype', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='crewmass', full_name='otw_power_calculator.WorkoutPowerRequest.crewmass', index=2, - number=3, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='powermeasured', full_name='otw_power_calculator.WorkoutPowerRequest.powermeasured', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='progressurl', full_name='otw_power_calculator.WorkoutPowerRequest.progressurl', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='secret', full_name='otw_power_calculator.WorkoutPowerRequest.secret', index=5, - number=6, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='silent', full_name='otw_power_calculator.WorkoutPowerRequest.silent', index=6, - number=7, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='boatclass', full_name='otw_power_calculator.WorkoutPowerRequest.boatclass', index=7, - number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='coastalbrand', full_name='otw_power_calculator.WorkoutPowerRequest.coastalbrand', index=8, - number=9, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=53, - serialized_end=245, -) - - -_CALCULATIONRESULT = _descriptor.Descriptor( - name='CalculationResult', - full_name='otw_power_calculator.CalculationResult', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='result', full_name='otw_power_calculator.CalculationResult.result', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=247, - serialized_end=282, -) - -DESCRIPTOR.message_types_by_name['WorkoutPowerRequest'] = _WORKOUTPOWERREQUEST -DESCRIPTOR.message_types_by_name['CalculationResult'] = _CALCULATIONRESULT -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -WorkoutPowerRequest = _reflection.GeneratedProtocolMessageType('WorkoutPowerRequest', (_message.Message,), { - 'DESCRIPTOR': _WORKOUTPOWERREQUEST, - '__module__': 'otw_power_calculator_pb2' - # @@protoc_insertion_point(class_scope:otw_power_calculator.WorkoutPowerRequest) -}) -_sym_db.RegisterMessage(WorkoutPowerRequest) - -CalculationResult = _reflection.GeneratedProtocolMessageType('CalculationResult', (_message.Message,), { - 'DESCRIPTOR': _CALCULATIONRESULT, - '__module__': 'otw_power_calculator_pb2' - # @@protoc_insertion_point(class_scope:otw_power_calculator.CalculationResult) -}) -_sym_db.RegisterMessage(CalculationResult) - - -_POWER = _descriptor.ServiceDescriptor( - name='Power', - full_name='otw_power_calculator.Power', - file=DESCRIPTOR, - index=0, - serialized_options=None, - serialized_start=284, - serialized_end=390, - methods=[ - _descriptor.MethodDescriptor( - name='CalcPower', - full_name='otw_power_calculator.Power.CalcPower', - index=0, - containing_service=None, - input_type=_WORKOUTPOWERREQUEST, - output_type=_CALCULATIONRESULT, - serialized_options=None, - ), - ]) -_sym_db.RegisterServiceDescriptor(_POWER) - -DESCRIPTOR.services_by_name['Power'] = _POWER +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1aotw-power-calculator.proto\x12\x14otw_power_calculator\"\xc0\x01\n\x13WorkoutPowerRequest\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x10\n\x08\x62oattype\x18\x02 \x01(\t\x12\x10\n\x08\x63rewmass\x18\x03 \x01(\x01\x12\x15\n\rpowermeasured\x18\x04 \x01(\x08\x12\x13\n\x0bprogressurl\x18\x05 \x01(\t\x12\x0e\n\x06secret\x18\x06 \x01(\t\x12\x0e\n\x06silent\x18\x07 \x01(\x08\x12\x11\n\tboatclass\x18\x08 \x01(\t\x12\x14\n\x0c\x63oastalbrand\x18\t \x01(\t\"#\n\x11\x43\x61lculationResult\x12\x0e\n\x06result\x18\x01 \x01(\x05\x32j\n\x05Power\x12\x61\n\tCalcPower\x12).otw_power_calculator.WorkoutPowerRequest\x1a\'.otw_power_calculator.CalculationResult\"\x00\x42\x18Z\x16./otw-power-calculatorb\x06proto3') +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'otw_power_calculator_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'Z\026./otw-power-calculator' + _globals['_WORKOUTPOWERREQUEST']._serialized_start=53 + _globals['_WORKOUTPOWERREQUEST']._serialized_end=245 + _globals['_CALCULATIONRESULT']._serialized_start=247 + _globals['_CALCULATIONRESULT']._serialized_end=282 + _globals['_POWER']._serialized_start=284 + _globals['_POWER']._serialized_end=390 # @@protoc_insertion_point(module_scope) diff --git a/rowers/otw_power_calculator_pb2_grpc.py b/rowers/otw_power_calculator_pb2_grpc.py index f6d10b5a..c3a58814 100644 --- a/rowers/otw_power_calculator_pb2_grpc.py +++ b/rowers/otw_power_calculator_pb2_grpc.py @@ -1,4 +1,5 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc import rowers.otw_power_calculator_pb2 as otw__power__calculator__pb2 @@ -12,36 +13,57 @@ class PowerStub(object): """Constructor. Args: - channel: A grpc.Channel. + channel: A grpc.Channel. """ self.CalcPower = channel.unary_unary( - '/otw_power_calculator.Power/CalcPower', - request_serializer=otw__power__calculator__pb2.WorkoutPowerRequest.SerializeToString, - response_deserializer=otw__power__calculator__pb2.CalculationResult.FromString, - ) + '/otw_power_calculator.Power/CalcPower', + request_serializer=otw__power__calculator__pb2.WorkoutPowerRequest.SerializeToString, + response_deserializer=otw__power__calculator__pb2.CalculationResult.FromString, + ) class PowerServicer(object): """Power service definition """ - def CalcPower(self, request, context): # pragma: no cover - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) # pragma: no cover - context.set_details('Method not implemented!') # pragma: no cover - raise NotImplementedError( - 'Method not implemented!') # pragma: no cover + def CalcPower(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') -def add_PowerServicer_to_server(servicer, server): # pragma: no cover +def add_PowerServicer_to_server(servicer, server): rpc_method_handlers = { - 'CalcPower': grpc.unary_unary_rpc_method_handler( - servicer.CalcPower, - request_deserializer=otw__power__calculator__pb2.WorkoutPowerRequest.FromString, - response_serializer=otw__power__calculator__pb2.CalculationResult.SerializeToString, - ), - } # pragma: no cover + 'CalcPower': grpc.unary_unary_rpc_method_handler( + servicer.CalcPower, + request_deserializer=otw__power__calculator__pb2.WorkoutPowerRequest.FromString, + response_serializer=otw__power__calculator__pb2.CalculationResult.SerializeToString, + ), + } generic_handler = grpc.method_handlers_generic_handler( - 'otw_power_calculator.Power', rpc_method_handlers) + 'otw_power_calculator.Power', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class Power(object): + """Power service definition + """ + + @staticmethod + def CalcPower(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/otw_power_calculator.Power/CalcPower', + otw__power__calculator__pb2.WorkoutPowerRequest.SerializeToString, + otw__power__calculator__pb2.CalculationResult.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/rowers/rowing_workout_metrics_pb2.py b/rowers/rowing_workout_metrics_pb2.py index d6422d38..6a4554b2 100644 --- a/rowers/rowing_workout_metrics_pb2.py +++ b/rowers/rowing_workout_metrics_pb2.py @@ -1,210 +1,37 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: rowing-workout-metrics.proto - -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import reflection as _reflection -from google.protobuf import message as _message +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor -import sys -_b = sys.version_info[0] < 3 and ( - lambda x: x) or (lambda x: x.encode('latin1')) +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor.FileDescriptor( - name='rowing-workout-metrics.proto', - package='rowing_workout_metrics', - syntax='proto3', - serialized_options=None, - serialized_pb=_b('\n\x1crowing-workout-metrics.proto\x12\x16' - 'rowing_workout_metrics\"p\n\x15WorkoutMetricsRequest' - '\x12\x10\n\x08\x66ilename' - '\x18\x01 \x01(\t\x12\x0b\n\x03sex' - '\x18\x02 \x01(\t\x12\x0b\n\x03\x66tp\x18\x03 \x01' - '(\x01\x12\r\n\x05hrftp\x18\x04 \x01(\x01\x12\r\n\x05hrmax' - '\x18\x05 \x01(\x01\x12\r\n\x05hrmin\x18\x06 \x01(\x01\"p\n\x16WorkoutMetricsResponse' - '\x12\x0b\n\x03tss\x18\x01 \x01(\x01\x12\r\n\x05normp\x18\x02 \x01(\x01\x12\r\n\x05trimp' - '\x18\x03 \x01(\x01\x12\r\n\x05hrtss\x18\x04 \x01(\x01\x12\r\n\x05normv' - '\x18\x05 \x01(\x01\x12\r\n\x05normw\x18\x06 \x01(\x01\x32w\n\x07Metrics' - '\x12l\n\x0b\x43\x61lcMetrics\x12-.rowing_workout_metrics.WorkoutMetricsRequest' - '\x1a..rowing_workout_metrics.WorkoutMetricsResponseb\x06proto3') -) -_WORKOUTMETRICSREQUEST = _descriptor.Descriptor( - name='WorkoutMetricsRequest', - full_name='rowing_workout_metrics.WorkoutMetricsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='filename', full_name='rowing_workout_metrics.WorkoutMetricsRequest.filename', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='sex', full_name='rowing_workout_metrics.WorkoutMetricsRequest.sex', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ftp', full_name='rowing_workout_metrics.WorkoutMetricsRequest.ftp', index=2, - number=3, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='hrftp', full_name='rowing_workout_metrics.WorkoutMetricsRequest.hrftp', index=3, - number=4, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='hrmax', full_name='rowing_workout_metrics.WorkoutMetricsRequest.hrmax', index=4, - number=5, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='hrmin', full_name='rowing_workout_metrics.WorkoutMetricsRequest.hrmin', index=5, - number=6, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=56, - serialized_end=168, -) - - -_WORKOUTMETRICSRESPONSE = _descriptor.Descriptor( - name='WorkoutMetricsResponse', - full_name='rowing_workout_metrics.WorkoutMetricsResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='tss', full_name='rowing_workout_metrics.WorkoutMetricsResponse.tss', index=0, - number=1, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='normp', full_name='rowing_workout_metrics.WorkoutMetricsResponse.normp', index=1, - number=2, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='trimp', full_name='rowing_workout_metrics.WorkoutMetricsResponse.trimp', index=2, - number=3, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='hrtss', full_name='rowing_workout_metrics.WorkoutMetricsResponse.hrtss', index=3, - number=4, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='normv', full_name='rowing_workout_metrics.WorkoutMetricsResponse.normv', index=4, - number=5, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='normw', full_name='rowing_workout_metrics.WorkoutMetricsResponse.normw', index=5, - number=6, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=170, - serialized_end=282, -) - -DESCRIPTOR.message_types_by_name['WorkoutMetricsRequest'] = _WORKOUTMETRICSREQUEST -DESCRIPTOR.message_types_by_name['WorkoutMetricsResponse'] = _WORKOUTMETRICSRESPONSE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -WorkoutMetricsRequest = _reflection.GeneratedProtocolMessageType('WorkoutMetricsRequest', (_message.Message,), { - 'DESCRIPTOR': _WORKOUTMETRICSREQUEST, - '__module__': 'rowing_workout_metrics_pb2' - # @@protoc_insertion_point(class_scope:rowing_workout_metrics.WorkoutMetricsRequest) -}) -_sym_db.RegisterMessage(WorkoutMetricsRequest) - -WorkoutMetricsResponse = _reflection.GeneratedProtocolMessageType('WorkoutMetricsResponse', (_message.Message,), { - 'DESCRIPTOR': _WORKOUTMETRICSRESPONSE, - '__module__': 'rowing_workout_metrics_pb2' - # @@protoc_insertion_point(class_scope:rowing_workout_metrics.WorkoutMetricsResponse) -}) -_sym_db.RegisterMessage(WorkoutMetricsResponse) - - -_METRICS = _descriptor.ServiceDescriptor( - name='Metrics', - full_name='rowing_workout_metrics.Metrics', - file=DESCRIPTOR, - index=0, - serialized_options=None, - serialized_start=284, - serialized_end=403, - methods=[ - _descriptor.MethodDescriptor( - name='CalcMetrics', - full_name='rowing_workout_metrics.Metrics.CalcMetrics', - index=0, - containing_service=None, - input_type=_WORKOUTMETRICSREQUEST, - output_type=_WORKOUTMETRICSRESPONSE, - serialized_options=None, - ), - ]) -_sym_db.RegisterServiceDescriptor(_METRICS) - -DESCRIPTOR.services_by_name['Metrics'] = _METRICS +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1crowing-workout-metrics.proto\x12\x16rowing_workout_metrics\"p\n\x15WorkoutMetricsRequest\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x0b\n\x03sex\x18\x02 \x01(\t\x12\x0b\n\x03\x66tp\x18\x03 \x01(\x01\x12\r\n\x05hrftp\x18\x04 \x01(\x01\x12\r\n\x05hrmax\x18\x05 \x01(\x01\x12\r\n\x05hrmin\x18\x06 \x01(\x01\"p\n\x16WorkoutMetricsResponse\x12\x0b\n\x03tss\x18\x01 \x01(\x01\x12\r\n\x05normp\x18\x02 \x01(\x01\x12\r\n\x05trimp\x18\x03 \x01(\x01\x12\r\n\x05hrtss\x18\x04 \x01(\x01\x12\r\n\x05normv\x18\x05 \x01(\x01\x12\r\n\x05normw\x18\x06 \x01(\x01\"=\n\tCPRequest\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x10\n\x08\x66iletype\x18\x02 \x01(\t\x12\x0c\n\x04tarr\x18\x03 \x03(\x01\"<\n\nCPResponse\x12\r\n\x05\x64\x65lta\x18\x01 \x03(\x01\x12\r\n\x05power\x18\x02 \x03(\x01\x12\x10\n\x08\x61vgpower\x18\x03 \x01(\x01\x32w\n\x07Metrics\x12l\n\x0b\x43\x61lcMetrics\x12-.rowing_workout_metrics.WorkoutMetricsRequest\x1a..rowing_workout_metrics.WorkoutMetricsResponse2T\n\x02\x43P\x12N\n\x05GetCP\x12!.rowing_workout_metrics.CPRequest\x1a\".rowing_workout_metrics.CPResponseB\x1aZ\x18./rowing-workout-metricsb\x06proto3') +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'rowing_workout_metrics_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'Z\030./rowing-workout-metrics' + _globals['_WORKOUTMETRICSREQUEST']._serialized_start=56 + _globals['_WORKOUTMETRICSREQUEST']._serialized_end=168 + _globals['_WORKOUTMETRICSRESPONSE']._serialized_start=170 + _globals['_WORKOUTMETRICSRESPONSE']._serialized_end=282 + _globals['_CPREQUEST']._serialized_start=284 + _globals['_CPREQUEST']._serialized_end=345 + _globals['_CPRESPONSE']._serialized_start=347 + _globals['_CPRESPONSE']._serialized_end=407 + _globals['_METRICS']._serialized_start=409 + _globals['_METRICS']._serialized_end=528 + _globals['_CP']._serialized_start=530 + _globals['_CP']._serialized_end=614 # @@protoc_insertion_point(module_scope) diff --git a/rowers/rowing_workout_metrics_pb2_grpc.py b/rowers/rowing_workout_metrics_pb2_grpc.py index 30aac7b5..2f5a91d7 100644 --- a/rowers/rowing_workout_metrics_pb2_grpc.py +++ b/rowers/rowing_workout_metrics_pb2_grpc.py @@ -1,4 +1,5 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc import rowers.rowing_workout_metrics_pb2 as rowing__workout__metrics__pb2 @@ -12,13 +13,13 @@ class MetricsStub(object): """Constructor. Args: - channel: A grpc.Channel. + channel: A grpc.Channel. """ self.CalcMetrics = channel.unary_unary( - '/rowing_workout_metrics.Metrics/CalcMetrics', - request_serializer=rowing__workout__metrics__pb2.WorkoutMetricsRequest.SerializeToString, - response_deserializer=rowing__workout__metrics__pb2.WorkoutMetricsResponse.FromString, - ) + '/rowing_workout_metrics.Metrics/CalcMetrics', + request_serializer=rowing__workout__metrics__pb2.WorkoutMetricsRequest.SerializeToString, + response_deserializer=rowing__workout__metrics__pb2.WorkoutMetricsResponse.FromString, + ) class MetricsServicer(object): @@ -26,22 +27,107 @@ class MetricsServicer(object): """ def CalcMetrics(self, request, context): - # missing associated documentation comment in .proto file - pass - context.set_code(grpc.StatusCode.UNIMPLEMENTED) # pragma: no cover - context.set_details('Method not implemented!') # pragma: no cover - raise NotImplementedError( - 'Method not implemented!') # pragma: no cover + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') -def add_MetricsServicer_to_server(servicer, server): # pragma: no cover +def add_MetricsServicer_to_server(servicer, server): rpc_method_handlers = { - 'CalcMetrics': grpc.unary_unary_rpc_method_handler( - servicer.CalcMetrics, - request_deserializer=rowing__workout__metrics__pb2.WorkoutMetricsRequest.FromString, - response_serializer=rowing__workout__metrics__pb2.WorkoutMetricsResponse.SerializeToString, - ), + 'CalcMetrics': grpc.unary_unary_rpc_method_handler( + servicer.CalcMetrics, + request_deserializer=rowing__workout__metrics__pb2.WorkoutMetricsRequest.FromString, + response_serializer=rowing__workout__metrics__pb2.WorkoutMetricsResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( - 'rowing_workout_metrics.Metrics', rpc_method_handlers) + 'rowing_workout_metrics.Metrics', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class Metrics(object): + """OTW-metrics service definition + """ + + @staticmethod + def CalcMetrics(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/rowing_workout_metrics.Metrics/CalcMetrics', + rowing__workout__metrics__pb2.WorkoutMetricsRequest.SerializeToString, + rowing__workout__metrics__pb2.WorkoutMetricsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + +class CPStub(object): + """GetCP service definition + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetCP = channel.unary_unary( + '/rowing_workout_metrics.CP/GetCP', + request_serializer=rowing__workout__metrics__pb2.CPRequest.SerializeToString, + response_deserializer=rowing__workout__metrics__pb2.CPResponse.FromString, + ) + + +class CPServicer(object): + """GetCP service definition + """ + + def GetCP(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_CPServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetCP': grpc.unary_unary_rpc_method_handler( + servicer.GetCP, + request_deserializer=rowing__workout__metrics__pb2.CPRequest.FromString, + response_serializer=rowing__workout__metrics__pb2.CPResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'rowing_workout_metrics.CP', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class CP(object): + """GetCP service definition + """ + + @staticmethod + def GetCP(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/rowing_workout_metrics.CP/GetCP', + rowing__workout__metrics__pb2.CPRequest.SerializeToString, + rowing__workout__metrics__pb2.CPResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/rowers/tasks.py b/rowers/tasks.py index 388af488..6572a1dd 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -1477,7 +1477,6 @@ def handle_calctrimp(id, csvfile = csvfilename+'.gz' else: # pragma: no cover return 0 - csvfile = os.path.abspath(csvfile) with grpc.insecure_channel( diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz index e380513e867d867d4c7b9150dbb1e0a971ee706e..41219d8855b45ea65b83040560a6a760f9deb700 100644 GIT binary patch literal 4000 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 GfB^s+y%|XW literal 4000 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 Date: Wed, 13 Mar 2024 18:57:18 +0100 Subject: [PATCH 3/3] working --- rowers/dataprep.py | 111 +++++++++++----------- rowers/datautils.py | 16 ++-- rowers/models.py | 21 ++-- rowers/rowing-workout-metrics.proto | 49 ---------- rowers/rowing_workout_metrics.proto | 49 ---------- rowers/rowing_workout_metrics_pb2.py | 8 +- rowers/rowing_workout_metrics_pb2_grpc.py | 65 ++++--------- rowers/tests/testdata/testdata.tcx.gz | Bin 4000 -> 4002 bytes rowers/utils.py | 6 +- 9 files changed, 97 insertions(+), 228 deletions(-) delete mode 100644 rowers/rowing-workout-metrics.proto delete mode 100644 rowers/rowing_workout_metrics.proto diff --git a/rowers/dataprep.py b/rowers/dataprep.py index d05ec634..26684810 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -502,8 +502,28 @@ def calculate_goldmedalstandard(rower, workout, recurrance=True): def setcp(workout, background=False, recurrance=True): - filename = 'media/cpdata_{id}.parquet.gz'.format(id=workout.id) + try: + filename = 'media/cpdata_{id}.parquet.gz'.format(id=workout.id) + df = pd.read_parquet(filename) + if not df.empty: + # check dts + tarr = datautils.getlogarr(4000) + if df['delta'][0] in tarr: + return(df, df['delta'], df['cp']) + except: + pass + + strokesdf = getsmallrowdata_db( + ['power', 'workoutid', 'time'], ids=[workout.id]) + + if strokesdf.empty: + return pd.DataFrame({'delta': [], 'cp': []}), pd.Series(dtype='float'), pd.Series(dtype='float') + + totaltime = strokesdf['time'].max() + maxt = totaltime/1000. + logarr = datautils.getlogarr(maxt) + csvfilename = workout.csvfilename # check what the real file name is if os.path.exists(csvfilename): @@ -514,80 +534,53 @@ def setcp(workout, background=False, recurrance=True): csvfile = csvfilename+'.gz' else: # pragma: no cover return pd.DataFrame({'delta': [], 'cp': []}), pd.Series(dtype='float'), pd.Series(dtype='float') + csvfile = os.path.abspath(csvfile) - strokesdf = getsmallrowdata_db( - ['power', 'workoutid', 'time'], ids=[workout.id]) - protos = grpc.protos("rowing_workout_metrics.proto") - services = grpc.services("rowing_workout_metrics.proto") - req = protos.CPRequest( - filename = csvfile, - filetype = "CSV", - tarr = datautils.getlogarr(1.05*strokesdf['time'].max()) - ) - response = services.GetCP(req, "localhost:50052", insecure=True) - delta = response.delta - cpvalues = response.power + with grpc.insecure_channel( + target='localhost:50052', + options=[('grpc.lb_policy_name', 'pick_first'), + ('grpc.enable_retries', 0), ('grpc.keepalive_timeout_ms', + 10000)] + ) as channel: + try: + grpc.channel_ready_future(channel).result(timeout=10) + except grpc.FutureTimeoutError: # pragma: no cover + dologging('metrics.log','grpc channel time out in setcp') + return pd.DataFrame({'delta': [], 'cp': []}), pd.Series(dtype='float'), pd.Series(dtype='float') + + stub = metrics_pb2_grpc.MetricsStub(channel) + req = metrics_pb2.CPRequest(filename = csvfile, filetype = "CSV", tarr = logarr) + + try: + response = stub.GetCP(req, timeout=60) + except Exception as e: + dologging('metrics.log', traceback.format_exc()) + return pd.DataFrame({'delta': [], 'cp': []}), pd.Series(dtype='float'), pd.Series(dtype='float') + + delta = pd.Series(np.array(response.delta)) + cpvalues = pd.Series(np.array(response.power)) powermean = response.avgpower + + df = pd.DataFrame({ 'delta': delta, 'cp': cpvalues, 'id': workout.id, }) + df.to_parquet(filename, engine='fastparquet', compression='GZIP') + if recurrance: goldmedalstandard, goldmedalduration = calculate_goldmedalstandard( workout.user, workout) workout.goldmedalstandard = goldmedalstandard workout.goldmedalduration = goldmedalduration workout.save() + return df, delta, cpvalues - - - try: - if strokesdf['power'].std() == 0: - return pd.DataFrame(), pd.Series(dtype='float'), pd.Series(dtype='float') - except (KeyError, TypeError): - return pd.DataFrame(), pd.Series(dtype='float'), pd.Series(dtype='float') - - if background: # pragma: no cover - _ = myqueue(queuelow, handle_setcp, strokesdf, filename, workout.id) - return pd.DataFrame({'delta': [], 'cp': []}), pd.Series(dtype='float'), pd.Series(dtype='float') - - if not strokesdf.empty: - totaltime = strokesdf['time'].max() - try: - powermean = strokesdf['power'].mean() - except KeyError: # pragma: no cover - powermean = 0 - - if powermean != 0: - thesecs = totaltime - maxt = 1.05 * thesecs - - if maxt > 0: - logarr = datautils.getlogarr(maxt) - dfgrouped = strokesdf.groupby(['workoutid']) - delta, cpvalues, avgpower = datautils.getcp(dfgrouped, logarr) - - df = pd.DataFrame({ - 'delta': delta, - 'cp': cpvalues, - 'id': workout.id, - }) - df.to_parquet(filename, engine='fastparquet', - compression='GZIP') - if recurrance: - goldmedalstandard, goldmedalduration = calculate_goldmedalstandard( - workout.user, workout) - workout.goldmedalstandard = goldmedalstandard - workout.goldmedalduration = goldmedalduration - workout.save() - return df, delta, cpvalues - - return pd.DataFrame({'delta': [], 'cp': []}), pd.Series(dtype='float'), pd.Series(dtype='float') def update_wps(r, types, mode='water', asynchron=True): @@ -723,6 +716,7 @@ def join_workouts(r, ids, title='Joined Workout', def fetchcp_new(rower, workouts): data = [] + for workout in workouts: cpfile = 'media/cpdata_{id}.parquet.gz'.format(id=workout.id) try: @@ -743,12 +737,15 @@ def fetchcp_new(rower, workouts): if len(data) > 1: df = pd.concat(data, axis=0) + try: df = df[df['cp'] == df.groupby(['delta'])['cp'].transform('max')] except KeyError: # pragma: no cover return pd.Series(dtype='float'), pd.Series(dtype='float'), 0, pd.Series(dtype='float'), pd.Series(dtype='float') df = df.sort_values(['delta']).reset_index() + df = df[df['cp']>20] + return df['delta'], df['cp'], 0, df['workout'], df['url'] diff --git a/rowers/datautils.py b/rowers/datautils.py index fcebd334..cb17a357 100644 --- a/rowers/datautils.py +++ b/rowers/datautils.py @@ -123,18 +123,18 @@ def cpfit(powerdf, fraclimit=0.0001, nmax=1000): def getlogarr(maxt): - maxlog10 = np.log10(maxt-5) + dtmin = 10 + maxlog10 = np.log10(maxt) # print(maxlog10,round(maxlog10)) - aantal = 10*round(maxlog10) + aantal = 40 logarr = np.arange(aantal+1)/10. + vs = 10.**logarr + res = [] - for la in logarr: - try: - v = 5+int(10.**(la)) - except ValueError: # pragma: no cover - v = 0 - res.append(v) + for v in vs: + if v > dtmin and vuIcmVC4TW=dT7J%RLD~vp}4~tUg!o!Q} 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 Iio}2c00)vf`2YX_ literal 4000 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 GfB^s+y%|XW diff --git a/rowers/utils.py b/rowers/utils.py index bf71456b..34f808ea 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -347,9 +347,9 @@ def isbreakthrough(delta, cpvalues, p0, p1, p2, p3, ratio): pwr *= ratio - delta = delta.values.astype(int) - cpvalues = cpvalues.values.astype(int) - pwr = pwr.astype(int) + delta = delta.astype(int, errors='ignore').values + cpvalues = cpvalues.astype(int, errors='ignore').values + pwr = pwr.astype(int, errors='ignore').values res = np.sum(cpvalues > pwr+1) res2 = np.sum(cpvalues > pwr2+1)