@@ -57,8 +57,13 @@ impl ValueInfoBlock {
57
57
. context ( StrContext :: Label ( "initial VIF" ) )
58
58
. parse_next ( input) ?;
59
59
60
+ let mut vif_context = "VIF" ;
61
+
60
62
let value_type = match raw_value {
61
- value if value <= 0b0111_1010 => parse_table_10 ( value) ,
63
+ value if value <= 0b0111_1010 => {
64
+ vif_context = "VIF in table 10" ;
65
+ parse_table_10 ( value)
66
+ }
62
67
VIF_EXTENSION_1 | VIF_EXTENSION_2 => {
63
68
if !extension {
64
69
return Err (
@@ -74,7 +79,7 @@ impl ValueInfoBlock {
74
79
( extension, value) = parse_vif_byte
75
80
. context ( StrContext :: Label ( "VIF extension byte" ) )
76
81
. parse_next ( input) ?;
77
- if raw_value == VIF_EXTENSION_1 && value == VIF_EXTENSION_2 {
82
+ if raw_value == VIF_EXTENSION_2 && value == VIF_EXTENSION_2 {
78
83
if !extension {
79
84
return Err ( ErrMode :: from_error_kind ( input, ErrorKind :: Verify )
80
85
. add_context (
@@ -87,10 +92,13 @@ impl ValueInfoBlock {
87
92
( extension, value) = parse_vif_byte
88
93
. context ( StrContext :: Label ( "VIF extension layer 2 byte" ) )
89
94
. parse_next ( input) ?;
95
+ vif_context = "VIF in table 13" ;
90
96
parse_table_13 ( value)
91
- } else if raw_value == VIF_EXTENSION_1 {
97
+ } else if raw_value == VIF_EXTENSION_2 {
98
+ vif_context = "VIF in table 12" ;
92
99
parse_table_12 ( value)
93
100
} else {
101
+ vif_context = "VIF in table 14" ;
94
102
parse_table_14 ( value)
95
103
}
96
104
}
@@ -109,7 +117,7 @@ impl ValueInfoBlock {
109
117
ErrMode :: from_error_kind ( input, ErrorKind :: Verify ) . add_context (
110
118
input,
111
119
& vif_checkpoint,
112
- StrContext :: Label ( "reserved vif" ) ,
120
+ StrContext :: Label ( vif_context ) ,
113
121
) ,
114
122
) ;
115
123
} ;
@@ -175,21 +183,119 @@ fn parse_table_10(value: u8) -> Option<ValueType> {
175
183
176
184
fn parse_table_12 ( value : u8 ) -> Option < ValueType > {
177
185
Some ( match value {
186
+ vif ! ( E000 00 nn) => ValueType :: Credit ( exp ( MASK_NN , value, -3 ) ) ,
187
+ vif ! ( E000 01 nn) => ValueType :: Debit ( exp ( MASK_NN , value, -3 ) ) ,
188
+ vif ! ( E000 1000 ) => ValueType :: UniqueMessageIdentification ,
189
+ vif ! ( E000 1001 ) => ValueType :: DeviceType ,
190
+ vif ! ( E000 1010 ) => ValueType :: Manufacturer ,
191
+ vif ! ( E000 1011 ) => ValueType :: ParameterSetIdentification ,
192
+ vif ! ( E000 1100 ) => ValueType :: ModelVersion ,
193
+ vif ! ( E000 1101 ) => ValueType :: HardwareVersionNumber ,
194
+ vif ! ( E000 1110 ) => ValueType :: MetrologyFirmwareVersionNumber ,
195
+ vif ! ( E000 1111 ) => ValueType :: OtherSoftwareVersionNumber ,
196
+ vif ! ( E001 0000 ) => ValueType :: CustomerLocation ,
197
+ vif ! ( E001 0001 ) => ValueType :: Customer ,
198
+ vif ! ( E001 0010 ) => ValueType :: AccessCodeUser ,
199
+ vif ! ( E001 0011 ) => ValueType :: AccessCodeOperator ,
200
+ vif ! ( E001 0100 ) => ValueType :: AccessCodeSystemOperator ,
201
+ vif ! ( E001 0101 ) => ValueType :: AccessCodeDeveloper ,
202
+ vif ! ( E001 0110 ) => ValueType :: Password ,
203
+ vif ! ( E001 0111 ) => ValueType :: ErrorFlags ,
204
+ vif ! ( E001 1000 ) => ValueType :: ErrorMask ,
205
+ vif ! ( E001 1001 ) => ValueType :: SecurityKey ,
206
+ vif ! ( E001 1010 ) => ValueType :: DigitalOutput ,
207
+ vif ! ( E001 1011 ) => ValueType :: DigitalInput ,
208
+ vif ! ( E001 1100 ) => ValueType :: BaudRate ,
209
+ vif ! ( E001 1101 ) => ValueType :: ResponseDelayTime ,
210
+ vif ! ( E001 1110 ) => ValueType :: Retry ,
211
+ vif ! ( E001 1111 ) => ValueType :: RemoteControl ,
212
+ vif ! ( E010 0000 ) => ValueType :: FirstStorageNumberForCyclicStorage ,
213
+ vif ! ( E010 0001 ) => ValueType :: LastStorageNumberForCyclicStorage ,
214
+ vif ! ( E010 0010 ) => ValueType :: SizeOfStorageBlock ,
215
+ vif ! ( E010 0011 ) => ValueType :: DescriptorForTariffAndSubunit ,
216
+ vif ! ( E010 01 nn) => ValueType :: StorageInterval ( DurationType :: decode_nn ( value) ) ,
217
+ vif ! ( E010 1000 ) => ValueType :: StorageInterval ( DurationType :: Months ) ,
218
+ vif ! ( E010 1001 ) => ValueType :: StorageInterval ( DurationType :: Years ) ,
219
+ vif ! ( E010 1010 ) => ValueType :: OperatorSpecific ,
220
+ vif ! ( E010 1011 ) => ValueType :: TimePointSecond ,
221
+ vif ! ( E010 11 nn) => ValueType :: DurationSinceLastReadout ( DurationType :: decode_nn ( value) ) ,
222
+ vif ! ( E011 0000 ) => ValueType :: StartDateTimeOfTariff ,
223
+ // Unfortunate overlap so we can't use the macro :(
224
+ // vif!(E011 00nn) => ValueType::DurationOfTariff(DurationType::decode_nn(value)),
225
+ 0b0011_0001 ..=0b0011_0011 => ValueType :: DurationOfTariff ( DurationType :: decode_nn ( value) ) ,
178
226
vif ! ( E011 01 nn) => ValueType :: PeriodOfTarrif ( DurationType :: decode_nn ( value) ) ,
179
227
vif ! ( E011 1000 ) => ValueType :: PeriodOfTarrif ( DurationType :: Months ) ,
180
228
vif ! ( E011 1001 ) => ValueType :: PeriodOfTarrif ( DurationType :: Years ) ,
181
- _ => todo ! ( "table 12 {value} {value:x} {value:b}" ) ,
229
+ vif ! ( E011 1010 ) => ValueType :: Dimensionless ,
230
+ vif ! ( E011 1011 ) => ValueType :: WirelessContainer ,
231
+ vif ! ( E011 11 nn) => {
232
+ ValueType :: PeriodOfNominalDataTransmissions ( DurationType :: decode_nn ( value) )
233
+ }
234
+ vif ! ( E100 nnnn) => ValueType :: Volts ( exp ( MASK_NNNN , value, -9 ) ) ,
235
+ vif ! ( E101 nnnn) => ValueType :: Amperes ( exp ( MASK_NNNN , value, -12 ) ) ,
236
+ vif ! ( E110 0000 ) => ValueType :: ResetCounter ,
237
+ vif ! ( E110 0001 ) => ValueType :: CumulationCounter ,
238
+ vif ! ( E110 0010 ) => ValueType :: ControlSignal ,
239
+ vif ! ( E110 0011 ) => ValueType :: DayOfWeek ,
240
+ vif ! ( E110 0100 ) => ValueType :: WeekNumber ,
241
+ vif ! ( E110 0101 ) => ValueType :: TimePointOfDayChange ,
242
+ vif ! ( E110 0110 ) => ValueType :: StateOfParameterActivation ,
243
+ vif ! ( E110 0111 ) => ValueType :: SpecialSupplierInformation ,
244
+ vif ! ( E110 10 pp) => ValueType :: DurationSinceLastCumulation ( DurationType :: decode_pp ( value) ) ,
245
+ vif ! ( E110 11 pp) => ValueType :: OperatingTimeBattery ( DurationType :: decode_pp ( value) ) ,
246
+ vif ! ( E111 0000 ) => ValueType :: DateAndTimeOfBatteryChange ,
247
+ vif ! ( E111 0001 ) => ValueType :: RFLevel ,
248
+ vif ! ( E111 0010 ) => ValueType :: DSTTypeK ,
249
+ vif ! ( E111 0011 ) => ValueType :: ListeningWindowManagement ,
250
+ vif ! ( E111 0100 ) => ValueType :: RemainingBatteryLife ( DurationType :: Days ) ,
251
+ vif ! ( E111 0101 ) => ValueType :: NumberTimesMeterStopped ,
252
+ vif ! ( E111 0110 ) => ValueType :: ManufacturerSpecificContainer ,
253
+ _ => return None ,
182
254
} )
183
255
}
184
256
185
257
fn parse_table_13 ( value : u8 ) -> Option < ValueType > {
186
- todo ! ( "table 13 {value} {value:x} {value:b}" )
258
+ Some ( match value {
259
+ vif ! ( E000 0000 ) => ValueType :: CurrentlySelectedApplication ,
260
+ vif ! ( E000 0010 ) => ValueType :: RemainingBatteryLife ( DurationType :: Months ) ,
261
+ vif ! ( E000 0011 ) => ValueType :: RemainingBatteryLife ( DurationType :: Years ) ,
262
+ _ => return None ,
263
+ } )
187
264
}
188
265
189
266
fn parse_table_14 ( value : u8 ) -> Option < ValueType > {
267
+ // "These codes were used until 2004, now they are reserved for future use."
190
268
Some ( match value {
191
- 0b0000_0000 ..=0b0000_0001 => ValueType :: Energy ( EnergyUnit :: MWh , exp ( MASK_N , value, -1 ) ) ,
192
- _ => todo ! ( "table 14 {value} {value:x} {value:b}" ) ,
269
+ vif ! ( E000 000 n) => ValueType :: Energy ( EnergyUnit :: MWh , exp ( MASK_N , value, -1 ) ) ,
270
+ vif ! ( E000 001 n) => ValueType :: ReactiveEnergy ( exp ( MASK_N , value, 0 ) ) ,
271
+ vif ! ( E000 010 n) => ValueType :: ApparentEnergy ( exp ( MASK_N , value, 0 ) ) ,
272
+ vif ! ( E000 100 n) => ValueType :: Energy ( EnergyUnit :: GJ , exp ( MASK_N , value, -1 ) ) ,
273
+ vif ! ( E000 11 nn) => ValueType :: Energy ( EnergyUnit :: MCal , exp ( MASK_NN , value, -1 ) ) ,
274
+ vif ! ( E001 000 n) => ValueType :: Volume ( VolumeUnit :: M3 , exp ( MASK_N , value, 2 ) ) ,
275
+ vif ! ( E001 01 nn) => ValueType :: ReactivePower ( exp ( MASK_NN , value, -3 ) ) ,
276
+ vif ! ( E001 100 n) => ValueType :: Mass ( MassUnit :: T , exp ( MASK_N , value, 2 ) ) ,
277
+ vif ! ( E001 101 n) => ValueType :: RelativeHumidity ( exp ( MASK_N , value, -1 ) ) ,
278
+ vif ! ( E010 0000 ) => ValueType :: Volume ( VolumeUnit :: Feet3 , 0 ) ,
279
+ vif ! ( E010 0001 ) => ValueType :: Volume ( VolumeUnit :: Feet3 , -1 ) , // The table says "0,1 feet³" and I don't know what that means
280
+ 0b0010_0010 ..=0b0010_0110 => ValueType :: RetiredCode ( value) ,
281
+ vif ! ( E010 100 n) => ValueType :: Power ( PowerUnit :: MW , exp ( MASK_N , value, -1 ) ) ,
282
+ vif ! ( E010 1010 ) => ValueType :: PhaseUU ,
283
+ vif ! ( E010 1011 ) => ValueType :: PhaseUI ,
284
+ vif ! ( E010 11 nn) => ValueType :: Frequency ( exp ( MASK_NN , value, -3 ) ) ,
285
+ vif ! ( E011 000 n) => ValueType :: Power ( PowerUnit :: GJph , exp ( MASK_N , value, -1 ) ) ,
286
+ vif ! ( E011 01 nn) => ValueType :: ApparentPower ( exp ( MASK_NN , value, -1 ) ) ,
287
+ 0b0101_1000 ..=0b0110_0111 => ValueType :: RetiredCode ( value) ,
288
+ vif ! ( E110 1000 ) => ValueType :: ResultingPowerFactorK ,
289
+ vif ! ( E110 1001 ) => ValueType :: ThermalOutputRatingFactorKq ,
290
+ vif ! ( E110 1010 ) => ValueType :: ThermalCouplingRatingFactorOverallKc ,
291
+ vif ! ( E110 1011 ) => ValueType :: ThermalCouplingRatingFactorRoomSideKcr ,
292
+ vif ! ( E110 1100 ) => ValueType :: ThermalCouplingRatingFactorHeaterSideKch ,
293
+ vif ! ( E110 1101 ) => ValueType :: LowTemperatureRatingFactorKt ,
294
+ vif ! ( E110 1110 ) => ValueType :: DisplayOutputScalingFactorKD ,
295
+ vif ! ( E111 00 nn) => ValueType :: RetiredCode ( value) ,
296
+ vif ! ( E111 01 nn) => ValueType :: ColdWarmTemperatureLimit ( exp ( MASK_NN , value, -3 ) ) ,
297
+ vif ! ( E111 1 nnn) => ValueType :: CumulativeMaxOfActivePower ( exp ( MASK_NNN , value, -3 ) ) ,
298
+ _ => return None ,
193
299
} )
194
300
}
195
301
@@ -262,6 +368,7 @@ pub enum ValueType {
262
368
Any ,
263
369
PlainText ( String ) ,
264
370
ManufacturerSpecific ,
371
+ RetiredCode ( u8 ) , // "These codes were used until 2004, now they are reserved for future use."
265
372
// Table 10 - Primary VIF-codes
266
373
Energy ( EnergyUnit , Exponent ) ,
267
374
Volume ( VolumeUnit , Exponent ) ,
@@ -302,6 +409,7 @@ pub enum ValueType {
302
409
Customer ,
303
410
AccessCodeUser ,
304
411
AccessCodeOperator ,
412
+ AccessCodeSystemOperator ,
305
413
AccessCodeDeveloper ,
306
414
Password ,
307
415
ErrorFlags ,
0 commit comments