Skip to content
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

Add multiple modules based on a template module and quantity #18

Merged
merged 4 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 90 additions & 9 deletions can.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#!/bin/python

from __future__ import annotations
from operator import mod
from unicodedata import normalize
import json
import re
from mako.template import Template

# TODO: escrever funções para facilitar a edição e criação de variações:

Check notice on line 10 in can.py

View check run for this annotation

codefactor.io / CodeFactor

can.py#L10

unresolved comment '# TODO: escrever fun��es para facilitar a edi��o e cria��o de varia��es:' (C100)
# - criar uma cópia do modulo, mensagem, byte ou bit
# - atualizar um campo do modulo
# - atualizar um campo de um topico do modulo
Expand Down Expand Up @@ -40,7 +41,7 @@
return False
return True

class topic:
class Topic:
def __init__(self, msg: str, id: int,frequency: int, description: str):
self.name = Can.convert_string(msg)

Expand Down Expand Up @@ -70,6 +71,43 @@
"frequency": self.frequency,
"frame_length": self.frame_length
}

@classmethod
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (llm): It's great to see the implementation of the from_dict class method for the Topic class. This method will significantly ease the creation of Topic instances from dictionaries, especially useful in the context of dynamically generating topics. However, it would be beneficial to add unit tests for this method to ensure its correct functionality and to handle edge cases properly.

def from_dict(cls, data: dict) -> Can.Topic:
topic = cls(
msg=data["name"],
id=data["id"],
frequency=data["frequency"],
description=data["description"]
)
for (i, byte) in enumerate(data["bytes"]):
# Signature byte is already described
if i == 0 or byte is None:
continue

topic.describe_byte(
name=byte["name"],
byte=i,
description=byte["description"],
btype=byte["type"],
units=byte["units"]
)

# Describe bits if byte is a bitfield
if byte["type"] != "bitfield":
continue

for bit in byte["bits"]:
# Skip if bit is not described
if bit is None:
continue

topic.describe_bit(
name=bit,
byte=i,
bit=byte["bits"].index(bit)
)
return topic

def __str__(self) -> str:
return json.dumps(self.get(), indent=4)
Expand Down Expand Up @@ -143,7 +181,7 @@
}

if self.bytes[byte]["type"] == "bitfield":
self.bytes[byte]["bits"] = [None]*8
self.bytes[byte]["bits"] = [None] * 8

def describe_bit(self, name: str, byte: int, bit: int):
self.validate_byte(byte)
Expand All @@ -158,7 +196,7 @@

self.bytes[byte]["bits"][bit] = name

class module:
class Module:
def __init__(self, name: str, signature: int, description: str):

self.validate_name(name)
Expand Down Expand Up @@ -220,17 +258,60 @@

def add_module(self, module):
for m in self.modules:
# Check if module name is unique
if m['name'] == dict(module.get()).get('name'):
raise ValueError("module field `name` must be unique!")
raise ValueError("module field `name` must be unique!", m['name'])
# Check if module signature is unique
if m['signature'] == dict(module.get()).get('signature'):
raise ValueError(
"module field `signature` must be unique!, module ",
m['name'],
" and ",
module.get()['name'],
" have the same signature: ",
m["signature"]
)
# Check if topics id is unique
for db_topic in m['topics']:
for topic in module.get()['topics']:
if topic['id'] == db_topic['id']:
print(f"WARNING: Topic id {topic['id']} is not unique",
f"conflict between module {m['name']} and {module.get()['name']}")

self.modules.append(module.get())

def add_multiple_modules(self, module: Module, quantity: int) -> None:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (llm): The addition of the add_multiple_modules method is a crucial feature for generating repeated modules efficiently. However, there's a need for comprehensive unit tests covering this method to validate the creation of multiple modules with unique names, signatures, and updated topic IDs. Tests should also verify that the correct number of modules is added and that their properties are correctly incremented.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (llm): While the add_multiple_modules method is a significant addition, it's important to ensure that the new module signatures and topic IDs do not conflict with existing ones in the CAN database. Consider adding validation logic to prevent such conflicts, which could lead to issues in message identification and handling.

'''
Add multiple modules based on a template module and a quantity
'''
for i in range(quantity):
# Create topics
topics = []
for topic in module.get()["topics"]:
new_topic = Can.Topic.from_dict(topic)
# Update topic id
new_topic.id = topic["id"] + i
topics.append(new_topic)

# Create module
new_module = Can.Module(
name=module.get()["name"] + "_" + str(i + 1),
signature=module.get()["signature"] + i,
description=module.get()["description"] + " " + str(i + 1)
)
# Add topics to module
for topic in topics:
new_module.add_topic(topic)

# Add module to database
self.add_module(new_module)

def import_json(self, filename: str):
with open(filename, 'r') as file:
data = dict(json.load(file))
self.version = data["version"]
for module in data["modules"]:
self.add_module(Can.module(
self.add_module(Can.Module(
name=module.get('name'),
signature=module.get('signature'),
description=module.get('description')
Expand Down Expand Up @@ -384,22 +465,22 @@


if __name__ == '__main__':
t1 = Can.topic("motor", 9, 100, "Motor controller parameters")
t1 = Can.Topic("motor", 9, 100, "Motor controller parameters")
t1.describe_byte("motor", 1, "Switches and states", "bitfield", "")
t1.describe_bit("motor on", 1, 0)
t1.describe_byte("D raw", 2, "Motor Duty Cycle", "uint8_t", "%")
t1.describe_byte("I raw", 3, "Motor Soft Start", "uint8_t", "%")
t2 = Can.topic("motor2", 19, 10, "Motor controller parameters")
t2 = Can.Topic("motor2", 19, 10, "Motor controller parameters")
t2.describe_byte("motor", 1, "Switches and states", "bitfield", "")
t2.describe_bit("motor on", 1, 0)
t2.describe_byte("D raw", 2, "Motor Duty Cycle", "uint8_t", "%")
t2.describe_byte("I raw", 3, "Motor Soft Start", "uint8_t", "%")
# print(t1)

m1 = Can.module("mic17", 10, "Modulo de Interface de Controle")
m1 = Can.Module("mic17", 10, "Modulo de Interface de Controle")
m1.add_topic(t1)
m1.add_topic(t2)
m2 = Can.module("mam21", 10, "Mamm")
m2 = Can.Module("mam21", 10, "Mamm")

# print(m1)

Expand Down
Loading
Loading