from cmath import rect
import json
import os
import time
from threading import Lock, Timer, Thread
import threading
import copy
import tempfile
import filecmp

import subprocess

from ipc_sma_tools import DSP_I2C_ADDRESS_1
from ipc_sma_tools import DSP_I2C_ADDRESS_2
from ipc_sma_tools import DSP_I2C_ADDRESS_3
from ipc_sma_tools import DSP_I2C_ADDRESS_4

from ipc_spi_mem import bootCheck, writeSPI, eraseSPI

# "pip3 install dbus-python" on Linux
import dbus
import dbus.mainloop.glib
import dbus.service

try:
    import OPi.GPIO as GPIO
except:
    print('GPIO library not found, disabling GPIO functionality.')
    GPIO = None

import ipc_common
import ipc_discoveryservice
import ipc_udpcommand
import ipc_peakreadbackservice
import ipc_constants
import ipc_filters
import ipc_sma_tools
import ipc_util
# from ipc_dsp_addresses import SW_VERSION
from ipc_common import DSP_VARIANT_FILE
file = open(DSP_VARIANT_FILE, "r")
about_string = str(file.read()).split(" ")
current_variant_value_for_import = about_string[0]
file.close()

if (current_variant_value_for_import == "variant1.code"):
	from ipc_dsp_addresses_variant1 import SW_VERSION
elif (current_variant_value_for_import == "variant2.code"):
	from ipc_dsp_addresses_variant2 import SW_VERSION
elif (current_variant_value_for_import == "variant3.code"):
	from ipc_dsp_addresses_variant3 import SW_VERSION
elif (current_variant_value_for_import == "variant4.code"):
	from ipc_dsp_addresses_variant4 import SW_VERSION
elif (current_variant_value_for_import == "variant5.code"):
	from ipc_dsp_addresses_variant5 import SW_VERSION
elif (current_variant_value_for_import == "variant6.code"):
	from ipc_dsp_addresses_variant6 import SW_VERSION
elif (current_variant_value_for_import == "variant7.code"):
	from ipc_dsp_addresses_variant7 import SW_VERSION
elif (current_variant_value_for_import == "variant8.code"):
	from ipc_dsp_addresses_variant2 import SW_VERSION
elif (current_variant_value_for_import == "variant9.code"):
	from ipc_dsp_addresses_variant5 import SW_VERSION
else:
	from ipc_dsp_addresses_variant1 import SW_VERSION

from ipc_util import python_to_dbus
import ipc_dsp


dhcp = threading.Event()


