ORM-like definition of new parts
Description
At the moment, I have to go into the KiCad library editor to create a new part. The net connections and net list are generated using skidl, but skidl is still utterly dependent on existing part libraries generated using KiCad.
I would like to see a 'model' or library that creates the part itself in python. We see similar models when we look as sqlalchemy classes which define and correspond to tables. In sqlalchemy, most users will create a models.py file which will entirely contain the SQL structure and my proposal is to implement a similar feature in skidl.
Motivation
This is OK, but it would be much more pythonic - and readable! - to create models using python syntax and use that to instantiate my part. Schematic part creation is great for those who have an existing library, but to use skidl for the workflow, it makes sense to have a 'from scratch' skidl option.
Current Part Generation
Using the example 'pic10f220-i/ot' from the documentation. The PIC10 has to be created using the schematic editor and skidl has to be configured to find that library and import it. The part definition is then entirely based on the KiCad part definition.
import skidl
pic10 = Part(lib='microchip_pic10mcu', name='pic10f220-i/ot')
Proposed Part Generation
The proposed ORM-like structure would likely consist of a custom library-like file and then the use-case (though it wouldn't have to be separated).
my_custom_parts.py
import skidl
class Pic10(BasePart):
name = 'pic10f220-i/ot'
pins = [
Pin(num=1, name='ICSPDAT/AN0/GP0', funct=skidl.Pin.BIDIRECTIONAL),
Pin(num=2, name='VSS', funct=skidl.Pin.POWER-IN),
Pin(num=3, name='ICSPCLK/AN1/GP1', funct=skidl.Pin.BIDIRECTIONAL),
Pin(num=4, name='T0CKI/FOSC4/GP2', funct=skidl.Pin.BIDIRECTIONAL),
Pin(num=5, name='VDD', funct=skidl.Pin.POWER-IN),
Pin(num=6, name='Vpp/~MCLR~/GP3', funct=skidl.Pin.INPUT)
]
# more stuff could be added, but wouldn't have to be - manufacturer, part number, etc
my_circuit.py
pic10 = Part(basepart=Pic10)
Additional Features
Assuming that the proposed feature is implemented, it would also be nice to have a 'lib_to_skidl.py' script similar in functionality to the existing 'netlist_to_skidl.py' that exists now.
I have started working on this on a fork. I suspect that it is quite simple if you know what you are doing, but I'm hacking my way through it.
I also added a couple of examples for my own testing. I will likely delete them once they evolve a bit, but I'm using them for my own development.
Yes, this is the way to go! I started with the KiCad libraries since that's the tool I was using. But it would be much better to have a native SKiDL ORM and libraries so people don't need KiCad. And a way to convert vendor libraries into the SKiDL format, as you said.
I think the existing Part class might be the place to start. Then a library might be just a dictionary of Parts. Haven't thought about it in detail, though.
Hey, I have noticed that the KiCad library is utilized in the template for Part._gen_netlist_comp_kicad(). Is this necessary or is there a valid method to dummy this part of the string?
I removed the (libsource...) portion of the component definition and the resulting netlist was still accepted by PCBNEW.
Hey, thanks for working on this. So, I believe that I have a prototype working, but I am having trouble finding the contribution guidelines. Could you link those from the readme?
Examples of part models:
class Resistor(PartModel):
name = 'resistor'
ref_prefix = 'R'
pins = [
Pin(num=1, name='pin1', funct=Pin.PASSIVE),
Pin(num=2, name='pin2', funct=Pin.PASSIVE),
]
manufacturer = 'Yageo'
part_number = 'RC0402JR-0710KL'
class Capacitor(PartModel):
name = 'capacitor'
ref_prefix = 'C'
pins = [
Pin(num=1, name='pin1', funct=Pin.PASSIVE),
Pin(num=2, name='pin2', funct=Pin.PASSIVE),
]
There are some unit tests you can run by typing tox in the top-level directory. These probably won't test your features, so you may want to add some. You can also issue a pull request and then I can look at what you've done.
Thanks. The netlist isn't generating appropriately, so I'm not going to do a pull request until I get that sorted out. Likely something simple, but I don't know. Thanks for your support.
I put some code into SKiDL to allow on-the-fly creation of parts and libraries. It's similar to what you were proposing.
@slightlynybbled, what happened with this? Your fork seems to be gone.
@kasbah, the initial cut hadn't fully worked and I lost track of it, xesscorp beat me to getting this started and I simply haven't had a chance to re-check it out. I was doing some pruning of my repositories and this one got the axe since it was so far behind. Would like to give it another shot, just haven't had time.
Just as an idea, it could be nice if you could use dicts instead of Pin() and simple strings for funct (maybe it looks more "pythonic" that way):
class Pic10(BasePart):
name = 'pic10f220-i/ot'
pins = [
dict(num=1, name='ICSPDAT/AN0/GP0', funct='bidirectional'),
dict(num=2, name='VSS', funct='power-in'),
dict(num=3, name='ICSPCLK/AN1/GP1', funct='bidirectional'),
# ...
]
Also, it would be great if you could create an instance of that part with:
pic10 = Pic10()
Instead of:
pic10 = Part(basepart=Pic10)