Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ repos:
rev: '7.2.0'
hooks:
- id: flake8
additional_dependencies:
- Flake8-pyproject

- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
Expand Down
24 changes: 16 additions & 8 deletions OMPython/ModelicaSystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,8 @@ def getSimulationOptions(self, names: Optional[str | list[str]] = None) -> dict[

Examples:
>>> mod.getSimulationOptions()
{'startTime': '0', 'stopTime': '1.234', 'stepSize': '0.002', 'tolerance': '1.1e-08', 'solver': 'dassl', 'outputFormat': 'mat'}
{'startTime': '0', 'stopTime': '1.234',
'stepSize': '0.002', 'tolerance': '1.1e-08', 'solver': 'dassl', 'outputFormat': 'mat'}
>>> mod.getSimulationOptions("stopTime")
['1.234']
>>> mod.getSimulationOptions(["tolerance", "stopTime"])
Expand Down Expand Up @@ -1099,8 +1100,10 @@ def simulate(
Examples:
mod.simulate()
mod.simulate(resultfile="a.mat")
mod.simulate(simflags="-noEventEmit -noRestart -override=e=0.3,g=10") # set runtime simulation flags, deprecated
mod.simulate(simargs={"noEventEmit": None, "noRestart": None, "override": "override": {"e": 0.3, "g": 10}}) # using simargs
# set runtime simulation flags, deprecated
mod.simulate(simflags="-noEventEmit -noRestart -override=e=0.3,g=10")
# using simargs
mod.simulate(simargs={"noEventEmit": None, "noRestart": None, "override": "override": {"e": 0.3, "g": 10}})
"""

if resultfile is None:
Expand Down Expand Up @@ -1385,7 +1388,8 @@ def setSimulationOptions(
) -> bool:
"""
This method is used to set simulation options. It can be called:
with a sequence of simulation options name and assigning corresponding values as arguments as show in the example below:
with a sequence of simulation options name and assigning corresponding values as arguments as show in the
example below:
usage
>>> setSimulationOptions("Name=value") # depreciated
>>> setSimulationOptions(["Name1=value1","Name2=value2"]) # depreciated
Expand All @@ -1409,7 +1413,8 @@ def setLinearizationOptions(
) -> bool:
"""
This method is used to set linearization options. It can be called:
with a sequence of linearization options name and assigning corresponding value as arguments as show in the example below
with a sequence of linearization options name and assigning corresponding value as arguments as show in the
example below
usage
>>> setLinearizationOptions("Name=value") # depreciated
>>> setLinearizationOptions(["Name1=value1","Name2=value2"]) # depreciated
Expand All @@ -1433,7 +1438,8 @@ def setOptimizationOptions(
) -> bool:
"""
This method is used to set optimization options. It can be called:
with a sequence of optimization options name and assigning corresponding values as arguments as show in the example below:
with a sequence of optimization options name and assigning corresponding values as arguments as show in the
example below:
usage
>>> setOptimizationOptions("Name=value") # depreciated
>>> setOptimizationOptions(["Name1=value1","Name2=value2"]) # depreciated
Expand Down Expand Up @@ -1573,7 +1579,8 @@ def convertMo2Fmu(self, version: str = "2.0", fmuType: str = "me_cs",
Examples:
>>> mod.convertMo2Fmu()
'/tmp/tmpmhfx9umo/CauerLowPassAnalog.fmu'
>>> mod.convertMo2Fmu(version="2.0", fmuType="me|cs|me_cs", fileNamePrefix="<default>", includeResources=True)
>>> mod.convertMo2Fmu(version="2.0", fmuType="me|cs|me_cs", fileNamePrefix="<default>",
includeResources=True)
'/tmp/tmpmhfx9umo/CauerLowPassAnalog.fmu'
"""

Expand All @@ -1596,7 +1603,8 @@ def convertMo2Fmu(self, version: str = "2.0", fmuType: str = "me_cs",
# to convert FMU to Modelica model
def convertFmu2Mo(self, fmuName): # 20
"""
In order to load FMU, at first it needs to be translated into Modelica model. This method is used to generate Modelica model from the given FMU. It generates "fmuName_me_FMU.mo".
In order to load FMU, at first it needs to be translated into Modelica model. This method is used to generate
Modelica model from the given FMU. It generates "fmuName_me_FMU.mo".
Currently, it only supports Model Exchange conversion.
usage
>>> convertFmu2Mo("c:/BouncingBall.Fmu")
Expand Down
2 changes: 1 addition & 1 deletion OMPython/OMCSession.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
import zmq

# TODO: replace this with the new parser
from OMPython.OMTypedParser import parseString as om_parser_typed
from OMPython.OMTypedParser import om_parser_typed
from OMPython.OMParser import om_parser_basic

# define logger using the current module name as ID
Expand Down
66 changes: 43 additions & 23 deletions OMPython/OMTypedParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
__status__ = "Prototype"
__maintainer__ = "https://openmodelica.org"

from typing import Any

from pyparsing import (
Combine,
Dict,
Expand All @@ -52,45 +54,45 @@
)


def convertNumbers(s, l, toks):
def convert_numbers(s, loc, toks):
n = toks[0]
try:
return int(n)
except ValueError:
return float(n)


def convertString2(s, s2):
def convert_string2(s, s2):
tmp = s2[0].replace("\\\"", "\"")
tmp = tmp.replace("\"", "\\\"")
tmp = tmp.replace("\'", "\\'")
tmp = tmp.replace("\f", "\\f")
tmp = tmp.replace("\n", "\\n")
tmp = tmp.replace("\r", "\\r")
tmp = tmp.replace("\t", "\\t")
return "'"+tmp+"'"
return "'" + tmp + "'"


def convertString(s, s2):
def convert_string(s, s2):
return s2[0].replace("\\\"", '"')


def convertDict(d):
def convert_dict(d):
return dict(d[0])


def convertTuple(t):
def convert_tuple(t):
return tuple(t[0])


def evaluateExpression(s, loc, toks):
def evaluate_expression(s, loc, toks):
# Convert the tokens (ParseResults) into a string expression
flat_list = [item for sublist in toks[0] for item in sublist]
expr = "".join(flat_list)
try:
# Evaluate the expression safely
return eval(expr)
except Exception:
except (SyntaxError, NameError):
return expr


Expand All @@ -102,42 +104,60 @@ def evaluateExpression(s, loc, toks):
(Word("*/", exact=1), 2, opAssoc.LEFT),
(Word("+-", exact=1), 2, opAssoc.LEFT),
],
).setParseAction(evaluateExpression)
).set_parse_action(evaluate_expression)

