mirror of
https://github.com/JoelBender/bacpypes
synced 2025-09-28 22:15:23 +08:00
Merge branch 'patch-6' of https://github.com/tjohnsonhvac/bacpypes into tjohnsonhvac-patch-6
This commit is contained in:
commit
8ebd58727d
|
@ -1730,7 +1730,8 @@ class AccessRule(Sequence):
|
||||||
]
|
]
|
||||||
|
|
||||||
class AccessThreatLevel(Unsigned):
|
class AccessThreatLevel(Unsigned):
|
||||||
pass
|
_low_limit = 0
|
||||||
|
_high_limit = 100
|
||||||
|
|
||||||
class AccumulatorRecord(Sequence):
|
class AccumulatorRecord(Sequence):
|
||||||
sequenceElements = \
|
sequenceElements = \
|
||||||
|
|
|
@ -594,8 +594,10 @@ class Boolean(Atomic):
|
||||||
class Unsigned(Atomic):
|
class Unsigned(Atomic):
|
||||||
|
|
||||||
_app_tag = Tag.unsignedAppTag
|
_app_tag = Tag.unsignedAppTag
|
||||||
|
_low_limit = 0
|
||||||
|
_high_limit = None
|
||||||
|
|
||||||
def __init__(self,arg = None):
|
def __init__(self, arg=None):
|
||||||
self.value = 0L
|
self.value = 0L
|
||||||
|
|
||||||
if arg is None:
|
if arg is None:
|
||||||
|
@ -603,14 +605,16 @@ class Unsigned(Atomic):
|
||||||
elif isinstance(arg, Tag):
|
elif isinstance(arg, Tag):
|
||||||
self.decode(arg)
|
self.decode(arg)
|
||||||
elif isinstance(arg, int):
|
elif isinstance(arg, int):
|
||||||
if (arg < 0):
|
if not self.is_valid(arg):
|
||||||
raise ValueError("unsigned integer required")
|
raise ValueError("value out of range")
|
||||||
self.value = long(arg)
|
self.value = long(arg)
|
||||||
elif isinstance(arg, long):
|
elif isinstance(arg, long):
|
||||||
if (arg < 0):
|
if not self.is_valid(arg):
|
||||||
raise ValueError("unsigned integer required")
|
raise ValueError("value out of range")
|
||||||
self.value = arg
|
self.value = arg
|
||||||
elif isinstance(arg, Unsigned):
|
elif isinstance(arg, Unsigned):
|
||||||
|
if not self.is_valid(arg.value):
|
||||||
|
raise ValueError("value out of range")
|
||||||
self.value = arg.value
|
self.value = arg.value
|
||||||
else:
|
else:
|
||||||
raise TypeError("invalid constructor datatype")
|
raise TypeError("invalid constructor datatype")
|
||||||
|
@ -621,7 +625,7 @@ class Unsigned(Atomic):
|
||||||
|
|
||||||
# reduce the value to the smallest number of octets
|
# reduce the value to the smallest number of octets
|
||||||
while (len(data) > 1) and (data[0] == '\x00'):
|
while (len(data) > 1) and (data[0] == '\x00'):
|
||||||
data = data[1:]
|
del data[0]
|
||||||
|
|
||||||
# encode the tag
|
# encode the tag
|
||||||
tag.set_app_data(Tag.unsignedAppTag, data)
|
tag.set_app_data(Tag.unsignedAppTag, data)
|
||||||
|
@ -643,10 +647,24 @@ class Unsigned(Atomic):
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_valid(cls, arg):
|
def is_valid(cls, arg):
|
||||||
"""Return True if arg is valid value for the class."""
|
"""Return True if arg is valid value for the class."""
|
||||||
return isinstance(arg, (int, long)) and (not isinstance(arg, bool)) and (arg >= 0)
|
if not isinstance(arg, (int, long)) or isinstance(arg, bool):
|
||||||
|
return False
|
||||||
|
if (arg < cls._low_limit):
|
||||||
|
return False
|
||||||
|
if (cls._high_limit is not None) and (arg > cls._high_limit):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Unsigned(%s)" % (self.value, )
|
return "%s(%s)" % (self.__class__.__name__, self.value)
|
||||||
|
|
||||||
|
class Unsigned8(Unsigned):
|
||||||
|
_low_limit = 0
|
||||||
|
_high_limit = 255
|
||||||
|
|
||||||
|
class Unsigned16(Unsigned):
|
||||||
|
_low_limit = 0
|
||||||
|
_high_limit = 65535
|
||||||
|
|
||||||
#
|
#
|
||||||
# Integer
|
# Integer
|
||||||
|
|
|
@ -1730,7 +1730,8 @@ class AccessRule(Sequence):
|
||||||
]
|
]
|
||||||
|
|
||||||
class AccessThreatLevel(Unsigned):
|
class AccessThreatLevel(Unsigned):
|
||||||
pass
|
_low_limit = 0
|
||||||
|
_high_limit = 100
|
||||||
|
|
||||||
class AccumulatorRecord(Sequence):
|
class AccumulatorRecord(Sequence):
|
||||||
sequenceElements = \
|
sequenceElements = \
|
||||||
|
|
|
@ -598,8 +598,10 @@ class Boolean(Atomic):
|
||||||
class Unsigned(Atomic):
|
class Unsigned(Atomic):
|
||||||
|
|
||||||
_app_tag = Tag.unsignedAppTag
|
_app_tag = Tag.unsignedAppTag
|
||||||
|
_low_limit = 0
|
||||||
|
_high_limit = None
|
||||||
|
|
||||||
def __init__(self,arg = None):
|
def __init__(self, arg=None):
|
||||||
self.value = 0L
|
self.value = 0L
|
||||||
|
|
||||||
if arg is None:
|
if arg is None:
|
||||||
|
@ -607,14 +609,16 @@ class Unsigned(Atomic):
|
||||||
elif isinstance(arg, Tag):
|
elif isinstance(arg, Tag):
|
||||||
self.decode(arg)
|
self.decode(arg)
|
||||||
elif isinstance(arg, int):
|
elif isinstance(arg, int):
|
||||||
if (arg < 0):
|
if not self.is_valid(arg):
|
||||||
raise ValueError("unsigned integer required")
|
raise ValueError("value out of range")
|
||||||
self.value = long(arg)
|
self.value = long(arg)
|
||||||
elif isinstance(arg, long):
|
elif isinstance(arg, long):
|
||||||
if (arg < 0):
|
if not self.is_valid(arg):
|
||||||
raise ValueError("unsigned integer required")
|
raise ValueError("value out of range")
|
||||||
self.value = arg
|
self.value = arg
|
||||||
elif isinstance(arg, Unsigned):
|
elif isinstance(arg, Unsigned):
|
||||||
|
if not self.is_valid(arg.value):
|
||||||
|
raise ValueError("value out of range")
|
||||||
self.value = arg.value
|
self.value = arg.value
|
||||||
else:
|
else:
|
||||||
raise TypeError("invalid constructor datatype")
|
raise TypeError("invalid constructor datatype")
|
||||||
|
@ -647,10 +651,24 @@ class Unsigned(Atomic):
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_valid(cls, arg):
|
def is_valid(cls, arg):
|
||||||
"""Return True if arg is valid value for the class."""
|
"""Return True if arg is valid value for the class."""
|
||||||
return isinstance(arg, (int, long)) and (not isinstance(arg, bool)) and (arg >= 0)
|
if not isinstance(arg, (int, long)) or isinstance(arg, bool):
|
||||||
|
return False
|
||||||
|
if (arg < cls._low_limit):
|
||||||
|
return False
|
||||||
|
if (cls._high_limit is not None) and (arg > cls._high_limit):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Unsigned(%s)" % (self.value, )
|
return "%s(%s)" % (self.__class__.__name__, self.value)
|
||||||
|
|
||||||
|
class Unsigned8(Unsigned):
|
||||||
|
_low_limit = 0
|
||||||
|
_high_limit = 255
|
||||||
|
|
||||||
|
class Unsigned16(Unsigned):
|
||||||
|
_low_limit = 0
|
||||||
|
_high_limit = 65535
|
||||||
|
|
||||||
#
|
#
|
||||||
# Integer
|
# Integer
|
||||||
|
|
|
@ -94,6 +94,7 @@ class ObjectTypesSupported(BitString):
|
||||||
, 'accessUser':35
|
, 'accessUser':35
|
||||||
, 'accessZone':36
|
, 'accessZone':36
|
||||||
, 'credentialDataInput':37
|
, 'credentialDataInput':37
|
||||||
|
, 'networkPort':56
|
||||||
, 'networkSecurity':38
|
, 'networkSecurity':38
|
||||||
, 'bitstringValue':39
|
, 'bitstringValue':39
|
||||||
, 'characterstringValue':40
|
, 'characterstringValue':40
|
||||||
|
@ -1101,9 +1102,50 @@ class ProgramState(Enumerated):
|
||||||
}
|
}
|
||||||
|
|
||||||
class PropertyIdentifier(Enumerated):
|
class PropertyIdentifier(Enumerated):
|
||||||
|
# TODO: Sort Alphabetically
|
||||||
vendor_range = (512, 4194303)
|
vendor_range = (512, 4194303)
|
||||||
enumerations = \
|
enumerations = \
|
||||||
{ 'absenteeLimit':244
|
{ 'absenteeLimit':244
|
||||||
|
, 'tags':486
|
||||||
|
, 'profileLocation':91
|
||||||
|
, 'eventDetectionEnabled':353
|
||||||
|
, 'apduLength':388
|
||||||
|
, 'linkSpeed':420
|
||||||
|
, 'linkSpeeds':421
|
||||||
|
, 'linkSpeedAutonegotiate':422
|
||||||
|
, 'networkInterfaceName':424
|
||||||
|
, 'bacnetIPMode':408
|
||||||
|
, 'ipAddress':400
|
||||||
|
, 'bacnetIPUDPPort':412
|
||||||
|
, 'ipSubnetMask':411
|
||||||
|
, 'ipDefaultGateway':401
|
||||||
|
, 'bacnetIPMulticastAddress':409
|
||||||
|
, 'ipDNSServer':406
|
||||||
|
, 'ipDHCPEnable':402
|
||||||
|
, 'ipDHCPLeaseTime':403
|
||||||
|
, 'ipDHCPLeaseTimeRemaining':404
|
||||||
|
, 'ipDHCPServer':405
|
||||||
|
, 'bacnetIPNATTraversal':410
|
||||||
|
, 'bacnetIPGlobalAddress':407
|
||||||
|
, 'bbmdBroadcastDistributionTable':414
|
||||||
|
, 'bbmdAcceptFDRegistrations':413
|
||||||
|
, 'bbmdForeignDeviceTable':415
|
||||||
|
, 'fdBBMDAddress':418
|
||||||
|
, 'fdSubscriptionLifetime':419
|
||||||
|
, 'bacnetIPv6Mode':435
|
||||||
|
, 'ipv6Address':436
|
||||||
|
, 'ipv6PrefixLength':437
|
||||||
|
, 'bacnetIPv6UDPPort':438
|
||||||
|
, 'ipv6DefaultGateway':439
|
||||||
|
, 'bacnetIPv6MulticastAddress':440
|
||||||
|
, 'ipv6DNSServer':441
|
||||||
|
, 'ipv6AutoAddressingEnabled':442
|
||||||
|
, 'ipv6DHCPLeaseTime':443
|
||||||
|
, 'ipv6DHCPLeaseTimeRemaining':444
|
||||||
|
, 'ipv6DHCPServer':445
|
||||||
|
, 'ipv6ZoneIndex':446
|
||||||
|
, 'virtualMACAddressTable':429
|
||||||
|
, 'routingTable':428
|
||||||
, 'acceptedModes':175
|
, 'acceptedModes':175
|
||||||
, 'accessAlarmEvents':245
|
, 'accessAlarmEvents':245
|
||||||
, 'accessDoors':246
|
, 'accessDoors':246
|
||||||
|
@ -1158,8 +1200,10 @@ class PropertyIdentifier(Enumerated):
|
||||||
, 'bufferSize':126
|
, 'bufferSize':126
|
||||||
, 'changeOfStateCount':15
|
, 'changeOfStateCount':15
|
||||||
, 'changeOfStateTime':16
|
, 'changeOfStateTime':16
|
||||||
|
, 'changesPending':416
|
||||||
, 'channelNumber':366
|
, 'channelNumber':366
|
||||||
, 'clientCovIncrement':127
|
, 'clientCovIncrement':127
|
||||||
|
, 'command':417
|
||||||
, 'configurationFiles':154
|
, 'configurationFiles':154
|
||||||
, 'controlGroups':367
|
, 'controlGroups':367
|
||||||
, 'controlledVariableReference':19
|
, 'controlledVariableReference':19
|
||||||
|
@ -1286,6 +1330,7 @@ class PropertyIdentifier(Enumerated):
|
||||||
, 'loggingRecord':184
|
, 'loggingRecord':184
|
||||||
, 'loggingType':197
|
, 'loggingType':197
|
||||||
, 'lowLimit':59
|
, 'lowLimit':59
|
||||||
|
, 'macAddress':423
|
||||||
, 'maintenanceRequired':158
|
, 'maintenanceRequired':158
|
||||||
, 'manipulatedVariableReference':60
|
, 'manipulatedVariableReference':60
|
||||||
, 'manualSlaveAddressBinding':170
|
, 'manualSlaveAddressBinding':170
|
||||||
|
@ -1317,6 +1362,9 @@ class PropertyIdentifier(Enumerated):
|
||||||
, 'musterPoint':287
|
, 'musterPoint':287
|
||||||
, 'negativeAccessRules':288
|
, 'negativeAccessRules':288
|
||||||
, 'networkAccessSecurityPolicies':332
|
, 'networkAccessSecurityPolicies':332
|
||||||
|
, 'networkNumber':425
|
||||||
|
, 'networkNumberQuality':427
|
||||||
|
, 'networkType': 427
|
||||||
, 'nodeSubtype':207
|
, 'nodeSubtype':207
|
||||||
, 'nodeType':208
|
, 'nodeType':208
|
||||||
, 'notificationClass':17
|
, 'notificationClass':17
|
||||||
|
@ -1365,6 +1413,7 @@ class PropertyIdentifier(Enumerated):
|
||||||
, 'propertyList':371
|
, 'propertyList':371
|
||||||
, 'proportionalConstant':93
|
, 'proportionalConstant':93
|
||||||
, 'proportionalConstantUnits':94
|
, 'proportionalConstantUnits':94
|
||||||
|
, 'protocolLevel':482
|
||||||
, 'protocolObjectTypesSupported':96
|
, 'protocolObjectTypesSupported':96
|
||||||
, 'protocolRevision':139
|
, 'protocolRevision':139
|
||||||
, 'protocolServicesSupported':97
|
, 'protocolServicesSupported':97
|
||||||
|
@ -1376,6 +1425,7 @@ class PropertyIdentifier(Enumerated):
|
||||||
, 'recipientList':102
|
, 'recipientList':102
|
||||||
, 'recordsSinceNotification':140
|
, 'recordsSinceNotification':140
|
||||||
, 'recordCount':141
|
, 'recordCount':141
|
||||||
|
, 'referencePort':483
|
||||||
, 'reliability':103
|
, 'reliability':103
|
||||||
, 'reliabilityEvaluationInhibit':357
|
, 'reliabilityEvaluationInhibit':357
|
||||||
, 'relinquishDefault':104
|
, 'relinquishDefault':104
|
||||||
|
@ -1565,11 +1615,107 @@ class WriteStatus(Enumerated):
|
||||||
, 'successful':2
|
, 'successful':2
|
||||||
, 'failed':3
|
, 'failed':3
|
||||||
}
|
}
|
||||||
|
class NetworkType(Enumerated):
|
||||||
|
enumerations = \
|
||||||
|
{ 'ethernet':0
|
||||||
|
, 'arcnet':1
|
||||||
|
, 'mstp':2
|
||||||
|
, 'ptp':3
|
||||||
|
, 'lontalk':4
|
||||||
|
, 'ipv4':5
|
||||||
|
, 'zigbee':6
|
||||||
|
, 'virtual': 7
|
||||||
|
# , 'non-bacnet': 8 Removed in Version 1, Revision 18
|
||||||
|
, 'ipv6':9
|
||||||
|
, 'serial':10
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProtocolLevel(Enumerated):
|
||||||
|
enumerations = \
|
||||||
|
{ 'physical':0
|
||||||
|
, 'protocol':1
|
||||||
|
, 'bacnetApplication':2
|
||||||
|
, 'nonBacnetApplication':3
|
||||||
|
}
|
||||||
|
|
||||||
|
class NetworkNumberQuality(Enumerated):
|
||||||
|
enumerations = \
|
||||||
|
{ 'unknown':0
|
||||||
|
, 'learned':1
|
||||||
|
, 'learnedConfigured':2
|
||||||
|
, 'configured':3
|
||||||
|
}
|
||||||
|
|
||||||
|
class NetworkPortCommand(Enumerated):
|
||||||
|
enumerations = \
|
||||||
|
{ 'idle':0
|
||||||
|
, 'discardChanges':1
|
||||||
|
, 'renewFdDRegistration':2
|
||||||
|
, 'restartSlaveDiscovery':3
|
||||||
|
, 'renewDHCP':4
|
||||||
|
, 'restartAutonegotiation':5
|
||||||
|
, 'disconnect':6
|
||||||
|
, 'restartPort':7
|
||||||
|
}
|
||||||
|
|
||||||
|
class IPMode(Enumerated):
|
||||||
|
enumerations = \
|
||||||
|
{ 'normal':0
|
||||||
|
, 'foreign':1
|
||||||
|
, 'bbmd':2
|
||||||
|
}
|
||||||
|
|
||||||
|
class RouterEntryStatus(Enumerated):
|
||||||
|
# This was defined directly in the RouterEntry Sequence in the standard, but I moved it up here because
|
||||||
|
# I didn't see anywhere else you defined something that way.
|
||||||
|
enumerations = \
|
||||||
|
{ 'available':0
|
||||||
|
, 'busy':1
|
||||||
|
, 'disconnected':2
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Forward Sequences
|
# Forward Sequences
|
||||||
#
|
#
|
||||||
|
|
||||||
|
class HostNPort(Sequence):
|
||||||
|
sequenceElements = \
|
||||||
|
[ Element('host', HostAddress)
|
||||||
|
, Element('port', Unsigned16)
|
||||||
|
]
|
||||||
|
|
||||||
|
class BDTEntry(Sequence):
|
||||||
|
sequenceElements = \
|
||||||
|
[ Element('bbmdAddress', HostNPort)
|
||||||
|
, Element('broadcastMask', OctetString) # shall be present if BACnet/IP, and absent for BACnet/IPv6
|
||||||
|
]
|
||||||
|
|
||||||
|
class FDTEntry(Sequence):
|
||||||
|
sequenceElements = \
|
||||||
|
[ Element('bacnetIPAddress', OctetString) # the 6-octet B/IP or 18-octet B/IPv6 address of the registrant
|
||||||
|
, Element('timeToLive', Unsigned16) # time to live in seconds at the time of registration
|
||||||
|
, Element('remainingTimeToLive', Unsigned16) # remaining time to live in seconds, incl. grace period
|
||||||
|
]
|
||||||
|
|
||||||
|
class VMACEntry(Sequence):
|
||||||
|
sequenceElements = \
|
||||||
|
[ Element('virtualMACAddress', OctetString) # maximum size 6 octets
|
||||||
|
, Element('nativeMACAddress', OctetString)
|
||||||
|
]
|
||||||
|
|
||||||
|
class RouterEntry(Sequence):
|
||||||
|
sequenceElements = \
|
||||||
|
[ Element('networkNumber', Unsigned16)
|
||||||
|
, Element('macAddress', OctetString)
|
||||||
|
, Element('status', RouterEntryStatus) # Defined Above
|
||||||
|
]
|
||||||
|
|
||||||
|
class NameValue(Sequence):
|
||||||
|
sequenceElements = \
|
||||||
|
[ Element('name', CharacterString)
|
||||||
|
, Element('value', Atomic) # IS ATOMIC CORRECT HERE? value is limited to primitive datatypes and BACnetDateTime
|
||||||
|
]
|
||||||
|
|
||||||
class DeviceAddress(Sequence):
|
class DeviceAddress(Sequence):
|
||||||
sequenceElements = \
|
sequenceElements = \
|
||||||
[ Element('networkNumber', Unsigned)
|
[ Element('networkNumber', Unsigned)
|
||||||
|
@ -1625,6 +1771,13 @@ class ObjectPropertyReference(Sequence):
|
||||||
, Element('propertyArrayIndex', Unsigned, 2, True)
|
, Element('propertyArrayIndex', Unsigned, 2, True)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class HostAddress(Choice):
|
||||||
|
choiceElements = \
|
||||||
|
[ Element('none', Null)
|
||||||
|
, Element('ipAddress', OctetString) # 4 octets for B/IP or 16 octets for B/IPv6
|
||||||
|
, Element('name', CharacterString) # Internet host name (see RFC 1123)
|
||||||
|
]
|
||||||
|
|
||||||
class ProcessIdSelection(Choice):
|
class ProcessIdSelection(Choice):
|
||||||
choiceElements = \
|
choiceElements = \
|
||||||
[ Element('processIdentifier', Unsigned)
|
[ Element('processIdentifier', Unsigned)
|
||||||
|
@ -1730,7 +1883,8 @@ class AccessRule(Sequence):
|
||||||
]
|
]
|
||||||
|
|
||||||
class AccessThreatLevel(Unsigned):
|
class AccessThreatLevel(Unsigned):
|
||||||
pass
|
_low_limit = 0
|
||||||
|
_high_limit = 100
|
||||||
|
|
||||||
class AccumulatorRecord(Sequence):
|
class AccumulatorRecord(Sequence):
|
||||||
sequenceElements = \
|
sequenceElements = \
|
||||||
|
|
|
@ -598,8 +598,10 @@ class Boolean(Atomic):
|
||||||
class Unsigned(Atomic):
|
class Unsigned(Atomic):
|
||||||
|
|
||||||
_app_tag = Tag.unsignedAppTag
|
_app_tag = Tag.unsignedAppTag
|
||||||
|
_low_limit = 0
|
||||||
|
_high_limit = None
|
||||||
|
|
||||||
def __init__(self,arg = None):
|
def __init__(self, arg=None):
|
||||||
self.value = 0
|
self.value = 0
|
||||||
|
|
||||||
if arg is None:
|
if arg is None:
|
||||||
|
@ -607,10 +609,12 @@ class Unsigned(Atomic):
|
||||||
elif isinstance(arg, Tag):
|
elif isinstance(arg, Tag):
|
||||||
self.decode(arg)
|
self.decode(arg)
|
||||||
elif isinstance(arg, int):
|
elif isinstance(arg, int):
|
||||||
if (arg < 0):
|
if not self.is_valid(arg):
|
||||||
raise ValueError("unsigned integer required")
|
raise ValueError("value out of range")
|
||||||
self.value = arg
|
self.value = arg
|
||||||
elif isinstance(arg, Unsigned):
|
elif isinstance(arg, Unsigned):
|
||||||
|
if not self.is_valid(arg.value):
|
||||||
|
raise ValueError("value out of range")
|
||||||
self.value = arg.value
|
self.value = arg.value
|
||||||
else:
|
else:
|
||||||
raise TypeError("invalid constructor datatype")
|
raise TypeError("invalid constructor datatype")
|
||||||
|
@ -643,10 +647,24 @@ class Unsigned(Atomic):
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_valid(cls, arg):
|
def is_valid(cls, arg):
|
||||||
"""Return True if arg is valid value for the class."""
|
"""Return True if arg is valid value for the class."""
|
||||||
return isinstance(arg, int) and (not isinstance(arg, bool)) and (arg >= 0)
|
if not isinstance(arg, int) or isinstance(arg, bool):
|
||||||
|
return False
|
||||||
|
if (arg < cls._low_limit):
|
||||||
|
return False
|
||||||
|
if (cls._high_limit is not None) and (arg > cls._high_limit):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Unsigned(%s)" % (self.value, )
|
return "%s(%s)" % (self.__class__.__name__, self.value)
|
||||||
|
|
||||||
|
class Unsigned8(Unsigned):
|
||||||
|
_low_limit = 0
|
||||||
|
_high_limit = 255
|
||||||
|
|
||||||
|
class Unsigned16(Unsigned):
|
||||||
|
_low_limit = 0
|
||||||
|
_high_limit = 65535
|
||||||
|
|
||||||
#
|
#
|
||||||
# Integer
|
# Integer
|
||||||
|
|
|
@ -12,7 +12,7 @@ import unittest
|
||||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||||
|
|
||||||
from bacpypes.errors import InvalidTag
|
from bacpypes.errors import InvalidTag
|
||||||
from bacpypes.primitivedata import Unsigned, Tag
|
from bacpypes.primitivedata import Unsigned, Unsigned8, Unsigned16, Tag
|
||||||
|
|
||||||
# some debugging
|
# some debugging
|
||||||
_debug = 0
|
_debug = 0
|
||||||
|
@ -104,6 +104,22 @@ class TestUnsigned(unittest.TestCase):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
Unsigned(-1)
|
Unsigned(-1)
|
||||||
|
|
||||||
|
def test_unsigned8(self):
|
||||||
|
if _debug: TestUnsigned._debug("test_unsigned8")
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
Unsigned8(-1)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
Unsigned8(256)
|
||||||
|
|
||||||
|
def test_unsigned16(self):
|
||||||
|
if _debug: TestUnsigned._debug("test_unsigned16")
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
Unsigned16(-1)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
Unsigned16(65536)
|
||||||
|
|
||||||
def test_unsigned_tag(self):
|
def test_unsigned_tag(self):
|
||||||
if _debug: TestUnsigned._debug("test_unsigned_tag")
|
if _debug: TestUnsigned._debug("test_unsigned_tag")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user