Exemple #1
0
def main():
    logger.debug("Starting Application")

    timing_queue = queue.Queue(
        maxsize=100
    )  #everything that lands here will get requested from the modbus
    publishing_queue = queue.Queue(
        maxsize=100
    )  #everything that lands here will get send to the cloud (telemetry, statusupdates, errors)

    schedule = Scheduler(
        timing_queue, publishing_queue
    )  #making sure to fill requests for the modbus_reader according to documentation
    modbus_client = Modbus_reader(
        timing_queue, publishing_queue
    )  #making sure to fullfill all modbus_reader requests from timing_queue and gives them to handle_mqtt
    mqtt_handler = handle_mqtt(
        publishing_queue, schedule,
        modbus_client)  #making sure to renew cloud connection

    schedule.daemon = True
    modbus_client.daemon = True
    mqtt_handler.daemon = True

    mqtt_handler.start()
    schedule.start()
    modbus_client.start()

    # endless loop
    while True:
        time.sleep(1000)

    logger.info("Quitting Application")
def read_setup(pub_queue, sleeptime=True, send_answer_to_cloud=False):

    port_config = dict()
    slave_config = dict()
    checkresult = False
    time.sleep(random.randint(5, 15) / 10)
    read_complete = 0

    logger.debug("check the setup_modbus.json")

    while not read_complete >= 5:

        try:
            checkresult, response, data_json = modbus_json_check(
                file=su.setup_modbus_filepath)

            if send_answer_to_cloud:
                logger.debug("setup_modbus.json response:" + str(response))

            port_config = data_json["port_config"]
            slave_config = data_json["slaveconfig"]
            read_complete = 5

            if send_answer_to_cloud:
                gmc.formatted_publish_message(
                    topic=gmc.TOPIC_STATE,
                    payload=
                    "Start up with modbus config: {}       JSON CHECKUP {}".
                    format(data_json, response),
                    c_queue=pub_queue)

        except Exception as e:
            try:
                if read_complete > 1:
                    gmc.formatted_publish_message(
                        topic=gmc.TOPIC_STATE,
                        payload="ERROR reading setup_modbus:" + str(e),
                        c_queue=pub_queue)
            finally:
                time.sleep(
                    3 + random.randint(0, 10)
                )  #randomized access if multiple read at the same time
                read_complete = read_complete + 1
    if not checkresult:  #unsuccessful, default
        port_config = {
            "port": "COM6",
            "baudrate": 9600,
            "databits": 8,
            "parity": "N",
            "stopbits": 1,
            "timeout_connection": 10
        }

        slave_config = {}
    return port_config, slave_config
def execute_configuration_message(update_json):

    global FILE_LOCK
    written = False
    while written == False:
        try:
            #[Start sleep until available]

            while FILE_LOCK == True:
                time.sleep(0.05)

            #[End sleep until available]

            logger.debug("executing update")
            FILE_LOCK = True

            with open(su.setup_modbus_temp_filepath,
                      'w') as f:  #write to temp file is not corrupted
                json.dump(update_json, f, ensure_ascii=False, indent=4)

            new_result, new_response, new_json = modbus_json_check(
                file=su.setup_modbus_temp_filepath, autolock_file=False)

            if (
                    new_json
            ) == update_json and new_result == True:  #if new temp file is not corrupted
                shutil.copy(su.setup_modbus_temp_filepath,
                            su.setup_modbus_filepath)  #overwrite old setup
                time.sleep(0.1)
                os.remove(su.setup_modbus_temp_filepath)  #delete temp setup
            else:  #temp file is for some reason corrupted
                os.remove(su.setup_modbus_temp_filepath)
                FILE_LOCK = False
                return False, "Failed to update the new file"

            written = True
            FILE_LOCK = False
        except Exception as e:
            logger.critical("ERROR writing new json: {}".format(e))
            FILE_LOCK = False
            time.sleep(random.randint(1, 10))  #try to open after sleep
            double_check, unused, unused2 = modbus_json_check(
                dictio=update_json)
            if double_check == False:  #should never be false, as this would mean the json that should be implemented is corrupted
                logger.critical(
                    "FATAL ERROR Trying to implement corrupted JSON {}".format(
                        e))
                return False, "FATAL ERROR Trying to implement corrupted JSON"

    return True, "SUCCESS"