class ServiceObject(dbus.service.Object):
    def __init__(self, conn, object_path, debug_mode, gpio_enabled):
        # Initial status for save timer is false (inactive)
        self.is_data_json_timer_active = False
        self.is_global_presets_json_timer_active = False
        self.is_speaker_presets_json_timer_active = False
        self.is_all_speaker_presets_json_timer_active = False
        self.data_json_timer = Timer(10.0, self.save_change_to_data_json)
        self.global_presets_json_timer = Timer(10.0, self.save_change_to_global_presets_json)
        self.speaker_presets_json_timer = Timer(10.0, self.save_change_to_speaker_presets_json)
        self.all_speaker_presets_json_timer = Timer(10.0, self.save_change_to_all_speaker_presets_json)

        self.write_first_config = True
        self.write_first_global_presets = True
        self.write_first_speaker_presets = True
        self.write_first_all_speaker_presets = True

        if (check_dhcp_in_config()):
            dhcp.set()

        bootCheck()

        dbus.service.Object.__init__(self, conn, object_path)

        file = open(ipc_common.DSP_VARIANT_FILE, "r")
        about_string = str(file.read()).split(" ")
        self.current_variant_value = about_string[0]
        self.current_variant_value = self.current_variant_value[:-5]
        file.close()

        # self.check_dsp_firmware_update()

        self.debug_mode = debug_mode

        global GPIO
        if not gpio_enabled and GPIO is not None:
            print('GPIO functionality disabled by user.')
            GPIO = None

        # ----------------- LOAD CONFIG FILE -----------------
        file1 = ipc_common.CONFIG_FILE_1
        file2 = ipc_common.CONFIG_FILE_2

        try:
            if os.path.isfile(ipc_common.CONFIG_FILE_1):
                if os.path.isfile(ipc_common.CONFIG_FILE_2):
                    mod_time_file1 = os.path.getmtime(ipc_common.CONFIG_FILE_1)
                    mod_time_file2 = os.path.getmtime(ipc_common.CONFIG_FILE_2)

                    if mod_time_file1 > mod_time_file2:
                        file1 = ipc_common.CONFIG_FILE_1
                        file2 = ipc_common.CONFIG_FILE_2
                    else:
                        file1 = ipc_common.CONFIG_FILE_1
                        file2 = ipc_common.CONFIG_FILE_2
        except Exception as e:
            print(f'Cannot compare modification time between config files')

        #Try to read the first file : CONFIG_FILE_1
        try:
            with open(file1, 'r+') as json_file:
                self.data = json.load(json_file)
        except(json.JSONDecodeError, IOError) as e:
            print(f"Error reading from {file1}: {e}")

            #Try to read the second file : CONFIG_FILE_2
            try:
                with open(file2, 'r+') as json_file:
                    self.data = json.load(json_file)
            except(json.JSONDecodeError, IOError) as e:
                print(f"Error reading from {file2}: {e}")

                #Try to read the backup file : SPEAKER_PRESETS_FILE_CLEAN
                try:
                    with open(ipc_common.CONFIG_FILE_CLEAN, 'r') as json_file:
                        self.data = json.load(json_file)
                except(json.JSONDecodeError, IOError) as e:
                    print(f"Error reading from {ipc_common.CONFIG_FILE_CLEAN}: {e}")

        # ----------------- LOAD SPEAKER PRESET FILE -----------------
        file1 = ipc_common.SPEAKER_PRESETS_FILE_1
        file2 = ipc_common.SPEAKER_PRESETS_FILE_2

        try:
            if os.path.isfile(ipc_common.SPEAKER_PRESETS_FILE_1):
                if os.path.isfile(ipc_common.SPEAKER_PRESETS_FILE_2):
                    mod_time_file1 = os.path.getmtime(ipc_common.SPEAKER_PRESETS_FILE_1)
                    mod_time_file2 = os.path.getmtime(ipc_common.SPEAKER_PRESETS_FILE_2)

                    if mod_time_file1 > mod_time_file2:
                        file1 = ipc_common.SPEAKER_PRESETS_FILE_1
                        file2 = ipc_common.SPEAKER_PRESETS_FILE_2
                    else:
                        file1 = ipc_common.SPEAKER_PRESETS_FILE_2
                        file2 = ipc_common.SPEAKER_PRESETS_FILE_1
        except Exception as e:
            print(f'Cannot compare modification time between speaker presets files')

        #Try to read the first file : SPEAKER_PRESETS_FILE_1
        try:
            with open(file1, 'r+') as json_file:
                self.speaker_presets = json.load(json_file)
        except(json.JSONDecodeError, IOError) as e:
            print(f"Error reading from {file1}: {e}")

            #Try to read the second file : SPEAKER_PRESETS_FILE_2
            try:
                with open(file2, 'r+') as json_file:
                    self.speaker_presets = json.load(json_file)
            except(json.JSONDecodeError, IOError) as e:
                print(f"Error reading from {file2}: {e}")

                #Try to read the backup file : SPEAKER_PRESETS_FILE_CLEAN
                try:
                    with open(ipc_common.SPEAKER_PRESETS_FILE_CLEAN, 'r') as json_file:
                        self.speaker_presets = json.load(json_file)
                except(json.JSONDecodeError, IOError) as e:
                    print(f"Error reading from {ipc_common.SPEAKER_PRESETS_FILE_CLEAN}: {e}")

        # ----------------- LOAD ALL SPEAKER PRESET FILE -----------------
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6" or self.current_variant_value == "variant9"):
            file1 = ipc_common.ALL_SPEAKER_PRESETS_FILE_1
            file2 = ipc_common.ALL_SPEAKER_PRESETS_FILE_2

            try:
                if os.path.isfile(ipc_common.ALL_SPEAKER_PRESETS_FILE_1):
                    if os.path.isfile(ipc_common.ALL_SPEAKER_PRESETS_FILE_2):
                        mod_time_file1 = os.path.getmtime(ipc_common.ALL_SPEAKER_PRESETS_FILE_1)
                        mod_time_file2 = os.path.getmtime(ipc_common.ALL_SPEAKER_PRESETS_FILE_2)

                        if mod_time_file1 > mod_time_file2:
                            file1 = ipc_common.ALL_SPEAKER_PRESETS_FILE_1
                            file2 = ipc_common.ALL_SPEAKER_PRESETS_FILE_2
                        else:
                            file1 = ipc_common.ALL_SPEAKER_PRESETS_FILE_2
                            file2 = ipc_common.ALL_SPEAKER_PRESETS_FILE_1
            except Exception as e:
                print(f'Cannot compare modification time between all presets files')

            #Try to read the first file : ALL_SPEAKER_PRESETS_FILE_1
            try:
                with open(file1, 'r+') as json_file:
                    self.all_speaker_presets = json.load(json_file)
            except(json.JSONDecodeError, IOError) as e:
                print(f"Error reading from {file1}: {e}")

                #Try to read the second file : ALL_SPEAKER_PRESETS_FILE_2
                try:
                    with open(file2, 'r+') as json_file:
                        self.all_speaker_presets = json.load(json_file)
                except(json.JSONDecodeError, IOError) as e:
                    print(f"Error reading from {file2}: {e}")

                    #Try to read the backup file : SPEAKER_PRESETS_FILE_CLEAN
                    try:
                        with open(ipc_common.ALL_SPEAKER_PRESETS_FILE_CLEAN, 'r') as json_file:
                            self.all_speaker_presets = json.load(json_file)
                    except(json.JSONDecodeError, IOError) as e:
                        print(f"Error reading from {ipc_common.ALL_SPEAKER_PRESETS_FILE_CLEAN}: {e}")


        # ----------------- LOAD GLOBAL SPEAKER PRESET FILE -----------------
        file1 = ipc_common.GLOBAL_PRESETS_FILE_1
        file2 = ipc_common.GLOBAL_PRESETS_FILE_2

        try:
            if os.path.isfile(ipc_common.GLOBAL_PRESETS_FILE_1):
                if os.path.isfile(ipc_common.GLOBAL_PRESETS_FILE_2):
                    mod_time_file1 = os.path.getmtime(ipc_common.GLOBAL_PRESETS_FILE_1)
                    mod_time_file2 = os.path.getmtime(ipc_common.GLOBAL_PRESETS_FILE_2)

                    if mod_time_file1 > mod_time_file2:
                        file1 = ipc_common.GLOBAL_PRESETS_FILE_1
                        file2 = ipc_common.GLOBAL_PRESETS_FILE_2
                    else:
                        file1 = ipc_common.GLOBAL_PRESETS_FILE_2
                        file2 = ipc_common.GLOBAL_PRESETS_FILE_1
        except Exception as e:
            print(f'Cannot compare modification time between global presets files')

        #Try to read the first file : GLOBAL_PRESETS_FILE_1
        try:
            with open(file1, 'r+') as json_file:
                self.global_presets = json.load(json_file)
        except(json.JSONDecodeError, IOError) as e:
            print(f"Error reading from {file1}: {e}")

            #Try to read the second file : GLOBAL_PRESETS_FILE_2
            try:
                with open(file2, 'r+') as json_file:
                    self.global_presets = json.load(json_file)
            except(json.JSONDecodeError, IOError) as e:
                print(f"Error reading from {file2}: {e}")

                #Try to read the backup file : SPEAKER_PRESETS_FILE_CLEAN
                try:
                    with open(ipc_common.GLOBAL_PRESETS_FILE_CLEAN, 'r') as json_file:
                        self.global_presets = json.load(json_file)
                except(json.JSONDecodeError, IOError) as e:
                    print(f"Error reading from {ipc_common.GLOBAL_PRESETS_FILE_CLEAN}: {e}")

        with open(ipc_common.OEM_FILE, 'r+') as json_file:
            try:
                self.oem = json.load(json_file)
            except ValueError as e:
                    print(e)
                    self.oem = {}
                    oem_label = {"oem_label":""}
                    oem_code = {"oem_code":"0000000000"}
                    self.oem.update(oem_label)
                    self.oem.update(oem_code)

        self.check_data_fields(self)

        self.check_data_json_timer()
        self.check_speaker_presets_json_timer()
        self.check_global_presets_json_timer()
        self.save_change_to_oem_json()

        self.populate_about_field()

        self.neighbours = []  # The list of neighbours in {hw_addr, ip_addr, desc, alive, last_report_time, model, cloud_device_name} format
        # The local device is always fixed at first place
        
        ip_infos = ipc_util.our_real_ip_addr(True).split()
        self.neighbours.append({
            'hw_addr': ipc_util.our_eth_mac_addr(),
            'ip_addr': ip_infos[0],
            'ip_subnet': ip_infos[1],
            'ip_gateway': ip_infos[2],
            'desc': "LOCAL",
            'model': self.data["settings"]["model"],
            'cloud_device_name': self.data["settings"].get("cloud_device_name", ipc_constants.DEFAULT_STRING),  # May not exist
            'serial': self.data["settings"].get("serial", ipc_constants.DEFAULT_STRING),  # May not exist
            'firmware_version': self.data["settings"].get("hardware_version", ipc_constants.DEFAULT_STRING),
            'oem_label': self.oem.get("oem_label", ipc_constants.DEFAULT_STRING),
            'oem_model': self.oem.get("oem_model", ipc_constants.DEFAULT_STRING),
            'oem_desc': self.oem.get("oem_desc", ipc_constants.DEFAULT_STRING),
            'dante_capable': self.data["settings"].get("dante_capable", ipc_constants.DEFAULT_BOOL),
            'alive': True,
            'last_report_time': 0.0
        })

        self.lock = Lock()

        with self.lock:
            # First-time setup: If initial SSID for WLAN is not set, generate one based on adapter's MAC address
            if self.data['settings']['SSID'] == 'PLACEHOLDER-NEEDS-TO-BE-REPLACED':
                new_ssid = 'AMP_' + ipc_util.our_wlan_mac_addr()[-5:].replace(':', '')
                self.data['settings']['SSID'] = new_ssid
                self.data['settings']['hotspot_pass'] = '12345678'   # Also set a valid initial password
                self.check_data_json_timer()
                self.__wlan_hotspot_params(ssid=new_ssid, wpa_version=None, channel=None, password='12345678')

        self.disc_svc = ipc_discoveryservice.IPCDiscoveryService(self)
        self.udpCommand_svc = ipc_udpcommand.IPCUdpCommand(self)
        self.readback_svc = ipc_peakreadbackservice.IPCPeakReadbackService(self.current_variant_value)

        # Wi-Fi is autoenabled on network restart. Check if we need to disable it.
        if self.data["settings"]["hotspot_status"] is False:
            self.__wlan_conf(False)
        else:
            self.__wlan_conf(True)

        if GPIO:
            # Power-off detection
            GPIO.setmode(GPIO.SUNXI)
            GPIO.setup(ipc_common.GPIO_PWRFAIL, GPIO.IN)

            # Rising/falling event detection somehow doesn't work, so we have to poll the pin manually.
            self.poweroff_detection_thread = Thread(
                target=handle_poweroff,
                name="PWROFF-M",
                kwargs={"readback_service": self.readback_svc, "givaipc_service": self}
            )
            self.poweroff_detection_thread.start()

            if (self.current_variant_value != "variant5" and self.current_variant_value != "variant6" and self.current_variant_value != "variant9"):
                # GPIO.setup(ipc_common.GPIO_OUTPUT_RELAY, GPIO.OUT)
                # Set output high -> relay is closed and status is OK !
                # GPIO.output(ipc_common.GPIO_OUTPUT_RELAY,GPIO.HIGH)

                GPIO.setup(ipc_common.BUTTON_STDBY, GPIO.IN)
                GPIO.setup(ipc_common.BUTTON_GPI, GPIO.IN)

                self.standby_input_thread = Thread(
                    target=handle_standby_input,
                    name="STDBY-M",
                    kwargs={"givaipc_service": self}
                )
                self.standby_input_thread.start()

                self.gpi_input_thread = Thread(
                    target=handle_gpi_input,
                    name="GPI-M",
                    kwargs={"givaipc_service": self}
                )
                self.gpi_input_thread.start()

                fail_relay_thread = Thread(target=fail_relay)
                fail_relay_thread.start()

        self.check_dsp_firmware_update()

        # Populate all DSP blocks with previous saved content
        try:
            ipc_dsp.dsp_global_boot_preset(self.current_variant_value,
                                      self.data["channels"],
                                      self.data["groups"],
                                      self.data["speaker_presets"],
                                      self.data["settings"])
        except OSError:
            print("DSP global preset: DSP disconnected, unable to access.")

        interface_thread = threading.Thread(target=monitor_interface, args=('eth0', 1), daemon=True)
        interface_thread.start()


    # Not a Dbus method - this is accessible only from system service host which runs the listening UDP socket
    def update_neighbour(self, our_hw_addr: str, hw_addr: str, ip_addr: str, ip_subnet:str, ip_gateway:str, desc: str, model: str, cloud_device_name: str, serial: str, firmware_version: str, oem_label: str, oem_model: str, oem_desc: str, dante_capable: bool, last_report_time: float):
        with self.lock:
            # Check if neighbour is already present (by hw_addr) and update its status
            for neighbour in self.neighbours:
                if neighbour['hw_addr'] == our_hw_addr:  # Don't check ourselves
                    continue
                if neighbour['hw_addr'] == hw_addr:
                    if not neighbour['alive']:
                        print('Neighbour \'{}\' ({} @ {}) is alive again.'.format(desc, hw_addr, ip_addr))
                    neighbour['ip_addr'] = ip_addr
                    neighbour['ip_subnet'] = ip_subnet
                    neighbour['ip_gateway'] = ip_gateway
                    neighbour['desc'] = desc
                    neighbour['model'] = model
                    neighbour['cloud_device_name'] = cloud_device_name
                    neighbour['serial'] = serial
                    neighbour['firmware_version'] = firmware_version
                    neighbour['oem_label'] = oem_label
                    neighbour['oem_model'] = oem_model
                    neighbour['oem_desc'] = oem_desc
                    neighbour['dante_capable'] = dante_capable
                    neighbour['alive'] = True
                    neighbour['last_report_time'] = last_report_time
                    return
            # Otherwise, add new element
            print("New neighbour \'{}\' ({} @ {}) reports in.".format(desc, hw_addr, ip_addr))
            self.neighbours.append({
                'hw_addr': hw_addr,
                'ip_addr': ip_addr,
                'ip_subnet': ip_subnet,
                'desc': desc,
                'model' : model,
                'cloud_device_name' : cloud_device_name,
                'serial' : serial,
                'firmware_version' : firmware_version,
                'oem_label' : oem_label,
                'oem_model' : oem_model,
                'oem_desc' : oem_desc,
                'dante_capable' : dante_capable,
                'alive': True,
                'last_report_time': last_report_time
            })

    # Not a Dbus method
    def check_neighbours(self, our_hw_addr: str):
        curr_time = time.time()
        with self.lock:
            for neighbour in self.neighbours:
                if neighbour['hw_addr'] == our_hw_addr:  # Don't check ourselves
                    continue
                if neighbour['alive'] and curr_time - neighbour['last_report_time'] > 7.0:
                    print('Neighbour \'{}\' ({} @ {}) not responding, disabling it until further notice.'.format(
                        neighbour['desc'],
                        neighbour['hw_addr'],
                        neighbour['ip_addr'])
                    )
                    neighbour['alive'] = False

    # Not a Dbus method
    def check_data_fields(self, arg):
        # Check if data.json is up to date (from v1.0)

        # Add signal generator to data.json file
        if (self.data["settings"].get("signal_generator") is None):
            signal_generator = {"signal_generator":{"frequency_generator": {"frequency":ipc_constants.SIG_GEN_FREQ_DEFAULT, "gain":ipc_constants.SIG_GEN_FREQ_GAIN_DEFAULT}, "pink_noise":{"gain": ipc_constants.SIG_GEN_PINK_NOISE_GAIN_DEFAULT}}}
            self.data["settings"].update(signal_generator)

        # Add 12 channels to data.json
        if (len(self.data["channels"]) == 4):
            last_ch = self.data["channels"][-1]
            self.data["channels"].extend([last_ch] * 12)

        if (len(self.data["speaker_presets"]) == 4):
            last_pr = self.data["speaker_presets"][-1]
            self.data["speaker_presets"].extend([last_pr] * 12)

            for i_folder in range(0, len(self.global_presets)):
                for i_file in range (0, len(self.global_presets[i_folder]["files"])):
                    last_channel = self.global_presets[i_folder]["files"][i_file]["user_settings"][-1]
                    self.global_presets[i_folder]["files"][i_file]["user_settings"].extend([last_channel] * 12)

                    last_preset = self.global_presets[i_folder]["files"][i_file]["speaker_presets"][-1]
                    self.global_presets[i_folder]["files"][i_file]["speaker_presets"].extend([last_preset] * 12)

        # If too much channels added in v1.3.4R, reduce them to 16 only
        if (len(self.global_presets) > 0) :
            if (len(self.global_presets[0]["files"]) > 0) :
                if (len(self.global_presets[0]["files"][0]["user_settings"]) > 16):
                    for i_folder in range(0, len(self.global_presets)):
                        for i_file in range (0, len(self.global_presets[i_folder]["files"])):
                            first_16_channels = self.global_presets[i_folder]["files"][i_file]["user_settings"][:16]
                            self.global_presets[i_folder]["files"][i_file]["user_settings"] = first_16_channels

                            first_16_presets = self.global_presets[i_folder]["files"][i_file]["speaker_presets"][:16]
                            self.global_presets[i_folder]["files"][i_file]["speaker_presets"] = first_16_presets

        # Add mixer settings to data.json file
        for i_channel in range (0, ipc_constants.NUM_OF_CHANNELS):
            if (self.data["channels"][i_channel].get("mixer") is None):
                mixer = {"mixer":[{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0}]}
                self.data["channels"][i_channel].update(mixer)
                # if (i_channel < 4):
                #     self.data["channels"][i_channel]["mixer"][self.data["channels"][i_channel]["source_pri"]]["gain"] = 0.0

        # Add last preset to data.json file
        for i_channel in range (0, ipc_constants.NUM_OF_CHANNELS):
            if (self.data["channels"][i_channel].get("preset") is None):
                preset = {"preset":""}
                self.data["channels"][i_channel].update(preset)



        # Update global preset 
        for i_folder in range(0, len(self.global_presets)):
            for i_file in range (0, len(self.global_presets[i_folder]["files"])):
                for i in range (0, int(ipc_constants.NUM_OF_CHANNELS)):
                    # Add mixer and preset settings to all global_presets.json
                    if (self.global_presets[i_folder]["files"][i_file]["user_settings"][i].get("preset") is None):
                        preset = {"preset":""}
                        self.global_presets[i_folder]["files"][i_file]["user_settings"][i].update(preset)
                    if not "mixer" in self.global_presets[i_folder]["files"][i_file]["user_settings"][i]:
                        mixer = {"mixer":[{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0},{"gain": -80.0}]}
                        self.global_presets[i_folder]["files"][i_file]["user_settings"][i].update(mixer)
                        index_source = self.global_presets[i_folder]["files"][i_file]["user_settings"][i]["source_pri"]
                        self.global_presets[i_folder]["files"][i_file]["user_settings"][i]["mixer"][index_source]["gain"] = 0.0
                    if (self.global_presets[i_folder]["files"][i_file]["speaker_presets"][i]["xover_hp_filter"].get("xover_hp_overide") is None):
                        overide = {"xover_hp_overide" : False}
                        self.global_presets[i_folder]["files"][i_file]["speaker_presets"][i]["xover_hp_filter"].update(overide)
                    if (self.global_presets[i_folder]["files"][i_file]["speaker_presets"][i]["xover_lp_filter"].get("xover_lp_overide") is None):
                        overide = {"xover_lp_overide" : False}
                        self.global_presets[i_folder]["files"][i_file]["speaker_presets"][i]["xover_lp_filter"].update(overide)
                    #check Limiter RMS/PEAK Threshold value
                    if (self.global_presets[i_folder]["files"][i_file]["speaker_presets"][i]["lim_rms"]["lim_rms_thres"] > ipc_constants.LIM_RMS_THRES_MAX ):
                        self.global_presets[i_folder]["files"][i_file]["speaker_presets"][i]["lim_rms"]["lim_rms_thres"] = ipc_constants.LIM_RMS_THRES_MAX
                    if (self.global_presets[i_folder]["files"][i_file]["speaker_presets"][i]["lim_peak"]["lim_peak_thres"] > ipc_constants.LIM_PEAK_THRES_MAX ):
                        self.global_presets[i_folder]["files"][i_file]["speaker_presets"][i]["lim_peak"]["lim_peak_thres"] = ipc_constants.LIM_PEAK_THRES_MAX
                    if (self.global_presets[i_folder]["files"][i_file]["user_settings"][i]["lim_rms"]["lim_rms_thres"] > ipc_constants.LIM_RMS_THRES_MAX ):
                        self.global_presets[i_folder]["files"][i_file]["user_settings"][i]["lim_rms"]["lim_rms_thres"] = ipc_constants.LIM_RMS_THRES_MAX
                    if (self.global_presets[i_folder]["files"][i_file]["user_settings"][i]["lim_peak"]["lim_peak_thres"] > ipc_constants.LIM_PEAK_THRES_MAX ):
                        self.global_presets[i_folder]["files"][i_file]["user_settings"][i]["lim_peak"]["lim_peak_thres"] = ipc_constants.LIM_PEAK_THRES_MAX

        if(len(self.global_presets)>0) :
            if (self.global_presets[0]["folder_name"] == "Default Folder" and self.global_presets[0]["files"][0]["file_name"] == "Default Preset"):
                for i in range (0, int(ipc_constants.NUM_OF_CHANNELS)):
                    # Update default channel name
                    for j, label in enumerate(ipc_constants.OLD_CHANNEL_NAME):
                        if self.global_presets[0]["files"][0]["user_settings"][i]["name"] == label:
                            self.global_presets[0]["files"][0]["user_settings"][i]["name"] = ipc_constants.NEW_CHANNEL_NAME[j]
                    # Set default mute value to True
                    self.global_presets[0]["files"][0]["user_settings"][i]["mute"] = True
                    # Set default gain value to 0.0
                    self.global_presets[0]["files"][0]["user_settings"][i]["gain"] = 0.0
                    for j in range(0, int(ipc_constants.NUM_OF_INPUTS)):
                        self.global_presets[0]["files"][0]["user_settings"][i]["mixer"][j]["gain"] = -80.0
                        if ((i%4) == j):
                            self.global_presets[0]["files"][0]["user_settings"][i]["mixer"][j]["gain"] = 0.0
                    # Set limiter to default max value on default global audio preset
                    self.global_presets[0]["files"][0]["user_settings"][i]["lim_rms"]["lim_rms_thres"] = ipc_constants.LIM_RMS_THRES_MAX
                    self.global_presets[0]["files"][0]["user_settings"][i]["lim_peak"]["lim_peak_thres"] = ipc_constants.LIM_PEAK_THRES_MAX
                    self.global_presets[0]["files"][0]["speaker_presets"][i]["lim_rms"]["lim_rms_thres"] = ipc_constants.LIM_RMS_THRES_MAX
                    self.global_presets[0]["files"][0]["speaker_presets"][i]["lim_peak"]["lim_peak_thres"] = ipc_constants.LIM_PEAK_THRES_MAX


        # Update speaker preset
        for i_folder in range(0, len(self.speaker_presets)):
            for i_file in range (0, len(self.speaker_presets[i_folder]["files"])):
                #check XOVER HP/LP overide
                if(self.speaker_presets[i_folder]["files"][i_file]["settings"]["xover_hp_filter"].get("xover_hp_overide") is None):
                    xover_hp_overide = {"xover_hp_overide":False}
                    self.speaker_presets[i_folder]["files"][i_file]["settings"]["xover_hp_filter"].update(xover_hp_overide)
                if(self.speaker_presets[i_folder]["files"][i_file]["settings"]["xover_hp_filter"].get("xover_lp_overide") is None):
                    xover_lp_overide = {"xover_lp_overide":False}
                    self.speaker_presets[i_folder]["files"][i_file]["settings"]["xover_lp_filter"].update(xover_lp_overide)

                # check extra infos on preset overide
                if (self.speaker_presets[i_folder]["files"][i_file].get("author") is None):
                    author = {"author":""}
                    self.speaker_presets[i_folder]["files"][i_file].update(author)
                if (self.speaker_presets[i_folder]["files"][i_file].get("version") is None):
                    version = {"version":""}
                    self.speaker_presets[i_folder]["files"][i_file].update(version)
                if (self.speaker_presets[i_folder]["files"][i_file].get("note") is None):
                    note = {"note":""}
                    self.speaker_presets[i_folder]["files"][i_file].update(note)
                if (self.speaker_presets[i_folder]["files"][i_file].get("oem_code") is None):
                    oem_code = {"oem_code":""}
                    self.speaker_presets[i_folder]["files"][i_file].update(oem_code)

                #check Limiter RMS/PEAK Threshold value
                if (self.speaker_presets[i_folder]["files"][i_file]["settings"]["lim_rms"]["lim_rms_thres"] > ipc_constants.LIM_RMS_THRES_MAX ):
                    self.speaker_presets[i_folder]["files"][i_file]["settings"]["lim_rms"]["lim_rms_thres"] = ipc_constants.LIM_RMS_THRES_MAX
                if (self.speaker_presets[i_folder]["files"][i_file]["settings"]["lim_peak"]["lim_peak_thres"] > ipc_constants.LIM_PEAK_THRES_MAX ):
                    self.speaker_presets[i_folder]["files"][i_file]["settings"]["lim_peak"]["lim_peak_thres"] = ipc_constants.LIM_PEAK_THRES_MAX

        #set limiter to default max value on default speaker preset
        if(len(self.speaker_presets)>0) :
            if (self.speaker_presets[0]["folder_name"] == "Factory Folder" and self.speaker_presets[0]["files"][0]["file_name"] == "Blank Preset"):
                self.speaker_presets[0]["files"][0]["settings"]["lim_rms"]["lim_rms_thres"] = ipc_constants.LIM_RMS_THRES_MAX
                self.speaker_presets[0]["files"][0]["settings"]["lim_peak"]["lim_peak_thres"] = ipc_constants.LIM_PEAK_THRES_MAX

        # check XOVER HP/LP overide on data.json file
        for i_channel in range (0, ipc_constants.NUM_OF_CHANNELS):
            if (self.data["speaker_presets"][i_channel]["xover_hp_filter"].get("xover_hp_overide") is None):
                overide = {"xover_hp_overide" : False}
                self.data["speaker_presets"][i_channel]["xover_hp_filter"].update(overide)
            if (self.data["speaker_presets"][i_channel]["xover_lp_filter"].get("xover_lp_overide") is None):
                overide = {"xover_lp_overide" : False}
                self.data["speaker_presets"][i_channel]["xover_lp_filter"].update(overide)

        # Set signal generator to -50dB after boot
        if self.data["settings"]["signal_generator"]["frequency_generator"]["gain"] > ipc_constants.SIG_GEN_FREQ_GAIN_DEFAULT:
            self.data["settings"]["signal_generator"]["frequency_generator"]["gain"] = ipc_constants.SIG_GEN_FREQ_GAIN_DEFAULT
        if self.data["settings"]["signal_generator"]["frequency_generator"]["frequency"] != ipc_constants.SIG_GEN_FREQ_DEFAULT:
            self.data["settings"]["signal_generator"]["frequency_generator"]["frequency"] = ipc_constants.SIG_GEN_FREQ_DEFAULT
        if self.data["settings"]["signal_generator"]["pink_noise"]["gain"] > ipc_constants.SIG_GEN_PINK_NOISE_GAIN_DEFAULT:
            self.data["settings"]["signal_generator"]["pink_noise"]["gain"] = ipc_constants.SIG_GEN_PINK_NOISE_GAIN_DEFAULT

        # Check UDP Port
        if (self.data["settings"].get("udp_port") is None):
            udp_port = {"udp_port":6790}
            self.data["settings"].update(udp_port)

        # Check amp stage disabled 
        if (self.data["settings"].get("amp_stage_disabled") is None):
            amp_stage_disabled = {"amp_stage_disabled":False}
            self.data["settings"].update(amp_stage_disabled)

        # Check OEM file
        # if not self.get("oem"):
        try :
            if (self.oem.get("oem_label") is None):
                oem_label = {"oem_label":""}
                self.oem.update(oem_label)
        except :
                oem_label = {"oem_label":""}
                self.oem.update(oem_label)
        try:
            if (self.oem.get("oem_code") is None):
                oem_code = {"oem_code":"0000000000"}
                self.oem.update(oem_code)
        except :
                oem_code = {"oem_code":"0000000000"}
                self.oem.update(oem_code)

        try:
            if (self.oem.get("oem_model") is None):
                oem_model = {"oem_model":""}
                self.oem.update(oem_model)
        except :
                oem_model = {"oem_model":""}
                self.oem.update(oem_model)

        try:
            if (self.oem.get("oem_desc") is None):
                oem_desc = {"oem_desc":""}
                self.oem.update(oem_desc)
        except :
                oem_desc = {"oem_desc":""}
                self.oem.update(oem_desc)

        # Check Dante Capable
        try:
            if (self.oem.get("dante_capable") is None):
                dante_capable = {"dante_capable":False}
                self.oem.update(dante_capable)
        except :
                dante_capable = {"dante_capable":False}
                self.oem.update(dante_capable)

        # Add OEM Label to data.json
        if (self.data["settings"].get("oem_label") is None):
            oem_label = {"oem_label":self.oem.get("oem_label")}
            self.data["settings"].update(oem_label)

        # Add HiZ filter to data.json
        if (self.data["settings"].get("high_impedance_filter") is None):
            high_impedance = {"high_impedance_filter": []}
            self.data["settings"].update(high_impedance)
            for i_channel in range (0, ipc_constants.NUM_OF_CHANNELS):
                    self.data["settings"]["high_impedance_filter"].append(False)

        # Add HiZ filter to data.json from 4 to 16 channels
        if (len(self.data["settings"].get("high_impedance_filter")) == 4):
            for i_channel in range (0, 12):
                    self.data["settings"]["high_impedance_filter"].append(False)

        # Add 16 channels bridge mode
        if (self.data["settings"].get("bridge_mode_56") is None):
            bridge_56 = {"bridge_mode_56": False}
            self.data["settings"].update(bridge_56)

        if (self.data["settings"].get("bridge_mode_78") is None):
            bridge_78 = {"bridge_mode_78": False}
            self.data["settings"].update(bridge_78)

        if (self.data["settings"].get("bridge_mode_910") is None):
            bridge_910 = {"bridge_mode_910": False}
            self.data["settings"].update(bridge_910)

        if (self.data["settings"].get("bridge_mode_1112") is None):
            bridge_1112 = {"bridge_mode_1112": False}
            self.data["settings"].update(bridge_1112)

        if (self.data["settings"].get("bridge_mode_1314") is None):
            bridge_1314 = {"bridge_mode_1314": False}
            self.data["settings"].update(bridge_1314)

        if (self.data["settings"].get("bridge_mode_1516") is None):
            bridge_1516 = {"bridge_mode_1516": False}
            self.data["settings"].update(bridge_1516)

        # Check Front Panel Lock
        if (self.data["settings"].get("front_lock") is None):
            front_lock = {"front_lock":False}
            self.data["settings"].update(front_lock)

        # Check locate status
        if (self.data["settings"].get("locate") is None):
            locate = {"locate":False}
            self.data["settings"].update(locate)

        # Disable locate at boot
        self.data["settings"]["locate"] = False

        # Update channels name if it's old default channel name
        for i_channel in range (0, ipc_constants.NUM_OF_CHANNELS):
            for j, label in enumerate(ipc_constants.OLD_CHANNEL_NAME):
                if self.data["channels"][i_channel]["name"] == label:
                    self.data["channels"][i_channel]["name"] = ipc_constants.NEW_CHANNEL_NAME[j]

    def __source_update(self, channel):
        global GPIO
        if GPIO:
            state = GPIO.input(ipc_common.GPIO_SOURCE_CHANGE)


            self.change_active_source(int(state))

    def __standby_update(self):
        global GPIO
        if GPIO:
            state = GPIO.input(ipc_common.GPIO_SOURCE_CHANGE)

            if state:
                amp_stage_disabled = False
                self.data["settings"]["amp_stage_disabled"] = amp_stage_disabled
                self.check_data_json_timer()
                ipc_dsp.dsp_amp_stage_disable(self.current_variant_value, amp_stage_disabled)
            else :
                amp_stage_disabled = True
                self.data["settings"]["amp_stage_disabled"] = amp_stage_disabled
                self.check_data_json_timer()
                ipc_dsp.dsp_amp_stage_disable(self.current_variant_value, amp_stage_disabled)
            
            self.check_data_json_timer()

    @dbus.service.method(ipc_common.NEIGHBOUR_GET_LIST_INTERFACE, in_signature='', out_signature='s')
    def list_neighbours(self):
        with self.lock:
            jstr = json.dumps(self.neighbours)
        return jstr

    @dbus.service.method(ipc_common.NEIGHBOUR_CLEAR_LIST_INTERFACE, in_signature='', out_signature='b')
    def clear_neighbours(self):
        with self.lock:
            self.neighbours.clear()
            # Re-insert local device at fixed first place
            ip_infos = ipc_util.our_real_ip_addr(True).split()
            self.neighbours.append({
                'hw_addr': ipc_util.our_eth_mac_addr(),
                'ip_addr': ip_infos[0],
                'ip_subnet': ip_infos[1],
                'ip_gateway': ip_infos[2],
                'desc': "LOCAL",
                'model': self.data["settings"]["model"],
                'cloud_device_name': self.data["settings"].get("cloud_device_name", ipc_constants.DEFAULT_STRING),  # May not exist
                'serial': self.data["settings"].get("serial", ipc_constants.DEFAULT_STRING),  # May not exist
                'firmware_version': self.data["settings"].get("hardware_version", ipc_constants.DEFAULT_STRING),
                'oem_label': self.oem.get("oem_label", ipc_constants.DEFAULT_STRING),
                'oem_model': self.oem.get("oem_model", ipc_constants.DEFAULT_STRING),
                'oem_desc': self.oem.get("oem_desc", ipc_constants.DEFAULT_STRING),
                'dante_capable': self.data["settings"].get("dante_capable", ipc_constants.DEFAULT_BOOL),
                'alive': True,
                'last_report_time': 0.0
            })
        return True

    @dbus.service.method(ipc_common.PROTOCOL_TEST_INTERFACE, in_signature='', out_signature='s')
    def protocol_test(self):
        return ipc_util.python_to_dbus('No keyboard found - press F1 to continue!')

    @dbus.service.method(ipc_common.JSON_DATA_INTERFACE, in_signature='s', out_signature='s')
    def get_json_data(self, keys):
        try:
            keys_list = json.loads(keys)
        except json.JSONDecodeError:
            return '<ERROR>'

        resp = []

        for keys_list_elem in keys_list:
            elems = keys_list_elem.split()    # We allow up to 4 arguments in JSON path
            if len(elems) == 0 or len(elems) > 4:
                resp.append('<ERROR>')
                continue

            try:
                if elems[0].isdigit():
                    temp1 = self.data[int(elems[0])]
                else:
                    temp1 = self.data[elems[0]]

                # If there are no more arguments, return current object
                if len(elems) == 1:
                    resp.append(temp1)
                    continue
                elif elems[1].isdigit():
                    temp2 = temp1[int(elems[1])]
                else:
                    temp2 = temp1[elems[1]]

                # If there are no more arguments, return current object
                if len(elems) == 2:
                    resp.append(temp2)
                    continue
                elif elems[2].isdigit():
                    temp3 = temp2[int(elems[2])]
                else:
                    temp3 = temp2[elems[2]]

                # If there are no more arguments, return current object
                if len(elems) == 3:
                    resp.append(temp3)
                    continue
                elif elems[3].isdigit():
                    temp4 = temp3[int(elems[3])]
                else:
                    temp4 = temp3[elems[3]]
                resp.append(temp4)

            except (KeyError, ValueError):
                resp.append('<ERROR>')

        return json.dumps(resp)

    @dbus.service.method(ipc_common.NEIGHBOUR_SETLOCALDESCRIPTION_INTERFACE, in_signature='s', out_signature='b')
    def set_local_description(self, desc):
        self.data['settings']['discovery_id'] = str(desc)
        self.check_data_json_timer()
        return True

    @dbus.service.method(ipc_common.PEAK_READBACK_START_INTERFACE, in_signature='', out_signature='b')
    def start_peak_readback(self):
        self.readback_svc.start_readback()
        return True

    @dbus.service.method(ipc_common.PEAK_READBACK_STOP_INTERFACE, in_signature='', out_signature='b')
    def stop_peak_readback(self):
        self.readback_svc.stop_readback()
        return True

    @dbus.service.method(ipc_common.ETHERNET_STATIC_CONFIG_INTERFACE, in_signature='s', out_signature='b')
    def eth_static_config(self, json_config):
        try:
            config = json.loads(json_config)
        except json.JSONDecodeError:
            return False

        ip_addr = config.get('ip_addr', ipc_constants.DEFAULT_STRING)
        netmask = config.get('netmask', ipc_constants.DEFAULT_STRING)
        gateway = config.get('gateway', ipc_constants.DEFAULT_STRING)
        dns_servers = config.get('dns_servers', ipc_constants.DEFAULT_STRING)

        ipc_util.debug_print('server: ethernet static configuration called with parameters: "{}" "{}" "{}" "{}"'.format(ip_addr, netmask, gateway, dns_servers), self.debug_mode)
        if ip_addr == ipc_constants.DEFAULT_STRING or netmask == ipc_constants.DEFAULT_STRING:
            return False    # Can't do it without IP address and netmask
        if gateway == ipc_constants.DEFAULT_STRING:
            gateway = None
        if dns_servers == ipc_constants.DEFAULT_STRING:
            dns_servers = None

        return self.__eth_conf(ip_addr=ip_addr, netmask=netmask, gateway=gateway, dns_servers=dns_servers)

    @dbus.service.method(ipc_common.ETHERNET_DHCP_CONFIG_INTERFACE, in_signature='', out_signature='b')
    def eth_dhcp_config(self):
        ipc_util.debug_print('server: ethernet DHCP configuration called', self.debug_mode)
        return self.__eth_conf(ip_addr=None, netmask=None, gateway=None, dns_servers=None)

    @dbus.service.method(ipc_common.HOTSPOT_ENABLED_INTERFACE, in_signature='b', out_signature='b')
    def hotspot_enabled(self, enabled):
        ipc_util.debug_print('server: hotspot enabled/disabled called', self.debug_mode)
        self.data["settings"]["hotspot_status"] = bool(enabled)
        self.check_data_json_timer()
        return self.__wlan_conf(bool(enabled))

    @dbus.service.method(ipc_common.HOTSPOT_CONFIG_GET_INTERFACE, in_signature='', out_signiture='sv')
    def hotspot_config_get(self):
        ipc_util.debug_print("server: get hotspot config called", self.debug_mode)
        return ipc_util.python_to_dbus({"ssid": self.data["settings"]["SSID"],
                                        "wpa_version": self.data["settings"]["hotspot_wpa_version"],
                                        "channel": self.data["settings"]["hotspot_wlan_channel"],
                                        "password": bool(self.data["settings"]["hotspot_pass"])})

    @dbus.service.method(ipc_common.HOTSPOT_CONFIG_SET_INTERFACE, in_signature='s', out_signature='b')
    def hotspot_config_set(self, json_config):
        ipc_util.debug_print('server: hotspot config called', self.debug_mode)
        try:
            config = json.loads(str(json_config))
            # All fields are optional and may be None
            ssid = config.get('ssid')
            wpa_version = config.get('wpa_version')
            channel = config.get('channel')
            password = config.get('password')
            dirty = False

            if ssid is not None:
                self.data['settings']['SSID'] = ssid
                dirty = True
            if wpa_version is not None:
                self.data['settings']['hotspot_wpa_version'] = wpa_version
                dirty = True
            if channel is not None:
                self.data['settings']['hotspot_wlan_channel'] = channel
                dirty = True
            if password is not None:
                self.data['settings']['hotspot_pass'] = password
                dirty = True

            if dirty:
                self.check_data_json_timer()

            return self.__wlan_hotspot_params(ssid=ssid, wpa_version=wpa_version, channel=channel, password=password)
        except (json.JSONDecodeError, KeyError):
            return False

    @dbus.service.method(ipc_common.CLOUD_ENABLED_INTERFACE, in_signature='b', out_signature='b')
    def cloud_enabled(self, enabled):
        ipc_util.debug_print('server: cloud enabled/disabled called', self.debug_mode)
        self.data["settings"]["cloud_enable"] = bool(enabled)
        self.check_data_json_timer()
        # ToDo Enable/Disable cloud

        with self.lock: 
            self.neighbours[0]['cloud_device_name'] =  self.data["settings"]["cloud_device_name"]

        command = ipc_common.APEX_SCRIPTS_FOLDER + "apexconnect.sh"
        # If enabled, start cloud, else - stop it
        if bool(self.data["settings"]["cloud_enable"]):
            command += " --service enable"
            command += " --relay \'apexconnect.me\'"
            command += " --name \'" + self.data["settings"]["cloud_device_name"] + "\'"
            command += " --secret \'afblijven\'"
            command += " --ssh yes"
            # If username or pass is empty string, don't pass it
            if self.data["settings"]["cloud_username"] != "" and self.data["settings"]["cloud_password"] != "":
                command += " --user \'" + self.data["settings"]["cloud_username"] + "\'"
                command += " --pass \'" + self.data["settings"]["cloud_password"] + "\'"
        else:
            command += " --service disable"
        ipc_util.debug_print("Executing: " + command, self.debug_mode)
        resp = os.system(command)
        return True

    @dbus.service.method(ipc_common.GLOBAL_PRESET_SET_FILE_INTERFACE, in_signature='s', out_signature='b')
    def global_preset_file_set(self, path):
        ipc_util.debug_print('server: global preset called', self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.global_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        copyUserSettings = copy.deepcopy(file_in_dict["user_settings"])
                        copyGroups = copy.deepcopy(file_in_dict["groups"])
                        copySpeakerPresets = copy.deepcopy(file_in_dict["speaker_presets"])
                        self.data["channels"] = copyUserSettings
                        self.data["groups"] = copyGroups
                        self.data["speaker_presets"] = copySpeakerPresets
                        self.check_data_json_timer()
                        self.check_speaker_presets_json_timer()
                        thread = Thread(target=ipc_dsp.dsp_global_audio_preset, args=(self.current_variant_value, copyUserSettings, copyGroups, copySpeakerPresets))
                        thread.start()
                        break
        return is_found

    @dbus.service.method(ipc_common.SPEAKER_PRESET_SET_FILE_INTERFACE, in_signature='si', out_signature='b')
    def speaker_preset_file_set(self, path, channel):
        ipc_util.debug_print('server: speaker preset called', self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        # We need to calculate final mute send, to preserve state in which system was
        # Impact from channel itself
        final_mute_state = bool(self.data["channels"][channel]["mute"])
        # Then, calculate group impact...
        for i_group in range(0, ipc_constants.NUM_OF_GROUPS):
            if self.data["channels"][channel]["assigned_to_group"][i_group]:
                final_mute_state = final_mute_state or bool(self.data["groups"][i_group]["mute"])
        for folder_in_dict in self.speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        copySettings = copy.deepcopy(file_in_dict["settings"])
                        self.data["speaker_presets"][channel] = copySettings
                        self.data["channels"][channel]["preset"] = path
                        self.data["channels"][channel]["name"] = file
                        # self.data["speaker_presets"][channel] = dict(file_in_dict["settings"])
                        ipc_dsp.dsp_speaker_preset(self.current_variant_value, channel, dict(file_in_dict["settings"]), final_mute_state)
                        break
        self.check_data_json_timer()
        return is_found
    
    @dbus.service.method(ipc_common.SPEAKER_PRESET_LABEL_SET_FILE_INTERFACE, in_signature='sib', out_signature='b')
    def speaker_preset_file_label_set(self, path, channel, label):
        ipc_util.debug_print('server: speaker preset called', self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        # We need to calculate final mute send, to preserve state in which system was
        # Impact from channel itself
        final_mute_state = bool(self.data["channels"][channel]["mute"])
        # Then, calculate group impact...
        for i_group in range(0, ipc_constants.NUM_OF_GROUPS):
            if self.data["channels"][channel]["assigned_to_group"][i_group]:
                final_mute_state = final_mute_state or bool(self.data["groups"][i_group]["mute"])
        for folder_in_dict in self.speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        copySettings = copy.deepcopy(file_in_dict["settings"])
                        self.data["speaker_presets"][channel] = copySettings
                        self.data["channels"][channel]["preset"] = path
                        if label == True:
                            self.data["channels"][channel]["name"] = file
                        # self.data["speaker_presets"][channel] = dict(file_in_dict["settings"])
                        ipc_dsp.dsp_speaker_preset(self.current_variant_value, channel, dict(file_in_dict["settings"]), final_mute_state)
                        break
        self.check_data_json_timer()
        return is_found

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_SET_FILE_INTERFACE, in_signature='s', out_signature='b')
    def all_speaker_preset_file_set(self, path):
        ipc_util.debug_print('server: global preset called', self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        final_mute_state = bool(self.data["channels"][0]["mute"])
        # Then, calculate group impact...
        for i_group in range(0, ipc_constants.NUM_OF_GROUPS):
            if self.data["channels"][0]["assigned_to_group"][i_group]:
                final_mute_state = final_mute_state or bool(self.data["groups"][i_group]["mute"])
        for folder_in_dict in self.all_speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        copySettings = copy.deepcopy(file_in_dict["settings"])
                        self.data["speaker_presets"] = copySettings
                        self.data["channels"][0]["preset"] = path
                        self.data["channels"][0]["name"] = file
                        # ipc_dsp.dsp_all_speaker_preset(self.current_variant_value, dict(file_in_dict["settings"]), final_mute_state)
                        ipc_dsp.dsp_all_speaker_preset(self.current_variant_value, copySettings, final_mute_state)
                        break
        self.check_data_json_timer()
        return is_found

    @dbus.service.method(ipc_common.HOME_PAGE_STATUS_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_home_page_status_get(self):
        ipc_util.debug_print('server: get home page status called', self.debug_mode)
        names_array = []
        faults_array = []
        mute_channels = []

        with self.lock:
            oem_lock = False
            if len(self.oem["oem_code"]) > 0 and self.oem["oem_code"] !="0000000000":
                oem_lock = True



            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                names_array.append(self.data["channels"][i].get("name", ipc_constants.DEFAULT_STRING))
                faults_array.append(self.data["channels"][i].get("fault", ipc_constants.DEFAULT_BOOL))
                mute_channels.append(self.data["channels"][i].get("mute", ipc_constants.DEFAULT_BOOL))

        return python_to_dbus({"names": names_array,
                               "faults": faults_array,
                               "mute_channels": mute_channels,
                               "cloud_enable": self.data["settings"].get("cloud_enable", ipc_constants.DEFAULT_BOOL),
                               "hotspot_status": self.data["settings"].get("hotspot_status", ipc_constants.DEFAULT_BOOL),
                               "oem_status": oem_lock, 
                               "locate": self.data["settings"].get("locate", ipc_constants.DEFAULT_BOOL)})

    @dbus.service.method(ipc_common.AUDIO_SIGGEN_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_audio_siggen_get(self):
        ipc_util.debug_print('server: get audio siggen called', self.debug_mode)
        return python_to_dbus ({"frequency_generator":{"frequency":self.data["settings"]["signal_generator"]["frequency_generator"].get("frequency", ipc_constants.DEFAULT_INT), 
                                                        "gain":self.data["settings"]["signal_generator"]["frequency_generator"].get("gain", ipc_constants.DEFAULT_FLOAT)},
                                "pink_noise":{"gain":self.data["settings"]["signal_generator"]["pink_noise"].get("gain", ipc_constants.DEFAULT_FLOAT)}})

    @dbus.service.method(ipc_common.AUDIO_LIMITER_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_audio_limiter_get(self, channel):
        ipc_util.debug_print('server: get audio limiter called', self.debug_mode)
        return python_to_dbus ({"lim_rms":{"lim_rms_thres":self.data["channels"][channel]["lim_rms"].get("lim_rms_thres", ipc_constants.DEFAULT_FLOAT),
                                                    "lim_rms_attack":self.data["channels"][channel]["lim_rms"].get("lim_rms_attack",ipc_constants.DEFAULT_FLOAT),
                                                    "lim_rms_release":self.data["channels"][channel]["lim_rms"].get("lim_rms_release",ipc_constants.DEFAULT_FLOAT)},
                                "lim_peak": {"lim_peak_thres":self.data["channels"][channel]["lim_peak"].get("lim_peak_thres", ipc_constants.DEFAULT_BOOL),
                                                    "lim_peak_release":self.data["channels"][channel]["lim_peak"].get("lim_peak_release",ipc_constants.DEFAULT_FLOAT)}})

    @dbus.service.method(ipc_common.AUDIO_XOVER_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_audio_xover_get(self, channel):
        ipc_util.debug_print('server: get audio xover called', self.debug_mode)
        return python_to_dbus ({"xover_hp_filter":{"xover_hp_enable":self.data["channels"][channel]["xover_hp_filter"].get("xover_hp_enable", ipc_constants.DEFAULT_BOOL),
                                                    "xover_hp_type":self.data["channels"][channel]["xover_hp_filter"].get("xover_hp_type",ipc_constants.DEFAULT_INT),
                                                    "xover_hp_freq":self.data["channels"][channel]["xover_hp_filter"].get("xover_hp_freq",ipc_constants.DEFAULT_FLOAT)},
                                "xover_lp_filter": {"xover_lp_enable":self.data["channels"][channel]["xover_lp_filter"].get("xover_lp_enable", ipc_constants.DEFAULT_BOOL),
                                                    "xover_lp_type":self.data["channels"][channel]["xover_lp_filter"].get("xover_lp_type",ipc_constants.DEFAULT_INT),
                                                    "xover_lp_freq":self.data["channels"][channel]["xover_lp_filter"].get("xover_lp_freq",ipc_constants.DEFAULT_FLOAT)}})

    @dbus.service.method(ipc_common.AUDIO_PEQ_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_audio_peq_get(self, channel):
        ipc_util.debug_print('server: get audio peq called', self.debug_mode)
        return python_to_dbus({"peq": [{"enable":self.data["channels"][channel]["peq"][0].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][0].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][0].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][0].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][0].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][1].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][1].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][1].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][1].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][1].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][2].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][2].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][2].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][2].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][2].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][3].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][3].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][3].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][3].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][3].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][4].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][4].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][4].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][4].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][4].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][5].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][5].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][5].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][5].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][5].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][6].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][6].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][6].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][6].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][6].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][7].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][7].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][7].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][7].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][7].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][8].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][8].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][8].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][8].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][8].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][9].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][9].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][9].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][9].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][9].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][10].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][10].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][10].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][10].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][10].get("q", ipc_constants.DEFAULT_FLOAT)},
                                        {"enable":self.data["channels"][channel]["peq"][11].get("enable", ipc_constants.DEFAULT_BOOL),
                                        "type":self.data["channels"][channel]["peq"][11].get("type", ipc_constants.DEFAULT_INT),
                                        "freq":self.data["channels"][channel]["peq"][11].get("freq", ipc_constants.DEFAULT_FLOAT),
                                        "gain":self.data["channels"][channel]["peq"][11].get("gain", ipc_constants.DEFAULT_FLOAT),
                                        "q":self.data["channels"][channel]["peq"][11].get("q", ipc_constants.DEFAULT_FLOAT)}]})

    @dbus.service.method(ipc_common.AUDIO_DELAY_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_audio_delay_get(self):
        ipc_util.debug_print('server: get audio delay called', self.debug_mode)
        names_array = []
        delays_array = []
        group_delays_array = []
        for i in range (0, ipc_constants.NUM_OF_CHANNELS):
            names_array.append(self.data["channels"][i].get("name", ipc_constants.DEFAULT_STRING))
            delays_array.append(self.data["channels"][i].get("delay_value", ipc_constants.DEFAULT_FLOAT))
            group_delays_array.append(self.data["channels"][i].get("group_delay_value", ipc_constants.DEFAULT_FLOAT))
        return python_to_dbus({"names": names_array, "delays": delays_array, "groupDelays": group_delays_array})

    @dbus.service.method(ipc_common.AUDIO_GAIN_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_audio_gain_get(self):
        ipc_util.debug_print('server: get audio gain called', self.debug_mode)
        names_array = []
        gains_array = []
        for i in range (0, ipc_constants.NUM_OF_CHANNELS):
            names_array.append(self.data["channels"][i].get("name", ipc_constants.DEFAULT_STRING))
            gains_array.append(self.data["channels"][i].get("gain", ipc_constants.DEFAULT_FLOAT))
        return python_to_dbus({"names": names_array, "gains": gains_array})

    @dbus.service.method(ipc_common.AUDIO_SOURCE_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_audio_source_get(self):
        ipc_util.debug_print('server: get audio source called', self.debug_mode)
        names_array = []
        source_pri_array = []
        for i in range (0, ipc_constants.NUM_OF_CHANNELS):
            names_array.append(self.data["channels"][i].get("name", ipc_constants.DEFAULT_STRING))
            source_pri_array.append(self.data["channels"][i].get("source_pri", ipc_constants.DEFAULT_INT))
        return python_to_dbus({"names": names_array, "sources":source_pri_array})

    @dbus.service.method(ipc_common.GLOBAL_PRESET_GET_FOLDER_NAMES_INTERFACE, in_signature='', out_signiture='as')
    def global_preset_folder_names_get(self):
        ipc_util.debug_print('server: get global presets folder names called', self.debug_mode)
        global_presets_folder_names = []
        for i_folder in range(0, len(self.global_presets), 1):
            folder = self.global_presets[i_folder].get("folder_name", ipc_constants.DEFAULT_STRING)
            global_presets_folder_names.append(folder)
        return python_to_dbus(global_presets_folder_names)

    @dbus.service.method(ipc_common.GLOBAL_PRESET_GET_FILE_NAMES_INTERFACE, in_signature='s', out_signiture='as')
    def global_preset_file_names_get(self, folder_name):
        ipc_util.debug_print('server: get global presets file names called', self.debug_mode)
        global_presets_file_names = []
        for folder_in_dict in self.global_presets:
            if folder_name == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    global_presets_file_names.append(file_in_dict["file_name"])
                break
        return python_to_dbus(global_presets_file_names)

    @dbus.service.method(ipc_common.SPEAKER_PRESET_GET_LIST_NAMES_INTERFACE, in_signature='', out_signiture='as')
    def speaker_preset_list_names_get(self):
        ipc_util.debug_print('server: get speaker presets list names called', self.debug_mode)
        speaker_presets_list_names = []
        f_name = ""
        for i_folder in range(0, len(self.speaker_presets), 1):
            f_name = self.speaker_presets[i_folder].get("folder_name", ipc_constants.DEFAULT_STRING)
            f_list = []
            for j_file in range(0, len(self.speaker_presets[i_folder]["files"]), 1):
                oem = False
                if len(self.speaker_presets[i_folder]["files"][j_file]["oem_code"]) > 0 and self.speaker_presets[i_folder]["files"][j_file]["oem_code"] != "0000000000" :
                    oem = True
                file = {"file_name" : self.speaker_presets[i_folder]["files"][j_file].get("file_name", ipc_constants.DEFAULT_STRING),
                        "author":self.speaker_presets[i_folder]["files"][j_file].get("author", ipc_constants.DEFAULT_STRING),
                        "version":self.speaker_presets[i_folder]["files"][j_file].get("version", ipc_constants.DEFAULT_STRING),
                        "note":self.speaker_presets[i_folder]["files"][j_file].get("note", ipc_constants.DEFAULT_STRING),
                        "oem":oem}
                f_list.append(file)
            folder = {"folder_name":f_name,"files":f_list}
            speaker_presets_list_names.append(folder)
        return python_to_dbus(speaker_presets_list_names)

    @dbus.service.method(ipc_common.SPEAKER_PRESET_GET_FOLDER_NAMES_INTERFACE, in_signature='', out_signiture='as')
    def speaker_preset_folder_names_get(self):
        ipc_util.debug_print('server: get speaker presets folder names called', self.debug_mode)
        speaker_presets_folder_names = []
        for i_folder in range(0, len(self.speaker_presets), 1):
            folder = self.speaker_presets[i_folder].get("folder_name", ipc_constants.DEFAULT_STRING)
            speaker_presets_folder_names.append(folder)
        return python_to_dbus(speaker_presets_folder_names)

    @dbus.service.method(ipc_common.SPEAKER_PRESET_GET_FILE_NAMES_INTERFACE, in_signature='s', out_signiture='as')
    def speaker_preset_file_names_get(self, folder_name):
        ipc_util.debug_print('server: get speaker presets file names called', self.debug_mode)
        speaker_presets_file_names = []
        for folder_in_dict in self.speaker_presets:
            if folder_name == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    speaker_presets_file_names.append(file_in_dict["file_name"])
                break
        return python_to_dbus(speaker_presets_file_names)

    @dbus.service.method(ipc_common.SPEAKER_PRESET_FILES_FROM_FOLDER_GET_INTERFACE, in_signature='s', out_signiture='as')
    def speaker_preset_files_from_folder_get(self, folder_name):
        ipc_util.debug_print('server: get speaker presets list names called', self.debug_mode)
        f_list = []
        f_name = ""
        for i_folder in range(0, len(self.speaker_presets), 1):
            f_name = self.speaker_presets[i_folder].get("folder_name", ipc_constants.DEFAULT_STRING)
            if folder_name == f_name:
                for j_file in range(0, len(self.speaker_presets[i_folder]["files"]), 1):
                    f_list.append(self.speaker_presets[i_folder]["files"][j_file])
        return python_to_dbus(f_list)

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_FILES_FROM_FOLDER_GET_INTERFACE, in_signature='s', out_signiture='as')
    def all_speaker_preset_files_from_folder_get(self, folder_name):
        ipc_util.debug_print('server: get speaker presets list names called', self.debug_mode)
        f_list = []
        f_name = ""
        for i_folder in range(0, len(self.all_speaker_presets), 1):
            f_name = self.all_speaker_presets[i_folder].get("folder_name", ipc_constants.DEFAULT_STRING)
            if folder_name == f_name:
                for j_file in range(0, len(self.all_speaker_presets[i_folder]["files"]), 1):
                    f_list.append(self.all_speaker_presets[i_folder]["files"][j_file])
        return python_to_dbus(f_list)

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_GET_LIST_NAMES_INTERFACE, in_signature='', out_signiture='as')
    # @dbus.service.method(ipc_common.SPEAKER_PRESET_GET_LIST_NAMES_INTERFACE, in_signature='', out_signiture='a{ssa(s)}')
    def all_speaker_preset_list_names_get(self):
        ipc_util.debug_print('server: get all speaker presets list names called', self.debug_mode)
        speaker_presets_list_names = []
        f_name = ""
        for i_folder in range(0, len(self.all_speaker_presets), 1):
            f_name = self.all_speaker_presets[i_folder].get("folder_name", ipc_constants.DEFAULT_STRING)
            f_list = []
            for j_file in range(0, len(self.all_speaker_presets[i_folder]["files"]), 1):
                oem = False
                if len(self.all_speaker_presets[i_folder]["files"][j_file]["oem_code"]) > 0 and self.all_speaker_presets[i_folder]["files"][j_file]["oem_code"] != "0000000000" :
                    oem = True
                file = {"file_name" : self.all_speaker_presets[i_folder]["files"][j_file].get("file_name", ipc_constants.DEFAULT_STRING),
                        "author":self.all_speaker_presets[i_folder]["files"][j_file].get("author", ipc_constants.DEFAULT_STRING),
                        "version":self.all_speaker_presets[i_folder]["files"][j_file].get("version", ipc_constants.DEFAULT_STRING),
                        "note":self.all_speaker_presets[i_folder]["files"][j_file].get("note", ipc_constants.DEFAULT_STRING),
                        "oem":oem}
                f_list.append(file)
            folder = {"folder_name":f_name,"files":f_list}
            speaker_presets_list_names.append(folder)
        return python_to_dbus(speaker_presets_list_names)

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_GET_FOLDER_NAMES_INTERFACE, in_signature='', out_signiture='as')
    def all_speaker_preset_folder_names_get(self):
        ipc_util.debug_print('server: get all speaker presets folder names called', self.debug_mode)
        speaker_presets_folder_names = []
        for i_folder in range(0, len(self.all_speaker_presets), 1):
            folder = self.all_speaker_presets[i_folder].get("folder_name", ipc_constants.DEFAULT_STRING)
            speaker_presets_folder_names.append(folder)
        return python_to_dbus(speaker_presets_folder_names)

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_GET_FILE_NAMES_INTERFACE, in_signature='s', out_signiture='as')
    def all_speaker_preset_file_names_get(self, folder_name):
        ipc_util.debug_print('server: get all speaker presets file names called', self.debug_mode)
        speaker_presets_file_names = []
        for folder_in_dict in self.all_speaker_presets:
            if folder_name == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    speaker_presets_file_names.append(file_in_dict["file_name"])
                break
        return python_to_dbus(speaker_presets_file_names)

    @dbus.service.method(ipc_common.HOTSPOT_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_hotspot_get(self):
        ipc_util.debug_print('server: get hotspot called', self.debug_mode)
        return python_to_dbus({"hotspot_status": self.data["settings"].get("hotspot_status", ipc_constants.DEFAULT_BOOL),
                               "SSID": self.data["settings"].get("SSID", ipc_constants.DEFAULT_STRING),
                               "hotspot_pass": self.data["settings"].get("hotspot_pass", ipc_constants.DEFAULT_STRING)})

    @dbus.service.method(ipc_common.CLOUD_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_cloud_get(self):
        ipc_util.debug_print('server: get cloud called', self.debug_mode)
        return python_to_dbus({"cloud_enable": self.data["settings"].get("cloud_enable", ipc_constants.DEFAULT_BOOL),
                               "cloud_device_name": self.data["settings"].get("cloud_device_name", ipc_constants.DEFAULT_STRING),
                               "cloud_username": self.data["settings"].get("cloud_username", ipc_constants.DEFAULT_STRING),
                               "cloud_password": self.data["settings"].get("cloud_password", ipc_constants.DEFAULT_STRING)})

    @dbus.service.method(ipc_common.NETWORK_GET_DATA_INTERFACE, in_signature='', out_signiture='sv')
    def data_network_get(self):
        ipc_util.debug_print('server: get network called', self.debug_mode)
        current_network = ipc_util.our_real_ip_addr(True)
        #  transform string array to int array
        ip_string_array = current_network.split()[0].split(".")
        ip_int_array = []
        for i in range(0, 4):
            ip_int_array.append(int(ip_string_array[i]))
        #  transform string array to int array
        subnet_string_array = current_network.split()[1].split(".")
        subnet_int_array = []
        for i in range(0, 4):
            subnet_int_array.append(int(subnet_string_array[i]))
        #  transform string array to int array
        gateway_string_array = current_network.split()[2].split(".")
        gateway_int_array = []
        for i in range(0, 4):
            gateway_int_array.append(int(gateway_string_array[i]))

        return python_to_dbus({"network_mode": ipc_util.is_network_static(),
                               "IP": ip_int_array,
                               "Subnet": subnet_int_array,
                               "Gateway": gateway_int_array})

    @dbus.service.method(ipc_common.ABOUT_GET_DATA_INTERFACE, in_signature='', out_signiture='s')
    def data_about_get(self):
        ipc_util.debug_print('server: get about called', self.debug_mode)
        return ipc_constants.SERVICE_VERSION

    @dbus.service.method(ipc_common.GROUP_MUTE_GET_INTERFACE, in_signature='i', out_signiture='b')
    def group_mute_get(self, group_number):
        ipc_util.debug_print('server: get group mute called', self.debug_mode)
        return self.data["groups"][group_number].get("mute", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.GROUP_GAIN_GET_INTERFACE, in_signature='i', out_signiture='d')
    def group_gain_get(self, group_number):
        ipc_util.debug_print('server: get group gain called', self.debug_mode)
        return self.data["groups"][group_number].get("gain", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.GROUP_POLARITY_GET_INTERFACE, in_signature='i', out_signiture='b')
    def group_polarity_get(self, group_number):
        ipc_util.debug_print('server: get group polarity called', self.debug_mode)
        return self.data["groups"][group_number].get("polarity", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.GROUP_DELAY_ENABLE_GET_INTERFACE, in_signature='i', out_signiture='b')
    def group_delay_enable_get(self, group_number):
        ipc_util.debug_print('server: get group delay enable called', self.debug_mode)
        return self.data["groups"][group_number].get("delay_enable", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.GROUP_DELAY_VALUE_GET_INTERFACE, in_signature='i', out_signiture='d')
    def group_delay_value_get(self, group_number):
        ipc_util.debug_print('server: get group delay value called', self.debug_mode)
        return self.data["groups"][group_number].get("delay_value", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.GROUP_NAME_GET_INTERFACE, in_signature='i', out_signiture='s')
    def group_name_get(self, group_number):
        ipc_util.debug_print('server: get group name called', self.debug_mode)
        return self.data["groups"][group_number].get("name", ipc_constants.DEFAULT_STRING)

    @dbus.service.method(ipc_common.SOLO_MUTE_GET_INTERFACE, in_signature='i', out_signiture='b')
    def solo_mute_get(self, channel):
        ipc_util.debug_print('server: get solo mute called', self.debug_mode)
        return self.data["channels"][channel].get("mute", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SOLO_GAIN_GET_INTERFACE, in_signature='i', out_signiture='d')
    def solo_gain_get(self, channel):
        ipc_util.debug_print('server: get solo gain called', self.debug_mode)
        return self.data["channels"][channel].get("gain", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_POLARITY_GET_INTERFACE, in_signature='i', out_signiture='b')
    def solo_polarity_get(self, channel):
        ipc_util.debug_print('server: get solo polarity called', self.debug_mode)
        return self.data["channels"][channel].get("polarity", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SOLO_DELAY_ENABLE_SET_INTERFACE, in_signature='i', out_signiture='b')
    def solo_delay_enable_get(self, channel):
        ipc_util.debug_print('server: get solo delay enable called', self.debug_mode)
        return self.data["channels"][channel].get("delay_enable", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SOLO_DELAY_VALUE_GET_INTERFACE, in_signature='i', out_signiture='d')
    def solo_delay_value_get(self, channel):
        ipc_util.debug_print('server: get solo delay value called', self.debug_mode)
        return self.data["channels"][channel].get("delay_value", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_XOVER_HP_ENABLE_GET_INTERFACE, in_signature='i', out_signiture='b')
    def solo_xover_hp_enable_get(self, channel):
        ipc_util.debug_print('server: get solo xover hp enable called', self.debug_mode)
        return self.data["channels"][channel]["xover_hp_filter"].get("xover_hp_enable", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SOLO_XOVER_HP_TYPE_GET_INTERFACE, in_signature='i', out_signiture='i')
    def solo_xover_hp_type_get(self, channel):
        ipc_util.debug_print('server: get solo xover hp type called', self.debug_mode)
        return self.data["channels"][channel]["xover_hp_filter"].get("xover_hp_type", ipc_constants.DEFAULT_INT)

    @dbus.service.method(ipc_common.SOLO_XOVER_HP_FREQ_GET_INTERFACE, in_signature='i', out_signiture='d')
    def solo_xover_hp_freq_get(self, channel):
        ipc_util.debug_print('server: get solo xover hp freq called', self.debug_mode)
        return self.data["channels"][channel]["xover_hp_filter"].get("xover_hp_freq", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_XOVER_LP_ENABLE_GET_INTERFACE, in_signature='i', out_signiture='b')
    def solo_xover_lp_enable_get(self, channel):
        ipc_util.debug_print('server: get solo xover lp enable called', self.debug_mode)
        return self.data["channels"][channel]["xover_lp_filter"].get("xover_lp_enable", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SOLO_XOVER_LP_TYPE_GET_INTERFACE, in_signature='i', out_signiture='i')
    def solo_xover_lp_type_get(self, channel):
        ipc_util.debug_print('server: get solo xover lp type called', self.debug_mode)
        return self.data["channels"][channel]["xover_lp_filter"].get("xover_lp_type", ipc_constants.DEFAULT_INT)

    @dbus.service.method(ipc_common.SOLO_XOVER_LP_FREQ_GET_INTERFACE, in_signature='i', out_signiture='d')
    def solo_xover_lp_freq_get(self, channel):
        ipc_util.debug_print('server: get solo xover lp freq called', self.debug_mode)
        return self.data["channels"][channel]["xover_lp_filter"].get("xover_lp_freq", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_LIM_RMS_THRES_GET_INTERFACE, in_signature='i', out_signiture='d')
    def solo_lim_rms_thres_get(self, channel):
        ipc_util.debug_print('server: get solo lim rms thres called', self.debug_mode)
        return self.data["channels"][channel]["lim_rms"].get("lim_rms_thres", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_LIM_RMS_ATTACK_GET_INTERFACE, in_signature='i', out_signiture='d')
    def solo_lim_rms_attack_get(self, channel):
        ipc_util.debug_print('server: get solo lim rms attack called', self.debug_mode)
        return self.data["channels"][channel]["lim_rms"].get("lim_rms_attack", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_LIM_RMS_RELEASE_GET_INTERFACE, in_signature='i', out_signiture='d')
    def solo_lim_rms_release_get(self, channel):
        ipc_util.debug_print('server: get solo lim rms release called', self.debug_mode)
        return self.data["channels"][channel]["lim_rms"].get("lim_rms_release", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_LIM_PEAK_THRES_GET_INTERFACE, in_signature='i', out_signiture='d')
    def solo_lim_peak_thres_get(self, channel):
        ipc_util.debug_print('server: get solo lim peak thres called', self.debug_mode)
        return self.data["channels"][channel]["lim_peak"].get("lim_peak_thres", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_LIM_PEAK_RELEASE_GET_INTERFACE, in_signature='i', out_signiture='d')
    def solo_lim_peak_release_get(self, channel):
        ipc_util.debug_print('server: get solo lim peak release called', self.debug_mode)
        return self.data["channels"][channel]["lim_peak"].get("lim_peak_release", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_CHANNEL_SOURCE_PRI_GET_INTERFACE, in_signature='i', out_signiture='i')
    def solo_channel_source_pri_get(self, channel):
        ipc_util.debug_print('server: get solo channel source called', self.debug_mode)
        return self.data["channels"][channel].get("source_pri", ipc_constants.DEFAULT_INT)

    @dbus.service.method(ipc_common.SOLO_CHANNEL_SOURCE_SEC_GET_INTERFACE, in_signature='i', out_signiture='i')
    def solo_channel_source_sec_get(self, channel):
        ipc_util.debug_print('server: get solo channel source called', self.debug_mode)
        return self.data["channels"][channel].get("source_sec", ipc_constants.DEFAULT_INT)

    @dbus.service.method(ipc_common.SOLO_CHANNEL_SOURCE_MIXER_GET_INTERFACE, in_signature='ii', out_signiture='d')
    def solo_channel_source_mixer_get(self, channel, source):
        ipc_util.debug_print("server: get solo channel source mixer called", self.debug_mode)
        return self.data["channels"][channel]["mixer"][source].get("gain", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_CHANNEL_SOURCE_MIXER_GET_ALL_INTERFACE, in_signature='i', out_signiture='ad')
    def solo_channel_source_mixer_all_get(self, channel):
        ipc_util.debug_print("server: get solo channel source mixer called", self.debug_mode)
        arrGain = []
        for i_source in range (0, ipc_constants.NUM_OF_INPUTS,1):
            arrGain.append(self.data["channels"][channel]["mixer"][i_source].get("gain", ipc_constants.DEFAULT_FLOAT))
        return arrGain

    @dbus.service.method(ipc_common.SOLO_CHANNEL_NAME_GET_INTERFACE, in_signature='i', out_signiture='s')
    def solo_channel_name_get(self, channel):
        ipc_util.debug_print('server: get solo channel name called', self.debug_mode)
        return self.data["channels"][channel].get("name", ipc_constants.DEFAULT_STRING)

    @dbus.service.method(ipc_common.GROUP_PEQ_ENABLE_GET_INTERFACE, in_signature='ii', out_signiture='b')
    def group_peq_enable_get(self, group_number, peq_channel):
        ipc_util.debug_print('server: get group peq enable called', self.debug_mode)
        return self.data["groups"][group_number]["peq"][peq_channel].get("enable", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.GROUP_PEQ_TYPE_GET_INTERFACE, in_signature='ii', out_signiture='i')
    def group_peq_type_get(self, group_number, peq_channel):
        ipc_util.debug_print('server: get group peq type called', self.debug_mode)
        return self.data["groups"][group_number]["peq"][peq_channel].get("type", ipc_constants.DEFAULT_INT)

    @dbus.service.method(ipc_common.GROUP_PEQ_FREQ_GET_INTERFACE, in_signature='ii', out_signiture='d')
    def group_peq_freq_get(self, group_number, peq_channel):
        ipc_util.debug_print('server: get group peq freq called', self.debug_mode)
        return self.data["groups"][group_number]["peq"][peq_channel].get("freq", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.GROUP_PEQ_GAIN_GET_INTERFACE, in_signature='ii', out_signiture='d')
    def group_peq_gain_get(self, group_number, peq_channel):
        ipc_util.debug_print('server: get group peq gain called', self.debug_mode)
        return self.data["groups"][group_number]["peq"][peq_channel].get("gain", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.GROUP_PEQ_Q_GET_INTERFACE, in_signature='ii', out_signiture='d')
    def group_peq_q_get(self, group_number, peq_channel):
        ipc_util.debug_print('server: get group q called', self.debug_mode)
        return self.data["groups"][group_number]["peq"][peq_channel].get("q", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.GROUP_MUTE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def group_mute_set(self, group_number, muted):
        ipc_util.debug_print('server: set group mute called', self.debug_mode)
        self.data["groups"][group_number]["mute"] = bool(muted)
        self.check_data_json_timer()
        #  check if change has effect on any channel
        for i_channel in range(0, ipc_constants.NUM_OF_CHANNELS):
            if 1 == self.data["channels"][i_channel]["assigned_to_group"][group_number]:
                # Impact from channel itself
                final_mute_state = bool(self.data["channels"][i_channel]["mute"])
                # Then, calculate group impact...
                for i_group in range(0, ipc_constants.NUM_OF_GROUPS):
                    if self.data["channels"][i_channel]["assigned_to_group"][i_group]:
                        final_mute_state = final_mute_state or bool(self.data["groups"][i_group]["mute"])
                ipc_dsp.dsp_solo_mute(self.current_variant_value, i_channel, bool(final_mute_state))
        return True

    @dbus.service.method(ipc_common.GROUP_GAIN_SET_INTERFACE, in_signature='id', out_signiture='b')
    def group_gain_set(self, group_number, gain):
        ipc_util.debug_print('server: set group gain called', self.debug_mode)
        self.data["groups"][group_number]["gain"] = float(gain)
        self.check_data_json_timer()
        if 1 == self.data["channels"][0]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_gain_set(self.current_variant_value, 0, group_number, float(gain))
        if 1 == self.data["channels"][1]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_gain_set(self.current_variant_value, 1, group_number, float(gain))
        if 1 == self.data["channels"][2]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_gain_set(self.current_variant_value, 2, group_number, float(gain))
        if 1 == self.data["channels"][3]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_gain_set(self.current_variant_value, 3, group_number, float(gain))

        return True

    @dbus.service.method(ipc_common.GROUP_POLARITY_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def group_polarity_set(self, group_number, polarity):
        ipc_util.debug_print("server: set group polarity called", self.debug_mode)
        self.data["groups"][group_number]["polarity"] = bool(polarity)
        self.check_data_json_timer()
        if 1 == self.data["channels"][0]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_polarity(self.current_variant_value, 0, group_number, bool(polarity))
        if 1 == self.data["channels"][1]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_polarity(self.current_variant_value, 1, group_number, bool(polarity))
        if 1 == self.data["channels"][2]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_polarity(self.current_variant_value, 2, group_number, bool(polarity))
        if 1 == self.data["channels"][3]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_polarity(self.current_variant_value, 3, group_number, bool(polarity))
        return True

    @dbus.service.method(ipc_common.GROUP_DELAY_ENABLE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def group_delay_enable_set(self, group_number, delay_enabled):
        ipc_util.debug_print("server: set group delay enable called", self.debug_mode)
        self.data["groups"][group_number]["delay_enable"] = bool(delay_enabled)
        self.check_data_json_timer()
        self.recalculate_group_delay_values()
        if 1 == self.data["channels"][0]["assigned_to_group"][group_number]:
            self.send_delay_value_to_dsp(0)
        if 1 == self.data["channels"][1]["assigned_to_group"][group_number]:
            self.send_delay_value_to_dsp(1)
        if 1 == self.data["channels"][2]["assigned_to_group"][group_number]:
            self.send_delay_value_to_dsp(2)
        if 1 == self.data["channels"][3]["assigned_to_group"][group_number]:
            self.send_delay_value_to_dsp(3)
        return True

    @dbus.service.method(ipc_common.GROUP_DELAY_VALUE_SET_INTERFACE, in_signature='id', out_signiture='b')
    def group_delay_value_set(self, group_number, delay_value):
        ipc_util.debug_print("server: set group delay value called", self.debug_mode)
        self.data["groups"][group_number]["delay_value"] = float(delay_value)
        self.check_data_json_timer()
        self.recalculate_group_delay_values()
        if 1 == self.data["channels"][0]["assigned_to_group"][group_number]:
            self.send_delay_value_to_dsp(0)
        if 1 == self.data["channels"][1]["assigned_to_group"][group_number]:
            self.send_delay_value_to_dsp(1)
        if 1 == self.data["channels"][2]["assigned_to_group"][group_number]:
            self.send_delay_value_to_dsp(2)
        if 1 == self.data["channels"][3]["assigned_to_group"][group_number]:
            self.send_delay_value_to_dsp(3)
        return True

    @dbus.service.method(ipc_common.GROUP_NAME_SET_INTERFACE, in_signature='is', out_signiture='b')
    def group_name_set(self, group_number, name):
        ipc_util.debug_print("server: set group name called", self.debug_mode)
        self.data["groups"][group_number]["name"] = str(name)
        self.check_data_json_timer()
        return True

    @dbus.service.method(ipc_common.SOLO_PEQ_ENABLE_GET_INTERFACE, in_signature='ii', out_signiture='b')
    def solo_peq_enable_get(self, channel, peq_channel):
        ipc_util.debug_print("server: get solo peq enable called", self.debug_mode)
        return self.data["channels"][channel]["peq"][peq_channel].get("enable", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SOLO_PEQ_TYPE_GET_INTERFACE, in_signature='ii', out_signiture='i')
    def solo_peq_type_get(self, channel, peq_channel):
        ipc_util.debug_print("server: get solo peq type called", self.debug_mode)
        return self.data["channels"][channel]["peq"][peq_channel].get("type", ipc_constants.DEFAULT_INT)

    @dbus.service.method(ipc_common.SOLO_PEQ_FREQ_GET_INTERFACE, in_signature='ii', out_signiture='d')
    def solo_peq_freq_get(self, channel, peq_channel):
        ipc_util.debug_print("server: get solo peq freq called", self.debug_mode)
        return self.data["channels"][channel]["peq"][peq_channel].get("freq", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_PEQ_GAIN_GET_INTERFACE, in_signature='ii', out_signiture='d')
    def solo_peq_gain_get(self, channel, peq_channel):
        ipc_util.debug_print("server: get solo peq gain called", self.debug_mode)
        return self.data["channels"][channel]["peq"][peq_channel].get("gain", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SOLO_PEQ_Q_GET_INTERFACE, in_signature='ii', out_signiture='d')
    def solo_peq_q_get(self, channel, peq_channel):
        ipc_util.debug_print("server: get solo peq q called", self.debug_mode)
        return self.data["channels"][channel]["peq"][peq_channel].get("q", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.AMP_MODULE_DISABLE_INTERFACE, in_signature='ib', out_signiture='b')
    def amp_module_disable_set(self, channel, disabled):
        ipc_util.debug_print("server: set amp module disable called", self.debug_mode)
        self.data["channels"][channel]["module_disabled"] = bool(disabled)
        self.check_data_json_timer()
        module_status = bool(disabled)
        ipc_dsp.dsp_amp_module_disable(self.current_variant_value, channel, module_status)
        return True
    
    @dbus.service.method(ipc_common.AMP_STAGE_DISABLE_INTERFACE, in_signature='b', out_signiture='b')
    def amp_stage_disable_set(self, disabled):
        ipc_util.debug_print("server: set amp stage disable called", self.debug_mode)
        self.data["settings"]["amp_stage_disabled"] = bool(disabled)
        self.check_data_json_timer()
        stage_status = bool(disabled)
        ipc_dsp.dsp_amp_stage_disable(self.current_variant_value,stage_status)
        return True

    @dbus.service.method(ipc_common.SOLO_MUTE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def solo_mute_set(self, channel, muted):
        ipc_util.debug_print("server: set solo mute called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["mute"] = bool(muted)
            mute_status = bool(muted)
            for i_group in range(0, ipc_constants.NUM_OF_GROUPS):  # calculate mute groups impact
                if 1 == self.data["channels"][0]["assigned_to_group"][i_group]:
                    mute_status = mute_status or self.data["groups"][i_group]["mute"]
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                ipc_dsp.dsp_solo_mute(self.current_variant_value, i, mute_status)
                self.data["channels"][i]["mute"] = bool(mute_status)
            self.check_data_json_timer()
        else :
            self.data["channels"][channel]["mute"] = bool(muted)
            self.check_data_json_timer()
            mute_status = bool(muted)
            for i_group in range(0, ipc_constants.NUM_OF_GROUPS):  # calculate mute groups impact
                if 1 == self.data["channels"][channel]["assigned_to_group"][i_group]:
                    mute_status = mute_status or self.data["groups"][i_group]["mute"]
            ipc_dsp.dsp_solo_mute(self.current_variant_value, channel, mute_status)
        return True

    @dbus.service.method(ipc_common.SOLO_GAIN_SET_INTERFACE, in_signature='id', out_signiture='b')
    def solo_gain_set(self, channel, gain):
        ipc_util.debug_print("server: set solo gain called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["gain"] = float(gain)
                ipc_dsp.dsp_channel_gain_solo_config(self.current_variant_value, i, float(gain))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["gain"] = float(gain)
            self.check_data_json_timer()
            ipc_dsp.dsp_channel_gain_solo_config(self.current_variant_value, channel, float(gain))
        return True

    @dbus.service.method(ipc_common.SOLO_POLARITY_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def solo_polarity_set(self, channel, polarity):
        ipc_util.debug_print("server: set solo polarity called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["polarity"] = bool(polarity)
                ipc_dsp.dsp_solo_polarity(self.current_variant_value, i, bool(polarity))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["polarity"] = bool(polarity)
            self.check_data_json_timer()
            ipc_dsp.dsp_solo_polarity(self.current_variant_value, channel, bool(polarity))
        return True

    @dbus.service.method(ipc_common.SOLO_DELAY_ENABLE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def solo_delay_enable_set(self, channel, delay_enabled):
        ipc_util.debug_print("server: set solo delay enable called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["delay_enable"] = bool(delay_enabled)
                self.recalculate_group_delay_values()  # in case somebody change json settings
                self.send_delay_value_to_dsp(i)
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["delay_enable"] = bool(delay_enabled)
            self.check_data_json_timer()
            self.recalculate_group_delay_values()  # in case somebody change json settings
            self.send_delay_value_to_dsp(channel)
        return True

    @dbus.service.method(ipc_common.SOLO_DELAY_VALUE_SET_INTERFACE, in_signature='id', out_signiture='b')
    def solo_delay_value_set(self, channel, delay_value):
        ipc_util.debug_print("server: set solo delay value called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["delay_value"] = float(delay_value)
                self.recalculate_group_delay_values()  # in case somebody change json settings
                self.send_delay_value_to_dsp(i)
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["delay_value"] = float(delay_value)
            self.check_data_json_timer()
            self.recalculate_group_delay_values()  # in case somebody change json settings
            self.send_delay_value_to_dsp(channel)
        return True

    @dbus.service.method(ipc_common.SOLO_XOVER_HP_ENABLE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def solo_xover_hp_enable_set(self, channel, enabled):
        ipc_util.debug_print("server: set solo xover hp enable called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["xover_hp_filter"]["xover_hp_enable"] = bool(enabled)
                if bool(enabled):
                    coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][i]["xover_hp_filter"]["xover_hp_type"],
                                                                        ipc_constants.XOVER_HP_TYPE,
                                                                        self.data["channels"][i]["xover_hp_filter"]["xover_hp_freq"])
                else:
                    coefficients = ipc_constants.DEFAULT_XOVER_FILTER
                ipc_dsp.dsp_set_solo_xover_hp_coeff(self.current_variant_value, i, ipc_util.scale_xover_coeff(coefficients))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["xover_hp_filter"]["xover_hp_enable"] = bool(enabled)
            self.check_data_json_timer()
            if bool(enabled):
                coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][channel]["xover_hp_filter"]["xover_hp_type"],
                                                                    ipc_constants.XOVER_HP_TYPE,
                                                                    self.data["channels"][channel]["xover_hp_filter"]["xover_hp_freq"])
            else:
                coefficients = ipc_constants.DEFAULT_XOVER_FILTER
            ipc_dsp.dsp_set_solo_xover_hp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SOLO_XOVER_HP_TYPE_SET_INTERFACE, in_signature='ii', out_signiture='b')
    def solo_xover_hp_type_set(self, channel, xover_type):
        ipc_util.debug_print("server: set solo xover hp type called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["xover_hp_filter"]["xover_hp_type"] = int(xover_type)
                if self.data["channels"][i]["xover_hp_filter"]["xover_hp_enable"]:
                    coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][i]["xover_hp_filter"]["xover_hp_type"],
                                                                        ipc_constants.XOVER_HP_TYPE,
                                                                        self.data["channels"][i]["xover_hp_filter"]["xover_hp_freq"])
                    ipc_dsp.dsp_set_solo_xover_hp_coeff(self.current_variant_value, i, ipc_util.scale_xover_coeff(coefficients))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["xover_hp_filter"]["xover_hp_type"] = int(xover_type)
            self.check_data_json_timer()
            if self.data["channels"][channel]["xover_hp_filter"]["xover_hp_enable"]:
                coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][channel]["xover_hp_filter"]["xover_hp_type"],
                                                                    ipc_constants.XOVER_HP_TYPE,
                                                                    self.data["channels"][channel]["xover_hp_filter"]["xover_hp_freq"])
                ipc_dsp.dsp_set_solo_xover_hp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SOLO_XOVER_HP_FREQ_SET_INTERFACE, in_signature='id', out_signiture='b')
    def solo_xover_hp_freq_set(self, channel, freq):
        ipc_util.debug_print("server: set solo xover hp freq called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["xover_hp_filter"]["xover_hp_freq"] = float(freq)
                if self.data["channels"][i]["xover_hp_filter"]["xover_hp_enable"]:
                    coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][i]["xover_hp_filter"]["xover_hp_type"],
                                                                        ipc_constants.XOVER_HP_TYPE,
                                                                        self.data["channels"][i]["xover_hp_filter"]["xover_hp_freq"])
                    ipc_dsp.dsp_set_solo_xover_hp_coeff(self.current_variant_value, i, ipc_util.scale_xover_coeff(coefficients))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["xover_hp_filter"]["xover_hp_freq"] = float(freq)
            self.check_data_json_timer()
            if self.data["channels"][channel]["xover_hp_filter"]["xover_hp_enable"]:
                coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][channel]["xover_hp_filter"]["xover_hp_type"],
                                                                    ipc_constants.XOVER_HP_TYPE,
                                                                    self.data["channels"][channel]["xover_hp_filter"]["xover_hp_freq"])
                ipc_dsp.dsp_set_solo_xover_hp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SOLO_XOVER_LP_ENABLE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def solo_xover_lp_enable_set(self, channel, enabled):
        ipc_util.debug_print("server: set solo xover lp enable called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["xover_lp_filter"]["xover_lp_enable"] = bool(enabled)
                if bool(enabled):
                    coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][i]["xover_lp_filter"]["xover_lp_type"],
                                                                        ipc_constants.XOVER_LP_TYPE,
                                                                        self.data["channels"][i]["xover_lp_filter"]["xover_lp_freq"])
                else:
                    coefficients = ipc_constants.DEFAULT_XOVER_FILTER
                ipc_dsp.dsp_set_solo_xover_lp_coeff(self.current_variant_value, i, ipc_util.scale_xover_coeff(coefficients))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["xover_lp_filter"]["xover_lp_enable"] = bool(enabled)
            self.check_data_json_timer()
            if bool(enabled):
                coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][channel]["xover_lp_filter"]["xover_lp_type"],
                                                                    ipc_constants.XOVER_LP_TYPE,
                                                                    self.data["channels"][channel]["xover_lp_filter"]["xover_lp_freq"])
            else:
                coefficients = ipc_constants.DEFAULT_XOVER_FILTER
            ipc_dsp.dsp_set_solo_xover_lp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SOLO_XOVER_LP_TYPE_SET_INTERFACE, in_signature='ii', out_signiture='b')
    def solo_xover_lp_type_set(self, channel, xover_type):
        ipc_util.debug_print("server: set solo xover lp type called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["xover_lp_filter"]["xover_lp_type"] = int(xover_type)
                if self.data["channels"][i]["xover_lp_filter"]["xover_lp_enable"]:
                    coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][i]["xover_lp_filter"]["xover_lp_type"],
                                                                        ipc_constants.XOVER_LP_TYPE,
                                                                        self.data["channels"][i]["xover_lp_filter"]["xover_lp_freq"])
                    ipc_dsp.dsp_set_solo_xover_lp_coeff(self.current_variant_value, i, ipc_util.scale_xover_coeff(coefficients))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["xover_lp_filter"]["xover_lp_type"] = int(xover_type)
            self.check_data_json_timer()
            if self.data["channels"][channel]["xover_lp_filter"]["xover_lp_enable"]:
                coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][channel]["xover_lp_filter"]["xover_lp_type"],
                                                                    ipc_constants.XOVER_LP_TYPE,
                                                                    self.data["channels"][channel]["xover_lp_filter"]["xover_lp_freq"])
                ipc_dsp.dsp_set_solo_xover_lp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SOLO_XOVER_LP_FREQ_SET_INTERFACE, in_signature='id', out_signiture='b')
    def solo_xover_lp_freq_set(self, channel, freq):
        ipc_util.debug_print("server: set solo xover lp freq called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["xover_lp_filter"]["xover_lp_freq"] = float(freq)
                if self.data["channels"][i]["xover_lp_filter"]["xover_lp_enable"]:
                    coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][i]["xover_lp_filter"]["xover_lp_type"],
                                                                        ipc_constants.XOVER_LP_TYPE,
                                                                        self.data["channels"][i]["xover_lp_filter"]["xover_lp_freq"])
                    ipc_dsp.dsp_set_solo_xover_lp_coeff(self.current_variant_value, i, ipc_util.scale_xover_coeff(coefficients))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["xover_lp_filter"]["xover_lp_freq"] = float(freq)
            self.check_data_json_timer()
            if self.data["channels"][channel]["xover_lp_filter"]["xover_lp_enable"]:
                coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][channel]["xover_lp_filter"]["xover_lp_type"],
                                                                    ipc_constants.XOVER_LP_TYPE,
                                                                    self.data["channels"][channel]["xover_lp_filter"]["xover_lp_freq"])
                ipc_dsp.dsp_set_solo_xover_lp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SOLO_LIM_RMS_THRES_SET_INTERFACE, in_signature='id', out_signiture='b')
    def solo_lim_rms_thres_set(self, channel, thres):
        ipc_util.debug_print("server: set solo lim rms thres called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["lim_rms"]["lim_rms_thres"] = float(thres)
                threshold_points = ipc_util.calculate_compressor_rms_coefficients(float(thres))
                ipc_dsp.dsp_set_solo_lim_rms_thres(self.current_variant_value, i, threshold_points)
            self.check_data_json_timer() 
        else:
            self.data["channels"][channel]["lim_rms"]["lim_rms_thres"] = float(thres)
            self.check_data_json_timer() 
            threshold_points = ipc_util.calculate_compressor_rms_coefficients(float(thres))
            ipc_dsp.dsp_set_solo_lim_rms_thres(self.current_variant_value, channel, threshold_points)
        return True

    @dbus.service.method(ipc_common.SOLO_LIM_RMS_ATTACK_SET_INTERFACE, in_signature='id', out_signiture='b')
    def solo_lim_rms_attack_set(self, channel, attack):
        ipc_util.debug_print("server: set solo lim rms attack called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["lim_rms"]["lim_rms_attack"] = float(attack)
                ipc_dsp.dsp_set_solo_lim_rms_attack(self.current_variant_value, i, float(attack))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["lim_rms"]["lim_rms_attack"] = float(attack)
            self.check_data_json_timer()
            ipc_dsp.dsp_set_solo_lim_rms_attack(self.current_variant_value, channel, float(attack))
        return True

    @dbus.service.method(ipc_common.SOLO_LIM_RMS_RELEASE_SET_INTERFACE, in_signature='id', out_signiture='b')
    def solo_lim_rms_release_set(self, channel, release):
        ipc_util.debug_print("server: set solo lim rms release called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["lim_rms"]["lim_rms_release"] = float(release)
                ipc_dsp.dsp_set_solo_lim_rms_release(self.current_variant_value, i, float(release))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["lim_rms"]["lim_rms_release"] = float(release)
            self.check_data_json_timer()
            ipc_dsp.dsp_set_solo_lim_rms_release(self.current_variant_value, channel, float(release))
        return True

    @dbus.service.method(ipc_common.SOLO_LIM_PEAK_THRES_SET_INTERFACE, in_signature='id', out_signiture='b')
    def solo_lim_peak_thres_set(self, channel, thres):
        ipc_util.debug_print("server: set solo lim peak thres called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["lim_peak"]["lim_peak_thres"] = float(thres)
                threshold_points = ipc_util.calculate_compressor_peak_coefficients(float(thres))
                ipc_dsp.dsp_set_solo_lim_peak_thres(self.current_variant_value, i, threshold_points)
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["lim_peak"]["lim_peak_thres"] = float(thres)
            self.check_data_json_timer()
            threshold_points = ipc_util.calculate_compressor_peak_coefficients(float(thres))
            ipc_dsp.dsp_set_solo_lim_peak_thres(self.current_variant_value, channel, threshold_points)
        return True

    @dbus.service.method(ipc_common.SOLO_LIM_PEAK_RELEASE_SET_INTERFACE, in_signature='id', out_signiture='b')
    def solo_lim_peak_release_set(self, channel, release):
        ipc_util.debug_print("server: set solo lim peak release called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["lim_peak"]["lim_peak_release"] = float(release)
                ipc_dsp.dsp_set_solo_lim_peak_release(self.current_variant_value, i, float(release))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["lim_peak"]["lim_peak_release"] = float(release)
            self.check_data_json_timer()
            ipc_dsp.dsp_set_solo_lim_peak_release(self.current_variant_value, channel, float(release))
        return True

    @dbus.service.method(ipc_common.SOLO_CHANNEL_SOURCE_PRI_SET_INTERFACE, in_signature='ii', out_signiture='b')
    def solo_channel_source_pri_set(self, channel, source):
        ipc_util.debug_print("server: set solo channel source pri called", self.debug_mode)
        # old_source_value = self.data["channels"][channel]["source_pri"]
        for i in range(0, 12):
            if source == i:
                self.data["channels"][channel]["mixer"][i]["gain"] = float(0.0)
            else:
                self.data["channels"][channel]["mixer"][i]["gain"] = float(-80.0)
            ipc_dsp.dsp_channel_source_mixer(self.current_variant_value, channel,i,float(self.data["channels"][channel]["mixer"][i]["gain"]))

        self.data["channels"][channel]["source_pri"] = int(source)
        self.check_data_json_timer()
        # if self.data["channels"][channel]["active_source"] == 0:  # if pri source is currently active, send change
        #     ipc_dsp.dsp_channel_source_mixer
        #     ipc_dsp.dsp_channel_source_config(self.current_variant_value, channel, old_source_value, 0)  # deactivate old source
        #     ipc_dsp.dsp_channel_source_config(self.current_variant_value, channel, source, 1)  # activate new source
        return True

    @dbus.service.method(ipc_common.SOLO_CHANNEL_SOURCE_SEC_SET_INTERFACE, in_signature='ii', out_signiture='b')
    def solo_channel_source_sec_set(self, channel, source):
        ipc_util.debug_print("server: set solo channel source sec called", self.debug_mode)
        old_source_value = self.data["channels"][channel]["source_sec"]
        self.data["channels"][channel]["source_sec"] = int(source)
        self.check_data_json_timer()
        if self.data["channels"][channel]["active_source"] == 1:  # if sec source is currently active, send change
            ipc_dsp.dsp_channel_source_config(self.current_variant_value, channel, old_source_value, 0)  # deactivate old source
            ipc_dsp.dsp_channel_source_config(self.current_variant_value, channel, source, 1)  # activate new source
        return True

    @dbus.service.method(ipc_common.SOLO_CHANNEL_SOURCE_MIXER_SET_INTERFACE, in_signature='iid', out_signiture='b')
    def solo_channel_source_mixer_set(self, channel, source, gain):
        ipc_util.debug_print("server: set solo channel source mixer called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["mixer"][source]["gain"] = float(gain)
                ipc_dsp.dsp_channel_source_mixer(self.current_variant_value, i, source, float(gain))
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["mixer"][source]["gain"] = float(gain)
            self.check_data_json_timer()
            ipc_dsp.dsp_channel_source_mixer(self.current_variant_value, channel, source, float(gain))
        return True

    @dbus.service.method(ipc_common.SOLO_CHANNEL_NAME_SET_INTERFACE, in_signature='is', out_signiture='b')
    def solo_channel_name_set(self, channel, name):
        ipc_util.debug_print("server: set solo channel name called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            self.data["channels"][0]["name"] = str(name)
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["name"] = str(name)
            self.check_data_json_timer()
        return True

    @dbus.service.method(ipc_common.GROUP_PEQ_ENABLE_SET_INTERFACE, in_signature='iib', out_signiture='b')
    def group_peq_enable_set(self, group_number, peq_channel, enabled):
        ipc_util.debug_print("server: set group peq enable called", self.debug_mode)
        self.data["groups"][group_number]["peq"][peq_channel]["enable"] = bool(enabled)
        self.check_data_json_timer()
        if bool(enabled):
            a1, a2, b0, b1, b2 = self.recalculate_group_peq_values(group_number, peq_channel)
            self.send_group_peq_coef_to_dsp(group_number, peq_channel, [b2, b1, b0, a2, a1])
        else:
            self.send_group_peq_coef_to_dsp(group_number, peq_channel, [0, 0, 1, 0, 0])  # if disabled, send default configuration
        return True

    @dbus.service.method(ipc_common.GROUP_PEQ_TYPE_SET_INTERFACE, in_signature='iii', out_signiture='b')
    def group_peq_type_set(self, group_number, peq_channel, peq_type):
        ipc_util.debug_print("server: set group peq type called", self.debug_mode)
        self.data["groups"][group_number]["peq"][peq_channel]["type"] = int(peq_type)
        self.check_data_json_timer()
        if bool(self.data["groups"][group_number]["peq"][peq_channel]["enable"]):
            a1, a2, b0, b1, b2 = self.recalculate_group_peq_values(group_number, peq_channel)
            self.send_group_peq_coef_to_dsp(group_number, peq_channel, [b2, b1, b0, a2, a1])
        return True

    @dbus.service.method(ipc_common.GROUP_PEQ_FREQ_SET_INTERFACE, in_signature='iid', out_signiture='b')
    def group_peq_freq_set(self, group_number, peq_channel, freq):
        ipc_util.debug_print("server: set group peq freq called", self.debug_mode)
        self.data["groups"][group_number]["peq"][peq_channel]["freq"] = float(freq)
        self.check_data_json_timer()
        if bool(self.data["groups"][group_number]["peq"][peq_channel]["enable"]):
            a1, a2, b0, b1, b2 = self.recalculate_group_peq_values(group_number, peq_channel)
            self.send_group_peq_coef_to_dsp(group_number, peq_channel, [b2, b1, b0, a2, a1])
        return True

    @dbus.service.method(ipc_common.GROUP_PEQ_GAIN_SET_INTERFACE, in_signature='iid', out_signiture='b')
    def group_peq_gain_set(self, group_number, peq_channel, gain):
        ipc_util.debug_print("server: set group peq gain called", self.debug_mode)
        self.data["groups"][group_number]["peq"][peq_channel]["gain"] = float(gain)
        self.check_data_json_timer()
        if bool(self.data["groups"][group_number]["peq"][peq_channel]["enable"]):
            a1, a2, b0, b1, b2 = self.recalculate_group_peq_values(group_number, peq_channel)
            self.send_group_peq_coef_to_dsp(group_number, peq_channel, [b2, b1, b0, a2, a1])
        return True

    @dbus.service.method(ipc_common.GROUP_PEQ_Q_SET_INTERFACE, in_signature='iid', out_signiture='b')
    def group_peq_q_set(self, group_number, peq_channel, q):
        ipc_util.debug_print("server: set group peq q called", self.debug_mode)
        self.data["groups"][group_number]["peq"][peq_channel]["q"] = float(q)
        self.check_data_json_timer()
        if bool(self.data["groups"][group_number]["peq"][peq_channel]["enable"]):
            a1, a2, b0, b1, b2 = self.recalculate_group_peq_values(group_number, peq_channel)
            self.send_group_peq_coef_to_dsp(group_number, peq_channel, [b2, b1, b0, a2, a1])
        return True

    @dbus.service.method(ipc_common.GROUP_PEQ_SET_INTERFACE, in_signature='iis', out_signiture='b')
    def group_peq_set(self, group_number, peq_channel, peq):
        ipc_util.debug_print("server: set group peq called", self.debug_mode)

        try:
            data = json.loads(peq)
        except json.JSONDecodeError:
            return False

        ena = data.get("ena", ipc_constants.DEFAULT_BOOL)
        freq = data.get("frequency", ipc_constants.DEFAULT_INT)
        gain = data.get("gain", ipc_constants.DEFAULT_FLOAT)
        q = data.get("q", ipc_constants.DEFAULT_FLOAT)
        type = data.get("type", ipc_constants.DEFAULT_INT)

        self.data["groups"][group_number]["peq"][peq_channel]["enable"] = ena
        self.data["groups"][group_number]["peq"][peq_channel]["freq"] = freq
        self.data["groups"][group_number]["peq"][peq_channel]["gain"] = gain
        self.data["groups"][group_number]["peq"][peq_channel]["q"] = q
        self.data["groups"][group_number]["peq"][peq_channel]["type"] = type

        self.check_data_json_timer()
        if bool(ena):
            a1, a2, b0, b1, b2 = self.recalculate_group_peq_values(group_number, peq_channel)
            self.send_group_peq_coef_to_dsp(group_number, peq_channel, [b2, b1, b0, a2, a1])
        else:
            self.send_group_peq_coef_to_dsp(group_number, peq_channel, [0, 0, 1, 0, 0])  # if disabled, send default configuration
        return True

    @dbus.service.method(ipc_common.SOLO_PEQ_SET_INTERFACE, in_signature='iis', out_signiture='b')
    def solo_peq_set(self, channel, peq_channel, peq):
        ipc_util.debug_print("server: set solo peq called", self.debug_mode)

        try:
            data = json.loads(peq)
        except json.JSONDecodeError:
            return False

        ena = data.get("ena", ipc_constants.DEFAULT_BOOL)
        freq = data.get("frequency", ipc_constants.DEFAULT_INT)
        gain = data.get("gain", ipc_constants.DEFAULT_FLOAT)
        q = data.get("q", ipc_constants.DEFAULT_FLOAT)
        type = data.get("type", ipc_constants.DEFAULT_INT)

        self.data["channels"][channel]["peq"][peq_channel]["enable"] = ena
        self.data["channels"][channel]["peq"][peq_channel]["freq"] = freq
        self.data["channels"][channel]["peq"][peq_channel]["gain"] = gain
        self.data["channels"][channel]["peq"][peq_channel]["q"] = q
        self.data["channels"][channel]["peq"][peq_channel]["type"] = type

        self.check_data_json_timer()
        if bool(ena):
            a0, a1, a2, b0, b1, b2 = ipc_filters.compute_peq_coeff(self.data["channels"][channel]["peq"][peq_channel]["type"],
                                                                self.data["channels"][channel]["peq"][peq_channel]["freq"],
                                                                self.data["channels"][channel]["peq"][peq_channel]["gain"],
                                                                self.data["channels"][channel]["peq"][peq_channel]["q"])
            a1, a2, b0, b1, b2 = ipc_util.rescale_peq_values(a0, a1, a2, b0, b1, b2)
            ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, channel, peq_channel, [b2, b1, b0, a2, a1])
        else:
            ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, channel, peq_channel, [0, 0, 1, 0, 0])  # if disabled, send default configuration
        return True

    @dbus.service.method(ipc_common.SOLO_PEQ_ENABLE_SET_INTERFACE, in_signature='iib', out_signiture='b')
    def solo_peq_enable_set(self, channel, peq_channel, enabled):
        ipc_util.debug_print("server: set solo peq enable called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["peq"][peq_channel]["enable"] = bool(enabled)
                if bool(enabled):
                    a0, a1, a2, b0, b1, b2 = ipc_filters.compute_peq_coeff(self.data["channels"][i]["peq"][peq_channel]["type"],
                                                                        self.data["channels"][i]["peq"][peq_channel]["freq"],
                                                                        self.data["channels"][i]["peq"][peq_channel]["gain"],
                                                                        self.data["channels"][i]["peq"][peq_channel]["q"])
                    a1, a2, b0, b1, b2 = ipc_util.rescale_peq_values(a0, a1, a2, b0, b1, b2)
                    ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, i, peq_channel, [b2, b1, b0, a2, a1])
                else:
                    ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, i, peq_channel, [0, 0, 1, 0, 0])  # if disabled, send default configuration
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["peq"][peq_channel]["enable"] = bool(enabled)
            self.check_data_json_timer()
            if bool(enabled):
                a0, a1, a2, b0, b1, b2 = ipc_filters.compute_peq_coeff(self.data["channels"][channel]["peq"][peq_channel]["type"],
                                                                    self.data["channels"][channel]["peq"][peq_channel]["freq"],
                                                                    self.data["channels"][channel]["peq"][peq_channel]["gain"],
                                                                    self.data["channels"][channel]["peq"][peq_channel]["q"])
                a1, a2, b0, b1, b2 = ipc_util.rescale_peq_values(a0, a1, a2, b0, b1, b2)
                ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, channel, peq_channel, [b2, b1, b0, a2, a1])
            else:
                ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, channel, peq_channel, [0, 0, 1, 0, 0])  # if disabled, send default configuration
        return True

    @dbus.service.method(ipc_common.SOLO_PEQ_TYPE_SET_INTERFACE, in_signature='iii', out_signiture='b')
    def solo_peq_type_set(self, channel, peq_channel, peq_type):
        ipc_util.debug_print("server: set solo peq type called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["peq"][peq_channel]["type"] = int(peq_type)
                array_coeff = ipc_util.recalculate_peq_values(self.data["channels"], i, peq_channel)
                ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, i, peq_channel, array_coeff)
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["peq"][peq_channel]["type"] = int(peq_type)
            self.check_data_json_timer()
            array_coeff = ipc_util.recalculate_peq_values(self.data["channels"], channel, peq_channel)
            ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, channel, peq_channel, array_coeff)
        return True

    @dbus.service.method(ipc_common.SOLO_PEQ_FREQ_SET_INTERFACE, in_signature='iid', out_signiture='b')
    def solo_peq_freq_set(self, channel, peq_channel, freq):
        ipc_util.debug_print("server: set solo peq freq called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["peq"][peq_channel]["freq"] = float(freq)
                array_coeff = ipc_util.recalculate_peq_values(self.data["channels"], i, peq_channel)
                ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, i, peq_channel, array_coeff)
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["peq"][peq_channel]["freq"] = float(freq)
            self.check_data_json_timer()
            array_coeff = ipc_util.recalculate_peq_values(self.data["channels"], channel, peq_channel)
            ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, channel, peq_channel, array_coeff)
        return True

    @dbus.service.method(ipc_common.SOLO_PEQ_GAIN_SET_INTERFACE, in_signature='iid', out_signiture='b')
    def solo_peq_gain_set(self, channel, peq_channel, gain):
        ipc_util.debug_print("server: set solo peq gain called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["peq"][peq_channel]["gain"] = float(gain)
                array_coeff = ipc_util.recalculate_peq_values(self.data["channels"], i, peq_channel)
                ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, i, peq_channel, array_coeff)
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["peq"][peq_channel]["gain"] = float(gain)
            self.check_data_json_timer()
            array_coeff = ipc_util.recalculate_peq_values(self.data["channels"], channel, peq_channel)
            ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, channel, peq_channel, array_coeff)
        return True

    @dbus.service.method(ipc_common.SOLO_PEQ_Q_SET_INTERFACE, in_signature='iid', out_signiture='b')
    def solo_peq_q_set(self, channel, peq_channel, q):
        ipc_util.debug_print("server: set solo peq q called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["peq"][peq_channel]["q"] = float(q)
                array_coeff = ipc_util.recalculate_peq_values(self.data["channels"], i, peq_channel)
                ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, i, peq_channel, array_coeff)
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["peq"][peq_channel]["q"] = float(q)
            self.check_data_json_timer()
            array_coeff = ipc_util.recalculate_peq_values(self.data["channels"], channel, peq_channel)
            ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, channel, peq_channel, array_coeff)
        return True

    @dbus.service.method(ipc_common.ASSIGN_CHANNEL_TO_GROUP_SET_INTERFACE, in_signature='iii', out_signiture='b')
    def assign_channel_to_group_set(self, channel, group_number, assign_value):
        ipc_util.debug_print("server: set assign channel to group called", self.debug_mode)
        if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6"):
            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                self.data["channels"][i]["assigned_to_group"][group_number] = int(assign_value)

                # recalculate group impact on mute
                group_mute_state = bool(self.data["channels"][i]["mute"])
                for i_group in range(0, ipc_constants.NUM_OF_GROUPS):
                    if self.data["channels"][i]["assigned_to_group"][i_group]:
                        group_mute_state = group_mute_state or bool(self.data["groups"][i_group]["mute"])
                ipc_dsp.dsp_solo_mute(self.current_variant_value, i, group_mute_state)
                if 0 == int(assign_value):
                    # recalculating delay values and sending it
                    self.recalculate_group_delay_values()
                    self.send_delay_value_to_dsp(i)
                    # sending default gain value
                    ipc_dsp.dsp_group_gain_set(self.current_variant_value, i, group_number, ipc_constants.DEFAULT_GAIN_VALUE)
                    # sending polarity
                    ipc_dsp.dsp_group_polarity(self.current_variant_value, i, group_number, ipc_constants.DEFAULT_POLARITY_VALUE)
                    # sending filter PEQ values
                    a1, a2, b0, b1, b2 = ipc_util.rescale_peq_values(ipc_constants.DEFAULT_FILTER["a0"],
                                                                    ipc_constants.DEFAULT_FILTER["a1"],
                                                                    ipc_constants.DEFAULT_FILTER["a2"],
                                                                    ipc_constants.DEFAULT_FILTER["b0"],
                                                                    ipc_constants.DEFAULT_FILTER["b1"],
                                                                    ipc_constants.DEFAULT_FILTER["b2"])
                    for i_peq in range(0, ipc_constants.NUM_OF_PEQ_FILTERS):
                        ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, i, group_number, i_peq, [b2, b1, b0, a2, a1])
                else:
                    # recalculating delay values and sending it
                    self.recalculate_group_delay_values()
                    self.send_delay_value_to_dsp(i)
                    # sending default gain value
                    ipc_dsp.dsp_group_gain_set(self.current_variant_value, i, group_number, self.data["groups"][group_number]["gain"])
                    # sending polarity
                    ipc_dsp.dsp_group_polarity(self.current_variant_value, i, group_number, self.data["groups"][group_number]["polarity"])
                    # sending filter PEQ values
                    for i_peq in range(0, ipc_constants.NUM_OF_PEQ_FILTERS):
                        a1, a2, b0, b1, b2 = self.recalculate_group_peq_values(group_number, i_peq)
                        ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, i, group_number, i_peq, [b2, b1, b0, a2, a1])
            self.check_data_json_timer()
        else:
            self.data["channels"][channel]["assigned_to_group"][group_number] = int(assign_value)
            self.check_data_json_timer()
            # recalculate group impact on mute
            group_mute_state = bool(self.data["channels"][channel]["mute"])
            for i_group in range(0, ipc_constants.NUM_OF_GROUPS):
                if self.data["channels"][channel]["assigned_to_group"][i_group]:
                    group_mute_state = group_mute_state or bool(self.data["groups"][i_group]["mute"])
            ipc_dsp.dsp_solo_mute(self.current_variant_value, channel, group_mute_state)
            if 0 == int(assign_value):
                self.data["groups"][group_number]["gain"] = float(ipc_constants.DEFAULT_GAIN_VALUE)
                self.data["groups"][group_number]["polarity"] = bool(ipc_constants.DEFAULT_POLARITY_VALUE)
                self.data["groups"][group_number]["delay_enable"] = bool(ipc_constants.DEFAULT_DELAY_ENABLE)
                self.data["groups"][group_number]["delay_value"] = float(ipc_constants.DEFAULT_DELAY_VALUE)
                # recalculating delay values and sending it
                self.recalculate_group_delay_values()
                self.send_delay_value_to_dsp(channel)
                # sending default gain value
                ipc_dsp.dsp_group_gain_set(self.current_variant_value, channel, group_number, ipc_constants.DEFAULT_GAIN_VALUE)
                # sending polarity
                ipc_dsp.dsp_group_polarity(self.current_variant_value, channel, group_number, ipc_constants.DEFAULT_POLARITY_VALUE)
                # sending filter PEQ values
                a1, a2, b0, b1, b2 = ipc_util.rescale_peq_values(ipc_constants.DEFAULT_FILTER["a0"],
                                                                ipc_constants.DEFAULT_FILTER["a1"],
                                                                ipc_constants.DEFAULT_FILTER["a2"],
                                                                ipc_constants.DEFAULT_FILTER["b0"],
                                                                ipc_constants.DEFAULT_FILTER["b1"],
                                                                ipc_constants.DEFAULT_FILTER["b2"])
                for i_peq in range(0, ipc_constants.NUM_OF_PEQ_FILTERS):
                    ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, channel, group_number, i_peq, [b2, b1, b0, a2, a1])
                    self.data["groups"][group_number]["peq"][i_peq]["enable"] = bool(ipc_constants.DEFAULT_PEQ_ENABLE)
                    self.data["groups"][group_number]["peq"][i_peq]["type"] = int(ipc_constants.DEFAULT_PEQ_TYPE)
                    self.data["groups"][group_number]["peq"][i_peq]["freq"] = float(ipc_constants.DEFAULT_PEQ_FREQ[i_peq])
                    self.data["groups"][group_number]["peq"][i_peq]["gain"] = float(ipc_constants.DEFAULT_PEQ_GAIN)
                    self.data["groups"][group_number]["peq"][i_peq]["q"] = float(ipc_constants.DEFAULT_PEQ_Q)

            else:
                # recalculating delay values and sending it
                self.recalculate_group_delay_values()
                self.send_delay_value_to_dsp(channel)
                # sending default gain value
                ipc_dsp.dsp_group_gain_set(self.current_variant_value, channel, group_number, self.data["groups"][group_number]["gain"])
                # sending polarity
                ipc_dsp.dsp_group_polarity(self.current_variant_value, channel, group_number, self.data["groups"][group_number]["polarity"])
                # sending filter PEQ values
                for i_peq in range(0, ipc_constants.NUM_OF_PEQ_FILTERS):
                    a1, a2, b0, b1, b2 = self.recalculate_group_peq_values(group_number, i_peq)
                    ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, channel, group_number, i_peq, [b2, b1, b0, a2, a1])
        return True

    @dbus.service.method(ipc_common.ASSIGN_CHANNEL_TO_GROUP_GET_INTERFACE, in_signature='i', out_signiture='sv')
    def assign_channel_to_group_get(self, channel):
        ipc_util.debug_print("server: get assign channel to group called", self.debug_mode)
        return python_to_dbus(self.data["channels"][channel].get("assigned_to_group", ipc_constants.DEFAULT_ARRAY_6))

    @dbus.service.method(ipc_common.SPEAKER_PRESET_GET_FILE_INTERFACE, in_signature='s', out_signiture='sv')
    def speaker_preset_file_get(self, path):
        ipc_util.debug_print("server: get speaker preset file called", self.debug_mode)
        folder, file = path.split("/")
        for folder_in_dict in self.speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        # return python_to_dbus(dict(file_in_dict["settings"]))
                        return python_to_dbus(dict(file_in_dict))
        return python_to_dbus(ipc_constants.DEFAULT_STRING)

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_GET_FILE_INTERFACE, in_signature='s', out_signiture='sv')
    def all_speaker_preset_file_get(self, path):
        ipc_util.debug_print("server: get all speaker preset file called", self.debug_mode)
        folder, file = path.split("/")
        for folder_in_dict in self.all_speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        # return python_to_dbus(dict(file_in_dict["settings"]))
                        return python_to_dbus(dict(file_in_dict))
        return python_to_dbus(ipc_constants.DEFAULT_STRING)

    @dbus.service.method(ipc_common.GLOBAL_PRESET_GET_FILE_INTERFACE, in_signature='s', out_signiture='sv')
    def global_preset_file_get(self, path):
        ipc_util.debug_print("server: get global preset file called", self.debug_mode)
        folder, file = path.split("/")
        for folder_in_dict in self.global_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        return python_to_dbus({"file_name": file_in_dict["file_name"],
                                               "bridge_mode_12": file_in_dict["bridge_mode_12"],
                                               "bridge_mode_34": file_in_dict["bridge_mode_34"],
                                               "user_settings": file_in_dict["user_settings"],
                                               "groups": file_in_dict["groups"],
                                               "speaker_presets": file_in_dict["speaker_presets"]})
        return python_to_dbus(ipc_constants.DEFAULT_STRING)

    @dbus.service.method(ipc_common.GLOBAL_PRESET_DELETE_FOLDER_INTERFACE, in_signature='s', out_signiture='b')
    def delete_global_preset_folder(self, folder_name):
        ipc_util.debug_print("server: delete global preset folder called", self.debug_mode)
        is_found = False
        for folder_in_dict in self.global_presets:
            if folder_name == folder_in_dict["folder_name"]:
                is_found = True
                self.global_presets.remove(folder_in_dict)
                self.check_global_presets_json_timer()
                break
        return is_found

    @dbus.service.method(ipc_common.GLOBAL_PRESET_CREATE_FOLDER_INTERFACE, in_signature='s', out_signiture='b')
    def create_global_preset_folder(self, folder_name):
        ipc_util.debug_print("server: create global preset folder", self.debug_mode)
        is_found = False
        for folder_in_dict in self.global_presets:
            if folder_name == folder_in_dict["folder_name"]:
                is_found = True
                break
        if is_found:
            print("Folder is already existing!")
        else:
            self.global_presets.append({"folder_name": str(folder_name), "files": []})
            self.check_global_presets_json_timer()
            print("Folder created!")
        return not is_found

    @dbus.service.method(ipc_common.GLOBAL_PRESET_DELETE_FILE_INTERFACE, in_signature='s', out_signiture='b')
    def delete_global_preset_file(self, path):
        ipc_util.debug_print("server: delete global preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.global_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        self.global_presets[self.global_presets.index(folder_in_dict)]["files"].remove(file_in_dict)
                        self.check_global_presets_json_timer()
                        break
        return is_found

    @dbus.service.method(ipc_common.SPEAKER_PRESET_DELETE_FOLDER_INTERFACE, in_signature='s', out_signiture='b')
    def delete_speaker_preset_folder(self, folder_name):
        ipc_util.debug_print("server: delete speaker preset folder", self.debug_mode)
        is_found = False
        for folder_in_dict in self.speaker_presets:
            if folder_name == folder_in_dict["folder_name"]:
                is_found = True
                self.speaker_presets.remove(folder_in_dict)
                self.check_speaker_presets_json_timer()
                break
        return is_found

    @dbus.service.method(ipc_common.SPEAKER_PRESET_CREATE_FOLDER_INTERFACE, in_signature='s', out_signiture='b')
    def create_speaker_preset_folder(self, folder_name):
        ipc_util.debug_print("server: create speaker preset folder", self.debug_mode)
        is_found = False
        for folder_in_dict in self.speaker_presets:
            if folder_name == folder_in_dict["folder_name"]:
                is_found = True
                break
        if is_found:
            print("Folder is already existing!")
        else:
            self.speaker_presets.append({"folder_name": str(folder_name), "files": []})
            self.check_speaker_presets_json_timer()
            print("Folder created!")
        return not is_found

    @dbus.service.method(ipc_common.SPEAKER_PRESET_CREATE_FILE_INTERFACE, in_signature='sss', out_signiture='b')
    def create_speaker_preset_file(self, path, channel, info):
        ipc_util.debug_print("server: create speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        info_dict = json.loads(info)
        is_found = False
        for folder_in_dict in self.speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        break
                if is_found:
                    print("There is element with same name!")
                else:
                    oem_value =""
                    if(info_dict.get("oem", ipc_constants.DEFAULT_BOOL)):
                        oem_value = self.oem["oem_code"]
                    d = {"file_name": file, "author": info_dict.get("author",ipc_constants.DEFAULT_STRING), 
                        "version": info_dict.get("version",ipc_constants.DEFAULT_STRING),
                        "note": info_dict.get("note",ipc_constants.DEFAULT_STRING),
                        "oem_code":oem_value, "settings": self.data["speaker_presets"][channel]}
                    self.speaker_presets[self.speaker_presets.index(folder_in_dict)]["files"].append(copy.deepcopy(d))
                    self.check_speaker_presets_json_timer()
        return not is_found

    @dbus.service.method(ipc_common.SPEAKER_PRESET_UPLOAD_FILE_INTERFACE, in_signature='ss', out_signiture='b')
    def upload_speaker_preset_file(self, path, preset):
        ipc_util.debug_print("server: upload speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        break
                if is_found:
                    print("There is element with same name!")
                else:
                    preset_dict = json.loads(preset)
                    if (preset_dict["settings"]["lim_rms"]["lim_rms_thres"] > ipc_constants.LIM_RMS_THRES_MAX ):
                        preset_dict["settings"]["lim_rms"]["lim_rms_thres"] = ipc_constants.LIM_RMS_THRES_MAX
                    if (preset_dict["settings"]["lim_peak"]["lim_peak_thres"] > ipc_constants.LIM_PEAK_THRES_MAX ):
                        preset_dict["settings"]["lim_peak"]["lim_peak_thres"] = ipc_constants.LIM_PEAK_THRES_MAX

                    # d = {"file_name": file, "settings": preset_dict}
                    self.speaker_presets[self.speaker_presets.index(folder_in_dict)]["files"].append(copy.deepcopy(preset_dict))
                    self.check_speaker_presets_json_timer()
        return not is_found

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_FILES_FROM_FOLDER_SET_INTERFACE, in_signature='ss', out_signiture='b')
    def all_speaker_preset_files_from_folder_set(self, folder_name, presets):
        ipc_util.debug_print("server: upload speaker preset file", self.debug_mode)
        duplicate = False
        presets_dict = json.loads(presets)
        for folder_in_dict in self.all_speaker_presets:
            if str(folder_name) == folder_in_dict["folder_name"]:
                for j_file in folder_in_dict["files"]:
                # for j in range (0, len(folder_in_dict["files"]), 1):
                    for i in range (0, len(presets_dict), 1):
                        if presets_dict[i].get("file_name") == j_file.get("file_name"):
                            duplicate = True
                            break
                if duplicate == False:
                    for i in range (0, len(presets_dict), 1):
                        self.all_speaker_presets[self.all_speaker_presets.index(folder_in_dict)]["files"].append(copy.deepcopy(presets_dict[i]))
        self.check_all_speaker_presets_json_timer()
        return duplicate

    @dbus.service.method(ipc_common.SPEAKER_PRESET_FILES_FROM_FOLDER_SET_INTERFACE, in_signature='ss', out_signiture='b')
    def speaker_preset_files_from_folder_set(self, folder_name, presets):
        ipc_util.debug_print("server: upload speaker preset file", self.debug_mode)
        duplicate = False
        presets_dict = json.loads(presets)
        for folder_in_dict in self.speaker_presets:
            if str(folder_name) == folder_in_dict["folder_name"]:
                for j_file in folder_in_dict["files"]:
                # for j in range (0, len(folder_in_dict["files"]), 1):
                    for i in range (0, len(presets_dict), 1):
                        if presets_dict[i].get("file_name") == j_file.get("file_name"):
                            duplicate = True
                            break
                if duplicate == False:
                    for i in range (0, len(presets_dict), 1):
                        self.speaker_presets[self.speaker_presets.index(folder_in_dict)]["files"].append(copy.deepcopy(presets_dict[i]))
        self.check_speaker_presets_json_timer()
        return duplicate

    @dbus.service.method(ipc_common.SPEAKER_PRESET_EDIT_FILE_INTERFACE, in_signature='sss', out_signiture='b')
    def edit_speaker_preset_file(self, path, channel, info):
        ipc_util.debug_print("server: edit speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        info_dict = json.loads(info)
        is_found = False
        for folder_in_dict in self.speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        d = self.data["speaker_presets"][channel]
                        self.speaker_presets[self.speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["settings"] = copy.deepcopy(d)
                        self.speaker_presets[self.speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["author"] = info_dict.get("author",ipc_constants.DEFAULT_STRING)
                        self.speaker_presets[self.speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["version"] = info_dict.get("version",ipc_constants.DEFAULT_STRING)
                        self.speaker_presets[self.speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["note"] = info_dict.get("note",ipc_constants.DEFAULT_STRING)
                        oem_value =""
                        if(info_dict.get("oem", ipc_constants.DEFAULT_BOOL) == True):
                            self.speaker_presets[self.speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["oem_code"] = self.oem["oem_code"]
                        else:
                            self.speaker_presets[self.speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["oem_code"] = ""
                        self.check_speaker_presets_json_timer()
                        break
        return is_found

    @dbus.service.method(ipc_common.SPEAKER_PRESET_RENAME_FILE_INTERFACE, in_signature='ss', out_signiture='b')
    def rename_speaker_preset_file(self, path, new_file_name):
        ipc_util.debug_print("server: rename speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        file_in_dict["file_name"] = new_file_name
                        self.check_speaker_presets_json_timer()
                        is_found = True
                        break
        return is_found

    @dbus.service.method(ipc_common.SPEAKER_PRESET_RENAME_FOLDER_INTERFACE, in_signature='ss', out_signiture='b')
    def rename_speaker_preset_folder(self, folder_name, new_folder_name):
        ipc_util.debug_print("server: rename speaker preset folder", self.debug_mode)
        is_found = False
        for folder_in_dict in self.speaker_presets:
            if folder_name == folder_in_dict["folder_name"]:
                is_found = True
                folder_in_dict["folder_name"] = new_folder_name
                self.check_speaker_presets_json_timer()
                break
        return is_found

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_DELETE_FOLDER_INTERFACE, in_signature='s', out_signiture='b')
    def delete_all_speaker_preset_folder(self, folder_name):
        ipc_util.debug_print("server: delete all speaker preset folder", self.debug_mode)
        is_found = False
        for folder_in_dict in self.all_speaker_presets:
            if folder_name == folder_in_dict["folder_name"]:
                is_found = True
                self.all_speaker_presets.remove(folder_in_dict)
                self.check_all_speaker_presets_json_timer()
                break
        return is_found

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_CREATE_FOLDER_INTERFACE, in_signature='s', out_signiture='b')
    def create_all_speaker_preset_folder(self, folder_name):
        ipc_util.debug_print("server: create all speaker preset folder", self.debug_mode)
        is_found = False
        for folder_in_dict in self.all_speaker_presets:
            if folder_name == folder_in_dict["folder_name"]:
                is_found = True
                break
        if is_found:
            print("Folder is already existing!")
        else:
            self.all_speaker_presets.append({"folder_name": str(folder_name), "files": []})
            self.check_all_speaker_presets_json_timer()
            print("Folder created!")
        return not is_found

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_CREATE_FILE_INTERFACE, in_signature='ss', out_signiture='b')
    def create_all_speaker_preset_file(self, path, info):
        ipc_util.debug_print("server: create all speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        info_dict = json.loads(info)
        is_found = False
        for folder_in_dict in self.all_speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        break
                if is_found:
                    print("There is element with same name!")
                else:
                    oem_value =""
                    if(info_dict.get("oem", ipc_constants.DEFAULT_BOOL)):
                        oem_value = self.oem["oem_code"]
                    d = {"file_name": file, "author": info_dict.get("author",ipc_constants.DEFAULT_STRING), 
                        "version": info_dict.get("version",ipc_constants.DEFAULT_STRING),
                        "note": info_dict.get("note",ipc_constants.DEFAULT_STRING),
                        "oem_code":oem_value, "settings": self.data["speaker_presets"]}
                    self.all_speaker_presets[self.all_speaker_presets.index(folder_in_dict)]["files"].append(copy.deepcopy(d))
                    self.check_all_speaker_presets_json_timer()
        return not is_found

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_UPLOAD_FILE_INTERFACE, in_signature='ss', out_signiture='b')
    def upload_all_speaker_preset_file(self, path, preset):
        ipc_util.debug_print("server: upload all speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.all_speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        break
                if is_found:
                    print("There is element with same name!")
                else:
                    preset_dict = json.loads(preset)
                    for i in range (0, ipc_constants.NUM_OF_CHANNELS) :
                        if (preset_dict["settings"][i]["lim_rms"]["lim_rms_thres"] > ipc_constants.LIM_RMS_THRES_MAX ):
                            preset_dict["settings"][i]["lim_rms"]["lim_rms_thres"] = ipc_constants.LIM_RMS_THRES_MAX
                        if (preset_dict["settings"][i]["lim_peak"]["lim_peak_thres"] > ipc_constants.LIM_PEAK_THRES_MAX ):
                            preset_dict["settings"][i]["lim_peak"]["lim_peak_thres"] = ipc_constants.LIM_PEAK_THRES_MAX

                    # d = {"file_name": file, "settings": preset_dict}
                    self.all_speaker_presets[self.all_speaker_presets.index(folder_in_dict)]["files"].append(copy.deepcopy(preset_dict))
                    self.check_all_speaker_presets_json_timer()
        return not is_found

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_EDIT_FILE_INTERFACE, in_signature='ss', out_signiture='b')
    def edit_all_speaker_preset_file(self, path, info):
        ipc_util.debug_print("server: edit all speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        info_dict = json.loads(info)
        is_found = False
        for folder_in_dict in self.all_speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        d = self.data["speaker_presets"]
                        copySettings = copy.deepcopy(d)
                        self.all_speaker_presets[self.all_speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["settings"] = copySettings
                        self.all_speaker_presets[self.all_speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["author"] = info_dict.get("author",ipc_constants.DEFAULT_STRING)
                        self.all_speaker_presets[self.all_speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["version"] = info_dict.get("version",ipc_constants.DEFAULT_STRING)
                        self.all_speaker_presets[self.all_speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["note"] = info_dict.get("note",ipc_constants.DEFAULT_STRING)
                        oem_value =""
                        if(info_dict.get("oem", ipc_constants.DEFAULT_BOOL) == True):
                            self.all_speaker_presets[self.all_speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["oem_code"] = self.oem["oem_code"]
                        else:
                            self.all_speaker_presets[self.all_speaker_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)]["oem_code"] = ""
                        self.check_all_speaker_presets_json_timer()
                        break
        return is_found

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_RENAME_FILE_INTERFACE, in_signature='ss', out_signiture='b')
    def rename_all_speaker_preset_file(self, path, new_file_name):
        ipc_util.debug_print("server: rename all speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.all_speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        file_in_dict["file_name"] = new_file_name
                        self.check_all_speaker_presets_json_timer()
                        is_found = True
                        break
        return is_found

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_RENAME_FOLDER_INTERFACE, in_signature='ss', out_signiture='b')
    def rename_all_speaker_preset_folder(self, folder_name, new_folder_name):
        ipc_util.debug_print("server: rename all speaker preset folder", self.debug_mode)
        is_found = False
        for folder_in_dict in self.all_speaker_presets:
            if folder_name == folder_in_dict["folder_name"]:
                is_found = True
                folder_in_dict["folder_name"] = new_folder_name
                self.check_all_speaker_presets_json_timer()
                break
        return is_found

    @dbus.service.method(ipc_common.GLOBAL_PRESET_CREATE_FILE_INTERFACE, in_signature='s', out_signiture='b')
    def create_global_preset_file(self, path):
        ipc_util.debug_print("server: create global preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.global_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        break
                if is_found:
                    print("There is element with same name!")
                else:
                    d = {"file_name": file,
                         "bridge_mode_12": self.data["settings"]["bridge_mode_12"],
                         "bridge_mode_34": self.data["settings"]["bridge_mode_34"],
                         "user_settings": self.data["channels"],
                         "groups": self.data["groups"],
                         "speaker_presets": self.data["speaker_presets"]}
                    self.global_presets[self.global_presets.index(folder_in_dict)]["files"].append(copy.deepcopy(d))
                    self.check_global_presets_json_timer()
        return not is_found

    @dbus.service.method(ipc_common.GLOBAL_PRESET_EDIT_FILE_INTERFACE, in_signature='s', out_signiture='b')
    def edit_global_preset_file(self, path):
        ipc_util.debug_print("server: edit global preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.global_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        d = {"file_name": file,
                             "bridge_mode_12": self.data["settings"]["bridge_mode_12"],
                             "bridge_mode_34": self.data["settings"]["bridge_mode_34"],
                             "user_settings": self.data["channels"],
                             "groups": self.data["groups"],
                             "speaker_presets": self.data["speaker_presets"]}
                        self.global_presets[self.global_presets.index(folder_in_dict)]["files"][folder_in_dict["files"].index(file_in_dict)] = copy.deepcopy(d)
                        self.check_global_presets_json_timer()
                        break
        return is_found

    @dbus.service.method(ipc_common.GLOBAL_PRESET_RENAME_FILE_INTERFACE, in_signature='ss', out_signiture='b')
    def rename_global_preset_file(self, path, new_file_name):
        ipc_util.debug_print("server: rename global preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.global_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        file_in_dict["file_name"] = new_file_name
                        self.check_global_presets_json_timer()
                        break
        return is_found

    @dbus.service.method(ipc_common.GLOBAL_PRESET_RENAME_FOLDER_INTERFACE, in_signature='ss', out_signiture='b')
    def rename_global_preset_folder(self, folder_name, new_folder_name):
        ipc_util.debug_print("server: rename global preset folder", self.debug_mode)
        is_found = False
        for folder_in_dict in self.global_presets:
            if folder_name == folder_in_dict["folder_name"]:
                is_found = True
                folder_in_dict["folder_name"] = new_folder_name
                self.check_global_presets_json_timer()
                break
        return is_found

    @dbus.service.method(ipc_common.GLOBAL_PRESET_UPLOAD_FILE_INTERFACE, in_signature='ss', out_signiture='b')
    def upload_global_preset_file(self, path, preset):
        ipc_util.debug_print("server: upload speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.global_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        break
                if is_found:
                    print("There is element with same name!")
                else:
                    preset_dict = json.loads(preset)
                    # d = {"file_name": file, "settings": preset_dict}
                    self.global_presets[self.global_presets.index(folder_in_dict)]["files"].append(copy.deepcopy(preset_dict))
                    self.check_global_presets_json_timer()
        return not is_found
    
    @dbus.service.method(ipc_common.SPEAKER_PRESET_DELETE_FILE_INTERFACE, in_signature='s', out_signiture='b')
    def delete_speaker_preset_file(self, path):
        ipc_util.debug_print("server: delete speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        self.speaker_presets[self.speaker_presets.index(folder_in_dict)]["files"].remove(file_in_dict)
                        self.check_speaker_presets_json_timer()
                        break
        return is_found

    @dbus.service.method(ipc_common.ALL_SPEAKER_PRESET_DELETE_FILE_INTERFACE, in_signature='s', out_signiture='b')
    def delete_all_speaker_preset_file(self, path):
        ipc_util.debug_print("server: delete all speaker preset file", self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.all_speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        self.all_speaker_presets[self.all_speaker_presets.index(folder_in_dict)]["files"].remove(file_in_dict)
                        self.check_all_speaker_presets_json_timer()
                        break
        return is_found

    @dbus.service.method(ipc_common.SPEAKER_GAIN_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_gain_get(self, channel):
        ipc_util.debug_print('server: get speaker gain', self.debug_mode)
        return self.data["speaker_presets"][channel].get("gain", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_POLARITY_GET_INTERFACE, in_signature='i', out_signiture='b')
    def speaker_polarity_get(self, channel):
        ipc_util.debug_print('server: get speaker polarity called', self.debug_mode)
        return self.data["speaker_presets"][channel].get("polarity", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SPEAKER_DELAY_ENABLE_SET_INTERFACE, in_signature='i', out_signiture='b')
    def speaker_delay_enable_get(self, channel):
        ipc_util.debug_print('server: get speaker delay enable called', self.debug_mode)
        return self.data["speaker_presets"][channel].get("delay_enable", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SPEAKER_DELAY_VALUE_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_delay_value_get(self, channel):
        ipc_util.debug_print('server: get speaker delay value called', self.debug_mode)
        return self.data["speaker_presets"][channel].get("delay_value", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_FIR_TABLE_GET_INTERFACE, in_signature='i', out_signiture='as')
    def speaker_fir_table_get(self, channel):
        ipc_util.debug_print('server: get speaker fir table called', self.debug_mode)
        return python_to_dbus(self.data["speaker_presets"][channel].get("fir_table", ipc_constants.DEFAULT_ARRAY_EMPTY))

    @dbus.service.method(ipc_common.SPEAKER_XOVER_HP_ENABLE_GET_INTERFACE, in_signature='i', out_signiture='b')
    def speaker_xover_hp_enable_get(self, channel):
        ipc_util.debug_print('server: get speaker xover hp enable called', self.debug_mode)
        return self.data["speaker_presets"][channel]["xover_hp_filter"].get("xover_hp_enable", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SPEAKER_XOVER_HP_TYPE_GET_INTERFACE, in_signature='i', out_signiture='i')
    def speaker_xover_hp_type_get(self, channel):
        ipc_util.debug_print('server: get speaker xover hp type called', self.debug_mode)
        return self.data["speaker_presets"][channel]["xover_hp_filter"].get("xover_hp_type", ipc_constants.DEFAULT_INT)

    @dbus.service.method(ipc_common.SPEAKER_XOVER_HP_FREQ_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_xover_hp_freq_get(self, channel):
        ipc_util.debug_print('server: get speaker xover hp freq called', self.debug_mode)
        return self.data["speaker_presets"][channel]["xover_hp_filter"].get("xover_hp_freq", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_XOVER_LP_ENABLE_GET_INTERFACE, in_signature='i', out_signiture='b')
    def speaker_xover_lp_enable_get(self, channel):
        ipc_util.debug_print('server: get speaker xover lp enable called', self.debug_mode)
        return self.data["speaker_presets"][channel]["xover_lp_filter"].get("xover_lp_enable", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SPEAKER_XOVER_LP_TYPE_GET_INTERFACE, in_signature='i', out_signiture='i')
    def speaker_xover_lp_type_get(self, channel):
        ipc_util.debug_print('server: get speaker xover lp type called', self.debug_mode)
        return self.data["speaker_presets"][channel]["xover_lp_filter"].get("xover_lp_type", ipc_constants.DEFAULT_INT)

    @dbus.service.method(ipc_common.SPEAKER_XOVER_LP_FREQ_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_xover_lp_freq_get(self, channel):
        ipc_util.debug_print('server: get speaker xover lp freq called', self.debug_mode)
        return self.data["speaker_presets"][channel]["xover_lp_filter"].get("xover_lp_freq", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_XOVER_HP_FREQ_FROM_PRESET_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_xover_hp_freq_get_from_preset(self, channel):
        hp_freq = 0.0
        if len(self.data["channels"][channel].get("preset", ipc_constants.DEFAULT_STRING))>0:
            path = self.data["channels"][channel].get("preset", ipc_constants.DEFAULT_STRING)
            folder, file = path.split("/")
            for folder_in_dict in self.speaker_presets:
                if folder == folder_in_dict["folder_name"]:
                    for file_in_dict in folder_in_dict["files"]:
                        if file == file_in_dict["file_name"]:
                            hp_freq = file_in_dict["settings"]["xover_hp_filter"].get("xover_hp_freq", ipc_constants.DEFAULT_FLOAT)
                            break
        ipc_util.debug_print('server: get speaker xover hp freq from preset called', self.debug_mode)
        return hp_freq

    @dbus.service.method(ipc_common.SPEAKER_XOVER_LP_FREQ_FROM_PRESET_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_xover_lp_freq_get_from_preset(self, channel):
        lp_freq = 0.0
        if len(self.data["channels"][channel].get("preset", ipc_constants.DEFAULT_STRING))>0:
            path = self.data["channels"][channel].get("preset", ipc_constants.DEFAULT_STRING)
            folder, file = path.split("/")
            for folder_in_dict in self.speaker_presets:
                if folder == folder_in_dict["folder_name"]:
                    for file_in_dict in folder_in_dict["files"]:
                        if file == file_in_dict["file_name"]:
                            lp_freq = file_in_dict["settings"]["xover_lp_filter"].get("xover_lp_freq", ipc_constants.DEFAULT_FLOAT)
                            break
        ipc_util.debug_print('server: get speaker xover lp freq from preset called', self.debug_mode)
        return lp_freq

    @dbus.service.method(ipc_common.SPEAKER_LIM_RMS_THRES_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_lim_rms_thres_get(self, channel):
        ipc_util.debug_print('server: get speaker lim rms thres called', self.debug_mode)
        return self.data["speaker_presets"][channel]["lim_rms"].get("lim_rms_thres", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_LIM_RMS_ATTACK_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_lim_rms_attack_get(self, channel):
        ipc_util.debug_print('server: get speaker lim rms attack called', self.debug_mode)
        return self.data["speaker_presets"][channel]["lim_rms"].get("lim_rms_attack", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_LIM_RMS_RELEASE_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_lim_rms_release_get(self, channel):
        ipc_util.debug_print('server: get speaker lim rms release called', self.debug_mode)
        return self.data["speaker_presets"][channel]["lim_rms"].get("lim_rms_release", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_LIM_PEAK_THRES_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_lim_peak_thres_get(self, channel):
        ipc_util.debug_print('server: get speaker lim peak thres called', self.debug_mode)
        return self.data["speaker_presets"][channel]["lim_peak"].get("lim_peak_thres", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_LIM_PEAK_RELEASE_GET_INTERFACE, in_signature='i', out_signiture='d')
    def speaker_lim_peak_release_get(self, channel):
        ipc_util.debug_print('server: get speaker lim peak release called', self.debug_mode)
        return self.data["speaker_presets"][channel]["lim_peak"].get("lim_peak_release", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_PEQ_ENABLE_GET_INTERFACE, in_signature='ii', out_signiture='b')
    def speaker_peq_enable_get(self, channel, peq_channel):
        ipc_util.debug_print("server: get speaker peq enable called", self.debug_mode)
        return self.data["speaker_presets"][channel]["peq"][peq_channel].get("enable", ipc_constants.DEFAULT_BOOL)

    @dbus.service.method(ipc_common.SPEAKER_PEQ_TYPE_GET_INTERFACE, in_signature='ii', out_signiture='i')
    def speaker_peq_type_get(self, channel, peq_channel):
        ipc_util.debug_print("server: get speaker peq type called", self.debug_mode)
        return self.data["speaker_presets"][channel]["peq"][peq_channel].get("type", ipc_constants.DEFAULT_INT)

    @dbus.service.method(ipc_common.SPEAKER_PEQ_FREQ_GET_INTERFACE, in_signature='ii', out_signiture='d')
    def speaker_peq_freq_get(self, channel, peq_channel):
        ipc_util.debug_print("server: get speaker peq freq called", self.debug_mode)
        return self.data["speaker_presets"][channel]["peq"][peq_channel].get("freq", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_PEQ_GAIN_GET_INTERFACE, in_signature='ii', out_signiture='d')
    def speaker_peq_gain_get(self, channel, peq_channel):
        ipc_util.debug_print("server: get speaker peq gain called", self.debug_mode)
        return self.data["speaker_presets"][channel]["peq"][peq_channel].get("gain", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_PEQ_Q_GET_INTERFACE, in_signature='ii', out_signiture='d')
    def speaker_peq_q_get(self, channel, peq_channel):
        ipc_util.debug_print("server: get speaker peq q called", self.debug_mode)
        return self.data["speaker_presets"][channel]["peq"][peq_channel].get("q", ipc_constants.DEFAULT_FLOAT)

    @dbus.service.method(ipc_common.SPEAKER_GAIN_SET_INTERFACE, in_signature='id', out_signiture='b')
    def speaker_gain_set(self, channel, gain):
        ipc_util.debug_print("server: set speaker gain called", self.debug_mode)
        self.data["speaker_presets"][channel]["gain"] = float(gain)
        self.check_data_json_timer()
        ipc_dsp.dsp_channel_gain_speaker_config(self.current_variant_value, channel, float(gain))
        return True
    
    @dbus.service.method(ipc_common.SPEAKER_MUTE_SET_INTERFACE, in_signature='id', out_signiture='b')
    def speaker_mute_set(self, channel, muted):
        ipc_util.debug_print("server: set solo mute called", self.debug_mode)
        self.data["channels"][channel]["mute"] = bool(muted)
        ipc_dsp.dsp_solo_mute(self.current_variant_value, channel, muted)
        self.check_data_json_timer()
        return True

    @dbus.service.method(ipc_common.SPEAKER_POLARITY_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def speaker_polarity_set(self, channel, polarity):
        ipc_util.debug_print("server: set speaker polarity called", self.debug_mode)
        self.data["speaker_presets"][channel]["polarity"] = bool(polarity)
        self.check_data_json_timer()
        ipc_dsp.dsp_speaker_polarity(self.current_variant_value, channel, polarity)
        return True

    @dbus.service.method(ipc_common.SPEAKER_DELAY_ENABLE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def speaker_delay_enable_set(self, channel, delay_enabled):
        ipc_util.debug_print("server: set speaker delay enable called", self.debug_mode)
        self.data["speaker_presets"][channel]["delay_enable"] = bool(delay_enabled)
        self.check_data_json_timer()
        if delay_enabled:
            if self.data["speaker_presets"][channel]["delay_value"] > ipc_constants.MAX_SPEAKER_DELAY_VALUE:
                ipc_dsp.dsp_channel_delay_speaker_config(self.current_variant_value, channel, ipc_constants.MAX_SPEAKER_DELAY_VALUE)
            else:
                ipc_dsp.dsp_channel_delay_speaker_config(self.current_variant_value, channel, self.data["speaker_presets"][channel]["delay_value"])
        else:
            ipc_dsp.dsp_channel_delay_speaker_config(self.current_variant_value, channel, 0.0)
        return True

    @dbus.service.method(ipc_common.SPEAKER_DELAY_VALUE_SET_INTERFACE, in_signature='id', out_signiture='b')
    def speaker_delay_value_set(self, channel, delay_value):
        ipc_util.debug_print("server: set speaker delay value called", self.debug_mode)
        self.data["speaker_presets"][channel]["delay_value"] = float(delay_value)
        self.check_data_json_timer()
        if self.data["speaker_presets"][channel]["delay_enable"]:
            if delay_value > ipc_constants.MAX_SPEAKER_DELAY_VALUE:
                ipc_dsp.dsp_channel_delay_speaker_config(self.current_variant_value, channel, ipc_constants.MAX_SPEAKER_DELAY_VALUE)
            else:
                ipc_dsp.dsp_channel_delay_speaker_config(self.current_variant_value, channel, delay_value)
        else:
            ipc_dsp.dsp_channel_delay_speaker_config(self.current_variant_value, channel, 0.0)
        return True

    @dbus.service.method(ipc_common.SPEAKER_FIR_TABLE_SET_INTERFACE, in_signature='ias', out_signiture='b')
    def speaker_fir_table_set(self, channel, fir_table):
        ipc_util.debug_print("server: set fir table called", self.debug_mode)
        self.data["speaker_presets"][channel]["fir_table"] = ipc_util.dbus_to_python(fir_table)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_speaker_fir_table(self.current_variant_value, channel, self.data["speaker_presets"][channel]["fir_table"])
        return True

    @dbus.service.method(ipc_common.SPEAKER_XOVER_HP_ENABLE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def speaker_xover_hp_enable_set(self, channel, enabled):
        ipc_util.debug_print("server: set speaker xover hp enable called", self.debug_mode)
        self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_enable"] = bool(enabled)
        self.check_data_json_timer()
        if bool(enabled):
            coefficients = ipc_filters.compute_xover_coefficients(self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_type"],
                                                                  ipc_constants.XOVER_HP_TYPE,
                                                                  self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_freq"])
        else:
            coefficients = ipc_constants.DEFAULT_XOVER_FILTER
        ipc_dsp.dsp_set_speaker_xover_hp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SPEAKER_XOVER_HP_TYPE_SET_INTERFACE, in_signature='ii', out_signiture='b')
    def speaker_xover_hp_type_set(self, channel, xover_type):
        ipc_util.debug_print("server: set speaker xover hp type called", self.debug_mode)
        self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_type"] = int(xover_type)
        self.check_data_json_timer()
        if self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_enable"]:
            coefficients = ipc_filters.compute_xover_coefficients(self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_type"],
                                                                  ipc_constants.XOVER_HP_TYPE,
                                                                  self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_freq"])
            ipc_dsp.dsp_set_speaker_xover_hp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SPEAKER_XOVER_HP_FREQ_SET_INTERFACE, in_signature='id', out_signiture='b')
    def speaker_xover_hp_freq_set(self, channel, freq):
        ipc_util.debug_print("server: set speaker xover hp freq called", self.debug_mode)
        self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_freq"] = float(freq)
        self.check_data_json_timer()
        if self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_enable"]:
            coefficients = ipc_filters.compute_xover_coefficients(self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_type"],
                                                                  ipc_constants.XOVER_HP_TYPE,
                                                                  self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_freq"])
            ipc_dsp.dsp_set_speaker_xover_hp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SPEAKER_XOVER_HP_OVERIDE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def speaker_xover_hp_overide_set(self, channel, enabled):
        ipc_util.debug_print("server: set speaker xover hp overide called", self.debug_mode)
        self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_overide"] = bool(enabled)
        self.check_data_json_timer()
        return True

    @dbus.service.method(ipc_common.SPEAKER_XOVER_LP_ENABLE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def speaker_xover_lp_enable_set(self, channel, enabled):
        ipc_util.debug_print("server: set speaker xover lp enable called", self.debug_mode)
        self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_enable"] = bool(enabled)
        self.check_data_json_timer()
        if bool(enabled):
            coefficients = ipc_filters.compute_xover_coefficients(self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_type"],
                                                                  ipc_constants.XOVER_LP_TYPE,
                                                                  self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_freq"])
        else:
            coefficients = ipc_constants.DEFAULT_XOVER_FILTER
        ipc_dsp.dsp_set_speaker_xover_lp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SPEAKER_XOVER_LP_TYPE_SET_INTERFACE, in_signature='ii', out_signiture='b')
    def speaker_xover_lp_type_set(self, channel, xover_type):
        ipc_util.debug_print("server: set speaker xover lp type called", self.debug_mode)
        self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_type"] = int(xover_type)
        self.check_data_json_timer()
        if self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_enable"]:
            coefficients = ipc_filters.compute_xover_coefficients(self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_type"],
                                                                  ipc_constants.XOVER_LP_TYPE,
                                                                  self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_freq"])
            ipc_dsp.dsp_set_speaker_xover_lp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SPEAKER_XOVER_LP_FREQ_SET_INTERFACE, in_signature='id', out_signiture='b')
    def speaker_xover_lp_freq_set(self, channel, freq):
        ipc_util.debug_print("server: set speaker xover lp freq called", self.debug_mode)
        self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_freq"] = float(freq)
        self.check_data_json_timer()
        if self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_enable"]:
            coefficients = ipc_filters.compute_xover_coefficients(self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_type"],
                                                                  ipc_constants.XOVER_LP_TYPE,
                                                                  self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_freq"])
            ipc_dsp.dsp_set_speaker_xover_lp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))
        return True

    @dbus.service.method(ipc_common.SPEAKER_XOVER_LP_OVERIDE_SET_INTERFACE, in_signature='ib', out_signiture='b')
    def speaker_xover_lp_overide_set(self, channel, enabled):
        ipc_util.debug_print("server: set speaker xover lp overide called", self.debug_mode)
        self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_overide"] = bool(enabled)
        self.check_data_json_timer()
        return True

    @dbus.service.method(ipc_common.SPEAKER_LIM_RMS_THRES_SET_INTERFACE, in_signature='id', out_signiture='b')
    def speaker_lim_rms_thres_set(self, channel, thres):
        ipc_util.debug_print("server: set speaker lim rms thres called", self.debug_mode)
        self.data["speaker_presets"][channel]["lim_rms"]["lim_rms_thres"] = float(thres)
        self.check_data_json_timer()
        threshold_points = ipc_util.calculate_compressor_rms_coefficients(float(thres))
        ipc_dsp.dsp_set_speaker_lim_rms_thres(self.current_variant_value, channel, threshold_points)
        return True

    @dbus.service.method(ipc_common.SPEAKER_LIM_RMS_ATTACK_SET_INTERFACE, in_signature='id', out_signiture='b')
    def speaker_lim_rms_attack_set(self, channel, attack):
        ipc_util.debug_print("server: set speaker lim rms attack called", self.debug_mode)
        self.data["speaker_presets"][channel]["lim_rms"]["lim_rms_attack"] = float(attack)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_speaker_lim_rms_attack(self.current_variant_value, channel, float(attack))
        return True

    @dbus.service.method(ipc_common.SPEAKER_LIM_RMS_RELEASE_SET_INTERFACE, in_signature='id', out_signiture='b')
    def speaker_lim_rms_release_set(self, channel, release):
        ipc_util.debug_print("server: set speaker lim rms release called", self.debug_mode)
        self.data["speaker_presets"][channel]["lim_rms"]["lim_rms_release"] = float(release)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_speaker_lim_rms_release(self.current_variant_value, channel, float(release))
        return True

    @dbus.service.method(ipc_common.SPEAKER_LIM_PEAK_THRES_SET_INTERFACE, in_signature='id', out_signiture='b')
    def speaker_lim_peak_thres_set(self, channel, thres):
        ipc_util.debug_print("server: set speaker lim peak thres called", self.debug_mode)
        self.data["speaker_presets"][channel]["lim_peak"]["lim_peak_thres"] = float(thres)
        self.check_data_json_timer()
        threshold_points = ipc_util.calculate_compressor_peak_coefficients(float(thres))
        ipc_dsp.dsp_set_speaker_lim_peak_thres(self.current_variant_value, channel, threshold_points)
        return True

    @dbus.service.method(ipc_common.SPEAKER_LIM_PEAK_RELEASE_SET_INTERFACE, in_signature='id', out_signiture='b')
    def speaker_lim_peak_release_set(self, channel, release):
        ipc_util.debug_print("server: set speaker lim peak release called", self.debug_mode)
        self.data["speaker_presets"][channel]["lim_peak"]["lim_peak_release"] = float(release)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_speaker_lim_peak_release(self.current_variant_value, channel, float(release))
        return True

    @dbus.service.method(ipc_common.SPEAKER_PEQ_ENABLE_SET_INTERFACE, in_signature='iib', out_signiture='b')
    def speaker_peq_enable_set(self, channel, peq_channel, enabled):
        ipc_util.debug_print("server: set speaker peq enable called", self.debug_mode)
        self.data["speaker_presets"][channel]["peq"][peq_channel]["enable"] = bool(enabled)
        self.check_data_json_timer()
        if bool(enabled):  # if peq is enabled, calc params and send it to DSP
            a0, a1, a2, b0, b1, b2 = ipc_filters.compute_peq_coeff(self.data["speaker_presets"][channel]["peq"][peq_channel]["type"],
                                                                   self.data["speaker_presets"][channel]["peq"][peq_channel]["freq"],
                                                                   self.data["speaker_presets"][channel]["peq"][peq_channel]["gain"],
                                                                   self.data["speaker_presets"][channel]["peq"][peq_channel]["q"])
            a1, a2, b0, b1, b2 = ipc_util.rescale_peq_values(a0, a1, a2, b0, b1, b2)
            ipc_dsp.dsp_set_speaker_peq_filter_coeff(self.current_variant_value, channel, peq_channel, [b2, b1, b0, a2, a1])
        else:
            ipc_dsp.dsp_set_speaker_peq_filter_coeff(self.current_variant_value, channel,
                                                     peq_channel,
                                                     [0, 0, 1, 0, 0])  # if disabled, send default configuration
        return True

    @dbus.service.method(ipc_common.SPEAKER_PEQ_TYPE_SET_INTERFACE, in_signature='iii', out_signiture='b')
    def speaker_peq_type_set(self, channel, peq_channel, peq_type):
        ipc_util.debug_print("server: set speaker peq type called", self.debug_mode)
        self.data["speaker_presets"][channel]["peq"][peq_channel]["type"] = int(peq_type)
        self.check_data_json_timer()
        array_coeff = ipc_util.recalculate_peq_values(self.data["speaker_presets"], channel, peq_channel)
        ipc_dsp.dsp_set_speaker_peq_filter_coeff(self.current_variant_value, channel, peq_channel, array_coeff)
        return True

    @dbus.service.method(ipc_common.SPEAKER_PEQ_FREQ_SET_INTERFACE, in_signature='iid', out_signiture='b')
    def speaker_peq_freq_set(self, channel, peq_channel, freq):
        ipc_util.debug_print("server: set speaker peq freq called", self.debug_mode)
        self.data["speaker_presets"][channel]["peq"][peq_channel]["freq"] = float(freq)
        self.check_data_json_timer()
        array_coeff = ipc_util.recalculate_peq_values(self.data["speaker_presets"], channel, peq_channel)
        ipc_dsp.dsp_set_speaker_peq_filter_coeff(self.current_variant_value, channel, peq_channel, array_coeff)
        return True

    @dbus.service.method(ipc_common.SPEAKER_PEQ_GAIN_SET_INTERFACE, in_signature='iid', out_signiture='b')
    def speaker_peq_gain_set(self, channel, peq_channel, gain):
        ipc_util.debug_print("server: set speaker peq gain called", self.debug_mode)
        self.data["speaker_presets"][channel]["peq"][peq_channel]["gain"] = float(gain)
        self.check_data_json_timer()
        array_coeff = ipc_util.recalculate_peq_values(self.data["speaker_presets"], channel, peq_channel)
        ipc_dsp.dsp_set_speaker_peq_filter_coeff(self.current_variant_value, channel, peq_channel, array_coeff)
        return True

    @dbus.service.method(ipc_common.SPEAKER_PEQ_Q_SET_INTERFACE, in_signature='iid', out_signiture='b')
    def speaker_peq_q_set(self, channel, peq_channel, q):
        ipc_util.debug_print("server: set speaker peq q called", self.debug_mode)
        self.data["speaker_presets"][channel]["peq"][peq_channel]["q"] = float(q)
        self.check_data_json_timer()
        array_coeff = ipc_util.recalculate_peq_values(self.data["speaker_presets"], channel, peq_channel)
        ipc_dsp.dsp_set_speaker_peq_filter_coeff(self.current_variant_value, channel, peq_channel, array_coeff)
        return True

    @dbus.service.method(ipc_common.BRIDGE_MODE_12_SET_INTERFACE, in_signature='b', out_signiture='b')
    def bridge_mode_12_set(self, enabled):
        ipc_util.debug_print("server: set bridge mode 12 called", self.debug_mode)
        self.data["settings"]["bridge_mode_12"] = bool(enabled)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_bridge_mode(self.current_variant_value, 0, enabled)  # 0 for bridge 12
        return True

    @dbus.service.method(ipc_common.BRIDGE_MODE_34_SET_INTERFACE, in_signature='b', out_signiture='b')
    def bridge_mode_34_set(self, enabled):
        ipc_util.debug_print("server: set bridge mode 34 called", self.debug_mode)
        self.data["settings"]["bridge_mode_34"] = bool(enabled)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_bridge_mode(self.current_variant_value, 1, enabled)  # 1 for bridge 34
        return True

    @dbus.service.method(ipc_common.BRIDGE_MODE_56_SET_INTERFACE, in_signature='b', out_signiture='b')
    def bridge_mode_56_set(self, enabled):
        ipc_util.debug_print("server: set bridge mode 56 called", self.debug_mode)
        self.data["settings"]["bridge_mode_56"] = bool(enabled)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_bridge_mode(self.current_variant_value, 2, enabled)  # 0 for bridge 12
        return True

    @dbus.service.method(ipc_common.BRIDGE_MODE_78_SET_INTERFACE, in_signature='b', out_signiture='b')
    def bridge_mode_78_set(self, enabled):
        ipc_util.debug_print("server: set bridge mode 78 called", self.debug_mode)
        self.data["settings"]["bridge_mode_78"] = bool(enabled)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_bridge_mode(self.current_variant_value, 3, enabled)  # 1 for bridge 34
        return True
    
    @dbus.service.method(ipc_common.BRIDGE_MODE_910_SET_INTERFACE, in_signature='b', out_signiture='b')
    def bridge_mode_910_set(self, enabled):
        ipc_util.debug_print("server: set bridge mode 910 called", self.debug_mode)
        self.data["settings"]["bridge_mode_910"] = bool(enabled)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_bridge_mode(self.current_variant_value, 4, enabled)  # 0 for bridge 12
        return True

    @dbus.service.method(ipc_common.BRIDGE_MODE_1112_SET_INTERFACE, in_signature='b', out_signiture='b')
    def bridge_mode_1112_set(self, enabled):
        ipc_util.debug_print("server: set bridge mode 1112 called", self.debug_mode)
        self.data["settings"]["bridge_mode_1112"] = bool(enabled)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_bridge_mode(self.current_variant_value, 5, enabled)  # 1 for bridge 34
        return True
    
    @dbus.service.method(ipc_common.BRIDGE_MODE_1314_SET_INTERFACE, in_signature='b', out_signiture='b')
    def bridge_mode_1314_set(self, enabled):
        ipc_util.debug_print("server: set bridge mode 1314 called", self.debug_mode)
        self.data["settings"]["bridge_mode_1314"] = bool(enabled)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_bridge_mode(self.current_variant_value, 6, enabled)  # 0 for bridge 12
        return True

    @dbus.service.method(ipc_common.BRIDGE_MODE_1516_SET_INTERFACE, in_signature='b', out_signiture='b')
    def bridge_mode_1516_set(self, enabled):
        ipc_util.debug_print("server: set bridge mode 1516 called", self.debug_mode)
        self.data["settings"]["bridge_mode_1516"] = bool(enabled)
        self.check_data_json_timer()
        ipc_dsp.dsp_set_bridge_mode(self.current_variant_value, 7, enabled)  # 1 for bridge 34
        return True
    
    @dbus.service.method(ipc_common.BRIDGE_MODE_12_GET_INTERFACE, in_signature='', out_signiture='b')
    def bridge_mode_12_get(self):
        ipc_util.debug_print("server: get bridge mode 12 called", self.debug_mode)
        return self.data["settings"]["bridge_mode_12"]

    @dbus.service.method(ipc_common.BRIDGE_MODE_34_GET_INTERFACE, in_signature='', out_signiture='b')
    def bridge_mode_34_get(self):
        ipc_util.debug_print("server: get bridge mode 34 called", self.debug_mode)
        return self.data["settings"]["bridge_mode_34"]
    
    @dbus.service.method(ipc_common.BRIDGE_MODE_56_GET_INTERFACE, in_signature='', out_signiture='b')
    def bridge_mode_56_get(self):
        ipc_util.debug_print("server: get bridge mode 56 called", self.debug_mode)
        return self.data["settings"]["bridge_mode_56"]

    @dbus.service.method(ipc_common.BRIDGE_MODE_78_GET_INTERFACE, in_signature='', out_signiture='b')
    def bridge_mode_78_get(self):
        ipc_util.debug_print("server: get bridge mode 78 called", self.debug_mode)
        return self.data["settings"]["bridge_mode_78"]
    
    @dbus.service.method(ipc_common.BRIDGE_MODE_910_GET_INTERFACE, in_signature='', out_signiture='b')
    def bridge_mode_910_get(self):
        ipc_util.debug_print("server: get bridge mode 910 called", self.debug_mode)
        return self.data["settings"]["bridge_mode_910"]

    @dbus.service.method(ipc_common.BRIDGE_MODE_1112_GET_INTERFACE, in_signature='', out_signiture='b')
    def bridge_mode_1112_get(self):
        ipc_util.debug_print("server: get bridge mode 1112 called", self.debug_mode)
        return self.data["settings"]["bridge_mode_1112"]
    
    @dbus.service.method(ipc_common.BRIDGE_MODE_1314_GET_INTERFACE, in_signature='', out_signiture='b')
    def bridge_mode_1314_get(self):
        ipc_util.debug_print("server: get bridge mode 1314 called", self.debug_mode)
        return self.data["settings"]["bridge_mode_1314"]

    @dbus.service.method(ipc_common.BRIDGE_MODE_1516_GET_INTERFACE, in_signature='', out_signiture='b')
    def bridge_mode_1516_get(self):
        ipc_util.debug_print("server: get bridge mode 1516 called", self.debug_mode)
        return self.data["settings"]["bridge_mode_1516"]

    @dbus.service.method(ipc_common.SIGGEN_FREQ_GEN_FREQUENCY_SET_INTERFACE, in_signature='i', out_signiture='b')
    def freq_gen_frequency_set(self, frequency):
        ipc_util.debug_print("server: set frequency generator frequency", self.debug_mode)
        self.data["settings"]["signal_generator"]["frequency_generator"]["frequency"] = int(frequency)
        ipc_dsp.dsp_generator_set_sinewave_freq(self.current_variant_value,self.data["settings"]["signal_generator"]["frequency_generator"]["frequency"])
        return True

    @dbus.service.method(ipc_common.SIGGEN_FREQ_GEN_GAIN_SET_INTERFACE, in_signature='d', out_signiture='b')
    def freq_gen_gain_set(self, gain):
        ipc_util.debug_print("server: set frequency generator gain", self.debug_mode)
        self.data["settings"]["signal_generator"]["frequency_generator"]["gain"] = float(gain)
        ipc_dsp.dsp_generator_set_sinewave_gain(self.current_variant_value,float(gain))
        return True

    @dbus.service.method(ipc_common.SIGGEN_PINK_NOISE_GAIN_SET_INTERFACE, in_signature='d', out_signiture='b')
    def pink_noise_gain_set(self, gain):
        ipc_util.debug_print("server: set pink noise gain", self.debug_mode)
        self.data["settings"]["signal_generator"]["pink_noise"]["gain"] = float(gain)
        ipc_dsp.dsp_generator_set_pinknoise_gain(self.current_variant_value,float(gain))
        return True

    @dbus.service.method(ipc_common.ETHERNET_GET_CONFIG_INTERFACE, in_signature='', out_signiture='sv')
    def ethernet_get_config(self):
        ipc_util.debug_print("server: get lan config called", self.debug_mode)
        network_info = ipc_util.our_real_ip_addr(True).split()
        return ipc_util.python_to_dbus({'ip': network_info[0],
                                        'mask': network_info[1],
                                        'gateway': network_info[2],
                                        'dhcp': not ipc_util.is_network_static()})

    @dbus.service.method(ipc_common.APEX_CLOUD_GET_INTERFACE, in_signature='', out_signiture='sv')
    def apex_cloud_get(self):
        ipc_util.debug_print("server: get apex cloud called", self.debug_mode)
        return ipc_util.python_to_dbus({"device_name": self.data["settings"]["cloud_device_name"],
                                        "username": self.data["settings"]["cloud_username"],
                                        "password": self.data["settings"]["cloud_password"],
                                        "enable": bool(self.data["settings"]["cloud_enable"])})

    @dbus.service.method(ipc_common.APEX_CLOUD_SET_INTERFACE, in_signature='s', out_signiture='b')
    def apex_cloud_set(self, config):
        ipc_util.debug_print("server: set apex cloud called", self.debug_mode)
        try:
            data = json.loads(config)
        except json.JSONDecodeError:
            return False

        if ipc_constants.DEFAULT_STRING == data.get("device_name", ipc_constants.DEFAULT_STRING):
            mac = ipc_util.our_eth_mac_addr.replace(':', '')
            self.data["settings"]["cloud_device_name"] = mac
        else:
            self.data["settings"]["cloud_device_name"] = data.get("device_name", ipc_constants.DEFAULT_STRING)

        self.data["settings"]["cloud_username"] = data.get("username", ipc_constants.DEFAULT_STRING)
        self.data["settings"]["cloud_password"] = data.get("password", ipc_constants.DEFAULT_STRING)
        self.data["settings"]["cloud_enable"] = data.get("enable", ipc_constants.DEFAULT_BOOL)
        self.check_data_json_timer()

        with self.lock: 
            self.neighbours[0]['cloud_device_name'] =  self.data["settings"]["cloud_device_name"]

        command = ipc_common.APEX_SCRIPTS_FOLDER + "apexconnect.sh"
        # If enabled, start cloud, else - stop it
        if bool(self.data["settings"]["cloud_enable"]):
            command += " --service enable"
            command += " --relay \'apexconnect.me\'"
            command += " --name \'" + self.data["settings"]["cloud_device_name"] + "\'"
            command += " --secret \'afblijven\'"
            command += " --ssh yes"
            # If username or pass is empty string, don't pass it
            if self.data["settings"]["cloud_username"] != "" and self.data["settings"]["cloud_password"] != "":
                command += " --user \'" + self.data["settings"]["cloud_username"] + "\'"
                command += " --pass \'" + self.data["settings"]["cloud_password"] + "\'"
        else:
            command += " --service disable"
        ipc_util.debug_print("Executing: " + command, self.debug_mode)
        resp = os.system(command)
        return resp == 0

    @dbus.service.method(ipc_common.SPOTIFY_CONFIG_GET_INTERFACE, in_signature='', out_signiture='sv')
    def spotify_config_get(self):
        ipc_util.debug_print("server: get spotify config called", self.debug_mode)
        return ipc_util.python_to_dbus({"device_name": self.data["settings"]["spotify_device_name"],
                                        "email": self.data["settings"]["spotify_email"],
                                        "password": self.data["settings"]["spotify_password"],
                                        "enable": bool(self.data["settings"]["spotify_enable"])})

    @dbus.service.method(ipc_common.SPOTIFY_CONFIG_SET_INTERFACE, in_signature='s', out_signiture='b')
    def spotify_config_set(self, config):
        ipc_util.debug_print("server: set spotify config called", self.debug_mode)
        try:
            data = json.loads(config)
        except json.JSONDecodeError:
            return False

        self.data["settings"]["spotify_device_name"] = data.get("device_name", ipc_constants.DEFAULT_STRING)
        self.data["settings"]["spotify_email"] = data.get("email", ipc_constants.DEFAULT_STRING)
        self.data["settings"]["spotify_password"] = data.get("password", ipc_constants.DEFAULT_STRING)
        self.data["settings"]["spotify_enable"] = data.get("enable", ipc_constants.DEFAULT_BOOL)
        self.check_data_json_timer()

        command = ipc_common.APEX_SCRIPTS_FOLDER + "apexspotify.sh"
        # If enabled, start spotify, else - stop it
        if bool(self.data["settings"]["spotify_enable"]):
            command += " --service enable"
            command += " --name \'" + self.data["settings"]["spotify_device_name"] + "\'"
            command += " --quality 320"
            # If username or pass is empty string, don't pass it
            if self.data["settings"]["spotify_password"] != "" and self.data["settings"]["spotify_email"] != "":
                command += " --user \'" + self.data["settings"]["spotify_email"] + "\'"
                command += " --pass \'" + self.data["settings"]["spotify_password"] + "\'"
        else:
            command += " --service disable"
        ipc_util.debug_print("Executing: " + command, self.debug_mode)
        resp = os.system(command)
        return resp == 0

    @dbus.service.method(ipc_common.AIRPLAY_CONFIG_GET_INTERFACE, in_signature='', out_signiture='sv')
    def airplay_config_get(self):
        ipc_util.debug_print("server: get airplay config called", self.debug_mode)
        return ipc_util.python_to_dbus({"device_name": self.data["settings"]["airplay_device_name"],
                                        "password": self.data["settings"]["airplay_password"],
                                        "enable": bool(self.data["settings"]["airplay_enable"])})

    @dbus.service.method(ipc_common.AIRPLAY_CONFIG_SET_INTERFACE, in_signature='s', out_signiture='b')
    def airplay_config_set(self, config):
        ipc_util.debug_print("server: set airplay config called", self.debug_mode)
        try:
            data = json.loads(config)
        except json.JSONDecodeError:
            return False

        self.data["settings"]["airplay_device_name"] = data.get("device_name", ipc_constants.DEFAULT_STRING)
        self.data["settings"]["airplay_password"] = data.get("password", ipc_constants.DEFAULT_STRING)
        self.data["settings"]["airplay_enable"] = data.get("enable", ipc_constants.DEFAULT_BOOL)
        self.check_data_json_timer()

        command = ipc_common.APEX_SCRIPTS_FOLDER + "apexairplay.sh"
        # If enabled, start airplay, else - stop it
        if bool(self.data["settings"]["airplay_enable"]):
            command += " --service enable"
            command += " --name \'" + self.data["settings"]["airplay_device_name"] + "\'"
            # If pass is empty string, don't pass it
            if self.data["settings"]["airplay_password"] != "":
                command += " --pass \'" + self.data["settings"]["airplay_password"] + "\'"
        else:
            command += " --service disable"
        ipc_util.debug_print("Executing: " + command, self.debug_mode)
        resp = os.system(command)
        return resp == 0

    @dbus.service.method(ipc_common.ABOUT_GET_INTERFACE, in_signature='', out_signiture='sv')
    def about_get(self):
        ipc_util.debug_print("server: get about called", self.debug_mode)
        return ipc_util.python_to_dbus({"model": self.data["settings"]["model"],
                                        "hardware_version": self.data["settings"]["hardware_version"],
                                        "serial": self.data["settings"]["serial"]})

    @dbus.service.method(ipc_common.STATUS_GET_INTERFACE, in_signature='', out_signiture='sv')
    def status_get(self):
        ipc_util.debug_print('server: get status called', self.debug_mode)
        # status = ipc_dsp.status_readback(self.current_variant_value)
        # ipc_util.debug_print('get status', self.debug_mode)
        # ipc_util.debug_print(status, self.debug_mode)
        return ipc_util.python_to_dbus({"byte_status": 0,
                                        "temperature": 0,
                                        "rtorvoltage": 0,
                                        "mainvoltage": 0})

        # return ipc_util.python_to_dbus(status)


    @dbus.service.method(ipc_common.STOP_SERVICE_INTERFACE, in_signature='', out_signature='')
    def quit(self):
        global GPIO
        if GPIO:
            try:
                GPIO.cleanup()
            except RuntimeError:
                pass
        self.mainloop.quit()
        self.readback_svc.end_service()
        self.disc_svc.stop_service()
        self.udpCommand_svc.stop_service()

    def change_active_source(self, new_active_source):
        for i_channel in range(0, ipc_constants.NUM_OF_CHANNELS):
            self.data["channels"][i_channel]["active_source"] = new_active_source
            if new_active_source == 0 and 5 <= self.data["channels"][i_channel]["source_pri"] <= 8:  # if sec source is currently active, send change
                ipc_dsp.dsp_channel_source_config(self.current_variant_value, i_channel, self.data["channels"][i_channel]["source_sec"], 0)  # deactivate old sec source
                ipc_dsp.dsp_channel_source_config(self.current_variant_value, i_channel, self.data["channels"][i_channel]["source_pri"], 1)  # activate new pri source
            elif new_active_source == 1 and 5 <= self.data["channels"][i_channel]["source_pri"] <= 8:  # if pri source is currently active, send change
                ipc_dsp.dsp_channel_source_config(self.current_variant_value, i_channel, self.data["channels"][i_channel]["source_pri"], 0)  # deactivate old pri source
                ipc_dsp.dsp_channel_source_config(self.current_variant_value, i_channel, self.data["channels"][i_channel]["source_sec"], 1)  # activate new sec source
        self.check_data_json_timer()

    def check_data_json_timer(self):
        if self.is_data_json_timer_active:
            self.data_json_timer.cancel()
        else:
            self.is_data_json_timer_active = True
        self.data_json_timer = Timer(10.0, self.save_change_to_data_json)
        self.data_json_timer.start()

    def check_global_presets_json_timer(self):
        if self.is_global_presets_json_timer_active:
            self.global_presets_json_timer.cancel()
        else:
            self.is_global_presets_json_timer_active = True
        self.global_presets_json_timer = Timer(10.0, self.save_change_to_global_presets_json)
        self.global_presets_json_timer.start()

    def check_speaker_presets_json_timer(self):
        if self.is_speaker_presets_json_timer_active:
            self.speaker_presets_json_timer.cancel()
        else:
            self.is_speaker_presets_json_timer_active = True
        self.speaker_presets_json_timer = Timer(10.0, self.save_change_to_speaker_presets_json)
        self.speaker_presets_json_timer.start()

    def check_all_speaker_presets_json_timer(self):
        if self.is_all_speaker_presets_json_timer_active:
            self.all_speaker_presets_json_timer.cancel()
        else:
            self.is_all_speaker_presets_json_timer_active = True
        self.all_speaker_presets_json_timer = Timer(10.0, self.save_change_to_all_speaker_presets_json)
        self.all_speaker_presets_json_timer.start()

    def save_change_to_data_json(self):
        try:
            if self.write_first_config:
                current_file = ipc_common.CONFIG_FILE_1
            else :
                current_file = ipc_common.CONFIG_FILE_2

            temp_file = tempfile.NamedTemporaryFile('w', delete=False, dir=os.path.dirname(current_file))

            with temp_file as f:
                json.dump(self.data, f, indent=4)

            if not os.path.exists(current_file) or not filecmp.cmp(temp_file.name, current_file, shallow=False):
                os.replace(temp_file.name, current_file)

            if os.path.exists(temp_file.name):
                os.remove(temp_file.name)

            command = "sync"
            os.system(command)

            self.write_first_config = not self.write_first_config

        except json.JSONDecodeError as e:
            print(f"Error encoding data to JSON: {e}")
        except IOError as e:
            print(f"Error writing to file {current_file}: {e}")



    def save_change_to_global_presets_json(self):
        try:
            if self.write_first_global_presets:
                current_file = ipc_common.GLOBAL_PRESETS_FILE_1
            else :
                current_file = ipc_common.GLOBAL_PRESETS_FILE_2

            temp_file = tempfile.NamedTemporaryFile('w', delete=False, dir=os.path.dirname(current_file))

            with temp_file as f:
                json.dump(self.global_presets, f, indent=4)

            if not os.path.exists(current_file) or not filecmp.cmp(temp_file.name, current_file, shallow=False):
                os.replace(temp_file.name, current_file)

            if os.path.exists(temp_file.name):
                os.remove(temp_file.name)

            command = "sync"
            os.system(command)

            self.write_first_global_presets = not self.write_first_global_presets

        except json.JSONDecodeError as e:
            print(f"Error encoding data to JSON: {e}")
        except IOError as e:
            print(f"Error writing to file {current_file}: {e}")

    def save_change_to_speaker_presets_json(self):
        try:
            if self.write_first_speaker_presets:
                current_file = ipc_common.SPEAKER_PRESETS_FILE_1
            else :
                current_file = ipc_common.SPEAKER_PRESETS_FILE_2

            temp_file = tempfile.NamedTemporaryFile('w', delete=False, dir=os.path.dirname(current_file))

            with temp_file as f:
                json.dump(self.speaker_presets, f, indent=4)

            if not os.path.exists(current_file) or not filecmp.cmp(temp_file.name, current_file, shallow=False):
                os.replace(temp_file.name, current_file)

            if os.path.exists(temp_file.name):
                os.remove(temp_file.name)

            command = "sync"
            os.system(command)

            self.write_first_speaker_presets = not self.write_first_speaker_presets

        except json.JSONDecodeError as e:
            print(f"Error encoding data to JSON: {e}")
        except IOError as e:
            print(f"Error writing to file {current_file}: {e}")



    def save_change_to_all_speaker_presets_json(self):
        try:
            if self.write_first_all_speaker_presets:
                current_file = ipc_common.ALL_SPEAKER_PRESETS_FILE_1
            else :
                current_file = ipc_common.ALL_SPEAKER_PRESETS_FILE_2

            temp_file = tempfile.NamedTemporaryFile('w', delete=False, dir=os.path.dirname(current_file))

            with temp_file as f:
                json.dump(self.all_speaker_presets, f, indent=4)

            if not os.path.exists(current_file) or not filecmp.cmp(temp_file.name, current_file, shallow=False):
                os.replace(temp_file.name, current_file)

            if os.path.exists(temp_file.name):
                os.remove(temp_file.name)

            command = "sync"
            os.system(command)

            self.write_first_all_speaker_presets = not self.write_first_all_speaker_presets

        except json.JSONDecodeError as e:
            print(f"Error encoding data to JSON: {e}")
        except IOError as e:
            print(f"Error writing to file {current_file}: {e}")

    def save_change_to_oem_json(self):
        with open(ipc_common.OEM_FILE, 'w') as json_file:
            json_string = json.dumps(self.oem, indent=4)
            json_file.write(json_string)

    def save_before_poweroff(self):
        if self.is_data_json_timer_active:
            self.is_data_json_timer_active = False
            self.save_change_to_data_json()

    def recalculate_group_peq_values(self, group_number, peq_channel):
        if self.data["groups"][group_number]["peq"][peq_channel]["enable"]:
            a0, a1, a2, b0, b1, b2 = ipc_filters.compute_peq_coeff(self.data["groups"][group_number]["peq"][peq_channel]["type"],
                                                                   self.data["groups"][group_number]["peq"][peq_channel]["freq"],
                                                                   self.data["groups"][group_number]["peq"][peq_channel]["gain"],
                                                                   self.data["groups"][group_number]["peq"][peq_channel]["q"])
            a1, a2, b0, b1, b2 = ipc_util.rescale_peq_values(a0, a1, a2, b0, b1, b2)
        else:
            a1, a2, b0, b1, b2 = ipc_util.rescale_peq_values(ipc_constants.DEFAULT_FILTER["a0"],
                                                             ipc_constants.DEFAULT_FILTER["a1"],
                                                             ipc_constants.DEFAULT_FILTER["a2"],
                                                             ipc_constants.DEFAULT_FILTER["b0"],
                                                             ipc_constants.DEFAULT_FILTER["b1"],
                                                             ipc_constants.DEFAULT_FILTER["b2"])
        return a1, a2, b0, b1, b2

    def recalculate_group_delay_values(self):
        # reset all values before recalculate 
        self.data["channels"][0]["group_delay_value"] = 0
        self.data["channels"][1]["group_delay_value"] = 0
        self.data["channels"][2]["group_delay_value"] = 0
        self.data["channels"][3]["group_delay_value"] = 0
        if (self.current_variant_value == "variant7") :
            self.data["channels"][4]["group_delay_value"] = 0
            self.data["channels"][5]["group_delay_value"] = 0
            self.data["channels"][6]["group_delay_value"] = 0
            self.data["channels"][7]["group_delay_value"] = 0
            self.data["channels"][8]["group_delay_value"] = 0
            self.data["channels"][9]["group_delay_value"] = 0
            self.data["channels"][10]["group_delay_value"] = 0
            self.data["channels"][11]["group_delay_value"] = 0
            self.data["channels"][12]["group_delay_value"] = 0
            self.data["channels"][13]["group_delay_value"] = 0
            self.data["channels"][14]["group_delay_value"] = 0
            self.data["channels"][15]["group_delay_value"] = 0
        for i_group in range(0, ipc_constants.NUM_OF_GROUPS):
            self.data["channels"][0]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                             self.data["channels"][0]["assigned_to_group"][i_group] * \
                                                             self.data["groups"][i_group]["delay_value"]
            self.data["channels"][1]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                             self.data["channels"][1]["assigned_to_group"][i_group] * \
                                                             self.data["groups"][i_group]["delay_value"]
            self.data["channels"][2]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                             self.data["channels"][2]["assigned_to_group"][i_group] * \
                                                             self.data["groups"][i_group]["delay_value"]
            self.data["channels"][3]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                             self.data["channels"][3]["assigned_to_group"][i_group] * \
                                                             self.data["groups"][i_group]["delay_value"]
            
            if (self.current_variant_value == "variant7" or self.current_variant_value == "variant8") :
                self.data["channels"][4]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][4]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][5]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][5]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][6]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][6]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][7]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][7]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][8]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][8]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][9]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][9]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][10]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][10]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][11]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][11]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][12]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][12]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][13]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][13]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][14]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][14]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]
                self.data["channels"][15]["group_delay_value"] += int(self.data["groups"][i_group]["delay_enable"]) * \
                                                                self.data["channels"][15]["assigned_to_group"][i_group] * \
                                                                self.data["groups"][i_group]["delay_value"]

    def send_group_peq_coef_to_dsp(self, group_number, peq_channel, coeff):
        if 1 == self.data["channels"][0]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 0, group_number, peq_channel, coeff)
        if 1 == self.data["channels"][1]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 1, group_number, peq_channel, coeff)
        if 1 == self.data["channels"][2]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 2, group_number, peq_channel, coeff)
        if 1 == self.data["channels"][3]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 3, group_number, peq_channel, coeff)
        
        if (self.current_variant_value == "variant7") :
            if 1 == self.data["channels"][4]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 4, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][5]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 5, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][6]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 6, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][7]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 7, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][8]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 8, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][9]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 9, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][10]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 10, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][11]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 11, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][12]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 12, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][13]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 13, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][14]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 14, group_number, peq_channel, coeff)
            if 1 == self.data["channels"][15]["assigned_to_group"][group_number]:
                ipc_dsp.dsp_set_group_peq_filter_coeff(self.current_variant_value, 15, group_number, peq_channel, coeff)

    def send_delay_value_to_dsp(self, channel):
        sum_delay_value = int(self.data["channels"][channel]["delay_enable"]) * self.data["channels"][channel]["delay_value"] + \
                          self.data["channels"][channel]["group_delay_value"]
        if sum_delay_value > ipc_constants.MAX_USER_AND_GROUP_DELAY_VALUE:
            ipc_dsp.dsp_channel_delay_config(self.current_variant_value, channel, ipc_constants.MAX_USER_AND_GROUP_DELAY_VALUE)
        else:
            ipc_dsp.dsp_channel_delay_config(self.current_variant_value, channel, sum_delay_value)

    def __eth_conf(self, ip_addr, netmask, gateway, dns_servers):
        # Step 1: Update /etc/network/interfaces.d/<iface>.conf
        try:
            conf_file = open('/etc/network/interfaces.d/' + ipc_common.ETHERNET_INTERFACE + '.conf', 'w')
            conf_file.write('auto ' + ipc_common.ETHERNET_INTERFACE + '\n')
            #static ip configuration
            if ip_addr is not None and netmask is not None:

                conf_file.write('iface ' + ipc_common.ETHERNET_INTERFACE + ' inet static\n')
                conf_file.write('    address {}\n'.format(ip_addr))
                conf_file.write('    netmask {}\n'.format(netmask))
                if gateway is not None:
                    conf_file.write('    gateway {}\n'.format(gateway))
                if dns_servers is not None and len(dns_servers) > 0:
                    conf_file.write('    dns-nameservers {}\n'.format(dns_servers))
                dhcp.clear()
                
            #dhcp ip configuration
            else:
                conf_file.write('iface ' + ipc_common.ETHERNET_INTERFACE + ' inet dhcp\n')
                dhcp.set()

            conf_file.flush()
            conf_file.close()

        except IOError:
            print('Unable to open /etc/network/interfaces.d/' + ipc_common.ETHERNET_INTERFACE + '.conf for writing.')

        # Step 2: Flush existing IP address
        if os.system('/bin/ip addr flush ' + ipc_common.ETHERNET_INTERFACE) != 0:
            print('Unable to flush existing ' + ipc_common.ETHERNET_INTERFACE + ' address.')
        
        # Step 3: Restart networking service
        os.system('sudo ifdown --force eth0')
        time.sleep(2)
        os.system('sudo ifup --force eth0')

        # Step 4: Wi-Fi is autoenabled on network restart. Check if we need to disable it.
        if self.data["settings"]["hotspot_status"] is False:
            self.__wlan_conf(False)

        return True

    def populate_about_field(self):
        file = open(ipc_common.DSP_VARIANT_FILE, "r")
        about_string = str(file.read()).split(" ")
        if "variant1.code" == about_string[0]:
            self.data["settings"]["model"] = "CP354"
        elif "variant2.code" == about_string[0]:
            self.data["settings"]["model"] = "CP704"
        elif "variant3.code" == about_string[0]:
            self.data["settings"]["model"] = "CP1504"
        elif "variant4.code" == about_string[0]:
            self.data["settings"]["model"] = "CP3004"
        elif "variant5.code" == about_string[0]:
            self.data["settings"]["model"] = "CP0701"
        elif "variant6.code" == about_string[0]:
            self.data["settings"]["model"] = "CP0702"
        elif "variant7.code" == about_string[0]:
            self.data["settings"]["model"] = "CP0716"
        elif "variant8.code" == about_string[0]:
            self.data["settings"]["model"] = "CP7164"
        elif "variant9.code" == about_string[0]:
            self.data["settings"]["model"] = "CP0703"
        else:
            self.data["settings"]["model"] = "Unknown model"
        self.data["settings"]["hardware_version"] = about_string[1]
        self.data["settings"]["hardware_version"] = ipc_constants.SERVICE_VERSION
        self.data["settings"]["serial"] = about_string[2]
        self.save_change_to_data_json()

    def check_dsp_firmware_update(self):
        ######################## variant1 CP354 ########################
        if self.current_variant_value == "variant1":
            print("Check SW version requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
            except OSError:
                print("DSP disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant1.code", DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required...")
        ######################## variant2 CP704 ########################
        elif self.current_variant_value == "variant2":
            print("Check SW version requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
            except OSError:
                print("DSP disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant2.code", DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required...")
        ######################## variant3 CP1504 ########################
        elif self.current_variant_value == "variant3":
            print("Check SW version for DSP1 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
            except OSError:
                print("DSP1 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant3.code", DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP1...")
            print("Check SW version for DSP2 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_2)
            except OSError:
                print("DSP2 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_2)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant3.code", DSP_I2C_ADDRESS_2)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_2)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_2)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_2):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP2...")
        ######################## variant4 CP3004 ########################
        elif self.current_variant_value == "variant4":
            print("Check SW version for DSP1 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
            except OSError:
                print("DSP1 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant4.code", DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP1...")

            print("Check SW version for DSP2 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_2)
            except OSError:
                print("DSP2 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_2)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant4.code", DSP_I2C_ADDRESS_2)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_2)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_2)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_2):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP2...")

            print("Check SW version for DSP3 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_3)
            except OSError:
                print("DSP3 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_3)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant4.code", DSP_I2C_ADDRESS_3)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_3)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_3)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_3):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP3...")

            print("Check SW version for DSP4 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_4)
            except OSError:
                print("DSP4 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_4)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant4.code", DSP_I2C_ADDRESS_4)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_4)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_4)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_4):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP4...")
        ######################## variant5 CP704 ########################
        elif self.current_variant_value == "variant5":
            print("Check SW version requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
            except OSError:
                print("DSP disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant5.code", DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required...")
        ######################## variant4 CP3004 ########################
        elif self.current_variant_value == "variant6":
            print("Check SW version for DSP1 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
            except OSError:
                print("DSP1 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant6.code", DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP1...")
        ######################## variant7 CP716 ########################
        elif self.current_variant_value == "variant7":
            print("Check SW version for DSP1 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
            except OSError:
                print("DSP1 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant7.code", DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP1...")

            print("Check SW version for DSP2 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_2)
            except OSError:
                print("DSP2 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_2)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant7.code", DSP_I2C_ADDRESS_2)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_2)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_2)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_2):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP2...")

            print("Check SW version for DSP3 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_3)
            except OSError:
                print("DSP3 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_3)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant7.code", DSP_I2C_ADDRESS_3)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_3)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_3)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_3):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP3...")

            print("Check SW version for DSP4 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_4)
            except OSError:
                print("DSP4 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_4)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant7.code", DSP_I2C_ADDRESS_4)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_4)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_4)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_4):
                    self.check_dsp_firmware_update()
                    return
        ######################## variant8 CP7164 ########################
        elif self.current_variant_value == "variant8":
            print("Check SW version for DSP1 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
            except OSError:
                print("DSP1 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant2.code", DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_1)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_1)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_1):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP1...")

            print("Check SW version for DSP2 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_2)
            except OSError:
                print("DSP2 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_2)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant2.code", DSP_I2C_ADDRESS_2)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_2)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_2)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_2):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP2...")

            print("Check SW version for DSP3 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_3)
            except OSError:
                print("DSP3 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_3)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant2.code", DSP_I2C_ADDRESS_3)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_3)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_3)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_3):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP3...")

            print("Check SW version for DSP4 requirement... %s" % SW_VERSION)
            try:
                running = ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_4)
            except OSError:
                print("DSP4 disconnected, unable to access.")
                return
            if running == 1:
                need_update = ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_4)
            else:
                need_update = 1
            if need_update == 1 or running == 0:
                print("Starting update process...")
                print(self.current_variant_value)
                ipc_sma_tools.dsp_update_eeprom("/home/orangepi/IpcSystemService/variant2.code", DSP_I2C_ADDRESS_4)
                ipc_sma_tools.dsp_reset(DSP_I2C_ADDRESS_4)
                ipc_sma_tools.dsp_getstatus(DSP_I2C_ADDRESS_4)
                #Add maximum amount of tries (3)
                if not ipc_sma_tools.dsp_checksoftware(SW_VERSION, DSP_I2C_ADDRESS_4):
                    self.check_dsp_firmware_update()
                    return
            else:
                print("No update required for DSP4...")

        os.system('systemctl start givalocalapp.service')

        time.sleep(2)
        
        os.system('systemctl start givawebsocket.service')

        # websocketstat = os.system('systemctl status givawebsocket')
        # if websocketstat == 0:
        #     print('Websocket is already running')
        # else:
        #     os.system('systemctl restart givawebsocket.service') 

        # os.system('sudo systemctl start givawebsocket.service')    
        #restart dnsmasq to give dhcp address from hotspot
        os.system('systemctl restart dnsmasq.service')
        #restart ntp service to sync internal clock
        os.system('systemctl restart systemd-timesyncd.service')

    @staticmethod
    def __wlan_conf(enable: bool):
        if enable:
            # os.system('/sbin/ifup wlan0')
            # if os.system('/bin/systemctl restart hostapd.service') != 0:
            #     print('Unable to restart access point service.')
            #     return False
            # # os.system('/sbin/ifup wlan0')

            # # return True
            return os.system('/sbin/ifup wlan0') == 0
        else:
            return os.system('/sbin/ifdown wlan0') == 0

    @staticmethod
    def __wlan_hotspot_params(ssid: str, wpa_version: int, channel: int, password: str):
        # Step 1: Reconstruct ipc_common.WLAN_AP_CONFIG file and restart hostapd service
        try:
            conf_file = open(ipc_common.WLAN_AP_CONFIG, 'r')
            input_lines = conf_file.readlines()
            conf_file.close()

            output_lines = list()
            for line in input_lines:
                if ssid is not None and line.strip().startswith('ssid='):
                    output_lines.append('ssid=' + ssid + '\n')
                elif wpa_version is not None and line.strip().startswith('wpa='):
                    output_lines.append('wpa=' + str(wpa_version) + '\n')
                elif channel is not None and line.strip().startswith('channel='):
                    output_lines.append('channel=' + str(channel) + '\n')
                elif password is not None and line.strip().startswith('wpa_passphrase='):
                    output_lines.append('wpa_passphrase=' + password + '\n')
                else:
                    output_lines.append(line)
            conf_file = open(ipc_common.WLAN_AP_CONFIG, 'w')
            conf_file.writelines(output_lines)
            conf_file.flush()
            conf_file.close()
        except IOError:
            print('Unable to open ' + ipc_common.WLAN_AP_CONFIG)
            return False

        # Step 2: Restart access point service
        if os.system('/bin/systemctl restart hostapd.service') != 0:
            print('Unable to restart access point service.')
            return False

        return True

    def udp_set_channel_gain(self, channel, gain):
        ipc_util.debug_print("UDP: set solo gain called", self.debug_mode)
        self.data["channels"][channel]["gain"] = float(gain)
        self.check_data_json_timer()
        ipc_dsp.dsp_channel_gain_solo_config(self.current_variant_value, channel, float(gain))
        return True

    def udp_set_group_gain(self, group_number, gain):
        ipc_util.debug_print('UDP: set group gain called', self.debug_mode)
        self.data["groups"][group_number]["gain"] = float(gain)
        self.check_data_json_timer()
        if 1 == self.data["channels"][0]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_gain_set(self.current_variant_value, 0, group_number, float(gain))
        if 1 == self.data["channels"][1]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_gain_set(self.current_variant_value, 1, group_number, float(gain))
        if 1 == self.data["channels"][2]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_gain_set(self.current_variant_value, 2, group_number, float(gain))
        if 1 == self.data["channels"][3]["assigned_to_group"][group_number]:
            ipc_dsp.dsp_group_gain_set(self.current_variant_value, 3, group_number, float(gain))

    def udp_set_channel_mute(self, channel, muted):
        ipc_util.debug_print("server: set solo mute called", self.debug_mode)
        self.data["channels"][channel]["mute"] = bool(muted)
        self.check_data_json_timer()
        mute_status = bool(muted)
        for i_group in range(0, ipc_constants.NUM_OF_GROUPS):  # calculate mute groups impact
            if 1 == self.data["channels"][channel]["assigned_to_group"][i_group]:
                mute_status = mute_status or self.data["groups"][i_group]["mute"]
        ipc_dsp.dsp_solo_mute(self.current_variant_value, channel, mute_status)

    def udp_set_group_mute(self, group_number, muted):
        ipc_util.debug_print('UDP: set group mute called', self.debug_mode)
        self.data["groups"][group_number]["mute"] = bool(muted)
        self.check_data_json_timer()
        #  check if change has effect on any channel
        for i_channel in range(0, ipc_constants.NUM_OF_CHANNELS):
            if 1 == self.data["channels"][i_channel]["assigned_to_group"][group_number]:
                # Impact from channel itself
                final_mute_state = bool(self.data["channels"][i_channel]["mute"])
                # Then, calculate group impact...
                for i_group in range(0, ipc_constants.NUM_OF_GROUPS):
                    if self.data["channels"][i_channel]["assigned_to_group"][i_group]:
                        final_mute_state = final_mute_state or bool(self.data["groups"][i_group]["mute"])
                ipc_dsp.dsp_solo_mute(self.current_variant_value, i_channel, bool(final_mute_state))

    def udp_set_all_mute(self, muted):
        ipc_util.debug_print('UDP: set all channels mute', self.debug_mode)
        for i_channel in range(0, ipc_constants.NUM_OF_CHANNELS):
            self.data["channels"][i_channel]["mute"] = bool(muted)
        self.check_data_json_timer()

        for i_channel in range(0, ipc_constants.NUM_OF_CHANNELS):
            mute_status = bool(muted)
            for i_group in range(0, ipc_constants.NUM_OF_GROUPS):  # calculate mute groups impact
                if 1 == self.data["channels"][i_channel]["assigned_to_group"][i_group]:
                    mute_status = mute_status or self.data["groups"][i_group]["mute"]
            ipc_dsp.dsp_solo_mute(self.current_variant_value, i_channel, mute_status)

    def udp_set_input_mixer_gain(self, channel, source, gain):
        ipc_util.debug_print('UDP: set solo channel source mixer called', self.debug_mode)
        self.data["channels"][channel]["mixer"][source]["gain"] = float(gain)
        self.check_data_json_timer()
        ipc_dsp.dsp_channel_source_mixer(self.current_variant_value, channel, source, float(gain))

    def udp_set_all_mixer_gain(self, channel, gains):
        ipc_util.debug_print('UDP: set all channel source mixer called', self.debug_mode)
        self.check_data_json_timer()
        for i_source in range (0, ipc_constants.NUM_OF_SOURCE_REDUCED):
            self.data["channels"][channel]["mixer"][i_source]["gain"] = float(gains[i_source])
            ipc_dsp.dsp_channel_source_mixer(self.current_variant_value, channel, i_source, float(gains[i_source]))

    def udp_set_speaker_preset(self, channel, path):
        ipc_util.debug_print('server: speaker preset called', self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        # We need to calculate final mute send, to preserve state in which system was
        # Impact from channel itself
        final_mute_state = bool(self.data["channels"][channel]["mute"])
        # Then, calculate group impact...
        for i_group in range(0, ipc_constants.NUM_OF_GROUPS):
            if self.data["channels"][channel]["assigned_to_group"][i_group]:
                final_mute_state = final_mute_state or bool(self.data["groups"][i_group]["mute"])
        for folder_in_dict in self.speaker_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        copySettings = copy.deepcopy(file_in_dict["settings"])
                        self.data["speaker_presets"][channel] = copySettings
                        self.check_speaker_presets_json_timer()
                        ipc_dsp.dsp_speaker_preset(self.current_variant_value, channel, dict(file_in_dict["settings"]), final_mute_state)
                        break
        return is_found

    def udp_set_global_preset(self, path):
        ipc_util.debug_print('server: global preset called', self.debug_mode)
        folder, file = path.split("/")
        is_found = False
        for folder_in_dict in self.global_presets:
            if folder == folder_in_dict["folder_name"]:
                for file_in_dict in folder_in_dict["files"]:
                    if file == file_in_dict["file_name"]:
                        is_found = True
                        copyUserSettings = copy.deepcopy(file_in_dict["user_settings"])
                        copyGroups = copy.deepcopy(file_in_dict["groups"])
                        copySpeakerPresets = copy.deepcopy(file_in_dict["speaker_presets"])
                        self.data["channels"] = copyUserSettings
                        self.data["groups"] = copyGroups
                        self.data["speaker_presets"] = copySpeakerPresets
                        self.check_data_json_timer()
                        self.check_speaker_presets_json_timer()
                        thread = Thread(target=ipc_dsp.dsp_global_audio_preset, args=(self.current_variant_value, copyUserSettings, copyGroups, copySpeakerPresets))
                        thread.start()
                        break
        return is_found

    @dbus.service.method(ipc_common.OEM_CHECK_CODE_GET_INTERFACE, in_signature='s', out_signiture='b')
    def oem_check_code(self, code):
        ipc_util.debug_print('OEM: check oem code',self.debug_mode)
        if code == "0000000000" and self.oem["oem_code"] == "" :
            return True
        if code == "" and self.oem["oem_code"] == "0000000000" :
            return True
        if code == self.oem["oem_code"]:
            return True
        else:
            return False
    @dbus.service.method(ipc_common.OEM_CODE_SET_INTERFACE, in_signature='ss', out_signiture='b')
    def oem_set_code(self, label, code):
        self.check_data_json_timer()
        ipc_util.debug_print('OEM: set oem code and label',self.debug_mode)
        try:
            oem_parameters = json.loads(label)
        except json.JSONDecodeError:
            return False
    
        self.oem["oem_code"] = code
        self.oem["oem_label"] = oem_parameters.get("label", ipc_constants.DEFAULT_STRING)
        self.oem["oem_model"] = oem_parameters.get("model", ipc_constants.DEFAULT_STRING)
        self.oem["oem_desc"] = oem_parameters.get("desc", ipc_constants.DEFAULT_STRING)
        self.oem["dante_capable"] = oem_parameters.get("danteCap", ipc_constants.DEFAULT_BOOL)
        self.data["settings"]["oem_label"] = oem_parameters.get("label", ipc_constants.DEFAULT_STRING)
        self.save_change_to_oem_json()
        writeSPI()
        return True

    @dbus.service.method(ipc_common.OEM_CODE_REMOVE_INTERFACE, in_signature='', out_signiture='b')
    def oem_remove_code(self):
        self.check_data_json_timer()
        ipc_util.debug_print('OEM: remove oem code',self.debug_mode)
        self.oem["oem_code"] = ""
        self.oem["oem_label"] = ""
        self.oem["oem_model"] = ""
        self.oem["oem_desc"] = ""
        self.oem["dante_capable"] = False
        self.data["settings"]["oem_label"] = ""
        self.save_change_to_oem_json()
        eraseSPI()
        return True
    
    @dbus.service.method(ipc_common.OEM_CODE_GET_STATUS_INTERFACE, in_signature='', out_signiture='sv')
    def oem_get_status(self):
        ipc_util.debug_print('OEM: get oem status', self.debug_mode)
        oem_code = False
        if len(self.oem["oem_code"]) > 0 and self.oem["oem_code"] !="0000000000":
            oem_code = True
        return ipc_util.python_to_dbus({"oem_code_enable": bool(oem_code),
                                        "oem_label": self.data["settings"]["oem_label"]})

    @dbus.service.method(ipc_common.SPOTIFY_CONFIG_GET_INTERFACE, in_signature='', out_signiture='sv')
    def spotify_config_get(self):
        ipc_util.debug_print("server: get spotify config called", self.debug_mode)
        return ipc_util.python_to_dbus({"device_name": self.data["settings"]["spotify_device_name"],
                                        "email": self.data["settings"]["spotify_email"],
                                        "password": self.data["settings"]["spotify_password"],
                                        "enable": bool(self.data["settings"]["spotify_enable"])})

    @dbus.service.method(ipc_common.HIZ_FILTER_SET_INTERFACE , in_signature='ib', out_signiture='b') 
    def hiz_filter_set(self, channel, filter):
        ipc_util.debug_print("server: set hiZ filter config", self.debug_mode)
        self.data["settings"]["high_impedance_filter"][channel] = bool(filter)
        self.check_data_json_timer()
        thread = Thread(target=ipc_dsp.dsp_set_hiz, args=(self.current_variant_value, channel, filter))
        thread.start()
        # ipc_dsp.dsp_solo_mute(self.current_variant_value, channel, True)
        # time.sleep(2)
        # ipc_dsp.dsp_set_hiz_filter_coeff(self.current_variant_value, channel, filter)
        # time.sleep(2)
        # ipc_dsp.dsp_solo_mute(self.current_variant_value, channel, False)
        return True
    
    @dbus.service.method(ipc_common.HIZ_FILTER_GET_INTERFACE , in_signature='i', out_signiture='b') 
    def hiz_filter_get(self, channel):
        ipc_util.debug_print("server: get hiZ filter config", self.debug_mode)
        return self.data["settings"]["high_impedance_filter"][channel]

    @dbus.service.method(ipc_common.AMP_FRONT_PANEL_LOCK_SET_INTERFACE , in_signature='b', out_signiture='b') 
    def front_lock_set(self, lock):
        ipc_util.debug_print("server: set front lock config", self.debug_mode)
        self.data["settings"]["front_lock"] = bool(lock)
        self.check_data_json_timer()
        return True
    
    @dbus.service.method(ipc_common.AMP_FRONT_PANEL_LOCK_GET_INTERFACE , in_signature='', out_signiture='b') 
    def front_lock_get(self):
        ipc_util.debug_print("server: get front lock config", self.debug_mode)
        return self.data["settings"]["front_lock"]
    
    @dbus.service.method(ipc_common.AMP_LOCATE_INTERFACE , in_signature='', out_signiture='b') 
    def locate_run(self):
        ipc_util.debug_print("server: get front lock config", self.debug_mode)
        self.data["settings"]["locate"] = True
        return True

    @dbus.service.method(ipc_common.AMP_RESET_LOCATE_INTERFACE , in_signature='', out_signiture='b') 
    def locate_reset(self):
        ipc_util.debug_print("server: get front lock config", self.debug_mode)
        self.data["settings"]["locate"] = False
        return True
    
    @dbus.service.method(ipc_common.AMP_RESET_DEFAULT_SETTING_INTERFACE , in_signature='', out_signiture='b') 
    def factory_reset(self):
        ipc_util.debug_print("server: run a factory reset", self.debug_mode)

        #Save device parameters
        t_model = self.data["settings"]["model"]
        t_hardware_version = self.data["settings"]["hardware_version"]
        t_serial = self.data["settings"]["serial"]
        t_discovery_id = self.data["settings"]["model"]
        t_oem_label = self.data["settings"]["oem_label"]

        try:
            #Load clean data.json file
            with open(ipc_common.CONFIG_FILE_CLEAN, 'r') as json_file:
                new_data_data =copy.deepcopy(json.load(json_file))
                self.data = new_data_data

                #Populate with previously saved device parameters
                self.data["settings"]["model"] = t_model
                self.data["settings"]["hardware_version"] = t_hardware_version
                self.data["settings"]["serial"] = t_serial
                self.data["settings"]["model"] = t_discovery_id
                self.data["settings"]["oem_label"] = t_oem_label

                if (t_model == "CP354"):
                    self.data["settings"]["discovery_id"] = t_model
                elif (t_model == "CP704"):
                    self.data["settings"]["discovery_id"] = t_model
                elif (t_model == "CP1504"):
                    self.data["settings"]["discovery_id"] = t_model
                elif (t_model == "CP3004"):
                    self.data["settings"]["discovery_id"] = t_model
                elif (t_model == "CP0716"):
                    self.data["settings"]["discovery_id"] = t_model
                elif (t_model == "CP7164"):
                    self.data["settings"]["discovery_id"] = t_model

            #Load clean speaker_presets.json
            with open(ipc_common.SPEAKER_PRESETS_FILE_CLEAN, 'r') as json_file:
                new_data_speaker = copy.deepcopy(json.load(json_file))
                self.speaker_presets = new_data_speaker

            #Load clean global_presets.json
            with open(ipc_common.GLOBAL_PRESETS_FILE_CLEAN, 'r') as json_file:
                new_data_global = copy.deepcopy(json.load(json_file))
                self.global_presets = new_data_global

            #Overwrite session.json file
            t_session = open(ipc_common.SESSION_FILE_CLEAN, "r")
            new_data_session = copy.deepcopy(t_session.read())
            t_session_content = new_data_session
            t_session.close()

            t_s = open(ipc_common.SESSION_FILE, "w")
            t_s.write(t_session_content)
            t_s.close()

            #Setup Wifi SSID
            if self.data['settings']['SSID'] == 'PLACEHOLDER-NEEDS-TO-BE-REPLACED':
                new_ssid = 'AMP_' + ipc_util.our_wlan_mac_addr()[-5:].replace(':', '')
                self.data['settings']['SSID'] = new_ssid
                self.data['settings']['hotspot_pass'] = '12345678'   # Also set a valid initial password
                self.__wlan_hotspot_params(ssid=new_ssid, wpa_version=None, channel=None, password='12345678')

            #Config Cloud Connect
            with self.lock: 
                self.neighbours[0]['cloud_device_name'] =  self.data["settings"]["cloud_device_name"]

            command = ipc_common.APEX_SCRIPTS_FOLDER + "apexconnect.sh"
            # If enabled, start cloud, else - stop it
            if bool(self.data["settings"]["cloud_enable"]):
                command += " --service enable"
                command += " --relay \'apexconnect.me\'"
                command += " --name \'" + self.data["settings"]["cloud_device_name"] + "\'"
                command += " --secret \'afblijven\'"
                command += " --ssh yes"
                # If username or pass is empty string, don't pass it
                if self.data["settings"]["cloud_username"] != "" and self.data["settings"]["cloud_password"] != "":
                    command += " --user \'" + self.data["settings"]["cloud_username"] + "\'"
                    command += " --pass \'" + self.data["settings"]["cloud_password"] + "\'"
            else:
                command += " --service disable"
            ipc_util.debug_print("Executing: " + command, self.debug_mode)
            resp = os.system(command)

            #Config Spotify
            command = ipc_common.APEX_SCRIPTS_FOLDER + "apexspotify.sh"
            # If enabled, start spotify, else - stop it
            if bool(self.data["settings"]["spotify_enable"]):
                command += " --service enable"
                command += " --name \'" + self.data["settings"]["spotify_device_name"] + "\'"
                command += " --quality 320"
                # If username or pass is empty string, don't pass it
                if self.data["settings"]["spotify_password"] != "" and self.data["settings"]["spotify_email"] != "":
                    command += " --user \'" + self.data["settings"]["spotify_email"] + "\'"
                    command += " --pass \'" + self.data["settings"]["spotify_password"] + "\'"
            else:
                command += " --service disable"
            ipc_util.debug_print("Executing: " + command, self.debug_mode)
            resp = os.system(command)

            #Config Airplay
            command = ipc_common.APEX_SCRIPTS_FOLDER + "apexairplay.sh"
            # If enabled, start airplay, else - stop it
            if bool(self.data["settings"]["airplay_enable"]):
                command += " --service enable"
                command += " --name \'" + self.data["settings"]["airplay_device_name"] + "\'"
                # If pass is empty string, don't pass it
                if self.data["settings"]["airplay_password"] != "":
                    command += " --pass \'" + self.data["settings"]["airplay_password"] + "\'"
            else:
                command += " --service disable"
            ipc_util.debug_print("Executing: " + command, self.debug_mode)
            resp = os.system(command)

            self.check_data_fields(self)

            #Save all the parameters
            self.check_data_json_timer()
            self.check_speaker_presets_json_timer()
            self.check_global_presets_json_timer()
            self.save_change_to_oem_json()

            self.populate_about_field()

            self.neighbours = []  # The list of neighbours in {hw_addr, ip_addr, desc, alive, last_report_time, model, cloud_device_name} format
            # The local device is always fixed at first place
            
            ip_infos = ipc_util.our_real_ip_addr(True).split()
            self.neighbours.append({
                'hw_addr': ipc_util.our_eth_mac_addr(),
                'ip_addr': ip_infos[0],
                'ip_subnet': ip_infos[1],
                'ip_gateway':ip_infos[2],
                'desc': "LOCAL",
                'model': self.data["settings"]["model"],
                'cloud_device_name': self.data["settings"].get("cloud_device_name", ipc_constants.DEFAULT_STRING),  # May not exist
                'serial': self.data["settings"].get("serial", ipc_constants.DEFAULT_STRING),  # May not exist
                'firmware_version': self.data["settings"].get("hardware_version", ipc_constants.DEFAULT_STRING),
                'oem_label': self.oem.get("oem_label", ipc_constants.DEFAULT_STRING),
                'oem_model': self.oem.get("oem_model", ipc_constants.DEFAULT_STRING),
                'oem_desc': self.oem.get("oem_desc", ipc_constants.DEFAULT_STRING),
                'dante_capable': self.data["settings"].get("dante_capable", ipc_constants.DEFAULT_BOOL),
                'alive': True,
                'last_report_time': 0.0
            })

            # Populate all DSP blocks with previous saved content
            thread = Thread(target=ipc_dsp.dsp_global_boot_preset, args=(self.current_variant_value,self.data["channels"], self.data["groups"], self.data["speaker_presets"], self.data["settings"]))
            thread.start()

            time.sleep(2)

            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                mute_status = True
                ipc_dsp.dsp_solo_mute(self.current_variant_value, i, mute_status)
                self.data["channels"][i]["mute"] = bool(mute_status)

            # #Save all the parameters
            # self.check_data_json_timer()
            # self.check_speaker_presets_json_timer()
            # self.check_global_presets_json_timer()
            # self.save_change_to_oem_json()

            self.populate_about_field()

            return True
        except:
            return False

    @dbus.service.method(ipc_common.AMP_RESET_DEFAULT_SETTING_INTERFACE , in_signature='', out_signiture='b') 
    def audio_reset(self):
        ipc_util.debug_print("server: run a audio reset", self.debug_mode)

        try:
            #Load clean data.json file
            with open(ipc_common.CONFIG_FILE_CLEAN, 'r') as json_file:
                clean_data = json.load(json_file)
                new_data_channel = copy.deepcopy(clean_data["channels"])
                self.data["channels"] = new_data_channel

            #Load clean speaker_presets.json
            with open(ipc_common.SPEAKER_PRESETS_FILE_CLEAN, 'r') as json_file:
                clean_speaker_preset = json.load(json_file)
                new_data_speaker = copy.deepcopy(clean_speaker_preset)
                self.speaker_presets = new_data_speaker

            #Load clean global_presets.json
            with open(ipc_common.GLOBAL_PRESETS_FILE_CLEAN, 'r') as json_file:
                clean_global_preset = json.load(json_file)
                new_data_global = copy.deepcopy(clean_global_preset)
                self.global_presets = new_data_global

            #Overwrite session.json file
            t_session = open(ipc_common.SESSION_FILE_CLEAN, "r")
            t_session_content = t_session.read()
            t_session.close()

            t_s = open(ipc_common.SESSION_FILE, "w")
            t_s.write(t_session_content)
            t_s.close()

            #Save all the parameters
            self.check_data_json_timer()
            self.check_speaker_presets_json_timer()
            self.check_global_presets_json_timer()
            self.save_change_to_oem_json()

            time.sleep(2)

            # Populate all DSP blocks with previous saved content
            thread = Thread(target=ipc_dsp.dsp_global_boot_preset, args=(self.current_variant_value,self.data["channels"], self.data["groups"], self.data["speaker_presets"], self.data["settings"]))
            # thread = Thread(target=ipc_dsp.dsp_global_audio_preset, args=(self.current_variant_value,self.data["channels"], self.data["groups"], self.data["speaker_presets"], self.data["settings"]))
            thread.start()

            time.sleep(2)

            for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                mute_status = True
                ipc_dsp.dsp_solo_mute(self.current_variant_value, i, mute_status)
                self.data["channels"][i]["mute"] = bool(mute_status)

            return True
        except:
            return False

    @dbus.service.method(ipc_common.COPY_CHANNEL_PARAMETERS_SET_INTERFACE , in_signature='iss', out_signiture='b')
    def copy_channel_parameters_set(self, source, destination, copyContent):
        ipc_util.debug_print("server: copy channel parameters", self.debug_mode)

        try:
            copy_parameters = json.loads(copyContent)
        except json.JSONDecodeError:
            return False

        copy_destination = destination.split(",")
        copy_destination = [int(i) for i in copy_destination]

        for channel in copy_destination:

            # #MIXER COPY
            if (copy_parameters.get("mixer", ipc_constants.DEFAULT_BOOL) == True):
                arrGain = []
                for i_source in range (0, ipc_constants.NUM_OF_INPUTS,1):
                    arrGain.append(self.data["channels"][source]["mixer"][i_source].get("gain", ipc_constants.DEFAULT_FLOAT))

                if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6" or self.current_variant_value == "variant9"):
                    pass
                else:
                    for i_source in range (0, ipc_constants.NUM_OF_INPUTS,1):
                        self.data["channels"][channel]["mixer"][i_source]["gain"] = arrGain[i_source]
                        ipc_dsp.dsp_channel_source_mixer(self.current_variant_value, channel, i_source, arrGain[i_source])


            #GAIN COPY
            if (copy_parameters.get("gain", ipc_constants.DEFAULT_BOOL) == True):
                copy_gain = self.data["channels"][source]["gain"]
                copy_polarity = self.data["channels"][source]["polarity"]

                if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6" or self.current_variant_value == "variant9"):
                    pass
                else:
                    self.data["channels"][channel]["gain"] = copy_gain
                    ipc_dsp.dsp_channel_gain_solo_config(self.current_variant_value, channel, copy_gain)
                    self.data["channels"][channel]["polarity"] = copy_polarity
                    ipc_dsp.dsp_solo_polarity(self.current_variant_value, channel, copy_polarity)

            # #DELAY COPY
            if (copy_parameters.get("delay", ipc_constants.DEFAULT_BOOL) == True):
                copy_delay_enable = self.data["channels"][source]["delay_enable"]
                copy_delay_value = self.data["channels"][source]["delay_value"]

                if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6" or self.current_variant_value == "variant9"):
                    pass
                else:
                    self.data["channels"][channel]["delay_enable"] = copy_delay_enable
                    self.data["channels"][channel]["delay_value"] = copy_delay_value
                    self.recalculate_group_delay_values()
                    self.send_delay_value_to_dsp(channel)

            # #PEQ COPY
            if (copy_parameters.get("peq", ipc_constants.DEFAULT_BOOL) == True):
                copy_peq = copy.deepcopy(self.data["channels"][source]["peq"])
                if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6" or self.current_variant_value == "variant9"):
                    pass
                else:
                    self.data["channels"][channel]["peq"] = copy_peq
                    for i_peq in range (0, ipc_constants.NUM_OF_PEQ_FILTERS, 1):
                        if bool(copy_peq[i_peq]["enable"]):
                            a0, a1, a2, b0, b1, b2 = ipc_filters.compute_peq_coeff(self.data["channels"][channel]["peq"][i_peq]["type"],
                                                                                self.data["channels"][channel]["peq"][i_peq]["freq"],
                                                                                self.data["channels"][channel]["peq"][i_peq]["gain"],
                                                                                self.data["channels"][channel]["peq"][i_peq]["q"])
                            a1, a2, b0, b1, b2 = ipc_util.rescale_peq_values(a0, a1, a2, b0, b1, b2)
                            ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, channel, i_peq, [b2, b1, b0, a2, a1])
                        else:
                            ipc_dsp.dsp_set_solo_peq_filter_coeff(self.current_variant_value, channel, i_peq, [0, 0, 1, 0, 0])  # if disabled, send default configuration

            # #XOVER
            if (copy_parameters.get("xover", ipc_constants.DEFAULT_BOOL) == True):
                copy_highpass_enable = self.data["channels"][source]["xover_hp_filter"]["xover_hp_enable"]
                copy_highpass_type = self.data["channels"][source]["xover_hp_filter"]["xover_hp_type"]
                copy_highpass_freq = self.data["channels"][source]["xover_hp_filter"]["xover_hp_freq"]

                copy_lowpass_enable = self.data["channels"][source]["xover_lp_filter"]["xover_lp_enable"]
                copy_lowpass_type = self.data["channels"][source]["xover_lp_filter"]["xover_lp_type"]
                copy_lowpass_freq = self.data["channels"][source]["xover_lp_filter"]["xover_lp_freq"]

                if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6" or self.current_variant_value == "variant9"):
                    pass
                else:
                    self.data["channels"][channel]["xover_hp_filter"]["xover_hp_enable"] = copy_highpass_enable
                    self.data["channels"][channel]["xover_hp_filter"]["xover_hp_type"] = copy_highpass_type
                    self.data["channels"][channel]["xover_hp_filter"]["xover_hp_freq"] = copy_highpass_freq
                    self.data["channels"][channel]["xover_lp_filter"]["xover_lp_enable"] = copy_lowpass_enable
                    self.data["channels"][channel]["xover_lp_filter"]["xover_lp_type"] = copy_lowpass_type
                    self.data["channels"][channel]["xover_lp_filter"]["xover_lp_freq"] = copy_lowpass_freq

                    if copy_highpass_enable:
                        coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][channel]["xover_hp_filter"]["xover_hp_type"],
                                                                            ipc_constants.XOVER_HP_TYPE,
                                                                            self.data["channels"][channel]["xover_hp_filter"]["xover_hp_freq"])
                    else:
                        coefficients = ipc_constants.DEFAULT_XOVER_FILTER
                    ipc_dsp.dsp_set_solo_xover_hp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))

                    if copy_lowpass_enable:
                        coefficients = ipc_filters.compute_xover_coefficients(self.data["channels"][channel]["xover_lp_filter"]["xover_lp_type"],
                                                                            ipc_constants.XOVER_LP_TYPE,
                                                                            self.data["channels"][channel]["xover_lp_filter"]["xover_lp_freq"])
                    else:
                        coefficients = ipc_constants.DEFAULT_XOVER_FILTER
                    ipc_dsp.dsp_set_solo_xover_lp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))

            # #LIMITER
            if (copy_parameters.get("limiter", ipc_constants.DEFAULT_BOOL) == True):

                copy_lim_rms_thres = self.data["channels"][source]["lim_rms"]["lim_rms_thres"]
                copy_lim_rms_attack = self.data["channels"][source]["lim_rms"]["lim_rms_attack"]
                copy_lim_rms_release = self.data["channels"][source]["lim_rms"]["lim_rms_release"]

                copy_lim_peak_thres = self.data["channels"][source]["lim_peak"]["lim_peak_thres"]
                copy_lim_peak_release = self.data["channels"][source]["lim_peak"]["lim_peak_release"]

                if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6" or self.current_variant_value == "variant9"):
                    pass
                else:
                    self.data["channels"][channel]["lim_rms"]["lim_rms_thres"] = copy_lim_rms_thres
                    self.data["channels"][channel]["lim_rms"]["lim_rms_attack"] = copy_lim_rms_attack
                    self.data["channels"][channel]["lim_rms"]["lim_rms_release"] = copy_lim_rms_release
                    self.data["channels"][channel]["lim_peak"]["lim_peak_thres"] = copy_lim_peak_thres
                    self.data["channels"][channel]["lim_peak"]["lim_peak_release"] = copy_lim_peak_release

                    threshold_points = ipc_util.calculate_compressor_rms_coefficients(float(copy_lim_rms_thres))
                    ipc_dsp.dsp_set_solo_lim_rms_thres(self.current_variant_value, channel, threshold_points)
                    ipc_dsp.dsp_set_solo_lim_rms_attack(self.current_variant_value, channel, float(copy_lim_rms_attack))
                    ipc_dsp.dsp_set_solo_lim_rms_release(self.current_variant_value, channel, float(copy_lim_rms_release))
                    threshold_points = ipc_util.calculate_compressor_peak_coefficients(float(copy_lim_peak_thres))
                    ipc_dsp.dsp_set_solo_lim_peak_thres(self.current_variant_value, channel, threshold_points)
                    ipc_dsp.dsp_set_solo_lim_peak_release(self.current_variant_value, channel, float(copy_lim_peak_release))

            # #PRESET
            if (copy_parameters.get("preset", ipc_constants.DEFAULT_BOOL) == True):
                copy_preset_name = self.data["channels"][source]["name"]
                copy_preset_path = self.data["channels"][source]["preset"]
                copy_preset = copy.deepcopy(self.data["speaker_presets"][source])
                copy_mute_state = bool(self.data["channels"][source]["mute"])

                if (self.current_variant_value == "variant5" or self.current_variant_value == "variant6" or self.current_variant_value == "variant9"):
                    pass
                else:
                    self.data["channels"][channel]["name"] = copy_preset_name
                    self.data["channels"][channel]["preset"] = copy_preset_path
                    self.data["speaker_presets"][channel] = copy_preset
                    ipc_dsp.dsp_speaker_preset(self.current_variant_value, channel, dict(copy_preset), copy_mute_state)

        self.check_data_json_timer()

        return True

    @dbus.service.method(ipc_common.COPY_PRESET_PARAMETERS_SET_INTERFACE , in_signature='iss', out_signiture='b')
    def copy_speaker_parameters_set(self, source, destination, copyContent):
        ipc_util.debug_print("server: copy preset parameters", self.debug_mode)

        try:
            copy_parameters = json.loads(copyContent)
        except json.JSONDecodeError:
            return False

        copy_destination = destination.split(",")
        copy_destination = [int(i) for i in copy_destination]

        for channel in copy_destination:

            #GAIN COPY
            if (copy_parameters.get("gain", ipc_constants.DEFAULT_BOOL) == True):
                copy_gain = self.data["speaker_presets"][source]["gain"]
                copy_polarity = self.data["speaker_presets"][source]["polarity"]

                self.data["speaker_presets"][channel]["gain"] = copy_gain
                ipc_dsp.dsp_channel_gain_speaker_config(self.current_variant_value, channel, copy_gain)
                self.data["speaker_presets"][channel]["polarity"] = copy_polarity
                ipc_dsp.dsp_speaker_polarity(self.current_variant_value, channel, copy_polarity)

            #DELAY COPY
            if (copy_parameters.get("delay", ipc_constants.DEFAULT_BOOL) == True):
                copy_delay_enable = self.data["speaker_presets"][source]["delay_enable"]
                copy_delay_value = self.data["speaker_presets"][source]["delay_value"]

                self.data["speaker_presets"][channel]["delay_enable"] = copy_delay_enable
                self.data["speaker_presets"][channel]["delay_value"] = copy_delay_value

                if copy_delay_enable:
                    if self.data["speaker_presets"][channel]["delay_value"] > ipc_constants.MAX_SPEAKER_DELAY_VALUE:
                        ipc_dsp.dsp_channel_delay_speaker_config(self.current_variant_value, channel, ipc_constants.MAX_SPEAKER_DELAY_VALUE)
                    else:
                        ipc_dsp.dsp_channel_delay_speaker_config(self.current_variant_value, channel, self.data["speaker_presets"][channel]["delay_value"])
                else:
                    ipc_dsp.dsp_channel_delay_speaker_config(self.current_variant_value, channel, 0.0)

            #PEQ COPY
            if (copy_parameters.get("peq", ipc_constants.DEFAULT_BOOL) == True):
                copy_peq = copy.deepcopy(self.data["speaker_presets"][source]["peq"])
                self.data["speaker_presets"][channel]["peq"] = copy_peq
                for i_peq in range (0, ipc_constants.NUM_OF_PEQ_FILTERS, 1):
                    if bool(copy_peq[i_peq]["enable"]):
                        a0, a1, a2, b0, b1, b2 = ipc_filters.compute_peq_coeff(self.data["speaker_presets"][channel]["peq"][i_peq]["type"],
                                                                            self.data["speaker_presets"][channel]["peq"][i_peq]["freq"],
                                                                            self.data["speaker_presets"][channel]["peq"][i_peq]["gain"],
                                                                            self.data["speaker_presets"][channel]["peq"][i_peq]["q"])
                        a1, a2, b0, b1, b2 = ipc_util.rescale_peq_values(a0, a1, a2, b0, b1, b2)
                        ipc_dsp.dsp_set_speaker_peq_filter_coeff(self.current_variant_value, channel, i_peq, [b2, b1, b0, a2, a1])
                    else:
                        ipc_dsp.dsp_set_speaker_peq_filter_coeff(self.current_variant_value, channel, i_peq, [0, 0, 1, 0, 0])  # if disabled, send default configuration

            #FIR
            if (copy_parameters.get("fir", ipc_constants.DEFAULT_BOOL) == True):
                copy_fir = copy.deepcopy(self.data["speaker_presets"][source]["fir_table"])
                self.data["speaker_presets"][channel]["fir_table"] = copy_fir
                ipc_dsp.dsp_set_speaker_fir_table(self.current_variant_value, channel, self.data["speaker_presets"][channel]["fir_table"])

            #XOVER
            if (copy_parameters.get("xover", ipc_constants.DEFAULT_BOOL) == True):
                copy_highpass_enable = self.data["speaker_presets"][source]["xover_hp_filter"]["xover_hp_enable"]
                copy_highpass_type = self.data["speaker_presets"][source]["xover_hp_filter"]["xover_hp_type"]
                copy_highpass_freq = self.data["speaker_presets"][source]["xover_hp_filter"]["xover_hp_freq"]
                copy_highpass_overide = self.data["speaker_presets"][source]["xover_hp_filter"]["xover_hp_overide"]

                copy_lowpass_enable = self.data["speaker_presets"][source]["xover_lp_filter"]["xover_lp_enable"]
                copy_lowpass_type = self.data["speaker_presets"][source]["xover_lp_filter"]["xover_lp_type"]
                copy_lowpass_freq = self.data["speaker_presets"][source]["xover_lp_filter"]["xover_lp_freq"]
                copy_lowpass_overide = self.data["speaker_presets"][source]["xover_lp_filter"]["xover_lp_overide"]


                self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_enable"] = copy_highpass_enable
                self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_type"] = copy_highpass_type
                self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_freq"] = copy_highpass_freq
                self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_overide"] = copy_highpass_overide
                self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_enable"] = copy_lowpass_enable
                self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_type"] = copy_lowpass_type
                self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_freq"] = copy_lowpass_freq
                self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_overide"] = copy_lowpass_overide

                if copy_highpass_enable:
                    coefficients = ipc_filters.compute_xover_coefficients(self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_type"],
                                                                        ipc_constants.XOVER_HP_TYPE,
                                                                        self.data["speaker_presets"][channel]["xover_hp_filter"]["xover_hp_freq"])
                else:
                    coefficients = ipc_constants.DEFAULT_XOVER_FILTER
                ipc_dsp.dsp_set_speaker_xover_hp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))

                if copy_lowpass_enable:
                    coefficients = ipc_filters.compute_xover_coefficients(self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_type"],
                                                                        ipc_constants.XOVER_LP_TYPE,
                                                                        self.data["speaker_presets"][channel]["xover_lp_filter"]["xover_lp_freq"])
                else:
                    coefficients = ipc_constants.DEFAULT_XOVER_FILTER
                ipc_dsp.dsp_set_speaker_xover_lp_coeff(self.current_variant_value, channel, ipc_util.scale_xover_coeff(coefficients))

            #LIMITER
            if (copy_parameters.get("limiter", ipc_constants.DEFAULT_BOOL) == True):

                copy_lim_rms_thres = self.data["speaker_presets"][source]["lim_rms"]["lim_rms_thres"]
                copy_lim_rms_attack = self.data["speaker_presets"][source]["lim_rms"]["lim_rms_attack"]
                copy_lim_rms_release = self.data["speaker_presets"][source]["lim_rms"]["lim_rms_release"]

                copy_lim_peak_thres = self.data["speaker_presets"][source]["lim_peak"]["lim_peak_thres"]
                copy_lim_peak_release = self.data["speaker_presets"][source]["lim_peak"]["lim_peak_release"]

                self.data["speaker_presets"][channel]["lim_rms"]["lim_rms_thres"] = copy_lim_rms_thres
                self.data["speaker_presets"][channel]["lim_rms"]["lim_rms_attack"] = copy_lim_rms_attack
                self.data["speaker_presets"][channel]["lim_rms"]["lim_rms_release"] = copy_lim_rms_release
                self.data["speaker_presets"][channel]["lim_peak"]["lim_peak_thres"] = copy_lim_peak_thres
                self.data["speaker_presets"][channel]["lim_peak"]["lim_peak_release"] = copy_lim_peak_release

                threshold_points = ipc_util.calculate_compressor_rms_coefficients(float(copy_lim_rms_thres))
                ipc_dsp.dsp_set_speaker_lim_rms_thres(self.current_variant_value, channel, threshold_points)
                ipc_dsp.dsp_set_speaker_lim_rms_attack(self.current_variant_value, channel, float(copy_lim_rms_attack))
                ipc_dsp.dsp_set_speaker_lim_rms_release(self.current_variant_value, channel, float(copy_lim_rms_release))
                threshold_points = ipc_util.calculate_compressor_peak_coefficients(float(copy_lim_peak_thres))
                ipc_dsp.dsp_set_speaker_lim_peak_thres(self.current_variant_value, channel, threshold_points)
                ipc_dsp.dsp_set_speaker_lim_peak_release(self.current_variant_value, channel, float(copy_lim_peak_release))

        self.check_data_json_timer()

        return True

