Shiro-Nek0 / Bluetooth-DMM.py

port of https://github.com/ludwich66/Bluetooth-DMM.git DMM protocol to python
GNU General Public License v2.0
2 stars 3 forks source link

Other Python Decoder (1) with some Debuginfos #1

Closed ludwich66 closed 1 year ago

ludwich66 commented 2 years ago
# BT-DMM 1, Karl without BTLE!
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import datetime

class Decoder:

    XORKEYS = [0x41, 0x21, 0x73, 0x55, 0xa2, 0xc1, 0x32, 0x71, 0x66, 0xaa, 0x3b]
    SEVENBITSEGMENTE = ["1111101", "0000101", "1011011", "0011111", "0100111", "0111110", "1111110", "0010101",
                        "1111111", "0111111", "1110111", "1001100", "1101010", "1001110", "1101000", "1111010",
                        "1110010", "0000000", "0000010"]
    SEGMENTWERTE = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'u', 't', 'o', 'L', 'E', 'F', ' ', '-']

    def __init__(self, gattdaten):
        self.gattdaten = gattdaten
        self.seg_werte = dict(zip(self.SEVENBITSEGMENTE, self.SEGMENTWERTE))
        self.einheit = self.strom = self.minimax = self.hold = self.rel = self.diode = self.auto = ""
        self.vorzeichen = "+"
        self.deziteiler = 1
        self.exponent = 0
        self.expo = 0
        self.expoText = ""
        self.displaytext = ""
        self.segment_is_numerisch = False
        self.string_segmente = ""
        self.value_segmente = 0
        self.value_segmente_dezimal = 0

    def main(self):
        self.prepare_input()
        self.create_string_digits()
        self.set_vorzeichen()
        self.set_dezimalteiler()
        self.set_einheit()
        self.set_exponent()
        self.set_strom()
        self.set_minmax()
        self.set_hold()
        self.set_rel()
        self.set_diode()
        self.set_auto()
        self.formatiere_ausgabe()
        self.set_string_segmente()
        self.set_ergebnis()
        self.ausgabe()

    def prepare_input(self):
        '''holt aus den gattdaten die hexwerte, dekodiert diese mit den XORwerten und verschiebt die bits'''
        rohdaten = self.gattdaten.split(": ")[1].split(" ")
        self.countBytes = len(rohdaten)
        eingangsdaten = [int(zahl, 16) for zahl in rohdaten]
        dekodiert = [(eingangsdaten[i] ^ self.XORKEYS[i]) for i in range(self.countBytes)]
        self.bmList = [[(dekodiert[j] >> i & 0b00000001) for i in range(8)] for j in range(self.countBytes)]
        self.bmStrings = [[str(i) for i in self.bmList[j]] for j in range(len(self.bmList))]
        #print(self.bmList)

    def create_string_digits(self):
        ''' aus Byte 3 bis 7 jeweils die letzten 3 bits als start und die ersten 4 bits
           des folgenden bytes als endbit zu einem stringdigit zusammenhängen '''
        self.stringdigits = [self.bmList[i][-3:] + self.bmList[i+1][:4] for i in range(3, 7)]

        self.string_1_digit = "".join(str(x) for x in self.stringdigits[0])
        self.string_2_digit = "".join(str(x) for x in self.stringdigits[1])
        self.string_3_digit = "".join(str(x) for x in self.stringdigits[2])
        self.string_4_digit = "".join(str(x) for x in self.stringdigits[3])

    def get_bit(self, bitname):
        '''liefert True/False für das jeweilige bit'''
        bitnames = ['vorzeichen', 'gleichstrom', 'wechselstrom', 'min', 'max', 'hold', 'rel', 'diode', 'auto',
                    'dz2', 'dz3', 'dz4', "°F", "°C", "F", "Hz", "Ohm", "V", "A"]
        if self.countBytes == 11:
            bitpositionen = [(3, 4), (9, 6), (8, 3), (8, 1), (8, 0), (7, 4), (8, 2), (7, 7), (10, 0),
                             (4, 4), (5, 4), (6, 4), (9, 6), (9, 7), (8, 4), (9, 5), (9, 0), (8, 1), (8, 6)]
        elif self.countBytes == 10:
            # !!!!!!!!auto stimmt hier die bitposition wahrscheinlich nicht!!!!!!!!!!!!
            # Was machen wir mit den nicht existenten? Byte0/0 zuordnen (=Null)
            #                  vz      DC      AC     xmin    xmax   hold     xrel    diod   xauto,
            #                  dz2     dz3     dz4    °F       °C      F      Hz      Ohm    V        A
            #
            bitpositionen = [(3, 4), (8, 2), (8, 3), (8, 1), (8, 0), (3, 1), (8, 2), (8, 5), (9, 0),
                             (4, 4), (5, 4), (6, 4), (9, 6), (9, 7), (8, 4), (9, 5), (9, 0), (8, 1), (8, 6)]

        bitmapping = dict(zip(bitnames, bitpositionen))
        byte = bitmapping[bitname][0]
        bit = bitmapping[bitname][1]
        return self.bmList[byte][bit]

    def set_vorzeichen(self):
        if self.get_bit('vorzeichen'):
            self.vorzeichen = "-"

    def set_dezimalteiler(self):
        ''''deziteiler ist mit 1 initialisiert; wenn ein bit der dezimalteilerbits True
            nimm den deziteiler in der position der dezimalteiler in der das bit True'''
        dezimalteiler = [0.001, 0.01, 0.1]
        dezimalteilerbits = [bit[4] for bit in self.bmList[4:7]]
        try:
            self.deziteiler = dezimalteiler[dezimalteilerbits.index(1)]
        except:
            pass

    def set_einheit(self):
        ''' liefert die einheit dessen bit True ist '''
        einheiten = ["°F", "°C", "F", "Hz", "Ohm", "V", "A"]
        for bezeichner in einheiten:
            if self.get_bit(bezeichner):
                self.einheit = bezeichner

    def set_exponent(self):
        '''exponent setzen und entsprechenden faktor'''
        exponentenBits_1 = [self.bmList[9][3], self.bmList[9][1], self.bmList[8][0]]
        faktor1 = [6, 3, -9]
        try:
            self.expo = faktor1[exponentenBits_1.index(1)]
        except:
            pass
        if self.bmList[9][2]:
            self.expo = -3
        if self.bmList[8][7]:
            self.expo = -6
        self.faktor = (10 ** self.expo)
        dict_faktor_bezeichner = {6: "M", 3: "k", 0: "", -3: "m", -6: "µ", -9: "n", }
        self.expoText = dict_faktor_bezeichner[self.expo]

    def set_strom(self):
        '''ermitteln ob gleichstrom oder wechselstrom'''
        if self.get_bit('gleichstrom'):
            self.strom = "DC"
        elif self.get_bit('wechselstrom'):
            self.strom = "AC"

    def set_minmax(self):
        '''Minimum und Maximum ermitteln....von was??????
       Das DMM misst kontinuierlich, es wird aber nur der kleinste oder größte Wert ausgegeben
       Rel zeigt die Spanne zwischen Min und Max Wert an!!!'''
        if self.get_bit('min'):
            self.minimax = "Min"
        elif self.get_bit('max'):
            self.minimax = "Max"

    def set_hold(self):
        if self.get_bit('hold'):
            self.hold = "hold"

    def set_rel(self):
        if self.get_bit('rel'):
            self.rel = 'rel'

    def set_diode(self):
        if self.get_bit('diode'):
            self.diode = 'diode'

    def set_auto(self):
        if self.get_bit('auto'):
            self.auto = 'auto'

    def formatiere_ausgabe(self):
        # Ausgabe formatieren
        DZ2 = DZ3 = DZ4 = "."

        A = self.seg_werte[self.string_1_digit]
        B = self.seg_werte[self.string_2_digit]
        C = self.seg_werte[self.string_3_digit]
        D = self.seg_werte[self.string_4_digit]

        if type(D) == int:
            self.segment_is_numerisch = True

        DZ2 = DZ2 * self.get_bit('dz2')
        DZ3 = DZ3 * self.get_bit('dz3')
        DZ4 = DZ4 * self.get_bit('dz4')

        self.displaytext = f"{self.vorzeichen}{A}{DZ2}{B}{DZ3}{C}{DZ4}{D} {self.expoText}{self.einheit}"

    def set_string_segmente(self):
        self.string_segmente = \
            f"{str(self.string_1_digit)}{str(self.string_2_digit)}{str(self.string_3_digit)}{str(self.string_4_digit)}"

    def set_ergebnis(self):
        if self.segment_is_numerisch:
            self.value_segmente = self.stringdigits[0] * 1000 + self.stringdigits[1] * 100 + \
                                  self.stringdigits[2] * 10 + self.stringdigits[3]

            self.value_segmente_dezimal_exponent = int(self.string_segmente) * self.deziteiler * self.faktor
            self.value_segmente_dezimal_exponent_vorzeichen = f"{self.vorzeichen}{self.value_segmente_dezimal_exponent}"
            self.value_segmente_dezimal_exponent_vorzeichen_einheit = f"{self.vorzeichen}{self.value_segmente_dezimal_exponent} {self.einheit}"

        else:
            self.value_segmente_dezimal_exponent = 0
            self.value_segmente_dezimal_exponent_vorzeichen = 0

            self.value_segmente_dezimal_exponent_vorzeichen_einheit = f"{self.vorzeichen}{self.value_segmente_dezimal_exponent}{self.expoText} {self.einheit}"

    def ausgabe(self):
        self.timestamp = datetime.datetime.today()
        self.konsolenausgabe = \
            f"{self.timestamp};{self.displaytext} ; {self.value_segmente_dezimal_exponent_vorzeichen};{self.einheit};{self.strom}; Stati: {self.auto} {self.minimax} {self.hold} {self.diode} {self.rel}"

