Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -877,7 +877,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 @@ -1061,8 +1062,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 @@ -1376,7 +1379,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 @@ -1400,7 +1404,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 @@ -1424,7 +1429,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 @@ -1564,7 +1570,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 @@ -1587,7 +1594,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 @@ -57,7 +57,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