bdns-plus allows a project to define the levels and volumes in use in their project.
Defaults 
You see that levels and volumes are set to None by default. In the background, bdns-plus generates levels and volumes tables supporting all numeric combinations where the level can be encoded by 2no integer digits and the volume can be encoded by 1no integer digit >= 1. See below.
The volume “code” and level “code” will be a parameter defined on every placed instance in Revit. These codes can then be used to build a tag, and also be used to map to the id and generate a BDNS compliant bdns_id.
For example, given the following data:
import  pandas as  pd 
from  IPython.display import  Markdown 
from  bdns_plus.tag import  Tag 
 
 
 equipment_data =  { 
     "abbreviation" : "AHU" , 
     "type" : 2 , 
     "level" : 1 , 
     "volume" : 3 , 
     "volume_level_instance" :1  
 } 
 tag =  Tag(equipment_data) 
 display(Markdown(tag.summary)) 
BDNS : AHU-3011
Instance : AHU/3/1/1
Type : AHU2
 
 
where the level is a -ve number, it is serialised to be (100 - basement level), i.e. B1 = -1 = 99. The default mapping tables above facilitate this to create a compliant BDNS tag:
 equipment_data =  { 
     "abbreviation" : "AHU" , 
     "type" : 2 , 
     "level" : - 1 , 
     "volume" : 1 , 
     "volume_level_instance" :1  
 } 
 tag =  Tag(equipment_data) 
 display(Markdown(tag.summary)) 
BDNS : AHU-1991
Instance : AHU/1/-1/1
Type : AHU2
 
 
 
Customising Volumes and Levels 
Setting the levels and volumes explicitly allows users to:
restrict the allowed values to a more limited set, and ensure compliance with that set 
extend the levels / volumes for extremely large projects (i.e. >90 floors, >9 basement floors, >9 volumes) 
add custom project encodings for levels and volumes
e.g. define volumes as A, B, C, D rather than numeric 
  
add encodings for things like mezzanine levels (see mezzanine example )
Note: this is not recommended as when codifying to an integer value for producing the BDNS tag it is impossible to map 1/2 floors (i.e. mezzanines). 
  
 
from  bdns_plus.models import  Config, to_records 
from  bdns_plus.tag import  Tag 
import  csv 
 
 _volumes =  """id,code,name  
1,A,Block A  
2,B,Block B  
3,C,Block C"""  
 
 
 _levels =  """id,code,name  
99,B1,Basement Level  
0,GF,Ground Floor  
1,L1,Level 1"""  
 
 _v =  to_records(list (csv.reader(_volumes.split(" \n " )))) 
 _l =  to_records(list (csv.reader(_levels.split(" \n " )))) 
 
 df_volumes, df_levels =  pd.DataFrame(_v), pd.DataFrame(_l) 
 layout =  dict (height= "100px" ) 
 gr_volumes, gr_levels =  mkgrid(df_volumes, layout= layout), mkgrid(df_levels, layout= layout) 
 
 display(gr_volumes) 
 display(gr_levels) 
 config =  Config(volumes= _v, levels= _l) 
 
 equipment_data =  { 
     "abbreviation" : "AHU" , 
     "type" : 2 , 
     "level" : "B1" , 
     "volume" : "B" , 
     "volume_level_instance" : 1  
 } 
 
 tag =  Tag(equipment_data, config= config) 
 display(Markdown(tag.summary)) 
BDNS : AHU-2991
Instance : AHU/B/B1/1
Type : AHU2