if __name__ == '__main__':

    eingangsdaten_1 = "Notification handle = 0x0009 value: 1b 84 71 f5 0f cc 28 fb f6 aa"
    eingangsdaten_2 = "Notification handle = 0x0009 value: 1b 84 70 d1 bd 8b dc 7a 36 aa 3a"

    testeingangsdaten = [eingangsdaten_1, eingangsdaten_2]

    for daten in testeingangsdaten:
        dec = Decoder(daten)
        dec.main()

        print(dec.konsolenausgabe)
ludwich66 commented 2 years ago
# BT-DMM 2, Karl without BTLE!
import datetime
import array

class Decoder:

    XORKEYS = [0x41, 0x21, 0x73, 0x55, 0xa2, 0xc1, 0x32, 0x71, 0x66, 0xaa, 0x3b]
    SEVENBITSEGMENTE = ["1111101", "0000101", "1011011", "0011111", "0100111", "0111110", "1111110", "0010101",
                        "1111111", "0111111", "1110111", "1001100", "1101010", "1001110", "1101000", "1111010",
                        "1110010", "0000000", "0000010"]
    SEGMENTWERTE = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'u', 't', 'o', 'L', 'E', 'F', ' ', '-']

    def __init__(self, gattdaten):
        self.gattdaten = gattdaten
        self.seg_werte = dict(zip(self.SEVENBITSEGMENTE, self.SEGMENTWERTE))
        self.einheit = self.strom = self.minimax = self.hold = self.rel = self.diode = self.auto = ""
        self.expoText = self.displaytext = " "
        self.vorzeichen = "+"
        self.deziteiler = 1
        self.exponent = self.expo = self.vlaue_segmente_dezimal = 0 
        self.segment_is_numerisch = False
        self.countBytes = 0

    def main(self):
        self.prepare_input()
        self.create_string_digits()
        self.set_vorzeichen()
        self.set_dezimalteiler()
        self.set_einheit()
        self.set_exponent()
        self.set_strom()
        self.set_minmax()
        self.set_hold()
        self.set_rel()
        self.set_diode()
        self.set_auto()
        self.set_segmentwerte_und_displaytext()
        self.set_string_segmente()
        self.set_ergebnis()
        self.ausgabe()

    def prepare_input(self):
        '''erstellt 2 2-dimensionale Listen (Bytes als sublisten) einal als int einmal as strings
           indem aus den gattdaten die hexwerte isoliert, diese dekodiert mit den XORwerten und die bits verschoben werde'''
        rohdaten = self.gattdaten.split(": ")[1].split(" ")
        self.countBytes = len(rohdaten)
        eingangsdaten = [int(zahl, 16) for zahl in rohdaten]
        dekodiert = [(eingangsdaten[i] ^ self.XORKEYS[i]) for i in range(self.countBytes)]
        self.bmList = [[(dekodiert[j] >> i & 0b00000001) for i in range(8)] for j in range(self.countBytes)]

    def create_string_digits(self):
        ''' aus Byte 3 bis 7 jeweils die letzten 3 bits als start und die ersten 4 bits
           des folgenden bytes als endbit zu einem stringdigit zusammenhängen '''
        self.stringdigits = [self.bmList[i][-3:] + self.bmList[i+1][:4] for i in range(3, 7)]

        self.string_1_digit = "".join(str(x) for x in self.stringdigits[0])
        self.string_2_digit = "".join(str(x) for x in self.stringdigits[1])
        self.string_3_digit = "".join(str(x) for x in self.stringdigits[2])
        self.string_4_digit = "".join(str(x) for x in self.stringdigits[3])

    def get_bit(self, bitname):
        '''liefert True/False für das jeweilige bit'''
        bitnames = ['vorzeichen', 'gleichstrom', 'wechselstrom', 'min', 'max', 'hold', 'rel', 'diode', 'auto',
                    'dz2', 'dz3', 'dz4', "°F", "°C", "F", "Hz", "Ohm", "V", "A"]

        if self.countBytes == 11:
            bitpositionen = [(3, 4), (9, 6), (8, 3), (8, 1), (8, 0), (7, 4), (8, 2), (7, 7), (10, 0),
                             (4, 4), (5, 4), (6, 4), (9, 6), (9, 7), (8, 4), (9, 5), (9, 0), (8, 1), (8, 6)]
        elif self.countBytes == 10:
            # !!!!!!!!auto stimmt hier die bitposition wahrscheinlich nicht!!!!!!!!!!!!
            bitpositionen = [(3, 4), (8, 2), (8, 3), (8, 1), (8, 0), (3, 1), (8, 2), (8, 5), (9, 0),
                             (4, 4), (5, 4), (6, 4), (9, 6), (9, 7), (8, 4), (9, 5), (9, 0), (8, 1), (8, 6)]

        bitmapping = dict(zip(bitnames, bitpositionen))
        byte = bitmapping[bitname][0]
        bit = bitmapping[bitname][1]
        return self.bmList[byte][bit]

    def set_vorzeichen(self):
        '''setzt vorzeichen auf minus wenn byte3 bit4 True'''
        if self.get_bit('vorzeichen'):
            self.vorzeichen = "-"

    def set_dezimalteiler(self):
        ''''deziteiler ist mit 1 initialisiert; wenn ein bit der dezimalteilerbits True
            nimm den deziteiler in der position der dezimalteiler in der das bit True'''
        dezimalteiler = [0.001, 0.01, 0.1]
        dezimalteilerbits = [bit[4] for bit in self.bmList[4:7]]
        try:
            self.deziteiler = dezimalteiler[dezimalteilerbits.index(1)]
        except:
            pass

    def set_einheit(self):
        ''' liefert die einheit dessen bit True ist '''
        einheiten = ["°F", "°C", "F", "Hz", "Ohm", "V", "A"]
        for bezeichner in einheiten:
            if self.get_bit(bezeichner):
                self.einheit = bezeichner

    def set_exponent(self):
        '''ermittelt den exponenten, setzt den faktor=10**expo und setzt  den bezeichner des expos expoText'''
        dict_expo_bezeichner = {6: "M", 3: "k", 0: "", -3: "m", -6: "µ", -9: "n",}

        exponentenBits = [self.bmList[9][3], self.bmList[9][1], self.bmList[8][0]]
        expos = [6, 3, -9]
        try:
            self.expo = expos[exponentenBits.index(1)]
        except:
            pass
        if self.bmList[9][2]:
            self.expo = -3
        if self.bmList[8][7]:
            self.expo = -6
        self.faktor = (10 ** self.expo)
        self.expoText = dict_expo_bezeichner[self.expo]

    def set_strom(self):
        '''ermitteln ob gleichstrom oder wechselstrom'''
        if self.get_bit('gleichstrom'):
            self.strom = "DC"
        elif self.get_bit('wechselstrom'):
            self.strom = "AC"

    def set_minmax(self):
        '''Minimum und Maximum ermitteln....von was??????
       Das DMM misst kontinuierlich, es wird aber nur der kleinste oder größte Wert ausgegeben
       Rel zeigt die Spanne zwischen Min und Max Wert an!!!'''
        if self.get_bit('min'):
            self.minimax = "Min"
        elif self.get_bit('max'):
            self.minimax = "Max"

    def set_hold(self):
        if self.get_bit('hold'):
            self.hold = "hold"

    def set_rel(self):
        if self.get_bit('rel'):
            self.rel = 'rel'

    def set_diode(self):
        if self.get_bit('diode'):
            self.diode = 'diode'

    def set_auto(self):
        if self.get_bit('auto'):
            self.auto = 'auto'

    def set_segmentwerte_und_displaytext(self):
        # Ausgabe formatieren

        A = self.seg_werte[self.string_1_digit]
        B = self.seg_werte[self.string_2_digit]
        C = self.seg_werte[self.string_3_digit]
        D = self.seg_werte[self.string_4_digit]

        if type(D) == int:
            self.segment_is_numerisch = True

        DZ2 = DZ3 = DZ4 = "."

        DZ2 = DZ2 * self.get_bit('dz2')
        DZ3 = DZ3 * self.get_bit('dz3')
        DZ4 = DZ4 * self.get_bit('dz4')

        self.displaytext = f"{self.vorzeichen}{A}{DZ2}{B}{DZ3}{C}{DZ4}{D} {self.expoText}{self.einheit}"

    def set_string_segmente(self):
        self.string_segmente = \
            f"{str(self.string_1_digit)}{str(self.string_2_digit)}{str(self.string_3_digit)}{str(self.string_4_digit)}"

    def set_ergebnis(self):
        if self.segment_is_numerisch:
            self.value_segmente = self.stringdigits[0] * 1000 + self.stringdigits[1] * 100 + \
                                  self.stringdigits[2] * 10 + self.stringdigits[3]

            self.value_segmente_dezimal_exponent = int(self.string_segmente) * self.deziteiler * self.faktor
            self.value_segmente_dezimal_exponent_vorzeichen = f"{self.vorzeichen}{self.value_segmente_dezimal_exponent}"
        else:
            self.value_segmente_dezimal_exponent = 0
            self.value_segmente_dezimal_exponent_vorzeichen = 0

            self.value_segmente_dezimal_exponent_vorzeichen_einheit = \
                    f"{self.vorzeichen}{self.value_segmente_dezimal_exponent}{self.expoText} {self.einheit}"

    def ausgabe(self):
        self.timestamp = datetime.datetime.today()
        self.konsolenausgabe = \
            f"{self.timestamp};{self.displaytext} ; {self.value_segmente_dezimal_exponent_vorzeichen};{self.einheit};{self.strom}; Stati: {self.auto} {self.minimax} {self.hold} {self.diode} {self.rel}"

