Пример #1
0
class Conf:
    def __init__(self, vrm):
        self.verrel = vrm

        #Set default variables
        self.verbose = False
        self.trace = False
        self.cfgfile = "grott.ini"
        self.minrecl = 100
        self.decrypt = True
        self.compat = False
        self.blockcmd = False  #Block Inverter and Shine configure commands
        self.noipf = False  #Allow IP change if needed
        self.gtime = "auto"  #time used =  auto: use record time or if not valid server time, alternative server: use always server time
        self.sendbuf = True  # enable / disable sending historical data from buffer
        self.valueoffset = 6
        self.inverterid = "automatic"
        self.mode = "proxy"
        self.grottport = 5279
        self.grottip = "default"  #connect to server IP adress
        self.outfile = "sys.stdout"
        self.tmzone = "local"  #set timezone (at this moment only used for influxdb)

        #Growatt server default
        self.growattip = "47.91.67.66"
        self.growattport = 5279

        #MQTT default
        self.mqttip = "localhost"
        self.mqttport = 1883
        self.mqtttopic = "energy/growatt"
        self.nomqtt = False  #not in ini file, can only be changed via start parms
        self.mqttauth = False
        self.mqttuser = "******"
        self.mqttpsw = "growatt2020"

        #pvoutput default
        self.pvoutput = False
        self.pvinverters = 1
        self.pvurl = "https://pvoutput.org/service/r2/addstatus.jsp"
        self.pvapikey = "yourapikey"
        self.pvsystemid = {}
        self.pvinverterid = {}
        self.pvsystemid[1] = "systemid1"
        self.pvinverterid[1] = "inverter1"

        #influxdb default
        self.influx = False
        self.influx2 = False
        self.ifdbname = "grottdb"
        self.ifip = "localhost"
        self.ifport = 8086
        self.ifuser = "******"
        self.ifpsw = "growatt2020"
        self.iftoken = "influx_token"
        self.iforg = "grottorg"
        self.ifbucket = "grottdb"

        #extension
        self.extension = False
        self.extname = "grottext"
        #self.extvar = {"ip": "localhost", "port":8000}
        self.extvar = {"none": "none"}

        print("Grott Growatt logging monitor : " + self.verrel)

        #Set parm's
        #prio: 1.Command line parms, 2.env. variables, 3.config file 4.program default
        #process command settings that set processing values (verbose, trace, output, config, nomqtt)
        self.parserinit()

        #Process config file
        self.procconf()

        #Process environmental variable
        self.procenv()

        #Process environmental variable to override config and environmental settings
        self.parserset()

        #Prepare invert settings
        self.SN = "".join(['{:02x}'.format(ord(x)) for x in self.inverterid])
        self.offset = 6
        if self.compat:
            self.offset = int(
                self.valueoffset
            )  #set offset for older inverter types or after record change by Growatt

        #prepare MQTT security
        if not self.mqttauth: self.pubauth = None
        else:
            self.pubauth = dict(username=self.mqttuser, password=self.mqttpsw)

        #define recordlayouts
        self.set_reclayouts()

        #define record whitlist (if blocking / filtering enabled
        self.set_recwl()

        #prepare influxDB
        if self.influx:
            if self.ifip == "localhost": self.ifip = '0.0.0.0'
            if self.influx2 == False:
                if self.verbose: print("")
                if self.verbose:
                    print("\t - " + "Grott InfluxDB V1 initiating started")
                try:
                    from influxdb import InfluxDBClient
                except:
                    if self.verbose:
                        print("\t - " +
                              "Grott Influxdb Library not installed in Python")
                    self.influx = False  # no influx processing any more till restart (and errors repared)
                    raise SystemExit("Grott Influxdb initialisation error")

                self.influxclient = InfluxDBClient(host=self.ifip,
                                                   port=self.ifport,
                                                   timeout=3,
                                                   username=self.ifuser,
                                                   password=self.ifpsw)

                try:
                    databases = [
                        db['name']
                        for db in self.influxclient.get_list_database()
                    ]
                except Exception as e:
                    if self.verbose:
                        print("\t - " + "Grott can not contact InfluxDB")
                    self.influx = False  # no influx processing any more till restart (and errors repared)
                    print("\t -", e)
                    raise SystemExit("Grott Influxdb initialisation error")

                #print(databases)
                if self.ifdbname not in databases:
                    if self.verbose:
                        print(
                            "\t - " +
                            "Grott grottdb not yet defined in influx, will  be created"
                        )
                    try:
                        self.influxclient.create_database(self.ifdbname)
                    except:
                        if self.verbose:
                            print(
                                "\t - " +
                                "Grott Unable to create or connect to influx database:",
                                self.ifdbname, " check user authorisation")
                        self.influx = False  # no influx processing any more till restart (and errors repared)
                        raise SystemExit("Grott Influxdb initialisation error")

                self.influxclient.switch_database(self.ifdbname)
            else:

                if self.verbose: print("")
                if self.verbose:
                    print("\t - " + "Grott InfluxDB V2 initiating started")
                try:
                    from influxdb_client import InfluxDBClient
                    from influxdb_client.client.write_api import SYNCHRONOUS
                except:
                    if self.verbose:
                        print(
                            "\t - " +
                            "Grott Influxdb-client Library not installed in Python"
                        )
                    self.influx = False  # no influx processing any more till restart (and errors repared)
                    raise SystemExit("Grott Influxdb initialisation error")

                #self.influxclient = InfluxDBClient(url='192.168.0.211:8086',org=self.iforg, token=self.iftoken)
                self.influxclient = InfluxDBClient(url=self.ifip + ":" +
                                                   self.ifport,
                                                   org=self.iforg,
                                                   token=self.iftoken)
                self.ifbucket_api = self.influxclient.buckets_api()
                self.iforganization_api = self.influxclient.organizations_api()
                self.ifwrite_api = self.influxclient.write_api(
                    write_options=SYNCHRONOUS)

                try:
                    buckets = self.ifbucket_api.find_bucket_by_name(
                        self.ifbucket)
                    organizations = self.iforganization_api.find_organizations(
                    )
                    #print(organizations)
                    if buckets == None:
                        print("\t - " + "influxDB bucket ", self.ifbucket,
                              "not defined")
                        self.influx = False
                        raise SystemExit("Grott Influxdb initialisation error")
                    orgfound = False
                    for org in organizations:
                        if org.name == self.iforg:
                            orgfound = True
                            break
                    if not orgfound:
                        print("\t - " + "influxDB organization", self.iforg,
                              "not defined or not authorisation to check")
                        ##self.influx = False
                        ##raise SystemExit("Grott Influxdb initialisation error")

                except Exception as e:
                    if self.verbose:
                        print("\t - " +
                              "Grott error: can not contact InfluxDB")
                    print(e)
                    self.influx = False  # no influx processing any more till restart (and errors repared)
                    raise SystemExit("Grott Influxdb initialisation error")

    def print(self):
        print("\nGrott settings:\n")
        print("_Generic:")
        print("\tversion:     \t", self.verrel)
        print("\tverbose:     \t", self.verbose)
        print("\ttrace:       \t", self.trace)
        print("\tconfig file: \t", self.cfgfile)
        print("\tminrecl:     \t", self.minrecl)
        print("\tdecrypt:     \t", self.decrypt)
        print("\tcompat:      \t", self.compat)
        print("\tblockcmd:    \t", self.blockcmd)
        print("\tnoipf:       \t", self.noipf)
        print("\ttime:        \t", self.gtime)
        print("\tsendbuf:     \t", self.sendbuf)
        print("\ttimezone:    \t", self.tmzone)
        print("\tvalueoffset: \t", self.valueoffset)
        print("\toffset:      \t", self.offset)
        print("\tinverterid:  \t", self.inverterid)
        print("\tmode:        \t", self.mode)
        print("\tgrottip      \t", self.grottip)
        print("\tgrottport    \t", self.grottport)
        #print("\tSN           \t",self.SN)
        print("_MQTT:")
        print("\tnomqtt       \t", self.nomqtt)
        print("\tmqttip:      \t", self.mqttip)
        print("\tmqttport:    \t", self.mqttport)
        print("\tmqtttopic:   \t", self.mqtttopic)
        print("\tmqtttauth:   \t", self.mqttauth)
        print("\tmqttuser:    \t", self.mqttuser)
        print("\tmqttpsw:     \t", "**secret**")  #scramble output if tested!
        #print("\tmqttpsw:     \t",self.mqttpsw)                       #scramble output if tested!
        print("_Growatt server:")
        print("\tgrowattip:   \t", self.growattip)
        print("\tgrowattport: \t", self.growattport)
        print("_PVOutput:")
        print("\tpvoutput:    \t", self.pvoutput)
        print("\tpvurl:       \t", self.pvurl)
        print("\tpvapikey:    \t", self.pvapikey)
        print("\tpvinverters: \t", self.pvinverters)
        if self.pvinverters == 1:
            print("\tpvsystemid:  \t", self.pvsystemid[1])
        else:
            print("\tpvsystemid:  \t", self.pvsystemid)
            print("\tpvinvertid:  \t", self.pvinverterid)
        print("_Influxdb:")
        print("\tinflux:      \t", self.influx)
        print("\tinflux2:     \t", self.influx2)
        print("\tdatabase:    \t", self.ifdbname)
        print("\tip:          \t", self.ifip)
        print("\tport:        \t", self.ifport)
        print("\tuser:        \t", self.ifuser)
        print("\tpassword:    \t", "**secret**")
        #print("\tpassword:    \t",self.ifpsw)
        print("\torganization:\t", self.iforg)
        print("\tbucket:      \t", self.ifbucket)
        print("\ttoken:       \t", "**secret**")
        #print("\ttoken:       \t",self.iftoken)

        print("_Extension:")
        print("\textension:   \t", self.extension)
        print("\textname:     \t", self.extname)
        print("\textvar:      \t", self.extvar)

        print()

    def parserinit(self):
        #Process commandline parameters init (read args, process c,v,o settings)
        parser = argparse.ArgumentParser(prog='grott')
        parser.add_argument('-v',
                            '--verbose',
                            help="set verbose",
                            action='store_true')
        parser.add_argument('--version', action='version', version=self.verrel)
        parser.add_argument(
            '-c',
            help="set config file if not specified config file is grott.ini",
            metavar="[config file]")
        parser.add_argument(
            '-o',
            help="set output file, if not specified output is stdout",
            metavar="[output file]")
        parser.add_argument(
            '-m',
            help="set mode (sniff or proxy), if not specified mode is sniff",
            metavar="[mode]")
        parser.add_argument(
            '-i',
            help=
            "set inverterid, if not specified inverterid of .ini file is used",
            metavar="[inverterid]")
        parser.add_argument('-nm',
                            '--nomqtt',
                            help="disable mqtt send",
                            action='store_true')
        parser.add_argument(
            '-t',
            '--trace',
            help=
            "enable trace, use in addition to verbose option (only available in sniff mode)",
            action='store_true')
        parser.add_argument('-p',
                            '--pvoutput',
                            help="enable pvoutput send (True/False)",
                            action='store_true')
        parser.add_argument('-b',
                            '--blockcmd',
                            help="block Growatt configure commands",
                            action='store_true')
        parser.add_argument('-n',
                            '--noipf',
                            help="Allow IP change from growatt website",
                            action='store_true')

        args, unknown = parser.parse_known_args()

        if (args.c != None): self.cfgfile = args.c
        #if (args.o != None) : sys.stdout = open(args.o, 'wb',0) changed to support unbuffered output in windows !!!
        if (args.o != None):
            sys.stdout = io.TextIOWrapper(open(args.o, 'wb', 0),
                                          write_through=True)
        self.verbose = args.verbose
        self.anomqtt = args.nomqtt
        self.apvoutput = args.pvoutput
        self.trace = args.trace
        self.ablockcmd = args.blockcmd
        self.anoipf = args.noipf

        if (args.m != None):
            #print("mode: ",args.m)
            if (args.m == "proxy"):
                self.amode = "proxy"
            else:
                self.amode = "sniff"  # default
        if (args.i != None
                and args.i != "none"):  # added none for docker support
            self.ainverterid = args.i

        if self.verbose:
            print("\nGrott Command line parameters processed:")
            print("\tverbose:     \t", self.verbose)
            print("\tconfig file: \t", self.cfgfile)
            print("\toutput file: \t", sys.stdout)
            print("\tnomqtt:      \t", self.anomqtt)
            print("\tinverterid:  \t", self.inverterid)
            print("\tpvoutput:    \t", self.apvoutput)
            print("\tblockcmd:    \t", self.ablockcmd)
            print("\tnoipf:       \t", self.noipf)

    def parserset(self):
        print("\nGrott override settings if set in commandline")
        if hasattr(self, "amode"):
            self.mode = self.amode
        if hasattr(self, "ablockcmd") and self.ablockcmd == True:
            self.blockcmd = self.ablockcmd
        if hasattr(self, "anoipf") and self.anoipf == True:
            self.noipf = self.anoipf
        if hasattr(self, "ainverterid"):
            self.inverterid = self.ainverterid
        if hasattr(self, "anomqtt") and self.anomqtt:
            self.nomqtt = self.anomqtt
        if hasattr(self, "apvoutput") and self.apvoutput:
            self.pvoutput = self.apvoutput
        #Correct Bool if changed to string during parsing process
        # if self.verbose == True or self.verbose == "True" : self.verbose = True
        # else : self.verbose = False
        self.verbose = str2bool(self.verbose)
        self.trace = str2bool(self.trace)
        self.decrypt = str2bool(self.decrypt)
        self.compat = str2bool(self.compat)
        self.blockcmd = str2bool(self.blockcmd)
        self.noipf = str2bool(self.noipf)
        self.sendbuf = str2bool(self.sendbuf)
        self.pvoutput = str2bool(self.pvoutput)
        self.nomqtt = str2bool(self.nomqtt)
        self.mqttauth = str2bool(self.mqttauth)
        self.influx = str2bool(self.influx)
        self.influx2 = str2bool(self.influx2)
        self.extension = str2bool(self.extension)

    def procconf(self):
        print("\nGrott process configuration file")
        config = configparser.ConfigParser()
        config.read(self.cfgfile)
        if config.has_option("Generic", "minrecl"):
            self.minrecl = config.getint("Generic", "minrecl")
        if config.has_option("Generic", "verbose"):
            self.verbose = config.getboolean("Generic", "verbose")
        if config.has_option("Generic", "decrypt"):
            self.decrypt = config.getboolean("Generic", "decrypt")
        if config.has_option("Generic", "compat"):
            self.compat = config.getboolean("Generic", "compat")
        if config.has_option("Generic", "inverterid"):
            self.inverterid = config.get("Generic", "inverterid")
        if config.has_option("Generic", "blockcmd"):
            self.blockcmd = config.get("Generic", "blockcmd")
        if config.has_option("Generic", "noipf"):
            self.noipf = config.get("Generic", "noipf")
        if config.has_option("Generic", "time"):
            self.gtime = config.get("Generic", "time")
        if config.has_option("Generic", "sendbuf"):
            self.sendbuf = config.get("Generic", "sendbuf")
        if config.has_option("Generic", "timezone"):
            self.tmzone = config.get("Generic", "timezone")
        if config.has_option("Generic", "mode"):
            self.mode = config.get("Generic", "mode")
        if config.has_option("Generic", "ip"):
            self.grottip = config.get("Generic", "ip")
        if config.has_option("Generic", "port"):
            self.grottport = config.getint("Generic", "port")
        if config.has_option("Generic", "valueoffset"):
            self.valueoffset = config.get("Generic", "valueoffset")
        if config.has_option("Growatt", "ip"):
            self.growattip = config.get("Growatt", "ip")
        if config.has_option("Growatt", "port"):
            self.growattport = config.getint("Growatt", "port")
        if config.has_option("MQTT", "nomqtt"):
            self.nomqtt = config.get("MQTT", "nomqtt")
        if config.has_option("MQTT", "ip"):
            self.mqttip = config.get("MQTT", "ip")
        if config.has_option("MQTT", "port"):
            self.mqttport = config.getint("MQTT", "port")
        if config.has_option("MQTT", "topic"):
            self.mqtttopic = config.get("MQTT", "topic")
        if config.has_option("MQTT", "auth"):
            self.mqttauth = config.getboolean("MQTT", "auth")
        if config.has_option("MQTT", "user"):
            self.mqttuser = config.get("MQTT", "user")
        if config.has_option("MQTT", "password"):
            self.mqttpsw = config.get("MQTT", "password")
        if config.has_option("PVOutput", "pvoutput"):
            self.pvoutput = config.get("PVOutput", "pvoutput")
        if config.has_option("PVOutput", "pvinverters"):
            self.pvinverters = config.getint("PVOutput", "pvinverters")
        if config.has_option("PVOutput", "apikey"):
            self.pvapikey = config.get("PVOutput", "apikey")
        # if more inverter are installed at the same interface (shinelink) get systemids
        #if self.pvinverters > 1 :
        for x in range(self.pvinverters + 1):
            if config.has_option("PVOutput", "systemid" + str(x)):
                self.pvsystemid[x] = config.get("PVOutput",
                                                "systemid" + str(x))
            if config.has_option("PVOutput", "inverterid" + str(x)):
                self.pvinverterid[x] = config.get("PVOutput",
                                                  "inverterid" + str(x))
        if self.pvinverters == 1:
            if config.has_option("PVOutput", "systemid"):
                self.pvsystemid[1] = config.get("PVOutput", "systemid")
        #INFLUX
        if config.has_option("influx", "influx"):
            self.influx = config.get("influx", "influx")
        if config.has_option("influx", "influx2"):
            self.influx2 = config.get("influx", "influx2")
        if config.has_option("influx", "dbname"):
            self.ifdbname = config.get("influx", "dbname")
        if config.has_option("influx", "ip"):
            self.ifip = config.get("influx", "ip")
        if config.has_option("influx", "port"):
            self.ifport = config.get("influx", "port")
        if config.has_option("influx", "user"):
            self.ifuser = config.get("influx", "user")
        if config.has_option("influx", "password"):
            self.ifpsw = config.get("influx", "password")
        if config.has_option("influx", "org"):
            self.iforg = config.get("influx", "org")
        if config.has_option("influx", "bucket"):
            self.ifbucket = config.get("influx", "bucket")
        if config.has_option("influx", "token"):
            self.iftoken = config.get("influx", "token")
        #extensionINFLUX
        if config.has_option("extension", "extension"):
            self.extension = config.get("extension", "extension")
        if config.has_option("extension", "extname"):
            self.extname = config.get("extension", "extname")
        if config.has_option("extension", "extvar"):
            self.extvar = eval(config.get("extension", "extvar"))

    def procenv(self):
        print("\nGrott process environmental variables")
        if os.getenv('gmode') in ("sniff", "proxy"):
            self.mode = os.getenv('gmode')
        if os.getenv('gverbose') != None: self.verbose = os.getenv('verbose')
        if os.getenv('gminrecl') != None:
            if 0 <= int(os.getenv('gminrecl')) <= 255:
                self.minrecl = os.getenv('gminrecl')
        if os.getenv('gdecrypt') != None: self.decrypt = os.getenv('gdecrypt')
        if os.getenv('gcompat') != None: self.compat = os.getenv('gcompat')
        if os.getenv('gblockcmd') != None:
            self.blockcmd = os.getenv('gblockcmd')
        if os.getenv('gnoipf') != None: self.noipf = os.getenv('gnoipf')
        if os.getenv('gtime') in ("auto", "server"):
            self.gtime = os.getenv('gtime')
        if os.getenv('gtimezone') != None: self.tmzone = os.getenv('gtimezone')
        if os.getenv('gsendbuf') != None: self.sendbuf = os.getenv('gsendbuf')
        if os.getenv('ginverterid') != None:
            self.inverterid = os.getenv('ginverterid')
        if os.getenv('ggrottip') != None:
            try:
                ipaddress.ip_address(os.getenv('ggrottip'))
                self.grottip = os.getenv('ggrottip')
            except:
                if self.verbose: print("\nGrott IP address env invalid")
        if os.getenv('ggrottport') != None:
            if 0 <= int(os.getenv('ggrottport')) <= 65535:
                self.grottport = os.getenv('ggrottport')
        if os.getenv('gvalueoffset') != None:
            if 0 <= int(os.getenv('gvalueoffset')) <= 255:
                self.valueoffset = os.getenv('gvalueoffset')
        if os.getenv('ggrowattip') != None:
            try:
                ipaddress.ip_address(os.getenv('ggrowattip'))
                self.growattip = os.getenv('ggrowattip')
            except:
                if self.verbose:
                    print("\nGrott Growatt server IP address env invalid")
        if os.getenv('ggrowattport') != None:
            if 0 <= int(os.getenv('ggrowattport')) <= 65535:
                self.growattport = os.getenv('ggrowattport')
        #handle mqtt environmentals
        if os.getenv('gnomqtt') != None: self.nomqtt = os.getenv('gnomqtt')
        if os.getenv('gmqttip') != None:
            try:
                ipaddress.ip_address(os.getenv('gmqttip'))
                self.mqttip = os.getenv('gmqttip')
            except:
                if self.verbose:
                    print("\nGrott MQTT server IP address env invalid")
        if os.getenv('gmqttport') != None:
            if 0 <= int(os.getenv('gmqttport')) <= 65535:
                self.mqttport = os.getenv('gmqttport')
        if os.getenv('gmqttauth') != None:
            self.mqttauth = os.getenv('gmqttauth')
        if os.getenv('gmqtttopic') != None:
            self.mqtttopic = os.getenv('gmqtttopic')
        if os.getenv('gmqttuser') != None:
            self.mqttuser = os.getenv('gmqttuser')
        if os.getenv('gmqttpassword') != None:
            self.mqttpsw = os.getenv('gmqttpassword')
        #Handle PVOutput variables
        if os.getenv('gpvoutput') != None:
            self.pvoutput = os.getenv('gpvoutput')
        if os.getenv('gpvapikey') != None:
            self.pvapikey = os.getenv('gpvapikey')
        if os.getenv('gpvinverters') != None:
            self.pvinverters = int(os.getenv('gpvinverters'))
        for x in range(self.pvinverters + 1):
            if os.getenv('gpvsystemid' + str(x)) != None:
                self.pvsystemid[x] = os.getenv('gpvsystemid' + str(x))
            if os.getenv('gpvinverterid' + str(x)) != None:
                self.pvinverterid[x] = os.getenv('gpvinverterid' + str(x))
        if self.pvinverters == 1:
            if os.getenv('gpvsystemid') != None:
                self.pvsystemid[1] = os.getenv('gpvsystemid')
        #Handle Influx
        if os.getenv('ginflux') != None: self.influx = os.getenv('ginflux')
        if os.getenv('ginflux2') != None: self.influx2 = os.getenv('ginflux2')
        if os.getenv('gifdbname') != None:
            self.ifdbname = os.getenv('gifdbname')
        if os.getenv('gifip') != None: self.ifip = os.getenv('gifip')
        if os.getenv('gifport') != None: self.ifport = os.getenv('gifport')
        if os.getenv('gifuser') != None: self.ifuser = os.getenv('gifuser')
        if os.getenv('gifpassword') != None:
            self.ifpsw = os.getenv('gifpassword')
        if os.getenv('giforg') != None: self.iforg = os.getenv('giforg')
        if os.getenv('gifbucket') != None:
            self.ifbucket = os.getenv('gifbucket')
        if os.getenv('giftoken') != None: self.iftoken = os.getenv('giftoken')
        #Handle Extension
        if os.getenv('gextension') != None:
            self.extension = os.getenv('gextension')
        if os.getenv('gextname') != None: self.extname = os.getenv('gextname')
        if os.getenv('gextvar') != None:
            self.extvar = eval(os.getenv('gextvar'))

    def set_recwl(self):
        #define record that will not be blocked or inspected if blockcmd is specified
        self.recwl = {
            "0103",  #announce record
            "0104",  #data record    
            "0116",  #ping    
            "0119",  #identify                       
            "0150",  #Archived record
            "5003",  #announce record
            "5004",  #data record    
            "5016",  #ping    
            "5019",  #identify
            "5050",  #Archived record
            "5103",  #announce record
            "5104",  #data record                          
            "5116",  #ping    
            "5119",  #identify
            "5150"  #Archived record
        }

        try:
            with open('recwl.txt') as f:
                self.recwl = f.read().splitlines()
            if self.verbose:
                print("\nGrott external record whitelist: 'recwl.txt' read")
        except:
            if self.verbose:
                print(
                    "\nGrott external record whitelist 'recwl.txt' not found")
        if self.verbose: print("\nGrott records whitelisted : ", self.recwl)

    def set_reclayouts(self):
        #define record layout to be used based on byte 4,6,7 of the header T+byte4+byte6+byte7
        self.recorddict = {}

        self.recorddict1 = {
            "T02NNNN": {
                "decrypt": "False",
                "pvserial": 36,
                "date": 56,
                "pvstatus": 78,
                "pvpowerin": 82,
                "pv1voltage": 90,
                "pv1current": 94,
                "pv1watt": 98,
                "pv2voltage": 106,
                "pv2current": 110,
                "pv2watt": 114,
                "pvpowerout": 122,
                "pvfrequentie": 130,
                "pvgridvoltage": 134,
                "pvenergytoday": 182,
                "pvenergytotal": 190,
                "pvtemperature": 206,
                "pvipmtemperature": 242,
            }
        }

        self.recorddict2 = {
            "T05NNNN": {
                "decrypt": "True",
                "pvserial": 36,
                "date": 56,
                "pvstatus": 78,
                "pvpowerin": 82,
                "pv1voltage": 90,
                "pv1current": 94,
                "pv1watt": 98,
                "pv2voltage": 106,
                "pv2current": 110,
                "pv2watt": 114,
                "pvpowerout": 122,
                "pvfrequentie": 130,
                "pvgridvoltage": 134,
                "pvenergytoday": 182,
                "pvenergytotal": 190,
                "pvtemperature": 206,
                "pvipmtemperature": 242,
            }
        }

        self.recorddict4 = {
            "T05NNNNX": {
                "decrypt": "True",
                "pvserial": 36,
                "date": 56,
                "pvstatus": 78,
                "pvpowerin": 82,
                "pv1voltage": 90,
                "pv1current": 94,
                "pv1watt": 98,
                "pv2voltage": 106,
                "pv2current": 110,
                "pv2watt": 114,
                "pvpowerout": 170,
                "pvfrequentie": 178,
                "pvgridvoltage": 182,
                "pvenergytoday": 274,
                "pvenergytotal": 282,
                "pvtemperature": 450,
                "pvipmtemperature": 454,
            }
        }

        self.recorddict3 = {
            "T06NNNN": {
                "decrypt": "True",
                "pvserial": 76,
                "date": 136,
                "pvstatus": 158,
                "pvpowerin": 162,
                "pv1voltage": 170,
                "pv1current": 174,
                "pv1watt": 178,
                "pv2voltage": 186,
                "pv2current": 190,
                "pv2watt": 194,
                "pvpowerout": 202,
                "pvfrequentie": 210,
                "pvgridvoltage": 214,
                "pvenergytoday": 262,
                "pvenergytotal": 270,
                "pvtemperature": 286,
                "pvipmtemperature": 322,
            }
        }

        self.recorddict5 = {
            "T06NNNNX": {
                "decrypt": "True",
                "pvserial": 76,
                "date": 136,
                "pvstatus": 158,
                "pvpowerin": 162,
                "pv1voltage": 170,
                "pv1current": 174,
                "pv1watt": 178,
                "pv2voltage": 186,
                "pv2current": 190,
                "pv2watt": 194,
                "pvpowerout": 250,
                "pvfrequentie": 258,
                "pvgridvoltage": 262,
                "pvenergytoday": 354,
                "pvenergytotal": 362,
                "pvtemperature": 530,
                "pvipmtemperature": 534
            }
        }

        self.recorddict.update(self.recorddict1)
        self.recorddict.update(self.recorddict2)
        self.recorddict.update(self.recorddict3)
        self.recorddict.update(self.recorddict4)
        self.recorddict.update(self.recorddict5)

        f = []
        print("\nGrott process json layout files")
        for (dirpath, dirnames, filenames) in walk('.'):
            f.extend(filenames)
            break
        for x in f:
            if ((x[0] == 't' or x[0] == 'T') and x.find('.json') > 0):
                print(x)
                with open(x) as json_file:
                    dicttemp = json.load(json_file)
                    #print(dicttemp)
                    self.recorddict.update(dicttemp)

        if self.verbose: print("\nGrott layout records loaded")
        for key in self.recorddict:
            if self.verbose: print(key, " : ")
            if self.verbose: print(self.recorddict[key])