def check_dhcp_in_config(file_path='/etc/network/interfaces.d/eth0.conf'):
    try:
        with open(file_path, 'r') as file:
            content = file.read()
            return 'dhcp' in content.lower()
    except FileNotFoundError:
        print(f"File {file_path} not found.")
        return False
    except Exception as e:
        print(f"An error occurred: {e}")
        return False


def monitor_interface(interface_name='eth0', check_interval=1):
    """
    Monitors the network interface in a background thread.
    """
    last_state = True

    while True:
        try:
            # Check the status of the interface
            with open(f'/sys/class/net/{interface_name}/operstate', 'r') as f:
                status = f.read().strip()
                if status == 'up':
                    if (last_state == False):
                        if dhcp.is_set():
                            command = 'sudo dhclient -r eth0 && sudo dhclient eth0'
                            os.system(command)
                    last_state = True
                else:
                    last_state = False
        except FileNotFoundError:
            print(f"Interface {interface_name} not found.")
            break

        # Wait for the specified interval before checking again
        time.sleep(check_interval)

def handle_poweroff(readback_service, givaipc_service):
    global GPIO
    if not GPIO:
        return

    try:
        while True:
            if GPIO.input('PL11'):
                # GPIO.setup(ipc_common.GPIO_OUTPUT_RELAY, GPIO.OUT)
                # GPIO.output(ipc_common.GPIO_OUTPUT_RELAY,GPIO.LOW)

                # If data.json timer is active, there are some unsaved changes -> stop timer and save changes
                givaipc_service.save_before_poweroff()

                # Signal readback service to stop, to prevent errors because it's unable to write to read-only filesystem
                readback_service.stop_event.set()

                GPIO.cleanup()

                # Emergency read-only remount of root filesystem to prevent damage to SD card.
                # https://en.wikipedia.org/wiki/Magic_SysRq_key
                # NOTE: This service must run under real root, not as sudo.
                sysrq_file = open('/proc/sysrq-trigger', 'w')
                sysrq_file.write('u')
                sysrq_file.close()

                # There's probably no time to do any further cleanup, so just leave the sistem to shut down.
                return
            else:
                time.sleep(.01)
    except (RuntimeError, FileNotFoundError):
        pass