if __name__ == '__main__':

    eingangsdaten = ["Notification handle = 0x0009 value: 1b 84 71 f5 0f cc 28 fb f6 aa",
                     "Notification handle = 0x0009 value: 1b 84 70 d1 bd 8b dc 7a 36 aa 3a",
                     "Notification handle = 0x0009 value: 1b 84 71 95 45 3a 79 ff 66 8a",
                     "Notification handle = 0x0009 value: 1b 84 70 b1 59 2a d9 7a f6 aa 3b",
                     "Notification handle = 0x0009 value: 1b 84 71 d5 bd 6b df fa 76 ae",
                     "Notification handle = 0x0009 value: 1b 84 71 95 2d 9b 9c fc 77 aa",
                     "Notification handle = 0x0009 value: 1b 84 71 95 45 3a 79 ff 66 8a",
                     "Notification handle = 0x0009 value: 1b 84 71 f1 2f 4e cd fa 6c aa",
                     "Notification handle = 0x0009 value: 1b 84 71 15 5c 6a 9f fc 60 aa",
                     "Notification handle = 0x0009 value: 1b 84 71 05 5c 6a bf fe 60 aa",
                     "Notification handle = 0x0009 value: 1b 84 71 bd 59 ca 98 fc 66 a9",
                     "Notification handle = 0x0009 value: 1b 84 71 55 e8 4f 68 ff 66 a9",
                     "Notification handle = 0x0009 value: 1b 84 71 f5 bf 2b dd fa 66 a3",
                     "Notification handle = 0x0009 value: 1b 84 71 55 a2 c1 d2 fa 66 2a",
                     "Notification handle = 0x0009 value: 1b 84 71 45 a2 c1 b8 fe 66 2a",
                     "Notification handle = 0x0009 value: 1b 84 71 45 a2 c1 d2 fe 66 2a",
                     "Notification handle = 0x0009 value: 1b 84 71 55 a2 c1 f2 f6 66 2a",
                     "Notification handle = 0x0009 value: 1b 84 71 55 48 6e cf fa 22 ae",
                     "Notification handle = 0x0009 value: 1b 84 71 55 58 0a d5 fe 22 aa"]

    for daten in eingangsdaten:
        dec = Decoder(daten)
        dec.main()

        print(dec.bmList)

        print(dec.konsolenausgabe)
ludwich66 commented 2 years ago
# Ludwichs Version -- without BT 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Decoder für die Bluetoothmessgeräte
# Multimeter (1):       Aneng 9002
# (11Byte Protocol)     BSIDE ZT-300AB
#                       ZOYI ZT-300AB
# Small-Multimeter (2): Aneng V05B # für dieses Gerät
# (10Byte Protocol)     BSIDE ZT-5B
#                       ZOYI ZT-5B
# Clamp-Multimeter (3): Aneng ST207
#                       BSIDE ZT-5BQ
#                       ZOYI ZT-5BQ
#
# Entwickler Pythoncode: Karl und Jürgen
#########################
# Was geht? - Was ging?:
##########################
# 2021-07-01 Programmaufruf mit Parameter angefangen “-h” “-s” “-f”
# 2021-07-04 textausgabe Ausgabeformat überarbeitet (
# 2021-07-05 Ausgabe der Statusparameter ( AC DC etc.) ; Minimaler Write CSV datei in UTF8
# 2021-07-07 Programmaufruf um Speichername  Reportdatei erweitert
# 2021-07-10 Zählweise der Bytes beginnen jetzt bei = NULL !!
# 2021-07-16 Neues Messgerät ANENG V05B liefert nur 10 Byte, die Digits sind OK der Rest ist zu reverse-enginieren
########################
# Importe
########################
import datetime
import sys
import os
import subprocess
# Deklarationen
dateiname = "" # Speichername  Reportdatei

################################################################################
# Nutzung / optionen / Hilfemenü
################################################################################
# >>> Python3 Decoder.py <opt>
# Optionen:
# -s "Speicher Dateiname"
# -t Mit Zeitstempel
# -h Hilfetext
# -f Format: Text, Text mit Einheit, Text mit expoEinheit,
# SI(Kommazahl mit Grundeinheit), Zahl(4Stellig) mit 3 Exponent,
# -v Einheit, expoEinheit
#
# Textausgaben?
# Auto
# _EF_
# _.OL_
# _O.L_
# _OL._
#

################################################################################
# Funktion Bytumwandlung
################################################################################
# Numerisch #######################################################################
def segment2dez(str_7bitSegment):  # Reihenfolge Segment EBAGFDC
    if str_7bitSegment == "1111101":
        return 0
    elif str_7bitSegment == "0000101":
        return 1
    elif str_7bitSegment == "1011011":
        return 2
    elif str_7bitSegment == "0011111":
        return 3
    elif str_7bitSegment == "0100111":
        return 4
    elif str_7bitSegment == "0111110":
        return 5
    elif str_7bitSegment == "1111110":
        return 6
    elif str_7bitSegment == "0010101":
        return 7
    elif str_7bitSegment == "1111111":
        return 8
    elif str_7bitSegment == "0111111":
        return 9
# Aplhanumerisch ###############################################################
    elif str_7bitSegment == "1110111":
        return "A"
    elif str_7bitSegment == "1001100":
        return "u"
    elif str_7bitSegment == "1101010":
        return "t"
    elif str_7bitSegment == "1001110":
        return "o"
    elif str_7bitSegment == "1101000":
        return "L"
    elif str_7bitSegment == "1111010":
        return "E"
    elif str_7bitSegment == "1110010":
        return "F"
    elif str_7bitSegment == "0000010":
        return "-"
    elif str_7bitSegment == "0000000":
        return " "
    return ("Pattern unbekannt")

