Cbus.Alfheimr
1.0.0
This package is being migrated to a new namespace, and will form part of a larger family of packages under the Cbus.Alfheimr name.
dotnet add package Cbus.Alfheimr --version 1.0.0
NuGet\Install-Package Cbus.Alfheimr -Version 1.0.0
<PackageReference Include="Cbus.Alfheimr" Version="1.0.0" />
<PackageVersion Include="Cbus.Alfheimr" Version="1.0.0" />
<PackageReference Include="Cbus.Alfheimr" />
paket add Cbus.Alfheimr --version 1.0.0
#r "nuget: Cbus.Alfheimr, 1.0.0"
#:package Cbus.Alfheimr@1.0.0
#addin nuget:?package=Cbus.Alfheimr&version=1.0.0
#tool nuget:?package=Cbus.Alfheimr&version=1.0.0
Cbus.Alfheimr Readme
This file provides an overview of the Cbus.Alfheimr project.
The project is a C# CBUS library. Its purpose is to make CBUS functionality available to .NET developers.
The code is a combination of hand-written code (attributes, factories, helpers, and interfaces) and generated code (enums, classes and structs) that are concrete implementations from CBUS-Defs.
None of the code is generated using any form of generative AI.
In this readme code that is hand-written is tagged with ✋ and code that is generated from CBUS-Defs is tagged with ⚡.
A broad understanding of CBUS is required to use this library, and it is assumed that readers of this readme have that knowledge.
One of the principles behind this library is to allow it to be used in a number ways. Consequently, it is not expected that all the provided functionality will be used in all cases.
History
This is the third version of creating a CBUS C#.NET library. The first two used T4 templates and source generators respectively.
Having written both previous versions and considered the maintenance and usage requirements it was felt that there was too much overhead and unnecessary complexity in using either of those approaches. Rather, the code only needs to be generated when there is a change to either the CBUS specification or the functional requirements of the library itself.
Both T4 templates and source generators allow code to be generated much more dynamically, but impose additional overheads and complexities to achieve that. There are also language restrictions; for example, T4 Templates only support .NET Standard, although they can produce code for any .NET version.
Consequently, this project now uses a standard console app to update the code from CBUS defs and the other data files. The interfaces and support code are updated manually.
Code Organisation
The code files are split into a number of sub-folders, and thus namespaces:
- Attributes
- Classes
- Enums
- Exceptions
- Factories
- Helpers
- Interfaces
- Structs
With this file and two text files in the root.
History.txt
This is the change history of CBUS-Defs.
Licence.txt
The licence both of CBUS-Defs, and of this project. Both need to be accepted to use this code; by using this code the user attests that they accept the licence conditions, and that they have the necessary authority to do so.
Attributes
OpCodeAttribte ✋
An attribute that is applied to an OpCode type that provides its name and number.
This allows op-codes to be discovered using the .NET type system.
Classes
- ModuleType ⚡
- ProcessorType ⚡
Both contain a number of static read-only properties, one for each defined module or processor type.
Enums
The enums that are defined by CBUS-Defs. Often used as parameters by the op-codes.
- BusTypeEnum ⚡
- CabFlagEnum ⚡
- CabSessionModeEnum ⚡
- CabSignalAspectEnum ⚡
- CommandErrorEnum ⚡
- CommandStationFlagEnum ⚡
- EngineFlagEnum ⚡
- ErrorEnum ⚡
- FastClockMonthEnum ⚡
- FastClockWkDayEnum ⚡
- ManufacturerEnum ⚡
- ParamEnum ⚡
- ParamFlagEnum ⚡
- ParamOffset ⚡
- ProcessorManufacturer ⚡
- ServiceModeStatus ⚡
Some enum files also contain a partial class of OpCodeHelper that provides type specific methods for that particular enum.
Exceptions
AlfheimrException ✋
Abstract.
The base exception type for the project.
AlfheimrOpCodeException ✋
Abstract.
The base op-code exception.
OpCodeFailedException ✋
Sealed, with only internal constructors.
The exception that is thrown when the creation of an Op-Code instance failed.
OpCodeNotKnownException ✋
Sealed, with only internal constructors.
The exception that is thrown when an unknown Op-Code is requested to be created. This includes where the name is not known, or the number is not assigned to an op-code, or the type of the op-code is undefined.
Factories
OpCodeFactory ✋
Static.
Contains a number of static creation methods for op-codes.
Helpers
OpCodeHelper ✋
Internal static.
A partial class that is extended for each of the enums.
Contains a number of internally used helper methods used by the op-codes.
These reduce the amount of boillerplate code that would otherwise be necesary in the op-code instances themselves.
Interfaces
ICbusOpCode ✋
The base interface that is applied to all Op-Codes.
ICbusOpCodeAccessoryData ✋
Applied to an Op-Code that could cary additional data bytes. Has a number of derived interfaces:
ICbusOpCodeAccessoryData0 ✋
ICbusOpCodeAccessoryData1 ✋
ICbusOpCodeAccessoryData2 ✋
ICbusOpCodeAccessoryData3 ✋
Indicates the number of attitional data bytes.
ICbusOpCodeAccessoryEventType ✋
Applied to an Accessory Op-Code that has an event type. Has a number of derived interfaces:
ICbusOpCodeAccessoryEventData ✋
Indicates that the Op-Code carries data describing the event.
ICbusOpCodeAccessoryEventOff ✋
Indicates an OFF event.
ICbusOpCodeAccessoryEventOn ✋
Indicates an ON event.
ICbusOpCodeAccessoryLength ✋
Applied to an Accessory type Op-Code when the event has a length. Has a number of derived interfaces:
ICbusOpCodeAccessoryLong ✋
Applied to an Accessory type Op-Code when the event is Long.
ICbusOpCodeAccessoryShort ✋
Applied to an Accessory type Op-Code when the event is Short.
ICbusOpCodeAccessorySubtype ✋
Applied to an Accessory type Op-Code that has a sub-type. Has a number of derived interfaces:
ICbusOpCodeAccessoryEvent ✋
Applied to an Accessory type Op-Code that has a sub-type of event.
ICbusOpCodeAccessoryRequest ✋
Applied to an Accessory type Op-Code that has a sub-type of request.
ICbusOpCodeAccessoryResponse ✋
Applied to an Accessory type Op-Code that has a sub-type of response.
ICbusOpCodeAccessoryWrite ✋
Applied to an Accessory type Op-Code that has a sub-type of write
ICbusOpCodeType ✋
Describes the type of an Op-Code. Has a number of derived interfaces:
ICbusOpCodeAccessory ✋
Applied to an Op-Code that has a type of 'Accessory'.
ICbusOpCodeConfig ✋
Applied to an Op-Code that has a type of 'Config'.
ICbusOpCodeDcc ✋
Applied to an Op-Code that has a type of 'DCC'.
ICbusOpCodeGeneral ✋
Applied to an Op-Code that has a type of 'General'.
IErrorReplyTo ✋
Describes an error response to an Op-Code. Has a derived generic interface:
IErrorReplyTo<T> ✋
Describes an error response to an Op-Code of type
T.
IReplyTo ✋
Describes the reply to an Op-Code. Has a derived generic interface:
IReplyTo<T> ✋
Describes the reply to an Op-Code of type
T.
These are all interfaces that are applied to the op-code instances. Not all op-codes have the same interfaces applied.
Using these interfaces allow pattern matching to be used on op-code instances which should greatly simplify the code and improve the understanding of it.
Structs
- OpCodes ⚡
There is on op-code struct for each differnet op-code. Given that there are 256 possible op-codes of which about half are defined, it will be appreciated that this is a very large file. It was felt that one single large file was preferable over 100+ smaller individual files.
How to Use
Install the nuget package.
Create instances of the op-codes. Send them over whichever transport you wish to use.
When an incoming message is received supply its data as a byte array to the OpCodeFactory.Create(byte[]) method.
This will return an instance of the corresponding Op-Code; or throw an exception if there is no matching Op-Code, or if the Op-Code cannot be created for some reason.
For an outgoing message use either OpCodeFactory.Create(string) supplying the name of the Op-Code, or directly instanciate the required Op-Code type using new and supply the appropriate parameters.
To communicate over a physical CAN bus implementation it will be necessary to convert the byte representation of each op-code into a form that can be sent to the bus. GridConnect is the usual protocol used for this purpose. Each Op-Code exposes its underlying data as a byte array; this can then be supplied to the desired implementation.
References
The official CBUS site:
The MERG CBUS Knowledgebase
https://www.merg.org.uk/merg_wiki/doku.php?id=cbuscentral:start
Note: this site is members only. Access can be gained by joining MERG, the Model Electronics Railway Group.
CBUS-Defs
https://github.com/MERG-DEV/cbusdefs
- Maintained by Pete Brownlow et al.
- Contains data definitions for CBUS used by this project.
Trademarks
CBUS ®️ is a registered trademark of Dr Michale Bolton.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Bcl.Memory (>= 10.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 1.0.0 | 157 | 4/19/2026 |
Initial version.