2121"""
2222
2323import re
24+ import fnmatch
25+ import ast
26+ from typing import Iterable , List , Union
2427import sys
2528import os
2629import pandas as pd
@@ -1303,12 +1306,15 @@ def init(self):
13031306 pass
13041307 object .__setattr__ (self , "mapping" , {})
13051308 object .__setattr__ (self , "_len_slices" , None )
1309+ object .__setattr__ (self , "banks" , {})
13061310 self .register = self .__dict__ .copy () # create attribute register with all registernames
13071311 for reg in self .__dict__ :
13081312 if reg != "register" and not hasattr (self .register [reg ], "_Register__has_reset" ):
13091313 self .register .pop (reg , None )
13101314 elif reg != "register" :
13111315 bank = self .register [reg ]._bank
1316+ if bank is not None and (bank not in self .banks or self .banks [bank ] < self .register [reg ].addr ):
1317+ self .banks [bank ] = self .register [reg ].addr
13121318 if bank is not None and bank != "" :
13131319 self .mapping [bank ] = self .register [reg ]._len_slices ()
13141320 self .mqtt_list = list (self .register ) + self .mqtt_all
@@ -1340,6 +1346,11 @@ def _mqtt2json(self, value, attr=None):
13401346 return value
13411347 return "nomqtt"
13421348
1349+ def _register_to_list (patterns : Union [str , Iterable [str ]]) -> List [str ]:
1350+ if isinstance (patterns , str ):
1351+ return [patterns ]
1352+ return list (patterns )
1353+
13431354 def close (self ):
13441355 pass
13451356
@@ -1383,19 +1394,68 @@ def set_bank(self, adr):
13831394 -------
13841395 adr.
13851396 """
1397+ if self .banks :
1398+ for bank in self .banks .keys ():
1399+ if adr <= self .banks [bank ]:
1400+ self ._bank = bank
1401+ break
13861402 if self .mapping != {}:
13871403 mybank = 0
13881404 for bank in self .mapping :
13891405 mybank = bank if adr >= bank else mybank
1390- self ._bank = mybank
1406+ # self._bank = mybank
13911407 self ._len_slices = self .mapping [mybank ]
1392- adr = adr - mybank
1408+ # adr = adr - mybank # TODO: cj 7.2.2026 das ist doch falsch, überprüfen mit HATC!!!!
13931409 else :
13941410 self ._bank = None
13951411 self ._len_slices = None
13961412 return adr
13971413
1414+ def _call_from_string (self , adr , callstr ):
1415+ regs = self ._register_to_list ()
1416+ call = ast .parse (callstr , mode = 'eval' ).body
1417+ args = [ast .literal_eval (a ) for a in call .args ]
1418+ kwargs = {kw .arg :ast .literal_eval (kw .value ) for kw in call .keywords }
1419+ index = 0
1420+ dat = args [0 ]
1421+ result = 0 if type (dat ) == list else []
1422+ for reg in regs :
1423+ if fnmatch .fnmatchcase (reg ._name , adr ):
1424+ function = getattr (getattr (self , reg ._name ), call .func .id )
1425+ if type (dat ) == list :
1426+ args [0 ] = dat [index ]
1427+ resu = function (* args , ** kwargs )
1428+ if type (dat ) == list :
1429+ result += resu
1430+ else :
1431+ result .append (resu )
1432+ index += 1
1433+ return result
1434+
13981435 def readreg (self , adr , bank = None , compare = None , onlycheck = True , tolerance = 0 , mask = None ):
1436+ if type (adr ) is str :
1437+ if len (adr ) == 0 :
1438+ mylogger .log_message (LogLevel .Error (), 'readreg: adr is empty' )
1439+ return
1440+ elif adr [0 ].isdigit ():
1441+ adr = list (common .arange (adr ))
1442+ else :
1443+ return self ._call_from_string (adr , f"read({ compare } , { onlycheck } , { tolerance } , { mask } )" )
1444+ if type (adr ) is list :
1445+ result = [] if compare is None else 0
1446+ index = 0
1447+ for a in adr :
1448+ comp = compare [index ] if type (compare ) is list else compare
1449+ resu = self ._readreg (a , bank , comp , onlycheck , tolerance , mask )
1450+ if compare is None :
1451+ result .append (resu )
1452+ else :
1453+ result += resu
1454+ index += 1
1455+ return result
1456+ return self ._readreg (adr , bank , compare , onlycheck , tolerance , mask )
1457+
1458+ def _readreg (self , adr , bank = None , compare = None , onlycheck = True , tolerance = 0 , mask = None ):
13991459 """
14001460 Read Register with selected protokoll.
14011461
@@ -1417,13 +1477,16 @@ def readreg(self, adr, bank=None, compare=None, onlycheck=True, tolerance=0, mas
14171477 0 = ok
14181478 1 = error
14191479 """
1480+ hadr = adr
14201481 if bank is not None :
14211482 self ._bank = bank
14221483 else :
14231484 adr = self .set_bank (adr )
14241485 if self ._bank is not None and self ._bank != "" :
14251486 self ._protocol .writebase (self ._bank )
14261487 value = self ._protocol .readreg (adr , compare = compare , tolerance = tolerance , mask = mask )
1488+ mylogger .log_message (LogLevel .Measure (), f"readreg(0x{ hadr :02x} ) == { hex (value )} " )
1489+ self .publish_set (f"readreg({ hadr } :02x)" , value )
14271490 if self ._len_slices is not None :
14281491 value &= 2 ** self ._len_slices - 1
14291492 if compare is not None :
@@ -1439,6 +1502,24 @@ def readreg(self, adr, bank=None, compare=None, onlycheck=True, tolerance=0, mas
14391502 return value
14401503
14411504 def writereg (self , adr , dat , bank = None ):
1505+ if type (adr ) is str :
1506+ if len (adr ) == 0 :
1507+ mylogger .log_message (LogLevel .Error (), 'writereg: adr is empty' )
1508+ return
1509+ elif adr [0 ].isdigit ():
1510+ adr = list (common .arange (adr ))
1511+ else :
1512+ return self ._call_from_string (adr , f"write({ dat } )" )
1513+ if type (adr ) is list :
1514+ index = 0
1515+ for a in adr :
1516+ d = dat [index ] if type (dat ) is list else dat
1517+ self ._writereg (a , d , bank )
1518+ index += 1
1519+ return
1520+ self ._writereg (adr , dat , bank )
1521+
1522+ def _writereg (self , adr , dat , bank = None ):
14421523 """
14431524 Write Register with selected protokoll.
14441525
@@ -1456,13 +1537,17 @@ def writereg(self, adr, dat, bank=None):
14561537 None.
14571538
14581539 """
1540+ hadr = adr
14591541 if bank is not None :
14601542 self ._bank = bank
14611543 else :
14621544 adr = self .set_bank (adr )
14631545 if self ._bank is not None and self ._bank != "" :
14641546 self ._protocol .writebase (self ._bank )
14651547 self ._protocol .writereg (adr , dat )
1548+ msg = f"writereg(0x{ hadr :02x} ) := { hex (dat )} "
1549+ mylogger .log_message (LogLevel .Measure (), msg )
1550+ self .publish_set (f"writereg({ hadr } )" , dat )
14661551
14671552 def reset (self ):
14681553 self ._protocol .reset ()
0 commit comments