- Update change log -
changelog.md
- Existing messages updated for new attributes or associations -
proto/zepben/protobuf/cim
- New messages added for new classes/enums:
- added to model -
proto/zepben/protobuf/cim
- added to producer (all three files) -
proto/zepben/protobuf/*p
- added to consumer
oneof identifiedObject
maps -proto/zepben/protobuf/*c
e.g.NetworkIdentifiedObject
- added to model -
- Descriptions copied from CIM and added as doc comments to new changes (on messages, property etc)
proto.lock
updated if there were breaking changes- Document changes in the model specification
Prerequisites:
- IntelliJ (other IDE's will work, but not pre-configured)
- Protobuf support in your IDE
- Maven
If your protobuf plugin is not configured as below, you will see errors in the IDE. Make sure the proto dir is included.
This repository uses protolock to ensure there are no breaking changes between releases.
The proto.lock file can be found at proto/zepben/proto.lock
. This file will be automatically kept up to date by the build pipeline - PR's should not update this file.
For testing, the protolock binary can be retrieved from https://github.com/nilslice/protolock/releases/. Download, extract, and add it to your PATH
.
Prior to merging, protolock is run automatically by the build pipeline, and will ensure no breaking changes have been made. You can test this prior to committing by running:
cd proto/zepben
protolock status
If you need to merge breaking changes your patch must:
-
Update the major version to the next release for each library
-
Force update the
proto.lock
file prior to committing.cd proto/zepben protolock commit --force git add proto.lock
-
Commit
proto.lock
changes with version updates.
Once you have installed the local package, update you project to reference the local version of testing.
cd java
-- edit pom.xml and change the version to <VERSION>-LOCAL# --
mvn clean install
cd python
-- edit setup.py and change the version to <VERSION>.local# --
python3 build.py --package
Restore the packages via VisualStudio with a correctly configured NuGet.
cd cs
-- edit evolve-grpc.csproj and change the version to <VERSION>-LOCAL# --
dotnet pack evolve-grpc.csproj -c Release -o ./ --no-restore
nuget init path/to/Zepben.Evolve.Grpc.<VERSION>.nupkg path/to/local/nuget/debug/repo
cd c
make
You can now copy the output files as needed to your C project.
The moduel specification is found in the spec folder. This folder contains YAML files that describe both the CIM profile and our Zepben profile. The YAML profile spec forms a neutral machine readable format that can be used to generate other formats such as documentation.
spec/
├── Evolve/
│ ├── extensions/
│ │ ├── IEC61968/
│ │ │ ├── .metadata.yaml
│ │ │ └── AssetInfo/
│ │ │ ├── RelayInfo.yaml
│ │ │ └── .metadata.yaml
│ │ └── .metadata.yaml
│ └── IEC61968/
│ ├── .metadata.yaml
│ └── AssetInfo/
│ ├── .metadata.yaml
│ └── CableInfo.yaml
└── TC57CIM/
└── IEC61968/
├── .metadata.yaml
└── AssetInfo/
├── .metadata.yaml
└── BusbarSectionInfo.yaml
Above is a simplified diagram of the structure that is present in the spec
folder. The folders form the following structure
- The top level folders in the
spec
folder represent profiles, we have two. The CIM standard and our own Zepben profile. - Inside a profile folder, there are folders that represent packages in that profile. Packages can contain other packages. Each package at minimum will contain a single file called
.metadata.yaml
which names the package and provides a description of whats in the package. - Packages can also contain other yaml files such as
RelayInfo.yaml
in the example. These files represent classes that are inside a package. - Classes contain the following attributes
name
- the name of the classdescription
- a description of the classancestors
- a list containing the class the current class inherits fromdescendents
- a list containing all direct inheritors of the current classattributes
- a list of objects containing:name
- the name of the attributetype
- the type of the attribute, this is normally another class in the profiledescription
- a description of the attribute
associations
- a list of object containing:source
- the name of the current classtarget
- the other class this class is associated totargetCardinality
- the cardinality against the target class, can be (0..1, 1, 0..*, 1..*).targetName
- the name of the association on the current class that can fetch the target classtargetDescription
- the description of the associationsource*
- same as target, but the relationship from the target class back to the current class. This may not always exist.
Using the above is not always easy, so here are a set of rules when trying to describe a class in the spec format. Keep in mind this is for the Zepben profile only. The CIM profile is purely generated:
- The location of the class file must match the package hierachy in code
name
anddescription
are always present- Is it a class or an enum? - if its an enum, fill in
name
anddescription
. All the enum values becomesattributes
with no type - Does the class inherit from another class? - Add as an
ancestor
in this class, and as adescendent
on the other class - If the fields don't end with
mrids
in proto - these are most likelyattributes
, document them as so. - For the other fields that end with
mrids
in proto this implies an association. In the Kotlin SDK, most fields on class that reference another model also imply an association.- The
source
andtarget
fields should be the names of the classes that form the association - Starting for the rest of the target fields first
- The cardinality is
0..*
if the field is aCollection
, if its a single object thats nullable, then its0..1
- The
targetName
is the name of the field in the Kotlin SDK - The
targetDescription
is the comment associated with the field in the SDK
- The cardinality is
- For the
source*
fields, navigate to thetarget
class- If there isn't a field that refer the
source
class, then don't fill in these fields - If there is, then fill in those fields using the same instructions as the
target*
fields but from the view of thetarget
class - If you do fill in the
source*
fields, then there should be an associaton on thetarget
class YAML as well
- If there isn't a field that refer the
- The
- When it comes to adding new classes, if the class already exists in the CIM profile spec, copy it into the Zepben spec at the same package path and then modify it
- If the class does not exist in CIM whether in the CIM published spec or the informal spec (
infiec61968
), then it should go into theextensions
folder - Everything the extensions folder should follow the class hierachy identical to where that extension would go in CIM.