################################################################################
# Funktion Inpudatenaufbereitung
################################################################################
def gatttool_parser(gatttausgabe):
    #(11Byte) ANENG_9002: parsen der Ausgabe des GATTTOOLs:  "Notification handle = 0x0009 value: 1b 84 70 b1 8c a2 17 76 66 aa 3b"
    #(10Byte) ANENG_V05B: parsen der Ausgabe des GATTTOOLs:  "Notification handle = 0x0009 value: 1b 84 70 b1 8c a2 17 76 66 aa"
    teile = gatttausgabe.split(" ")
    anz_teile = len(teile)
    print("len : ",anz_teile) # 9002 = 16 Teile; V05B = 15 Teile
    byte0strcodet = "0x" + teile[5] # 0x1b
    byte1strcodet = "0x" + teile[6]
    byte2strcodet = "0x" + teile[7]
    byte3strcodet = "0x" + teile[8]
    byte4strcodet = "0x" + teile[9]
    byte5strcodet = "0x" + teile[10]
    byte6strcodet = "0x" + teile[11]
    byte7strcodet = "0x" + teile[12]
    byte8strcodet = "0x" + teile[13]
    byte9strcodet = "0x" + teile[14]
    if anz_teile == 15:
        byte10strcodet = "0x00"
    if anz_teile == 16:
        byte10strcodet = "0x" + teile[15]
    return(byte0strcodet,byte1strcodet,byte2strcodet,byte3strcodet,byte4strcodet,byte5strcodet,byte6strcodet,byte7strcodet,byte8strcodet,byte9strcodet,byte10strcodet)
    # print(byte0strcodet,byte1strcodet,byte2strcodet,byte3strcodet,byte4strcodet,byte5strcodet,byte6strcodet,byte7strcodet,byte8strcodet,byte9strcodet,byte10strcodet)
    # Liefert Tuple ('0x1b', '0x84', '0x70', '0xb1', '0x8c', '0xa2', '0x17', '0x76', '0x66', '0xaa', '0x3b')

################################################################################
# Programmstart
################################################################################
# Parameterhilfe Optionen nach: >>> python3 main.py -h -s Datei.csv -f SI, Text, Value,
for i in range(len(sys.argv)):
    if sys.argv[i] == '-h':
        print("Hilfetextausgabe")
        print("-h: Decoder für die Messgeräte A B C")
        print("-s: Dateiname zum Speichern")
        print("-f: Ausgabeformat")
        print("-t: Zeitstempel")
        print("-si Einheitenformat")
    if sys.argv[i] == '-s':
        print("-s: folgend der CSV Name der CSV Datei unter dem gesichert wird")
        print(i)
        dateiname = sys.argv[i + 1]
    if sys.argv[i] == '-f':
        print("-f: Format der Ausgabe A ")
        print("-f: Format der Ausgabe B ")
    if sys.argv[i] == '-t':
        print("TimeStampText")
        print("-t: Format der Ausgabe A ")
        print("-t: Format der Ausgabe B ")
    if sys.argv[i] == '-si':
        print("Timestamp SI")
#print("DEBUG Dateiname :", dateiname)
vorhanden = os.path.exists(dateiname)
#print(vorhanden)
if vorhanden == 1:
    response = input("Der Dateiname wird bereits genutzt - Überschreiben? < j / n >  \n")
    #print("DEBUG Response:", response)
    if response == "n" or response == "N":
        print("Bitte geben sie einen anderen Dateinamen ein")
        quit()
    if response != "n" and response != "j":
        print("DEBUG: Antwort nicht n oder j")

################################################################################
# Simuliere Eingangsdaten aus der BT Schnittstelle // Testdatensätze
# nur eine Zeile aktivieren
################################################################################
#Aufruf gatttool
# sudo gatttool -b FC:58:FA:77:0B:33 --car-read --listen -a 9
'''p = subprocess.Popen([r"C:\...\programm.exe", "-h"], stdout=subprocess.PIPE)
p.wait()
print p.stdout.read()'''
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 51 42 ba 33 71 66 a0 3a") # OL
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 6a 9f 3c 66 aa 3b") # 0022°C #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 8c a2 17 76 66 aa 3b") # Auto #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 51 42 ba 33 71 66 a0 3a")  # EF ?? OL status auto #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 6a df 3a 66 aa 3b") # 0020 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 6a 3f 3b 66 aa 3b") # 0021 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 6a 9f 3c 66 aa 3b") # 0022 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 6a bf 3e 66 aa 3b") # 0023 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 6a 7f 3f 66 aa 3b") # 0024 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 6a ff 36 66 aa 3b") # 0025 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 6a df 36 66 aa 3b") # 0026 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 4a 98 5c 66 aa 3b") # 0072 °F  #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 6a 9f 3c 66 aa 3b") # 0073 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 4a 78 5f 66 aa 3b") # 0074 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 4a f8 56 66 aa 3b") # 0075 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 4a f8 56 66 aa 3b") # 0076 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 4a b8 5b 66 aa 3b") # 0077 #
input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 4a d8 5e 66 aa 3b") # 0078  #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 4a f8 5e 66 aa 3b") # 0079 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 2a dd 5a 66 aa 3b") # 0080 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 2a 3d 5b 66 aa 3b") # 0081 #
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 51 42 aa 23 71 66 a8 3b") # Ω OL
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 51 42 ba 33 71 66 a0 3a") # MΩ OL
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 51 52 aa 33 71 66 ac 3b") # KΩ OL
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b9 49 ca 28 7b 66 a8 3b") # 001.1 Ω BUzzer
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 59 2a d9 7a f6 aa 3b") # nF 0.000
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 f1 1f 2c dd 7e 56 aa 3a") # µF 2.288
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 d1 bd 8b dc 7a 36 aa 3a") # mF
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 59 2a d9 7a 66 ab 3a") # Hz
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 a1 a9 3b 79 7f 66 fa 3b") # minus -01.04
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 59 52 aa 33 f1 67 ba 3b") # _.OL_ Diode, Buzzer, Max
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b3 59 2a d9 7a 66 fa 3b") # rel DC V
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 59 2a d9 7a 6e 2a 3b") # A AC true RMS
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 70 b1 49 3a d9 7a 66 6a 32") # 00.00 mA DC
################################################################################
## Neue Wert vom Messgeraet ANENG V05B 16-07-2021 nur 10 Byte!! (FF als Dummy
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 b5 8c a2 17 f6 66 aa FF") ##BT Auto
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 5d 52 aa 33 f1 44 aa FF") ##BT .OL Diode Buzzer V
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 b7 8c a2 17 f6 66 aa FF") ##BT Auto Hold
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 b5 59 ca 78 ff 77 aa FF") ##BT 0.014 nF
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 b5 59 2a d9 fa 66 8a FF") ##BT  .00
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 61 df f6 66 2a") ##BT __26°C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 21 dd fa 66 ea FF") ##BT __80°F
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 5f 52 aa 33 f1 44 aa FF") ## BT .Ol Diode Buzzer HOLD
# Daten vom V05B 17.07.2021
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 e8 4f 68 ff 66 a9") # 147.4 kOhm
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 bd 59 ca 98 fc 66 a9") # 0.012 ohm, buzzer , Led
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 5d a2 6b cf fe 66 ab") # _12.8 ohm, buzzer, LED
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 f5 bf 2b dd fa 66 a3") # 2.180 MOhm
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 f5 5f 46 98 fc 44 aa") # 2.674, V, Diode,
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 5d 52 aa 33 f1 44 aa") # V, Diode, buzzer _.OL_
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 f5 0f cc 28 fb f6 aa") # 221.1 mikroFarad
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 d5 bd 6b df fa 76 ae") # 3.131 milliFarad
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 95 2d 9b 9c fc 77 aa") # 97,42nFarad
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 b5 59 2a d9 fa 66 8a") # 0.000 Hz
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 95 45 3a 79 ff 66 8a") # 50.04 Hz
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 95 45 3a 39 fb 66 8a") # 50.01 Hz
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 f1 2f 4e ad fe 6c aa") # 233.3 AC ,Blitz, V, true rms
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 f1 2f 4e cd fa 6c aa") # 233.0 AC ,Blitz, V, true rms
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 15 5c 6a 9f fc 60 aa") # 4.022 DC V
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 05 5c 6a bf fe 60 aa") # Minus -4.023 DC V
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 38 0e d5 fe 60 aa") # 1.358V DC
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 45 38 0e f5 fe 60 aa") # Minus -1.359 VDC
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 61 df fe 66 2a") # 28 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 61 bf fb 66 2a") # 27 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 61 df f6 66 2a") # 26 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 61 ff f6 66 2a") # 25 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 61 7f ff 66 2a") # 24 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 61 bf fe 66 2a") # 23 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 61 9f fc 66 2a") # 22 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 41 d8 f6 66 ea") # 76 °F
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 41 78 ff 66 ea") # 74? °F
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 41 b8 fe 66 ea") # 73 °F
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 c1 d2 fa 66 2a") #0 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 45 a2 c1 b8 fe 66 2a") #-13 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 45 a2 c1 d2 fe 66 2a") #-8 °C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 a2 c1 f2 f6 66 2a") # 5°C
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 48 2a c9 fe 22 ae") # 100.8 mA DC
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 48 6e cf fa 22 ae") # 182.0 mA DC
#input = gatttool_parser("Notification handle = 0x0009 value: 1b 84 71 55 58 0a d5 fe 22 aa") # 1.058 A DC

