import sunspec2.smdx as smdx
import sunspec2.mdef as mdef
import xml.etree.ElementTree as ET
import pytest
import copy
def test_to_smdx_filename():
assert smdx.to_smdx_filename(77) == 'smdx_00077.xml'
def test_model_filename_to_id():
assert smdx.model_filename_to_id('smdx_00077.xml') == 77
with pytest.raises(Exception) as exc:
smdx.model_filename_to_id('smdx_abc.xml')
assert 'Error extracting model id from filename' in str(exc.value)
def test_from_smdx_file():
smdx_304 = {'id': 304, 'group': {'name': 'inclinometer', 'type': 'group', 'points': [
{'name': 'ID', 'value': 304, 'desc': 'Model identifier', 'label': 'Model ID', 'size': 1, 'mandatory': 'M',
'static': 'S', 'type': 'uint16'},
{'name': 'L', 'desc': 'Model length', 'label': 'Model Length', 'size': 1, 'mandatory': 'M', 'static': 'S',
'type': 'uint16'}], 'groups': [{'name': 'incl', 'type': 'group', 'count': 0, 'points': [
{'name': 'Inclx', 'type': 'int32', 'size': 2, 'mandatory': 'M', 'units': 'Degrees', 'sf': -2, 'label': 'X',
'desc': 'X-Axis inclination'},
{'name': 'Incly', 'type': 'int32', 'size': 2, 'units': 'Degrees', 'sf': -2, 'label': 'Y',
'desc': 'Y-Axis inclination'},
{'name': 'Inclz', 'type': 'int32', 'size': 2, 'units': 'Degrees', 'sf': -2, 'label': 'Z',
'desc': 'Z-Axis inclination'}]}], 'label': 'Inclinometer Model',
'desc': 'Include to support orientation measurements'}}
assert smdx.from_smdx_file('./sunspec2/models/smdx/smdx_00304.xml') == smdx_304
def test_from_smdx_file_symbols():
mdef = smdx.from_smdx_file('sunspec2/models/smdx/smdx_00803.xml')
for point_def in mdef["group"]["groups"][0]["points"]:
if point_def["name"] != "StrSt":
continue
symbol = point_def["symbols"][1]
assert symbol["name"] == "CONTACTOR_STATUS"
assert symbol["label"] == "Contactor Status"
assert symbol["desc"].startswith("String")
assert symbol["detail"]
break
else:
pytest.fail("Point not found")
def test_from_smdx():
tree = ET.parse('./sunspec2/models/smdx/smdx_00304.xml')
root = tree.getroot()
mdef_not_found = copy.deepcopy(root)
mdef_not_found.remove(mdef_not_found.find('model'))
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx(mdef_not_found)
duplicate_fixed_btype_str = '''
'''
duplicate_fixed_btype_xml = ET.fromstring(duplicate_fixed_btype_str)
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx(duplicate_fixed_btype_xml)
dup_repeating_btype_str = '''
'''
dup_repeating_btype_xml = ET.fromstring(dup_repeating_btype_str)
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx(dup_repeating_btype_xml)
invalid_btype_root = copy.deepcopy(root)
invalid_btype_root.find('model').find('block').set('type', 'abc')
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx(invalid_btype_root)
dup_fixed_p_def_str = '''
'''
dup_fixed_p_def_xml = ET.fromstring(dup_fixed_p_def_str)
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx(dup_fixed_p_def_xml)
dup_repeating_p_def_str = '''
'''
dup_repeating_p_def_xml = ET.fromstring(dup_repeating_p_def_str)
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx(dup_repeating_p_def_xml)
def test_from_smdx_point():
smdx_point_str = """"""
smdx_point_xml = ET.fromstring(smdx_point_str)
assert smdx.from_smdx_point(smdx_point_xml) == {'name': 'Mn', 'type': 'string', 'size': 16, 'mandatory': 'M'}
missing_pid_xml = copy.deepcopy(smdx_point_xml)
del missing_pid_xml.attrib['id']
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx_point(missing_pid_xml)
missing_ptype = copy.deepcopy(smdx_point_xml)
del missing_ptype.attrib['type']
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx_point(missing_ptype)
unk_ptype = copy.deepcopy(smdx_point_xml)
unk_ptype.attrib['type'] = 'abc'
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx_point(unk_ptype)
missing_len = copy.deepcopy(smdx_point_xml)
del missing_len.attrib['len']
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx_point(missing_len)
unk_mand_type = copy.deepcopy(smdx_point_xml)
unk_mand_type.attrib['mandatory'] = 'abc'
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx_point(unk_mand_type)
unk_access_type = copy.deepcopy(smdx_point_xml)
unk_access_type.attrib['access'] = 'abc'
with pytest.raises(mdef.ModelDefinitionError):
smdx.from_smdx_point(unk_access_type)
def test_indent():
pass