omcRecord = Forward()
omcValue = Forward()

# pyparsing's replace_with (and thus replaceWith) has incorrect type
# annotation: https://github.com/pyparsing/pyparsing/issues/602
TRUE = Keyword("true").setParseAction(replaceWith(True)) # type: ignore
FALSE = Keyword("false").setParseAction(replaceWith(False)) # type: ignore
NONE = (Keyword("NONE") + Suppress("(") + Suppress(")")).setParseAction(replaceWith(None)) # type: ignore
TRUE = Keyword("true").set_parse_action(replaceWith(True)) # type: ignore
FALSE = Keyword("false").set_parse_action(replaceWith(False)) # type: ignore
NONE = (Keyword("NONE") + Suppress("(") + Suppress(")")).set_parse_action(replaceWith(None)) # type: ignore
SOME = (Suppress(Keyword("SOME")) + Suppress("(") + omcValue + Suppress(")"))

omcString = QuotedString(quoteChar='"', escChar='\\', multiline=True).setParseAction(convertString)
omcString = QuotedString(quoteChar='"', escChar='\\', multiline=True).set_parse_action(convert_string)
omcNumber = Combine(Optional('-') + ('0' | Word('123456789', nums)) +
Optional('.' + Word(nums)) +
Optional(Word('eE', exact=1) + Word(nums + '+-', nums)))