def modbus_json_check(file=str(), dictio=dict(), autolock_file=True):
    """checks the JSON Format from file or from dictionary"""
    global FILE_LOCK

    response = "\t This is the modbus_json_check check \n"

    try:
        #[Start Read Data]

        if dictio and file:  #not possible
            logger.error("Error: Using file and dict at the same time")
            return False, "Error: Using file and dict at the same time", json.dumps(
                {"empty": "empty"})
        elif file:
            #[Start read file]
            opened = False

            while opened == False:
                #[Start sleep until available]
                sleep_max = 0
                while (FILE_LOCK == True
                       and autolock_file == True) or sleep_max > 50:
                    time.sleep(0.05)
                    sleep_max += 1
                #[End sleep until available]

                try:
                    if autolock_file: FILE_LOCK = True

                    if (file != su.setup_modbus_temp_filepath) and (
                            os.path.exists(su.setup_modbus_temp_filepath)
                    ):  #setup_modbus_temp_filepath exists, but we did not plan to check it
                        logger.critical(
                            "The System had a crash updating the Temp file, fixing the update"
                        )
                        shutil.copy(su.setup_modbus_temp_filepath,
                                    su.setup_modbus_filepath)
                        os.remove(su.setup_modbus_temp_filepath)

                    with open(file) as f:
                        data_json = json.load(f)
                    opened = True
                    if autolock_file: FILE_LOCK = False
                except Exception as e:
                    logger.debug("ERROR reading json: {}".format(e))
                    if autolock_file: FILE_LOCK = False
                    time.sleep(random.randint(1, 10))  #try to open after sleep
            #[End read file]

        elif dictio:
            data_json = dictio

        #[End Read Data]
        #[Start Validate Schema]
        try:
            conf_Schema.validate(data_json)

            response = response + " \n FINAL RESPONSE: Schema correct"
            checkresult = True
        except SchemaError as e:
            response = response + " \n FINAL RESPONSE: Schema INCORRECT due to " + str(
                e)
            checkresult = False
        #[End Validate Schema]

        return checkresult, response, data_json

    except Exception as e:
        response = response + "error in completing check" + str(e)
        return False, response, json.dumps({"empty": "empty"})
def check_configuration_message(config_payload, scheduler_obj,
                                modbus_reader_obj, publising_queue):
    logger.info("check new message on content")
    """checks for the Configuration Messages and applies them when the new and deployment formally correct"""

    answer_config_update = " /Config Subscription Message received"

    novel_json_content = False  #
    absolute_success_update = False  #whether successfull update
    replacing_file_success = False  #
    content_correct = False  #
    received_json_checkresult = False  #

    current_checkresult, current_response, current_json = modbus_json_check(
        file=su.setup_modbus_filepath)
    #answer_config_update = answer_config_update + str(" \n CURRENT JSON running is ") + str(current_json) #current json

    content_correct = bool("content_start" in config_payload
                           and "content_end" in config_payload
                           and "configuration_update_modbus" in config_payload)

    if content_correct:  #elements of a correct config message exists
        try:

            received_json_string = config_payload.split(
                "content_start")[1].split("content_end")[0]
            received_json = json.loads(
                received_json_string
            )  #will not work, if a invalid json it throws an error

            received_json_checkresult, received_json_response, unused_json = modbus_json_check(
                dictio=received_json)

            if received_json_checkresult == True:

                answer_config_update = answer_config_update + str(
                    "\n Received JSON is valid")  #json is currently used
                if current_json != received_json:
                    novel_json_content = True
                    logger.debug(
                        "SUCCESS! Received a new, valid JSON. Will update an use:  {}"
                        .format(received_json))
                    result = "UPDATING"

                    # [Start UPDATE]
                    replacing_file_success, answer_update = execute_configuration_message(
                        received_json)  #use the new json
                    answer_config_update = answer_config_update + answer_update
                    # [End UPDATE]
                elif current_json == received_json:
                    answer_config_update = answer_config_update + str(
                        "\n CURRENT JSON is the SAME as received JSON, not changing setup "
                    )  #json is currently used
            elif received_json_checkresult == False:

                answer_config_update = answer_config_update + "\n received JSON is invalid: {} ".format(
                    received_json_response)
        except Exception as e:
            received_json_checkresult = False
            answer_config_update = answer_config_update + "\n ERROR content between content_start and content_end is not a JSON {} ".format(
                e)

    elif not content_correct:
        answer_config_update = answer_config_update + str(
            "\n  configuration_update_modbus, content_start, content_end is missing as header, not valid configuration"
        )

    if replacing_file_success:
        try:
            logger.debug("config about to be implemented ")

            scheduler_obj.stopkill()
            modbus_reader_obj.stopkill()
            logger.debug("stopped all, wait before starting up")
            time.sleep(3)
            logger.debug("starting modbus and scheduler back up")

            scheduler_obj.startup()
            modbus_reader_obj.startup()
            absolute_success_update = True
        except Exception as e:
            absolute_success_update = False
            result = result + "BUT FAILED"
        logger.debug("config implemented ")

    if not content_correct:
        result = " configuration_update_modbus, content_start, content_end is missing as header - NO Further Processing "
    elif not received_json_checkresult:
        result = "JSON between content_start and  content_end is invalid - NO Further Processing "
    elif not novel_json_content:
        result = "JSON sent already in use"
    else:
        # JSON was further Processed "

        if replacing_file_success:
            if absolute_success_update:
                result = "SUCCESS, using received_json {} ".format(
                    received_json)
            elif not absolute_success_update:
                result = "ERROR JSON was further processed and saved, but not implemented due to an error"
        if not replacing_file_success:
            result = "Fatal ERROR JSON was further processed, but writing failed"

    answer_config_update = answer_config_update + "\n  RESULT: {} \n".format(
        result)
    logger.info(answer_config_update)
    gmc.formatted_publish_message(topic=gmc.TOPIC_STATE,
                                  payload=answer_config_update,
                                  c_queue=publising_queue)

    return