################################################################################
# Input
################################################################################
# Hinweis
if "input" not in globals():
    print("Fehler: keine Eingangsdaten / Input auskommentiert ")
byte0codet = int(input[0], 16)
byte1codet = int(input[1], 16)
byte2codet = int(input[2], 16)
byte3codet = int(input[3], 16)
byte4codet = int(input[4], 16)
byte5codet = int(input[5], 16)
byte6codet = int(input[6], 16)
byte7codet = int(input[7], 16)
byte8codet = int(input[8], 16)
byte9codet = int(input[9], 16)
byte10codet = int(input[10], 16)
################################################################################
# XOR-Key
byte0xorkey = 0x41
byte1xorkey = 0x21
byte2xorkey = 0x73
byte3xorkey = 0x55
byte4xorkey = 0xa2
byte5xorkey = 0xc1
byte6xorkey = 0x32
byte7xorkey = 0x71
byte8xorkey = 0x66
byte9xorkey = 0xaa
byte10xorkey = 0x3b
################################################################################
# Decodet
byte0decodet = byte0codet ^ byte0xorkey
byte1decodet = byte1codet ^ byte1xorkey
byte2decodet = byte2codet ^ byte2xorkey
byte3decodet = byte3codet ^ byte3xorkey
byte4decodet = byte4codet ^ byte4xorkey
byte5decodet = byte5codet ^ byte5xorkey
byte6decodet = byte6codet ^ byte6xorkey
byte7decodet = byte7codet ^ byte7xorkey
byte8decodet = byte8codet ^ byte8xorkey
byte9decodet = byte9codet ^ byte9xorkey
byte10decodet = byte10codet ^ byte10xorkey

################################################################################
# Bytes werden gedreht (MSB/LSB) und auf Bits gesplittet
################################################################################
Byte0_0_00 = (byte0decodet >> 0) & 0b00000001
Byte0_1_01 = (byte0decodet >> 1) & 0b00000001
Byte0_2_02 = (byte0decodet >> 2) & 0b00000001
Byte0_3_03 = (byte0decodet >> 3) & 0b00000001
Byte0_4_04 = (byte0decodet >> 4) & 0b00000001
Byte0_5_05 = (byte0decodet >> 5) & 0b00000001
Byte0_6_06 = (byte0decodet >> 6) & 0b00000001
Byte0_7_07 = (byte0decodet >> 7) & 0b00000001

Byte1_0_08 = (byte1decodet >> 0) & 0b00000001
Byte1_1_09 = (byte1decodet >> 1) & 0b00000001
Byte1_2_10 = (byte1decodet >> 2) & 0b00000001
Byte1_3_11 = (byte1decodet >> 3) & 0b00000001
Byte1_4_12 = (byte1decodet >> 4) & 0b00000001
Byte1_5_13 = (byte1decodet >> 5) & 0b00000001
Byte1_6_14 = (byte1decodet >> 6) & 0b00000001
Byte1_7_15 = (byte1decodet >> 7) & 0b00000001

Byte2_0_16 = (byte2decodet >> 0) & 0b00000001 #Gerätetyp DMM(1)9002=1  smallDMM(2) V05B=0
Byte2_1_17 = (byte2decodet >> 1) & 0b00000001
Byte2_2_18 = (byte2decodet >> 2) & 0b00000001
Byte2_3_19 = (byte2decodet >> 3) & 0b00000001
Byte2_4_20 = (byte2decodet >> 4) & 0b00000001
Byte2_5_21 = (byte2decodet >> 5) & 0b00000001
Byte2_6_22 = (byte2decodet >> 6) & 0b00000001
Byte2_7_23 = (byte2decodet >> 7) & 0b00000001

Byte3_0_24 = (byte3decodet >> 0) & 0b00000001  # ?      ## ?
Byte3_1_25 = (byte3decodet >> 1) & 0b00000001  # Delta∆ ## Hold
Byte3_2_26 = (byte3decodet >> 2) & 0b00000001  #        ## Blitz (>40V)
Byte3_3_27 = (byte3decodet >> 3) & 0b00000001  # Buzzer ## Buzzer (R<50Ohm)
Byte3_4_28 = (byte3decodet >> 4) & 0b00000001  # LCD Segment1: -____ Minus ## einheitlich
Byte3_5_29 = (byte3decodet >> 5) & 0b00000001  # LCD Segment1: 8___ D1e
Byte3_6_30 = (byte3decodet >> 6) & 0b00000001  # LCD Segment1: 8___ D1b
Byte3_7_31 = (byte3decodet >> 7) & 0b00000001  # LCD Segment1: 8___ D1a

Byte4_0_32 = (byte4decodet >> 0) & 0b00000001  # LCD Segment1: 8___ D1g
Byte4_1_33 = (byte4decodet >> 1) & 0b00000001  # LCD Segment1: 8___ D1f
Byte4_2_34 = (byte4decodet >> 2) & 0b00000001  # LCD Segment1: 8___ D1d
Byte4_3_35 = (byte4decodet >> 3) & 0b00000001  # LCD Segment1: 8___ D1c
Byte4_4_36 = (byte4decodet >> 4) & 0b00000001  # LCD Segment2: _.___ DP2
Byte4_5_37 = (byte4decodet >> 5) & 0b00000001  # LCD Segment2: _8__ D2e
Byte4_6_38 = (byte4decodet >> 6) & 0b00000001  # LCD Segment2: _8__ D2b
Byte4_7_39 = (byte4decodet >> 7) & 0b00000001  # LCD Segment2: _8__ D2a

Byte5_0_40 = (byte5decodet >> 0) & 0b00000001  # LCD Segment2: _8__ D2g
Byte5_1_41 = (byte5decodet >> 1) & 0b00000001  # LCD Segment2: _8__ D2f
Byte5_2_42 = (byte5decodet >> 2) & 0b00000001  # LCD Segment2: _8__ D2d
Byte5_3_43 = (byte5decodet >> 3) & 0b00000001  # LCD Segment2: _8__ D2c
Byte5_4_44 = (byte5decodet >> 4) & 0b00000001  # LCD Segment3: __.__ DP3
Byte5_5_45 = (byte5decodet >> 5) & 0b00000001  # LCD Segment3: __8_ D3e
Byte5_6_46 = (byte5decodet >> 6) & 0b00000001  # LCD Segment3: __8_ D3b
Byte5_7_47 = (byte5decodet >> 7) & 0b00000001  # LCD Segment3: __8_ D3a

Byte6_0_48 = (byte6decodet >> 0) & 0b00000001  # LCD Segment3: __8_ D3g
Byte6_1_49 = (byte6decodet >> 1) & 0b00000001  # LCD Segment3: __8_ D3f
Byte6_2_50 = (byte6decodet >> 2) & 0b00000001  # LCD Segment3: __8_ D3d
Byte6_3_51 = (byte6decodet >> 3) & 0b00000001  # LCD Segment3: __8_ D3c
Byte6_4_52 = (byte6decodet >> 4) & 0b00000001  # LCD Segment4: ___._ DP4
Byte6_5_53 = (byte6decodet >> 5) & 0b00000001  # LCD Segment4: ___8 D4e
Byte6_6_54 = (byte6decodet >> 6) & 0b00000001  # LCD Segment4: ___8 D4b
Byte6_7_55 = (byte6decodet >> 7) & 0b00000001  # LCD Segment4: ___8 D4a

