-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: added method for returning full plan object #34
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The gateway_get_full_plan is almost identical to the gateway_get_plan (the only difference is that the latter only returns one ActionPlanID). Can you rewrite the gateway_get_plan method to utilize the gateway_get_full_plan?
era_5g_client/client.py
Outdated
@@ -254,6 +254,35 @@ def gateway_get_plan(self, taskid: str, resource_lock: bool, robot_id: str) -> s | |||
except KeyError as e: | |||
raise FailedToConnect(f"Could not get the plan: {e}") | |||
|
|||
|
|||
def gateway_get_full_plan(self, taskid: str, resource_lock: bool, robot_id: str) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method does not return a string but a response (a dict probably?). Moreover, should it return the whole response? I think it would be better if we could create a data class that will describe the plan and return it (similar to MiddlewareInfo in https://github.com/5G-ERA/era-5g-client/blob/main/era_5g_client/dataclasses.py).
Hello Michal, Bartosz, can you check the dataclasses file and the parser_middleware_plan_info in client.py The idea is that the response from the middleware will be translated into a dataclass object defined with the middleware response. Please do not merge as i still want to do proper testing :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adrianLIrobotics, the logic looks good to me, but please correct the changes mentioned in the comments. On top of this, please make sure to address the changes that @Kapim has requested.
Thanks!
era_5g_client/dataclasses.py
Outdated
# Is currently been used by the robot | ||
enabled: bool | ||
|
||
def build_api_endpoint(self, path: str) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adrianLIrobotics is this function needed here? I don't see how the topic needs to build an API endpoint :)
era_5g_client/dataclasses.py
Outdated
# Onboarded time for network application. | ||
onboardedTime: str | ||
|
||
def build_api_endpoint(self, path: str) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as in the previous class
era_5g_client/dataclasses.py
Outdated
# Services of the action | ||
services : list[MiddlewareServiceInfo] | ||
|
||
def build_api_endpoint(self, path: str) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here
era_5g_client/dataclasses.py
Outdated
# List of actions in the task | ||
actionSequence: list[MiddlewareActionInfo] | ||
|
||
def build_api_endpoint(self, path: str) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, this function does not need to be duplicated this many times
era_5g_client/client.py
Outdated
topicPubData = service["rosTopicsPub"] | ||
topicSubData = service["rosTopicsSub"] | ||
for z in range(0,len(topicPubData)): | ||
rosTopicsPub.append(MiddlewareRosTopicModel(topicPubData["name"],topicPubData["type"],topicPubData["description"],topicPubData["enabled"] )) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can a constructor be created in the dataclass
to accept the dictionary? Then in this constructor, we could extract all the necessary data. It would make this section of the code much cleaner and easy to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should keep the constructor as it is but either implement some "from_dict" static method which will instantiate the object from the dictionary or use, e.g., the dacite.from_dict method to create the instance rosTopicPub.append(dacite.from_dict(data_class=MiddlewareRosTopicModel, data=topicPubData))
. @ZdenekM, what would be the best way to instantiate the dataclass model here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I definitely agree with @Artonus that we should make this section more cleaner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Kapim If you need from_dict
method for dataclasses, takes a look here: https://github.com/s-knibbs/dataclasses-jsonschema/ - pretty cool, I used it in arcor2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And because properties in a dictionary are named in the camelCase
convention and properties in dataclasses will be in snake_case
, we will need to convert the dictionary between those with this: https://github.com/nficano/humps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I looked better, and it seems there is a mix of camelCase
and PascalCase
(ServiceType
).
# The name of the task | ||
name: str | ||
# Block semantic planning, use predefined action seq. | ||
ReplanActionPlannerLocked: bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adrianLIrobotics I believe that these names don't follow the correct python name format, and this is why you can't get the CI build passing.
@Kapim can you confirm it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you should follow the PEP 8 style guide, i.e., the variable names should be snake_case formatted (lowercase with words separated by underscores). Only classes should use the PascalCase format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added a few more comments
era_5g_client/client.py
Outdated
def parser_middleware_plan_info(self, response: dict) -> MiddlewarePlanInfo: | ||
actionSequenceData = response['ActionSequence'] | ||
action_list = [] | ||
for x in range(0,len(actionSequenceData)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is more "Pythonic" to iterate through iterable like this for action in actionSequenceData:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, action_list = []
should have a type annotation.
era_5g_client/client.py
Outdated
action = actionSequenceData[x] | ||
service_list = [] | ||
serviceData = action["services"] | ||
for y in range(0,len(serviceData)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above, please use for service in serviceData:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add type annotation to service_list = []
.
era_5g_client/client.py
Outdated
rosTopicsSub = [] | ||
topicPubData = service["rosTopicsPub"] | ||
topicSubData = service["rosTopicsSub"] | ||
for z in range(0,len(topicPubData)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above. Moreover, is the topicPubData a list or something? Because inside the cycle, you are not iterating through it and only extracting the data from it.
era_5g_client/client.py
Outdated
topicPubData = service["rosTopicsPub"] | ||
topicSubData = service["rosTopicsSub"] | ||
for z in range(0,len(topicPubData)): | ||
rosTopicsPub.append(MiddlewareRosTopicModel(topicPubData["name"],topicPubData["type"],topicPubData["description"],topicPubData["enabled"] )) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should keep the constructor as it is but either implement some "from_dict" static method which will instantiate the object from the dictionary or use, e.g., the dacite.from_dict method to create the instance rosTopicPub.append(dacite.from_dict(data_class=MiddlewareRosTopicModel, data=topicPubData))
. @ZdenekM, what would be the best way to instantiate the dataclass model here?
era_5g_client/client.py
Outdated
topicPubData = service["rosTopicsPub"] | ||
topicSubData = service["rosTopicsSub"] | ||
for z in range(0,len(topicPubData)): | ||
rosTopicsPub.append(MiddlewareRosTopicModel(topicPubData["name"],topicPubData["type"],topicPubData["description"],topicPubData["enabled"] )) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I definitely agree with @Artonus that we should make this section more cleaner
# The name of the task | ||
name: str | ||
# Block semantic planning, use predefined action seq. | ||
ReplanActionPlannerLocked: bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you should follow the PEP 8 style guide, i.e., the variable names should be snake_case formatted (lowercase with words separated by underscores). Only classes should use the PascalCase format.
@adrianLIrobotics Before making a commit, please run |
@adrianLIrobotics Also, please merge commits into one so we have a clear and comprehensible history. Many thanks! |
@adrianLIrobotics do you plan to work on this in the near future? |
Closing for no activity. |
I added another method for returning the whole plan for later parsing in the AC/AS.
Many thanks!