def fail_relay():
    global GPIO

    if not GPIO:
        return

    while True:
        with open(ipc_common.PEAK_READBACK_FILE, "r", os.O_NONBLOCK) as readback_file:
            raw_readback_data = readback_file.read()
        try:
            readback_data = json.loads(raw_readback_data)
        except Exception:
            time.sleep(1)

        amp_on_status = 0
        AMP_ON = "g"
        # for i in range (1, 2):
        if (readback_data["g1"] == 0):
            amp_on_status = 1
        else:
            amp_on_status = 0

        # if (amp_on_status>0):
        #     GPIO.output(ipc_common.GPIO_OUTPUT_RELAY,GPIO.LOW)
        # else:
        #     GPIO.output(ipc_common.GPIO_OUTPUT_RELAY,GPIO.HIGH)

        time.sleep(1)


def handle_standby_input(givaipc_service):
    global GPIO
    if not GPIO:
        return
    previous_state = False

    while True:
        if (GPIO.input(ipc_common.BUTTON_STDBY) == GPIO.HIGH):
            #TURN OFF AMPLIFIER STAGE -> SET STANDBY FOR ALL MODULES
            amp_stage_disabled = True
            givaipc_service.data["settings"]["amp_stage_disabled"] = amp_stage_disabled
            givaipc_service.check_data_json_timer()
            ipc_dsp.dsp_amp_stage_disable(givaipc_service.current_variant_value, amp_stage_disabled)
            previous_state = True
        else:
            #TURN ON AMPLIFIER STAGE
            amp_stage_disabled = False
            if (previous_state):
                givaipc_service.data["settings"]["amp_stage_disabled"] = amp_stage_disabled
                givaipc_service.check_data_json_timer()
                ipc_dsp.dsp_amp_stage_disable(givaipc_service.current_variant_value, amp_stage_disabled)
            previous_state = False

        time.sleep(.5)

def handle_gpi_input(givaipc_service):
    global GPIO
    temp_mute_status = [True] * ipc_constants.NUM_OF_CHANNELS

    if not GPIO:
        return
    
    previous_state = False

    while True:
        if (GPIO.input(ipc_common.BUTTON_GPI) == GPIO.HIGH):
            #MUTE ALL CHANNELS
            mute_status = True
            if (previous_state):
                for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                    if (givaipc_service.data["channels"][i]["mute"] == False):
                        temp_mute_status[i] = False
                    ipc_dsp.dsp_solo_mute(givaipc_service.current_variant_value, i, mute_status)
                    givaipc_service.data["channels"][i]["mute"] = bool(mute_status)
                givaipc_service.check_data_json_timer()
            previous_state = True
        else:
            if (previous_state):
                for i in range (0, ipc_constants.NUM_OF_CHANNELS):
                    if (temp_mute_status[i] == False):
                        ipc_dsp.dsp_solo_mute(givaipc_service.current_variant_value, i, False)
                        givaipc_service.data["channels"][i]["mute"] = bool(False)
                givaipc_service.check_data_json_timer()
            previous_state = False
        time.sleep(.5)