Byte7_0_56 = (byte7decodet >> 0) & 0b00000001  # LCD Segment4: ___8 D4g
Byte7_1_57 = (byte7decodet >> 1) & 0b00000001  # LCD Segment4: ___8 D4f
Byte7_2_58 = (byte7decodet >> 2) & 0b00000001  # LCD Segment4: ___8 D4d
Byte7_3_59 = (byte7decodet >> 3) & 0b00000001  # LCD Segment4: ___8 D4c
Byte7_4_60 = (byte7decodet >> 4) & 0b00000001  # Hold   ## ?
Byte7_5_61 = (byte7decodet >> 5) & 0b00000001  # °F     ## ?
Byte7_6_62 = (byte7decodet >> 6) & 0b00000001  # °C     ## ?
Byte7_7_63 = (byte7decodet >> 7) & 0b00000001  # Diode  ## ?

Byte8_0_64 = (byte8decodet >> 0) & 0b00000001  # Max    ## nano
Byte8_1_65 = (byte8decodet >> 1) & 0b00000001  # Min    ## V
Byte8_2_66 = (byte8decodet >> 2) & 0b00000001  # rel %  ## DC
Byte8_3_67 = (byte8decodet >> 3) & 0b00000001  # AC     ## AC
Byte8_4_68 = (byte8decodet >> 4) & 0b00000001  # F      ## F
Byte8_5_69 = (byte8decodet >> 5) & 0b00000001  # µ(F)   ## Diode
Byte8_6_70 = (byte8decodet >> 6) & 0b00000001  # m(F)   ## A
Byte8_7_71 = (byte8decodet >> 7) & 0b00000001  # n(F)   ## µ

Byte9_0_72 = (byte9decodet >> 0) & 0b00000001  # Hz     ## Ω
Byte9_1_73 = (byte9decodet >> 1) & 0b00000001  # Ω      ## k
Byte9_2_74 = (byte9decodet >> 2) & 0b00000001  # k(Ω)   ## m
Byte9_3_75 = (byte9decodet >> 3) & 0b00000001  # M(Ω)   ## M
Byte9_4_76 = (byte9decodet >> 4) & 0b00000001  # V      ##
Byte9_5_77 = (byte9decodet >> 5) & 0b00000001  # m(V)   ## Hz
Byte9_6_78 = (byte9decodet >> 6) & 0b00000001  # DC     ## °F
Byte9_7_79 = (byte9decodet >> 7) & 0b00000001  # A      ## °C

Byte10_0_80 = (byte10decodet >> 0) & 0b00000001  # Auto ## nicht vorhanden
Byte10_1_81 = (byte10decodet >> 1) & 0b00000001  # ?    ## nicht vorhanden
Byte10_2_82 = (byte10decodet >> 2) & 0b00000001  # µ(A) ## nicht vorhanden
Byte10_3_83 = (byte10decodet >> 3) & 0b00000001  # m(A) ## nicht vorhanden
Byte10_4_84 = (byte10decodet >> 4) & 0b00000001  # ?    ## nicht vorhanden
Byte10_5_85 = (byte10decodet >> 5) & 0b00000001  # ?    ## nicht vorhanden
Byte10_6_86 = (byte10decodet >> 6) & 0b00000001  # ?    ## nicht vorhanden
Byte10_7_87 = (byte10decodet >> 7) & 0b00000001  # ?    ## nicht vorhanden

################################################################################
# Digit Balken der 7 Segmentanzeige werden aus den Bits zusammengesetzt
################################################################################
# 8___ -> example "1010101"
str_1_digit = str(Byte3_5_29) + str(Byte3_6_30) + str(Byte3_7_31) + str(Byte4_0_32) + str(Byte4_1_33) + str(Byte4_2_34) + str(Byte4_3_35)
# _8__
str_2_digit = str(Byte4_5_37) + str(Byte4_6_38) + str(Byte4_7_39) + str(Byte5_0_40) + str(Byte5_1_41) + str(Byte5_2_42) + str(Byte5_3_43)
# __8_
str_3_digit = str(Byte5_5_45) + str(Byte5_6_46) + str(Byte5_7_47) + str(Byte6_0_48) + str(Byte6_1_49) + str(Byte6_2_50) + str(Byte6_3_51)
# ___8
str_4_digit = str(Byte6_5_53) + str(Byte6_6_54) + str(Byte6_7_55) + str(Byte7_0_56) + str(Byte7_1_57) + str(Byte7_2_58) + str(Byte7_3_59)

################################################################################
# Dezimalstelle / Vorzeichen
################################################################################
# Vorzeichen
if Byte3_4_28 == 1:
    vorzeichen = -1 #
elif Byte3_4_28 == 0:
    vorzeichen = 1
################################################################################
# Dezimalstelle / Teiler
################################################################################
# 0.000 (Value / 1000)
if Byte4_4_36 == 1:
    dezimalteiler = 1/1000
# 00.00 (Value / 100)
if Byte5_4_44 == 1:
    dezimalteiler = 1/100
# 000.0 (Value / 10)
if Byte6_4_52 == 1:
    dezimalteiler = 1/10
# 0000 (Value / 1)
if Byte6_4_52 == 0 and Byte5_4_44 == 0 and Byte4_4_36 == 0:
    dezimalteiler = 1/1

#################################################################################
# Einheit - Grundeinheit °F,°C, F, Hz, Ω, V, A
#################################################################################
# Unterscheidung der Messgeräte_#Gerätetyp? 9002=1 V05B=0
# typ2=0
if Byte2_0_16 == 0:
    # Grad Fahrenheit US-Temperatur
    if Byte9_6_78 == 1: # °F
        einheit = "°F"
    # Grad Cesius Temperatur
    elif Byte9_7_79 == 1: # °C
        einheit = "°C"
    # Farad - Kapazität
    elif Byte8_4_68 == 1:# F Farad
        einheit = "F"
    # Hz Hertz Schwingungen/Sekunde
    elif Byte9_5_77 == 1 : # Hz
        einheit = "Hz"
    # Ω Ohm Widerstand
    elif Byte9_0_72 == 1:
        einheit = "Ω"
    # V Volt Spannung
    elif Byte8_1_65 == 1 : # V
        einheit = "V"
    # A Ampere Strom
    elif Byte8_6_70 == 1: # A
        einheit = "A"
    else :
        einheit = "nv" #no value
# Typ1=1
if Byte2_0_16 == 1:
    if Byte7_5_61 == 1:  # °F
        einheit = "°F"
        # Grad Cesius Temperatur
    elif Byte7_6_62 == 1:  # °C
        einheit = "°C"
        # Farad - Kapazität
    elif Byte8_4_68 == 1:  # F Farad
        einheit = "F"
        # Hz Hertz Schwingungen/Sekunde
    elif Byte9_0_72 == 1:  # Hz
        einheit = "Hz"
        # Ω Ohm Widerstand
    elif Byte9_1_73 == 1:
        einheit = "Ω"
        # V Volt Spannung
    elif Byte9_4_76 == 1:  # V
        einheit = "V"
        # A Ampere Strom
    elif Byte9_7_79 == 1:  # A
        einheit = "A"
    else:
        einheit = "nv"  # no value
################################################################################
# Statusanzeigen DC, AC, HOLD, MIN, MAX, Rel%, Auto, Diode, BUZZER, DMM-TYP
################################################################################
# Status AC / DC
# Typ2=0
if Byte2_0_16  == 0:
    if Byte8_2_66 == 1:
        str_gleich_wechsel_strom = "DC"
    elif Byte8_3_67 == 1:
        str_gleich_wechsel_strom = "AC"
    else :
        str_gleich_wechsel_strom = ""

# Typ1=1
if Byte2_0_16 == 1:
    if Byte9_6_78 == 1:
        str_gleich_wechsel_strom = "DC"
    elif Byte8_3_67 == 1:
        str_gleich_wechsel_strom = "AC"
    else:
        str_gleich_wechsel_strom = ""

################################################################################
# Status Min. / Max. #######
################################################################################
# Typ2=0 small dmm
if Byte2_0_16  == 0:
    str_min_max = ""

# Typ1=1  dmm
if Byte2_0_16 == 1:
    if Byte8_1_65 == 1:
        str_min_max = "Min"
    elif Byte8_0_64 == 1:
        str_min_max = "Max"
    else:
        str_min_max = ""
################################################################################
# Status Hold #######
################################################################################
# Typ2=0 small dmm
if Byte2_0_16  == 0:
    if Byte3_1_25 == 1:
        str_hold = "Hold"
    else:
        str_hold = ""

# Typ1=1  dmm
if Byte2_0_16 == 1:
    if Byte7_4_60 == 1:
        str_hold = "Hold"
    else:
        str_hold = ""