# ident = Word(alphas + "_", alphanums + "_") | Combine("'" + Word(alphanums + "!#$%&()*+,-./:;<>=?@[]^{}|~ ") + "'")
ident = Word(alphas + "_", alphanums + "_") | QuotedString(quoteChar='\'', escChar='\\').setParseAction(convertString2)
ident = (Word(alphas + "_", alphanums + "_")
| QuotedString(quoteChar='\'', escChar='\\').set_parse_action(convert_string2))
fqident = Forward()
fqident << ((ident + "." + fqident) | ident)
omcValues = delimitedList(omcValue)
omcTuple = Group(Suppress('(') + Optional(omcValues) + Suppress(')')).setParseAction(convertTuple)
omcArray = Group(Suppress('{') + Optional(omcValues) + Suppress('}')).setParseAction(convertTuple)
omcArraySpecialTypes = Group(Suppress('{') + delimitedList(arrayDimension) + Suppress('}')).setParseAction(convertTuple)
omcValue << (omcString | omcNumber | omcRecord | omcArray | omcArraySpecialTypes | omcTuple | SOME | TRUE | FALSE | NONE | Combine(fqident))
omcTuple = Group(Suppress('(') + Optional(omcValues) + Suppress(')')).set_parse_action(convert_tuple)
omcArray = Group(Suppress('{') + Optional(omcValues) + Suppress('}')).set_parse_action(convert_tuple)
omcArraySpecialTypes = Group(Suppress('{')
+ delimitedList(arrayDimension)
+ Suppress('}')).set_parse_action(convert_tuple)
omcValue << (omcString
| omcNumber
| omcRecord
| omcArray
| omcArraySpecialTypes
| omcTuple
| SOME
| TRUE
| FALSE
| NONE
| Combine(fqident))
recordMember = delimitedList(Group(ident + Suppress('=') + omcValue))
omcRecord << Group(Suppress('record') + Suppress(fqident) + Dict(recordMember) + Suppress('end') + Suppress(fqident) + Suppress(';')).setParseAction(convertDict)
omcRecord << Group(Suppress('record')
+ Suppress(fqident)
+ Dict(recordMember)
+ Suppress('end')
+ Suppress(fqident)
+ Suppress(';')).set_parse_action(convert_dict)

omcGrammar = Optional(omcValue) + StringEnd()

omcNumber.setParseAction(convertNumbers)
omcNumber.set_parse_action(convert_numbers)


def parseString(string):
res = omcGrammar.parseString(string)
def om_parser_typed(string) -> Any:
res = omcGrammar.parse_string(string)
if len(res) == 0:
return
return None
return res[0]
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,8 @@ Documentation = "https://openmodelica.org/doc/OpenModelicaUsersGuide/latest/ompy
Issues = "https://github.com/OpenModelica/OMPython/issues"
"Release Notes" = "https://github.com/OpenModelica/OMPython/releases"
Download = "https://pypi.org/project/OMPython/#files"

[tool.flake8]
max-line-length = 120
extend-ignore = [
]
2 changes: 0 additions & 2 deletions setup.cfg

This file was deleted.

6 changes: 3 additions & 3 deletions tests/test_linearization.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ def test_getters(tmp_path):

mod.setInputs(u1=10, u2=0)
[A, B, C, D] = mod.linearize()
g = float(mod.getParameters("g")[0])
l = float(mod.getParameters("l")[0])
param_g = float(mod.getParameters("g")[0])
param_l = float(mod.getParameters("l")[0])
assert mod.getLinearInputs() == ["u1", "u2"]
assert mod.getLinearStates() == ["omega", "phi"]
assert mod.getLinearOutputs() == ["y1", "y2"]
assert np.isclose(A, [[0, g/l], [1, 0]]).all()
assert np.isclose(A, [[0, param_g / param_l], [1, 0]]).all()
assert np.isclose(B, [[0, 0], [0, 1]]).all()
assert np.isclose(C, [[0.5, 1], [0, 1]]).all()
assert np.isclose(D, [[1, 0], [1, 0]]).all()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_typedParser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from OMPython import OMTypedParser

typeCheck = OMTypedParser.parseString
typeCheck = OMTypedParser.om_parser_typed


def test_newline_behaviour():
Expand Down