################################################################################
# Status Relativ / Delta  #######
################################################################################
# Typ2=0 small dmm
if Byte2_0_16  == 0:
    str_rel = ""

# Typ1=1  dmm
if Byte2_0_16 == 1:
    if Byte3_1_25 == 1:
        str_rel = "Rel"
    else:
        str_rel = ""

################################################################################
# Status Diode #######
################################################################################
# Typ2=0 small dmm
if Byte2_0_16  == 0:
    if Byte8_5_69 == 1:
        str_diode = "Diode"
    else:
        str_diode = ""

# Typ1=1  dmm
if Byte2_0_16 == 1:
    if Byte7_7_63 == 1:
        str_diode = "Diode"
    else:
        str_diode = ""
################################################################################
# Status Buzzer #######
################################################################################
# Typ2=0 small dmm
if Byte2_0_16  == 0:
    if Byte3_3_27 == 1:
        str_buzzer = "BEEP"
    else:
        str_buzzer = ""

# Typ1=1  dmm
if Byte2_0_16 == 1:
    if Byte3_3_27 == 1:
        str_buzzer = "BEEP"
    else:
        str_buzzer = ""

################################################################################
# Status DMM_Typ #######
################################################################################
if Byte2_0_16 == 1:
    str_dmm_typ = "Multimeter"
if Byte2_0_16 == 0:
    str_dmm_typ = "Small-Multimeter"

################################################################################
# Status Auto ####### Messbereichswechsel ist automatisch
################################################################################
# Typ2=0 small dmm
if Byte2_0_16  == 0:
    str_auto = ""

# Typ1=1  dmm
if Byte2_0_16 == 1:
    if Byte10_0_80 == 1:
        str_auto = "Auto"
    else:
        str_auto = ""

#################################################################################
# Exponents
#################################################################################
# Byte9_2_74  # m(F) 10^-3
# Byte8_7_71  # µ(F) 10^-6
# Byte8_0_64  # n(F) 10^-9
# Byte9_1_73 # k(Ω) 10^3
# Byte9_3_75 # M(Ω) 10^6
## Byte10_5_77 # m(V) 10^-3
## Byte11_3_83 # m(A) 10^-3
## Byte11_2_82 # µ(A) 10^-6
###############################
# Typ2=0 small dmm
if Byte2_0_16  == 0:
    # Mega M ok
    if Byte9_3_75 == 1:
        exponent = 10 ** 6
    # kilo k ok
    if Byte9_1_73 == 1:
        exponent = 10 ** 3
    # none / keiner
    if Byte9_2_74 == 0 and Byte8_7_71 == 0 and Byte8_0_64 == 0 and Byte9_1_73 == 0 and Byte9_3_75 == 0:
        exponent = 10 ** 0
    # milli m ok
    if Byte9_2_74 == 1:
        exponent = 10 ** -3
    # mµkro µ
    if Byte8_7_71 == 1:
        exponent = 10 ** -6
    # nano n
    if Byte8_0_64 == 1:
        exponent = 10 ** -9

# Byte9_6_70  # m(F) 10^-3
# Byte9_5_69  # µ(F) 10^-6
# Byte9_7_71  # n(F) 10^-9
# Byte10_2_74 # k(Ω) 10^3
# Byte10_3_75 # M(Ω) 10^6
# Byte10_5_77 # m(V) 10^-3
# Byte11_3_83 # m(A) 10^-3
# Byte11_2_82 # µ(A) 10^-6
###############################
# Typ1=1  dmm
if Byte2_0_16 == 1:
    # Mega M
    if Byte9_3_75 == 1:
        exponent = 10 ** 6
    # kilo k
    if Byte9_2_74 == 1:
        exponent = 10 ** 3
    # none / keiner
    if Byte8_6_70 == 0 and Byte8_5_69 == 0 and Byte8_7_71 == 0 and Byte9_2_74 == 0 and Byte9_3_75 == 0 and Byte9_5_77 == 0 and Byte10_3_83 == 0 and Byte10_2_82 == 0:
        exponent = 10 ** 0
    # milli m
    if Byte8_6_70 == 1 or Byte9_5_77 == 1 or Byte10_3_83 == 1:
        exponent = 10 ** -3
    # mµkro µ
    if Byte8_5_69 == 1 or Byte10_2_82 == 1:
        exponent = 10 ** -6
    # nano n
    if Byte8_7_71 == 1:
        exponent = 10 ** -9
################################################################################
# Exponent2text           Einheit mF etc.
################################################################################
# Typ2=0 small dmm
if Byte2_0_16  == 0:
    if exponent == 10 ** 6:
        expo = "M"
    if exponent == 10 ** 3:
        expo = "k"
    if exponent == 10 ** 0:
        expo = ""
    if exponent == 10 ** -3:
        expo = "m"
    if exponent == 10 ** -6:
        expo = "µ"
    if exponent == 10 ** -9:
        expo = "n"

# Typ1=1  dmm
if Byte2_0_16 == 1:
    if exponent == 10 ** 6:
        expo = "M"
    if exponent == 10 ** 3:
        expo = "k"
    if exponent == 10 ** 0:
        expo = ""
    if exponent == 10 ** -3:
        expo = "m"
    if exponent == 10 ** -6:
        expo = "µ"
    if exponent == 10 ** -9:
        expo = "n"

################################################################################
# Konsolenausgabe Si-Value  Display // dezimal Zahl // Exponentialzahl (M, k, m, µ, n)
################################################################################
# Vorzeichen
# Neue Textausgabe + VZ + DP
if Byte3_4_28 == 1:
    VZ = "-"
elif Byte3_4_28 == 0:
    VZ = ""
# Segment Digit 1
A = str(segment2dez(str_1_digit))

#Dezimalpunkt zwischen 1. und 2. Stelle
if Byte4_4_36 == 1:
    DZ2 = "."
elif Byte4_4_36 == 0:
    DZ2 = ""

# Segment Digit 2
B = str(segment2dez(str_2_digit))

#Dezimalpunkt zwischen 2. und 3. Stelle
if Byte5_4_44 == 1:
    DZ3 = "."
elif Byte5_4_44 == 0:
    DZ3 = ""

# Segment Digit 3
C = str(segment2dez(str_3_digit))

#Dezimalpunkt zwischen 3. und 4. Stelle
if Byte6_4_52 == 1:
    DZ4 = "."
elif Byte6_4_52 == 0:
    DZ4 = ""

# Segment Digit 4
D = str(segment2dez(str_4_digit))

displaytext = VZ + A + DZ2 + B + DZ3 + C + DZ4 + D
#print("DEBUG displatext: " + VZ + A + DZ2 + B + DZ3 + C + DZ4 + D)

####DEBUG
print("str_1_digit: ",type(segment2dez(str_1_digit)))
print(segment2dez(str_1_digit))
print("str_2_digit: ",type(segment2dez(str_2_digit)))
print(segment2dez(str_2_digit))
print("str_3_digit: ",type(segment2dez(str_3_digit)))
print(segment2dez(str_3_digit))
print("str_4_digit: ",type(segment2dez(str_4_digit)))
print(segment2dez(str_4_digit))

# es müssen jetzt auch Leerzeichen beachtet und ignoriert werden
#  bei nur einer Zahl (123456789) 0 gehört zu den Buchstaben!!

# "" Leersegment - DMM(1) liefert "0021" °C, DMM(2) liefert "  21" °C  --> Type STR
# "-" Bindestrich - Bei NCV
# "L" Over"Load" --> Type STR

'''_.OL_
_O.L_
_OL._'''

segmemt_num_ABCD = type(segment2dez(str_1_digit)) == int and  type(segment2dez(str_2_digit)) == int and  type(segment2dez(str_3_digit)) == int and  type(segment2dez(str_4_digit)) == int
segmemt_num_BCD =  segment2dez(str_1_digit) == " " and type(segment2dez(str_2_digit)) == int and type(segment2dez(str_3_digit)) == int and type(segment2dez(str_4_digit)) == int
segmemt_num_CD = segment2dez(str_1_digit) == " " and segment2dez(str_2_digit) == " "  and type(segment2dez(str_3_digit)) == int and type(segment2dez(str_4_digit)) == int
segmemt_num_D = segment2dez(str_1_digit) == " " and segment2dez(str_2_digit) == " "  and segment2dez(str_3_digit) == " "  and type(segment2dez(str_4_digit)) == int

segment_is_numerisch = segmemt_num_ABCD == 1 or segmemt_num_BCD == 1 or segmemt_num_CD == 1 or segmemt_num_D == 1
print("SEG_C ", segmemt_num_D)
print("SEG_CD ", segmemt_num_CD)
print("SEG_BCD ", segmemt_num_BCD)
print("SEG_ABCD ", segmemt_num_ABCD)
print("Segment_is_numerisch: ",segment_is_numerisch)

#print("A:",A,type(A))
#print("B:",B,type(B))
#print("C:",C,type(C))
#print("D:",D,type(D))

string_segmente = str(segment2dez(str_1_digit)) + \
                  str(segment2dez(str_2_digit)) + \
                  str(segment2dez(str_3_digit)) + \
                  str(segment2dez(str_4_digit))
print("string_segmente",string_segmente)
#if type(A) != str or type(B) != str or type(C) != str or type(D) != str:

if segment_is_numerisch == 1:
    if segment2dez(str_1_digit) == " ":
        A = 0
        print(segment2dez(str_1_digit))
    if segment2dez(str_2_digit) == " ":
        B = 0
    if segment2dez(str_3_digit) == " ":
        C = 0
    if segment2dez(str_4_digit) == " ":
        D = 0
    value_segmente = int(A) * 1000 + int(B) * 100 + int(C) * 10 + int(D) * 1
    print("DEBUG A: ", A)
    print("DEBUG B: ", B)
    print("DEBUG C: ", C)
    print("DEBUG D: ", D)
    print("DEBUG Value_Segmete: ", value_segmente)
else :
    value_segmente = 0 # wenn die Anzeige nicht numerisch ist, wird der wert wegen der Berechnung auf 0 gesetzt --> sollte nichts werden
    #print("Value_Segmete2: ", value_segmente)

##print("String_Segmente: ", string_segmente)

value_segmente_dezimal = value_segmente * dezimalteiler
#print("Value_Segmete: ", value_segmente)
#print( "value_Segmete_dezimal: ", value_segmente_dezimal)

value_segmente_dezimal_exponent = value_segmente * dezimalteiler * exponent
##print( "value_Segmete_dezimal_exponent: ", value_segmente_dezimal_exponent )

# Verrechnung von value_segmente und dezimalteiler und exponent und vorzeichen
value_segmente_dezimal_exponent_vorzeichen = value_segmente * dezimalteiler * exponent * vorzeichen
##print( "value_Segmete_dezimal_exponent_vorzeichen: ", value_segmente_dezimal_exponent_vorzeichen )
# Value Looks good ;-)

##print("TEXT Einheit: ", einheit)

# Verrechnung von value_segmente und dezimalteiler und exponent und vorzeichen und einheit
value_segmente_dezimal_exponent_vorzeichen_einheit = str(value_segmente * dezimalteiler * exponent * vorzeichen) + " " + einheit
##print( "TEXT value_Segmete_dezimal_exponent_vorzeichen_einheit: ", value_segmente_dezimal_exponent_vorzeichen_einheit )
# string Looks good ;-)
################################################################################

value_segmente_dezimal_vorzeichen_expo_einheit = str(value_segmente * dezimalteiler * vorzeichen) + " " + expo + einheit
##print("value_segmente_dezimal_vorzeichen_expo_einheit: ", value_segmente_dezimal_vorzeichen_expo_einheit)

# Konsolen-Ausgabe: 2021-07-04 20:39:03.527254; 0L ;0.01;MΩ
timestamp = datetime.datetime.now()

#print(timestamp)
print("#TESTKONSOLENAUSGABE################")
value_timestamp_segmente_dezimal_vorzeichen_expo_einheit_acdc = str(timestamp) + ";" + displaytext + ";" + str(value_segmente * dezimalteiler * vorzeichen) +  ";" + expo + einheit +  ";" + str_gleich_wechsel_strom
#print("value_timestamp_segmente_dezimal_vorzeichen_expo_einheit: ")
print("Datum ZeitMilli;Display;Wert;Einheit")
print(value_timestamp_segmente_dezimal_vorzeichen_expo_einheit_acdc)
print("Statusanzeigen: " + str_hold + str_rel + str_diode + str_dmm_typ + str_buzzer + str_auto + str_min_max)
#print(str_gleich_wechsel_strom, str_hold, str_min_max, str_rel, str_diode, str_auto)
print("#/TESTKONSOLENAUSGABE################")

dateiausgabe = value_timestamp_segmente_dezimal_vorzeichen_expo_einheit_acdc + ";" + str_hold + str_min_max + str_rel + str_diode #

##print("string_timestamp_segmente_dezimal_vorzeichen_expo_einheit: ")
##print(value_timestamp_segmente_dezimal_vorzeichen_expo_einheit)

################################################################################
# Dateiausgabe
################################################################################
# dateiname kommt aus dem Startparameter
if dateiname != "":
    file = open(dateiname,"a", encoding='utf-8') # Date zum schreiben öffnen w= write a = append
    file.write(str(dateiausgabe) + "\n")
    file.close() # Datei zumachen
    print("Datei angelegt")
################################################################################
# Netzwerk / MQTT Ausgabe
################################################################################
# todo
################################################################################

################################################################################
# ENDE PYTHON3 CODE
################################################################################

def test():
    print("")
    print("Debug-Bytes")
    print("Byte 1")
    print(Byte0_0_00)
    print(Byte0_1_01)
    print(Byte0_2_02)
    print(Byte0_3_03)
    print(Byte0_4_04)
    print(Byte0_5_05)
    print(Byte0_6_06)
    print(Byte0_7_07)
    print("Byte 2")
    print(Byte1_0_08)
    print(Byte1_1_09)
    print(Byte1_2_10)
    print(Byte1_3_11)
    print(Byte1_4_12)
    print(Byte1_5_13)
    print(Byte1_6_14)
    print(Byte1_7_15)
    print("Byte 3")
    print(Byte2_0_16)
    print(Byte2_1_17)
    print(Byte2_2_18)
    print(Byte2_3_19)
    print(Byte2_4_20)
    print(Byte2_5_21)
    print(Byte2_6_22)
    print(Byte2_7_23)
    print("Byte 4 E4 1110 0100")
    print(Byte3_0_24)
    print(Byte3_1_25)
    print(Byte3_2_26)
    print(Byte3_3_27)
    print(Byte3_4_28)
    print(Byte3_5_29)
    print(Byte3_6_30)
    print(Byte3_7_31)
    print("Byte 5 EB 1110 1011")
    print(Byte4_0_32)
    print(Byte4_1_33)
    print(Byte4_2_34)
    print(Byte4_3_35)
    print(Byte4_4_36)
    print(Byte4_5_37)
    print(Byte4_6_38)
    print(Byte4_7_39)
    print("Byte 6 AB 1010 1011")
    print(Byte5_0_40)
    print(Byte5_1_41)
    print(Byte5_2_42)
    print(Byte5_3_43)
    print(Byte5_4_44)
    print(Byte5_5_45)
    print(Byte5_6_46)
    print(Byte5_7_47)
    print("Byte 7 ")
    print(Byte6_0_48)
    print(Byte6_1_49)
    print(Byte6_2_50)
    print(Byte6_3_51)
    print(Byte6_4_52)
    print(Byte6_5_53)
    print(Byte6_6_54)
    print(Byte6_7_55)
    print("Byte 8")
    print(Byte7_0_56)
    print(Byte7_1_57)
    print(Byte7_2_58)
    print(Byte7_3_59)
    print(Byte7_4_60)
    print(Byte7_5_61)
    print(Byte7_6_62)
    print(Byte7_7_63)
    print("Byte 9")
    print(Byte8_0_64)
    print(Byte8_1_65)
    print(Byte8_2_66)
    print(Byte8_3_67)
    print(Byte8_4_68)
    print(Byte8_5_69)
    print(Byte8_6_70)
    print(Byte8_7_71)
    print("Byte 10")
    print(Byte9_0_72)
    print(Byte9_1_73)
    print(Byte9_2_74)
    print(Byte9_3_75)
    print(Byte9_4_76)
    print(Byte9_5_77)
    print(Byte9_6_78)
    print(Byte9_7_79)
    print("Byte 11")
    print(Byte10_0_80)
    print(Byte10_1_81)
    print(Byte10_2_82)
    print(Byte10_3_83)
    print(Byte10_4_84)
    print(Byte10_5_85)
    print(Byte10_6_86)
    print(Byte10_7_87)

#test()
Shiro-Nek0 commented 1 year ago

Ended up rewriting it, and now that i have the multi-meter on hand added BLE function via bleak (finally)