Compare commits

..

4 Commits

Author SHA1 Message Date
Miguel 00f3b6d2ec Creado x7 para actualizar los valores 2025-05-17 23:54:50 +02:00
Miguel f76f593fef feat: Enhance S7_DB_Utils scripts with configuration loading and Excel documentation generation
- Added configuration loading functionality in x4.py and x5.py to retrieve working directory and other settings.
- Updated x4.py to print the working directory being used.
- Refactored error handling in log.txt to reflect successful execution and improved logging messages.
- Created detailed technical documentation for the parsed S7 data JSON format.
- Added a new script x6.py to generate Excel documentation for Data Blocks (DBs) from parsed JSON data.
- Implemented functions to format data types and flatten members for Excel export in x6.py.
- Improved directory structure documentation in readme.md for better clarity on project organization.
2025-05-17 21:32:11 +02:00
Miguel 884166b60e Add S7 data block and JSON documentation generator
- Created a new data block file `reconstructed_s7_source_stat.txt` containing structured data for HMI Blender parameters.
- Implemented a Python script `x5.py` to generate Markdown documentation from parsed S7 JSON data, including formatting for UDTs and DBs.
- The script includes functions for formatting data types, offsets, and generating tables for members, as well as handling current values and comments.
2025-05-17 14:48:28 +02:00
Miguel de5134920d Add initial implementation of Recipe Production and HMI Blender Parameters
- Introduced a new data type "Recipe_Prod" with various parameters related to production settings, including syrup properties, CO2 factors, and production rates.
- Created a data block "HMI_Blender_Parameters" to encapsulate processor options and settings for the blender, including various operational flags and parameters for different components.
- Initialized default values for recipe parameters and process setup configurations to ensure proper operation of the production system.
2025-05-17 14:31:37 +02:00
21 changed files with 1647 additions and 6053 deletions

View File

@ -0,0 +1,229 @@
# Technical Documentation: Parsed S7 Data JSON Format
Last Updated: 2025-05-17
## 1. Introduction
This document describes the structure and content of the JSON file generated by the S7 source parser (`x3.py`). The JSON file provides a detailed, structured representation of User Defined Types (UDTs) and Data Blocks (DBs) parsed from Siemens S7 source files (e.g., `.udt`, `.db` text exports).
The primary goal of this JSON format is to enable other processes, such as automated documentation generation, data analysis, HMI/SCADA integration, or source code reconstruction, by providing a consistent and machine-readable format of the S7 block data.
## 2. Overall JSON Structure
The root of the JSON file is an object containing two main keys:
* `"udts"`: An array of UDT definition objects.
* `"dbs"`: An array of DB definition objects.
```json
{
"udts": [ /* Array of UdtInfo objects */ ],
"dbs": [ /* Array of DbInfo objects */ ]
}
````
## 3\. UDT Definition Object (`UdtInfo`)
Each object in the `"udts"` array represents a single User Defined Type.
| Key | Type | Description | Presence |
| :-------------------- | :---------- | :-------------------------------------------------------------------------- | :---------- |
| `name` | String | The name of the UDT (e.g., "Recipe\_Prod"). | Mandatory |
| `family` | String | The family of the UDT as defined in the source (e.g., "DataType"). | Optional |
| `version` | String | The version of the UDT (e.g., "0.1"). | Optional |
| `total_size_in_bytes` | Integer | The total calculated size of the UDT in bytes, including any padding. | Mandatory |
| `members` | Array | An array of `VariableInfo` objects representing the members of this UDT. | Mandatory |
**Example `UdtInfo` Object:**
```json
{
"name": "MyUDT",
"family": "DataType",
"version": "1.0",
"total_size_in_bytes": 128,
"members": [
{
"name": "FirstMember",
"data_type": "INT",
"byte_offset": 0.0,
"size_in_bytes": 2,
"initial_value": "0",
"comment": "Initial counter"
/* ... more VariableInfo objects ... */
}
]
}
```
## 4\. DB Definition Object (`DbInfo`)
Each object in the `"dbs"` array represents a single Data Block.
| Key | Type | Description | Presence |
| :------------------------------------- | :---------- | :-------------------------------------------------------------------------------------------------------- | :---------- |
| `name` | String | The name of the DB (e.g., "HMI\_Blender\_Parameters"). | Mandatory |
| `title` | String | The `TITLE` property of the DB, often including S7 language settings (e.g., "{ S7\_language := '...' }"). | Optional |
| `family` | String | The family of the DB (e.g., "Resource"). | Optional |
| `version` | String | The version of the DB (e.g., "0.0"). | Optional |
| `total_size_in_bytes` | Integer | The total calculated size of the DB's declaration section in bytes, including padding. | Mandatory |
| `members` | Array | An array of `VariableInfo` objects representing the variables declared in the DB. | Mandatory |
| `_begin_block_assignments_ordered` | Array | An array of 2-element arrays (tuples) `[path_string, value_string]`, preserving the order of assignments from the `BEGIN` block. | Optional |
| `_initial_values_from_begin_block` | Object | A dictionary mapping full variable paths (String) to their assigned values (String) from the `BEGIN` block. Used by the parser to populate `current_value` and `current_element_values`. | Optional |
**Example `DbInfo` Object:**
```json
{
"name": "InstanceDB",
"title": "{ S7_language := 'English' }",
"family": "ApplicationData",
"version": "0.5",
"total_size_in_bytes": 256,
"members": [
{
"name": "MotorSpeed",
"data_type": "DINT",
"byte_offset": 0.0,
"size_in_bytes": 4,
"initial_value": "0",
"current_value": "1500"
/* ... more VariableInfo objects ... */
}
],
"_begin_block_assignments_ordered": [
["MotorSpeed", "1500"],
["Settings.Mode", "1"],
["Alarms[1]", "TRUE"]
],
"_initial_values_from_begin_block": {
"MotorSpeed": "1500",
"Settings.Mode": "1",
"Alarms[1]": "TRUE"
}
}
```
## 5\. Variable Information Object (`VariableInfo`)
This object is used for members within UDTs and DBs.
| Key | Type | Description | Presence |
| :------------------------- | :---------- | :---------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------- |
| `name` | String | Name of the variable/member. | Mandatory |
| `data_type` | String | The base S7 data type (e.g., "BOOL", "INT", "REAL", "STRING", "MyUDTName"). For UDT instances, this is the UDT name *without* quotes. | Mandatory |
| `byte_offset` | Float | The absolute byte offset from the start of the parent block (DB or UDT). For `BOOL` types, this is a float `X.Y` where `X` is the byte and `Y` is the bit number (0-7). | Mandatory |
| `size_in_bytes` | Integer | The size of this variable in bytes. For single `BOOL` types, this is `0`. For `BOOL` arrays, it's the number of bytes spanned by the array. | Mandatory |
| `bit_size` | Integer | The size of the variable in bits. Typically `1` for `BOOL` and `0` for byte-aligned types. | Optional (Defaults to 0) |
| `udt_source_name` | String | If `data_type` is a UDT, this field holds the original UDT name *with* quotes as found in the source (e.g., `"MyUDTName"`). | Optional (Present for UDTs) |
| `string_length` | Integer | For `STRING` types, the declared maximum length of the string (N in `STRING[N]`). The actual storage is N+2 bytes. | Optional (Present for STRINGs) |
| `array_dimensions` | Array | An array of `ArrayDimension` objects if the variable is an array. Empty if not an array. | Optional (Present for Arrays) |
| `initial_value` | String | The initial value assigned in the declaration part (e.g., `:= 10`, `:= 'text'`). Stored as a string. | Optional |
| `current_value` | String | The effective value of the variable after considering the `BEGIN` block assignments (for DBs) or the `initial_value` (for UDT members). Stored as a string. For arrays, this field might represent a global assignment if present, but individual element values are preferred in `current_element_values`. | Optional |
| `comment` | String | The line comment associated with the variable declaration. | Optional |
| `children` | Array | If this variable is a `STRUCT` or an instance of a UDT, this array contains `VariableInfo` objects for its members. For UDT instances, these are the *expanded* members of the UDT. | Optional (Present for STRUCTs/UDTs) |
| `is_udt_expanded_member` | Boolean | `true` if this `VariableInfo` object represents a member that was expanded from a UDT definition (i.e., it's a child of a UDT instance variable). `false` otherwise. | Optional (Defaults to `false`) |
| `current_element_values` | Object | For array variables in DBs, this dictionary stores the current values of individual array elements assigned in the `BEGIN` block. Keys are string representations of indices (e.g., "1", "1,0"), values are the assigned string values. | Optional (Present for Arrays in DBs with BEGIN block assignments) |
**Example `VariableInfo` Object (for an INT):**
```json
{
"name": "CycleCount",
"data_type": "INT",
"byte_offset": 10.0,
"size_in_bytes": 2,
"bit_size": 0,
"initial_value": "0",
"current_value": "123",
"comment": "Counts machine cycles",
"is_udt_expanded_member": false
}
```
**Example `VariableInfo` Object (for an Array of BOOLs in a DB):**
```json
{
"name": "StatusBits",
"data_type": "BOOL",
"byte_offset": 12.0,
"size_in_bytes": 2,
"bit_size": 1,
"array_dimensions": [
{ "lower_bound": 0, "upper_bound": 15, "count": 16 }
],
"is_udt_expanded_member": false,
"current_element_values": {
"0": "TRUE",
"5": "FALSE"
}
}
```
**Example `VariableInfo` Object (for a UDT instance in a DB):**
```json
{
"name": "MainRecipe",
"data_type": "Recipe_Prod",
"byte_offset": 100.0,
"size_in_bytes": 184,
"udt_source_name": "\"Recipe_Prod\"",
"is_udt_expanded_member": false,
"children": [
{
"name": "_Name",
"data_type": "STRING",
"byte_offset": 100.0,
"size_in_bytes": 34,
"string_length": 32,
"initial_value": "'Default Name'",
"current_value": "'Apple Pie Mix'",
"is_udt_expanded_member": true
/* ... other expanded members ... */
}
]
}
```
## 6\. Array Dimension Object (`ArrayDimension`)
Each object in the `array_dimensions` array of a `VariableInfo` object.
| Key | Type | Description | Presence |
| :------------ | :------ | :---------------------------------------- | :---------- |
| `lower_bound` | Integer | The lower bound of the array dimension. | Mandatory |
| `upper_bound` | Integer | The upper bound of the array dimension. | Mandatory |
| `count` | Integer | The number of elements in this dimension (`upper_bound - lower_bound + 1`). This is calculated and included by the parser. | Mandatory |
**Example `ArrayDimension` Object:**
```json
{
"lower_bound": 1,
"upper_bound": 10,
"count": 10
}
```
For a multi-dimensional array like `ARRAY [1..2, 0..4] OF ...`, the `array_dimensions` key in `VariableInfo` would be:
```json
"array_dimensions": [
{ "lower_bound": 1, "upper_bound": 2, "count": 2 },
{ "lower_bound": 0, "upper_bound": 4, "count": 5 }
]
```
## 7\. Data Interpretation Notes
* **Offsets**: `byte_offset` is always absolute from the start of its containing UDT or DB. For `BOOL`s, the fractional part indicates the bit number (e.g., `34.0` is byte 34, bit 0; `34.7` is byte 34, bit 7).
* **`current_value` vs. `initial_value`**:
* For UDT members (when describing the UDT definition itself), `current_value` is not typically relevant as UDTs are type definitions. Their `initial_value` from the UDT declaration is the primary value.
* For DB members, `initial_value` is from the declaration section. `current_value` reflects the value after considering the `BEGIN` block assignments. If a variable is not mentioned in the `BEGIN` block, its `current_value` will typically be its `initial_value`.
* **`current_element_values` for Arrays**: This field in `VariableInfo` (for DB arrays) provides specific values for array elements that were explicitly assigned in the `BEGIN` block. The keys are strings representing the index (or comma-separated indices for multi-dimensional arrays) as found in the S7 source's `BEGIN` block (e.g., "1", "0,15").
* **`_begin_block_assignments_ordered` in `DbInfo`**: This array of `[path_string, value_string]` tuples is the most reliable source for reconstructing the `BEGIN` block in its original order. The `path_string` can be hierarchical (e.g., `MyStruct.MyArray[1]._Member`).
* **String Values**: String literals (e.g., initial values for `STRING` types) are typically enclosed in single quotes in the JSON, mirroring S7 syntax (e.g., `'My Text'`).
* **Boolean Values**: Boolean values in `initial_value`, `current_value`, or values within `current_element_values` and `_begin_block_assignments_ordered` are stored as strings "TRUE" or "FALSE" (or potentially raw `true`/`false` if the parser output Python booleans, which should then be interpreted as S7 `TRUE`/`FALSE`). The parser (`x3.py`) should aim to store them as "TRUE"/"FALSE" strings for consistency.

View File

@ -1,550 +0,0 @@
DATA_BLOCK "HMI_Blender_Parameters"
TITLE =
{ S7_language := '28(1) Albanese 15.06.2005 17:07:04' }
FAMILY : Resource
VERSION : 0.0
STRUCT
STAT0 : STRUCT
STAT1 : STRUCT
STAT2 : INT := 6;
STAT3 : REAL := 2.000000e-01;
STAT4 : REAL := 8.000000e-01;
STAT5 : BOOL := TRUE;
STAT6 : BOOL ;
STAT7 : BOOL ;
STAT8 : BOOL ;
STAT9 : BOOL ;
STAT10 : BOOL ;
STAT11 : BOOL := TRUE;
STAT12 : BOOL ;
STAT13 : BOOL := TRUE;
STAT14 : BOOL ;
STAT15 : BOOL ;
STAT16 : BOOL ;
STAT17 : BOOL ;
STAT18 : BOOL := TRUE;
STAT19 : BOOL ;
STAT20 : BOOL ;
STAT21 : INT := 6;
STAT22 : BOOL ;
STAT23 : BOOL ;
STAT24 : BOOL ;
STAT25 : BOOL ;
STAT26 : BOOL ;
STAT27 : BOOL := TRUE;
STAT28 : BOOL := TRUE;
STAT29 : INT := 1;
STAT30 : BOOL := TRUE;
STAT31 : INT := 4;
STAT32 : INT ;
STAT33 : BOOL ;
STAT34 : BOOL ;
STAT35 : BOOL ;
STAT36 : BOOL ;
STAT37 : BOOL ;
STAT38 : BOOL := TRUE;
STAT39 : BOOL ;
STAT40 : BOOL ;
STAT41 : BOOL := TRUE;
STAT42 : BOOL ;
STAT43 : BOOL := TRUE;
STAT44 : BOOL ;
STAT45 : BOOL := TRUE;
STAT46 : BOOL ;
STAT47 : BOOL ;
STAT48 : BOOL := TRUE;
STAT49 : INT ;
STAT50 : INT := 2;
STAT51 : BOOL := TRUE;
STAT52 : BOOL ;
STAT53 : BOOL ;
STAT54 : BOOL ;
STAT55 : BOOL ;
STAT56 : BOOL ;
STAT57 : BOOL ;
STAT58 : BOOL := TRUE;
STAT59 : BOOL ;
STAT60 : BOOL ;
STAT61 : BOOL ;
STAT62 : BOOL ;
STAT63 : BOOL ;
STAT64 : BOOL := TRUE;
STAT65 : BOOL ;
STAT66 : BOOL ;
STAT67 : INT := 1;
STAT68 : INT ;
STAT69 : INT := 1;
STAT70 : INT ;
STAT71 : INT ;
STAT72 : INT := 6;
END_STRUCT ;
END_STRUCT ;
STAT73 : ARRAY [1 .. 9 ] OF INT ;
STAT74 : REAL := 5.000000e-02;
STAT75 : REAL := 6.500000e+01;
STAT76 : STRUCT
STAT77 : STRING [32 ] := ' ';
STAT78 : BOOL ;
STAT79 : BOOL ;
STAT80 : BOOL ;
STAT81 : BOOL ;
STAT82 : BOOL ;
STAT83 : BOOL ;
STAT84 : BOOL ;
STAT85 : BOOL ;
STAT86 : BYTE ;
STAT87 : BYTE ;
STAT88 : BYTE ;
STAT89 : INT := 1;
STAT90 : INT ;
STAT91 : REAL := 5.000000e+01;
STAT92 : REAL := 1.255800e+00;
STAT93 : REAL := 1.000000e+00;
STAT94 : REAL := 1.045000e+01;
STAT95 : REAL := 9.000000e+02;
STAT96 : REAL := 2.000000e+01;
STAT97 : REAL ;
STAT98 : REAL ;
STAT99 : REAL := 1.000000e+00;
STAT100 : REAL := 1.000000e+00;
STAT101 : REAL := 1.000000e+01;
STAT102 : REAL := 1.000000e+01;
STAT103 : REAL ;
STAT104 : REAL ;
STAT105 : REAL ;
STAT106 : REAL ;
STAT107 : REAL ;
STAT108 : REAL ;
STAT109 : REAL ;
STAT110 : REAL ;
STAT111 : REAL ;
STAT112 : REAL ;
STAT113 : REAL ;
STAT114 : REAL ;
STAT115 : REAL ;
STAT116 : REAL ;
STAT117 : REAL := 9.700000e-01;
STAT118 : REAL ;
STAT119 : REAL := 1.000000e+00;
STAT120 : REAL ;
STAT121 : REAL ;
STAT122 : INT ;
STAT123 : REAL ;
STAT124 : REAL ;
STAT125 : REAL ;
STAT126 : REAL ;
END_STRUCT ;
STAT127 : ARRAY [1 .. 5 ] OF INT ;
STAT128 : STRING [32 ] := ' ';
STAT129 : INT ;
STAT130 : ARRAY [1 .. 18 ] OF INT ;
STAT131 : STRUCT
STAT132 : REAL ;
STAT133 : REAL ;
STAT134 : REAL := 1.580000e-03;
STAT135 : REAL := 9.000000e-03;
STAT136 : REAL := 1.700000e-02;
STAT137 : REAL := 5.700000e+00;
STAT138 : REAL := 2.000000e+00;
STAT139 : REAL := 2.000000e+00;
STAT140 : REAL := 1.000000e+01;
STAT141 : REAL := 1.000000e+01;
STAT142 : REAL := 1.000000e+01;
STAT143 : REAL := 6.000000e+01;
STAT144 : REAL := 5.000000e+01;
STAT145 : REAL := 2.500000e+01;
STAT146 : REAL := 6.500000e+01;
STAT147 : REAL := 1.200000e+01;
STAT148 : REAL := 1.000000e+01;
STAT149 : REAL ;
STAT150 : REAL := 3.000000e+01;
STAT151 : REAL := 1.000000e+00;
STAT152 : REAL := 5.000000e+00;
STAT153 : REAL := 5.000000e+00;
STAT154 : REAL := 1.000000e+02;
STAT155 : REAL := 2.000000e+02;
STAT156 : REAL := 2.000000e+01;
STAT157 : REAL := 2.000000e+01;
STAT158 : REAL := 2.000000e+01;
STAT159 : INT := 1;
STAT160 : REAL := 2.000000e+01;
STAT161 : REAL := 7.000000e-01;
STAT162 : REAL := 4.250000e+02;
STAT163 : REAL := 2.550000e+03;
STAT164 : REAL := 9.000000e+00;
STAT165 : REAL ;
STAT166 : REAL := 1.600000e+03;
STAT167 : REAL := 2.000000e+01;
STAT168 : REAL := 1.400000e+01;
STAT169 : REAL := 1.610000e+03;
STAT170 : REAL := 2.877000e+03;
STAT171 : INT := 80;
STAT172 : REAL := 8.000000e+01;
STAT173 : REAL := 9.000000e+01;
STAT174 : REAL := 4.000000e+00;
STAT175 : REAL := 1.020000e+03;
STAT176 : REAL := 1.000000e+02;
STAT177 : REAL := 2.300000e+03;
STAT178 : REAL := 7.500000e-01;
STAT179 : REAL := 5.000000e-01;
STAT180 : REAL := 3.000000e-02;
STAT181 : REAL := 1.400000e-03;
STAT182 : REAL ;
STAT183 : WORD := W#16#6;
STAT184 : WORD := W#16#50;
STAT185 : WORD := W#16#1;
STAT186 : REAL := 3.000000e+01;
STAT187 : REAL := 4.000000e+01;
STAT188 : REAL := 9.000000e+01;
STAT189 : REAL := 2.500000e+02;
STAT190 : REAL := 5.500000e-01;
STAT191 : REAL := 4.000000e-01;
STAT192 : REAL := 9.000000e-01;
STAT193 : REAL := 1.500000e+01;
STAT194 : REAL := 4.500000e+01;
STAT195 : REAL := 5.000000e+01;
STAT196 : REAL := 4.000000e+00;
STAT197 : REAL := 2.000000e+01;
STAT198 : REAL := 5.000000e+00;
STAT199 : REAL := 5.000000e+00;
STAT200 : REAL := 5.000000e+00;
STAT201 : REAL := 5.000000e+00;
STAT202 : REAL := 1.000000e+01;
STAT203 : REAL ;
STAT204 : REAL := 1.150000e+02;
STAT205 : REAL := 1.650000e+02;
STAT206 : REAL := 2.600000e+02;
STAT207 : REAL := 1.650000e+02;
STAT208 : REAL := 6.700000e+01;
STAT209 : INT := 50;
STAT210 : REAL := 9.000000e+01;
STAT211 : REAL := 8.700000e+01;
STAT212 : REAL := 5.070000e+02;
STAT213 : REAL := 2.110000e+02;
STAT214 : REAL := 8.600000e+01;
STAT215 : REAL := 8.500000e+01;
STAT216 : REAL := 1.150000e+02;
STAT217 : REAL := 3.200000e+01;
STAT218 : REAL := 5.000000e+00;
STAT219 : REAL := 5.000000e+00;
STAT220 : REAL ;
STAT221 : REAL ;
STAT222 : REAL ;
STAT223 : REAL ;
STAT224 : REAL := 1.800000e+01;
STAT225 : REAL := 2.000000e+00;
STAT226 : REAL := 2.000000e+00;
STAT227 : REAL := 5.000000e+01;
STAT228 : REAL := 5.000000e+01;
STAT229 : DINT := L#1500;
STAT230 : DINT := L#1500;
STAT231 : DINT := L#1000;
STAT232 : DINT := L#1000;
STAT233 : INT := 30;
STAT234 : INT := 30;
STAT235 : INT := 10;
STAT236 : INT := 10;
STAT237 : INT := 10;
STAT238 : REAL := 3.500000e+02;
STAT239 : INT := 30;
STAT240 : INT := 30;
STAT241 : INT := 30;
STAT242 : INT := 30;
STAT243 : INT := 30;
STAT244 : INT := 30;
STAT245 : INT := 30;
STAT246 : INT := 30;
STAT247 : REAL := 3.000000e+01;
STAT248 : REAL := 3.000000e+01;
STAT249 : REAL ;
STAT250 : REAL ;
STAT251 : REAL ;
STAT252 : REAL := 5.000000e+01;
END_STRUCT ;
STAT253 : BOOL ;
STAT254 : REAL ;
END_STRUCT ;
BEGIN
STAT0.STAT1.STAT2 := 6;
STAT0.STAT1.STAT3 := 4.500000e-01;
STAT0.STAT1.STAT4 := 8.000000e-01;
STAT0.STAT1.STAT5 := TRUE;
STAT0.STAT1.STAT6 := FALSE;
STAT0.STAT1.STAT7 := FALSE;
STAT0.STAT1.STAT8 := FALSE;
STAT0.STAT1.STAT9 := TRUE;
STAT0.STAT1.STAT10 := FALSE;
STAT0.STAT1.STAT11 := TRUE;
STAT0.STAT1.STAT12 := FALSE;
STAT0.STAT1.STAT13 := TRUE;
STAT0.STAT1.STAT14 := FALSE;
STAT0.STAT1.STAT15 := FALSE;
STAT0.STAT1.STAT16 := FALSE;
STAT0.STAT1.STAT17 := FALSE;
STAT0.STAT1.STAT18 := TRUE;
STAT0.STAT1.STAT19 := FALSE;
STAT0.STAT1.STAT20 := FALSE;
STAT0.STAT1.STAT21 := 6;
STAT0.STAT1.STAT22 := FALSE;
STAT0.STAT1.STAT23 := FALSE;
STAT0.STAT1.STAT24 := FALSE;
STAT0.STAT1.STAT25 := TRUE;
STAT0.STAT1.STAT26 := FALSE;
STAT0.STAT1.STAT27 := TRUE;
STAT0.STAT1.STAT28 := TRUE;
STAT0.STAT1.STAT29 := 1;
STAT0.STAT1.STAT30 := TRUE;
STAT0.STAT1.STAT31 := 4;
STAT0.STAT1.STAT32 := 0;
STAT0.STAT1.STAT33 := FALSE;
STAT0.STAT1.STAT34 := FALSE;
STAT0.STAT1.STAT35 := FALSE;
STAT0.STAT1.STAT36 := FALSE;
STAT0.STAT1.STAT37 := FALSE;
STAT0.STAT1.STAT38 := TRUE;
STAT0.STAT1.STAT39 := FALSE;
STAT0.STAT1.STAT40 := FALSE;
STAT0.STAT1.STAT41 := TRUE;
STAT0.STAT1.STAT42 := FALSE;
STAT0.STAT1.STAT43 := TRUE;
STAT0.STAT1.STAT44 := FALSE;
STAT0.STAT1.STAT45 := TRUE;
STAT0.STAT1.STAT46 := FALSE;
STAT0.STAT1.STAT47 := FALSE;
STAT0.STAT1.STAT48 := TRUE;
STAT0.STAT1.STAT49 := 0;
STAT0.STAT1.STAT50 := 2;
STAT0.STAT1.STAT51 := TRUE;
STAT0.STAT1.STAT52 := FALSE;
STAT0.STAT1.STAT53 := FALSE;
STAT0.STAT1.STAT54 := FALSE;
STAT0.STAT1.STAT55 := FALSE;
STAT0.STAT1.STAT56 := FALSE;
STAT0.STAT1.STAT57 := FALSE;
STAT0.STAT1.STAT58 := TRUE;
STAT0.STAT1.STAT59 := TRUE;
STAT0.STAT1.STAT60 := FALSE;
STAT0.STAT1.STAT61 := FALSE;
STAT0.STAT1.STAT62 := FALSE;
STAT0.STAT1.STAT63 := FALSE;
STAT0.STAT1.STAT64 := TRUE;
STAT0.STAT1.STAT65 := FALSE;
STAT0.STAT1.STAT66 := FALSE;
STAT0.STAT1.STAT67 := 1;
STAT0.STAT1.STAT68 := 0;
STAT0.STAT1.STAT69 := 1;
STAT0.STAT1.STAT70 := 0;
STAT0.STAT1.STAT71 := 0;
STAT0.STAT1.STAT72 := 6;
STAT73[1] := 0;
STAT73[2] := 0;
STAT73[3] := 0;
STAT73[4] := 0;
STAT73[5] := 0;
STAT73[6] := 0;
STAT73[7] := 0;
STAT73[8] := 0;
STAT73[9] := 0;
STAT74 := 5.000000e-02;
STAT75 := 9.000000e+01;
STAT76.STAT77 := '';
STAT76.STAT78 := TRUE;
STAT76.STAT79 := FALSE;
STAT76.STAT80 := FALSE;
STAT76.STAT81 := FALSE;
STAT76.STAT82 := FALSE;
STAT76.STAT83 := TRUE;
STAT76.STAT84 := FALSE;
STAT76.STAT85 := FALSE;
STAT76.STAT86 := B#16#0;
STAT76.STAT87 := B#16#14;
STAT76.STAT88 := B#16#0;
STAT76.STAT89 := 2;
STAT76.STAT90 := 1;
STAT76.STAT91 := 3.935000e+01;
STAT76.STAT92 := 1.166600e+00;
STAT76.STAT93 := 1.000000e+00;
STAT76.STAT94 := 8.600000e+00;
STAT76.STAT95 := 2.500000e-01;
STAT76.STAT96 := 3.934034e+00;
STAT76.STAT97 := 4.000000e-01;
STAT76.STAT98 := 2.500000e+00;
STAT76.STAT99 := 9.000000e-01;
STAT76.STAT100 := 3.500000e+00;
STAT76.STAT101 := 1.600000e+01;
STAT76.STAT102 := 3.500000e+01;
STAT76.STAT103 := 0.000000e+00;
STAT76.STAT104 := 0.000000e+00;
STAT76.STAT105 := 0.000000e+00;
STAT76.STAT106 := 8.800000e+00;
STAT76.STAT107 := 8.400000e+00;
STAT76.STAT108 := 2.800000e+00;
STAT76.STAT109 := 2.200000e+00;
STAT76.STAT110 := 0.000000e+00;
STAT76.STAT111 := 0.000000e+00;
STAT76.STAT112 := 0.000000e+00;
STAT76.STAT113 := 0.000000e+00;
STAT76.STAT114 := 0.000000e+00;
STAT76.STAT115 := 0.000000e+00;
STAT76.STAT116 := 0.000000e+00;
STAT76.STAT117 := 8.500000e-01;
STAT76.STAT118 := 0.000000e+00;
STAT76.STAT119 := 0.000000e+00;
STAT76.STAT120 := 0.000000e+00;
STAT76.STAT121 := 0.000000e+00;
STAT76.STAT122 := 0;
STAT76.STAT123 := 0.000000e+00;
STAT76.STAT124 := 0.000000e+00;
STAT76.STAT125 := 0.000000e+00;
STAT76.STAT126 := 0.000000e+00;
STAT127[1] := 0;
STAT127[2] := 0;
STAT127[3] := 0;
STAT127[4] := 0;
STAT127[5] := 0;
STAT128 := '';
STAT129 := 0;
STAT130[1] := 0;
STAT130[2] := 0;
STAT130[3] := 0;
STAT130[4] := 0;
STAT130[5] := 0;
STAT130[6] := 0;
STAT130[7] := 0;
STAT130[8] := 0;
STAT130[9] := 0;
STAT130[10] := 0;
STAT130[11] := 0;
STAT130[12] := 0;
STAT130[13] := 0;
STAT130[14] := 0;
STAT130[15] := 0;
STAT130[16] := 0;
STAT130[17] := 0;
STAT130[18] := 0;
STAT131.STAT132 := 0.000000e+00;
STAT131.STAT133 := 0.000000e+00;
STAT131.STAT134 := 1.000000e-03;
STAT131.STAT135 := 7.800000e-03;
STAT131.STAT136 := 1.390000e-02;
STAT131.STAT137 := 5.700000e+00;
STAT131.STAT138 := 2.000000e+00;
STAT131.STAT139 := 2.200000e+00;
STAT131.STAT140 := 2.100000e+01;
STAT131.STAT141 := 2.000000e+01;
STAT131.STAT142 := 5.000000e+00;
STAT131.STAT143 := 6.000000e+01;
STAT131.STAT144 := 5.000000e+01;
STAT131.STAT145 := 2.500000e+01;
STAT131.STAT146 := 4.000000e+01;
STAT131.STAT147 := 2.400000e+01;
STAT131.STAT148 := 1.400000e+01;
STAT131.STAT149 := 3.000000e-01;
STAT131.STAT150 := 3.000000e+01;
STAT131.STAT151 := 1.000000e+00;
STAT131.STAT152 := 4.000000e+00;
STAT131.STAT153 := 2.000000e+00;
STAT131.STAT154 := 1.000000e+02;
STAT131.STAT155 := 5.000000e+02;
STAT131.STAT156 := 5.000000e+01;
STAT131.STAT157 := 8.000000e+00;
STAT131.STAT158 := 1.900000e+01;
STAT131.STAT159 := 1;
STAT131.STAT160 := 2.000000e+02;
STAT131.STAT161 := 5.000000e-01;
STAT131.STAT162 := 4.500000e+02;
STAT131.STAT163 := 2.500000e+03;
STAT131.STAT164 := 1.220000e+01;
STAT131.STAT165 := 1.000000e+00;
STAT131.STAT166 := 3.950000e+02;
STAT131.STAT167 := -2.500000e+01;
STAT131.STAT168 := 3.618000e+01;
STAT131.STAT169 := 1.400000e+03;
STAT131.STAT170 := 2.520000e+03;
STAT131.STAT171 := 91;
STAT131.STAT172 := 1.000000e+02;
STAT131.STAT173 := 1.600000e+02;
STAT131.STAT174 := 3.200000e+00;
STAT131.STAT175 := 1.050000e+03;
STAT131.STAT176 := 4.600000e+01;
STAT131.STAT177 := 1.625000e+03;
STAT131.STAT178 := 1.000000e+00;
STAT131.STAT179 := 1.300000e+00;
STAT131.STAT180 := 4.090000e-02;
STAT131.STAT181 := 1.400000e-03;
STAT131.STAT182 := 4.500000e+02;
STAT131.STAT183 := W#16#0;
STAT131.STAT184 := W#16#78;
STAT131.STAT185 := W#16#1;
STAT131.STAT186 := 3.000000e+01;
STAT131.STAT187 := 4.000000e+01;
STAT131.STAT188 := 3.000000e+01;
STAT131.STAT189 := 5.000000e+00;
STAT131.STAT190 := 4.900000e-01;
STAT131.STAT191 := 3.000000e-01;
STAT131.STAT192 := 9.000000e-01;
STAT131.STAT193 := 1.500000e+01;
STAT131.STAT194 := 3.500000e+01;
STAT131.STAT195 := 5.000000e+01;
STAT131.STAT196 := 4.000000e+00;
STAT131.STAT197 := 2.000000e+01;
STAT131.STAT198 := 5.000000e+00;
STAT131.STAT199 := 5.000000e+00;
STAT131.STAT200 := 5.000000e+00;
STAT131.STAT201 := 5.000000e+00;
STAT131.STAT202 := 6.000000e+01;
STAT131.STAT203 := 0.000000e+00;
STAT131.STAT204 := 1.500000e+02;
STAT131.STAT205 := 1.650000e+02;
STAT131.STAT206 := 2.600000e+02;
STAT131.STAT207 := 1.650000e+02;
STAT131.STAT208 := 6.700000e+01;
STAT131.STAT209 := 300;
STAT131.STAT210 := 9.000000e+01;
STAT131.STAT211 := 8.700000e+01;
STAT131.STAT212 := 5.070000e+02;
STAT131.STAT213 := 2.110000e+02;
STAT131.STAT214 := 8.600000e+01;
STAT131.STAT215 := 8.500000e+01;
STAT131.STAT216 := 1.150000e+02;
STAT131.STAT217 := 3.200000e+01;
STAT131.STAT218 := 5.000000e+00;
STAT131.STAT219 := 5.000000e+00;
STAT131.STAT220 := 0.000000e+00;
STAT131.STAT221 := 0.000000e+00;
STAT131.STAT222 := 0.000000e+00;
STAT131.STAT223 := 0.000000e+00;
STAT131.STAT224 := 2.000000e+01;
STAT131.STAT225 := 5.000000e+00;
STAT131.STAT226 := 1.000000e+01;
STAT131.STAT227 := 5.000000e+01;
STAT131.STAT228 := 5.000000e+01;
STAT131.STAT229 := L#1500;
STAT131.STAT230 := L#1500;
STAT131.STAT231 := L#1000;
STAT131.STAT232 := L#1000;
STAT131.STAT233 := 30;
STAT131.STAT234 := 30;
STAT131.STAT235 := 10;
STAT131.STAT236 := 10;
STAT131.STAT237 := 10;
STAT131.STAT238 := 3.500000e+02;
STAT131.STAT239 := 30;
STAT131.STAT240 := 30;
STAT131.STAT241 := 30;
STAT131.STAT242 := 30;
STAT131.STAT243 := 30;
STAT131.STAT244 := 30;
STAT131.STAT245 := 30;
STAT131.STAT246 := 30;
STAT131.STAT247 := 3.000000e+01;
STAT131.STAT248 := 3.000000e+01;
STAT131.STAT249 := 0.000000e+00;
STAT131.STAT250 := 0.000000e+00;
STAT131.STAT251 := 0.000000e+00;
STAT131.STAT252 := 5.000000e+01;
STAT253 := FALSE;
STAT254 := 0.000000e+00;
END_DATA_BLOCK

View File

@ -1,467 +0,0 @@
Address;Name;;Type;Initial value;Actual value;Comment
0.0;Processor_Options.Blender_OPT._ModelNum;;INT;6;6;
2.0;Processor_Options.Blender_OPT._CO2_Offset;;REAL;4.500000e-01;4.500000e-01;
6.0;Processor_Options.Blender_OPT._MaxSyrDeltaBrix;;REAL;8.000000e-01;8.000000e-01;
10.0;Processor_Options.Blender_OPT._BrixMeter;;BOOL;TRUE;TRUE;
10.1;Processor_Options.Blender_OPT.Spare101;;BOOL;FALSE;FALSE;
10.2;Processor_Options.Blender_OPT._TrackH2OEnable;;BOOL;FALSE;FALSE;
10.3;Processor_Options.Blender_OPT._PAmPDSType;;BOOL;FALSE;FALSE;"0)Cobrix 200
0 1)Carbo 2 000"
10.4;Processor_Options.Blender_OPT._HistoricalTrends;;BOOL;TRUE;TRUE;"0)Not Presen
t 1)Present"
10.5;Processor_Options.Blender_OPT._PowerMeter;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
10.6;Processor_Options.Blender_OPT._Report;;BOOL;TRUE;TRUE;"0)Not Presen
t 1)Present"
10.7;Processor_Options.Blender_OPT._Balaiage;;BOOL;FALSE;FALSE;
11.0;Processor_Options.Blender_OPT._Valves_FullFeedback;;BOOL;TRUE;TRUE;"Valves contr
ol Full feed back"
11.1;Processor_Options.Blender_OPT._Valves_SingleFeedback;;BOOL;FALSE;FALSE;"Valves contr
ol Single fe edback"
11.2;Processor_Options.Blender_OPT._PumpsSafetySwitches;;BOOL;FALSE;FALSE;"Pumps with S
afety Switch es"
11.3;Processor_Options.Blender_OPT._SurgeProtectionAct;;BOOL;FALSE;FALSE;
11.4;Processor_Options.Blender_OPT._DBC_Type;;BOOL;FALSE;FALSE;"0) Deox,Carb
o,Blend 1)D eox,Blend,Ca rbo"
11.5;Processor_Options.Blender_OPT._CO2InletMeter;;BOOL;TRUE;TRUE;"0)Not Presen
t 1)Present"
11.6;Processor_Options.Blender_OPT._ProductO2Meter;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
11.7;Processor_Options.Blender_OPT._CopressedAirInletMeter;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
12.0;Processor_Options.Blender_OPT._MeterType;;INT;6;6;"1)Maselli 2)
AntoonPaar 3
)4-20mA 4)UC 05 UR22 5)mP DSPA 6)MR02"
14.0;Processor_Options.Blender_OPT._MeterReceiveOnly;;BOOL;FALSE;FALSE;
14.1;Processor_Options.Blender_OPT._SyrBrixMeter;;BOOL;FALSE;FALSE;
14.2;Processor_Options.Blender_OPT._Flooding_Start_Up;;BOOL;FALSE;FALSE;"0)Not Select
ed 1)Sele cted"
14.3;Processor_Options.Blender_OPT._FastChangeOverEnabled;;BOOL;TRUE;TRUE;
14.4;Processor_Options.Blender_OPT._WaterInletMeter;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
14.5;Processor_Options.Blender_OPT._BlendFillSystem;;BOOL;TRUE;TRUE;
14.6;Processor_Options.Blender_OPT._TrackFillerSpeed;;BOOL;TRUE;TRUE;
16.0;Processor_Options.Blender_OPT._SignalExchange;;INT;1;1;"FILLER - 0=
Hardwire; 1= Ethernet"
18.0;Processor_Options.Blender_OPT._CoolerPresent;;BOOL;TRUE;TRUE;
20.0;Processor_Options.Blender_OPT._CoolerControl;;INT;4;4;"0)External 1
)Water 2)Pro duct 3)Water
+Product-2 C trl 4)Water+ Product-1 Ct
rl"
22.0;Processor_Options.Blender_OPT._CoolerType;;INT;0;0;"0)Glycol 1)A
mmonia"
24.0;Processor_Options.Blender_OPT._LocalCIP;;BOOL;FALSE;FALSE;
24.1;Processor_Options.Blender_OPT._ICS_CustomerHotWater;;BOOL;FALSE;FALSE;"0)No Hot Wat
er from Cust omer 1)Hot W ater from Cu stomer Avail able"
24.2;Processor_Options.Blender_OPT._ICS_CustomerChemRecov;;BOOL;FALSE;FALSE;"0)No Custome
r's Chemical s Recovery 1
)Customer's Chemicals Re covery Avail
able"
24.3;Processor_Options.Blender_OPT._CIPSignalExchange;;BOOL;FALSE;FALSE;"CIP - 0= Har
dwire; 1= Et hernet"
24.4;Processor_Options.Blender_OPT._ICS_CustomerChemicals;;BOOL;FALSE;FALSE;"0)Chemicals
from ICS 1)C hemicals fro m Customer"
24.5;Processor_Options.Blender_OPT._CarboPresent;;BOOL;TRUE;TRUE;
24.6;Processor_Options.Blender_OPT._InverterSyrupPumpPPP302;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
24.7;Processor_Options.Blender_OPT._InverterWaterPumpPPN301;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
25.0;Processor_Options.Blender_OPT._DoubleDeair;;BOOL;TRUE;TRUE;
25.1;Processor_Options.Blender_OPT._DeairPreMixed;;BOOL;FALSE;FALSE;"Deox Premixe
d Inlet"
25.2;Processor_Options.Blender_OPT._Deaireation;;BOOL;TRUE;TRUE;"0)SAG 1)SAE/
SAF"
25.3;Processor_Options.Blender_OPT._StillWaterByPass;;BOOL;FALSE;FALSE;
25.4;Processor_Options.Blender_OPT._ManifoldSetting;;BOOL;TRUE;TRUE;"0)Manual 1)A
utomatic"
25.5;Processor_Options.Blender_OPT._InverterProdPumpPPM303;;BOOL;FALSE;FALSE;
25.6;Processor_Options.Blender_OPT._SidelCip;;BOOL;FALSE;FALSE;
25.7;Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP;;BOOL;TRUE;TRUE;"0)Comunicati
on with CP 1)Comunicat
ion with CPU
PN"
26.0;Processor_Options.Blender_OPT._2ndOutlet;;INT;0;0;"0)No 2nd Out
let 1)2nd O utlet No Sta ndalone 2)2 nd Outlet St andalone"
28.0;Processor_Options.Blender_OPT._Promass;;INT;2;2;
30.0;Processor_Options.Blender_OPT._WaterPromass;;BOOL;TRUE;TRUE;"0)Promag 1)P
romass"
30.1;Processor_Options.Blender_OPT._ProductConductimeter;;BOOL;FALSE;FALSE;
30.2;Processor_Options.Blender_OPT._ICS_CustomerH2ORecov;;BOOL;FALSE;FALSE;"0)No Custome
r's H2O Reco very 1)Custo mer's H2O Re covery Avail able"
30.3;Processor_Options.Blender_OPT.Spare303;;BOOL;FALSE;FALSE;
30.4;Processor_Options.Blender_OPT._CO2_GAS2_Injection;;BOOL;FALSE;FALSE;"0)Only CO2 I
njection 1)G AS2 Injectio n"
30.5;Processor_Options.Blender_OPT._InverterVacuuPumpPPN304;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
30.6;Processor_Options.Blender_OPT._InverterBoostPumpPPM307;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
30.7;Processor_Options.Blender_OPT._RunOut_Water;;BOOL;TRUE;TRUE;"0)Syrup Runo
ut without W ater 1)Syrup runout with Water pushi
ng"
31.0;Processor_Options.Blender_OPT._FlowMeterType;;BOOL;FALSE;TRUE;"0)Endrees Ha
user -- 1)Mi cromotion"
31.1;Processor_Options.Blender_OPT._SidelFiller;;BOOL;FALSE;FALSE;"0)Filler Sim
onazzi -- 1)Filler Sid el Filling"
31.2;Processor_Options.Blender_OPT._Simulation;;BOOL;FALSE;FALSE;
31.3;Processor_Options.Blender_OPT._ProductCoolingCTRL;;BOOL;FALSE;FALSE;"0)none 1) TT
M307"
31.4;Processor_Options.Blender_OPT._ChillerCTRL;;BOOL;FALSE;FALSE;"Chiller Pres
sure Cross C ontrol"
31.5;Processor_Options.Blender_OPT._CO2_SterileFilter;;BOOL;TRUE;TRUE;"CO2 Inlet wi
th Steril Fi lter"
31.6;Processor_Options.Blender_OPT._InverterRecirPumpPPM306;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
31.7;Processor_Options.Blender_OPT._ProdPressReleaseRVM304;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
32.0;Processor_Options.Blender_OPT._VacuumPump;;INT;1;1;"0)None 1)Ste
rling 2)Nash Elmo"
34.0;Processor_Options.Blender_OPT._GAS2InjectionType;;INT;0;0;"0)None 1)N2
2)Steril Air"
36.0;Processor_Options.Blender_OPT._InjectionPress_Ctrl;;INT;1;1;"0)Manual 1)N
orgren v1 2) Norgren v2"
38.0;Processor_Options.Blender_OPT._ProdPressureType;;INT;0;0;"0)Only CO2 1
)CO2+SterilA ir 2)CO2+N2"
40.0;Processor_Options.Blender_OPT._CIPHeatType;;INT;0;0;"0)Steam 1)El
ectric"
42.0;Processor_Options.Blender_OPT._EHS_NrRes;;INT;6;6;"Number of He
at Resistanc es"
44.0;Spare1[1];;INT;0;0;
46.0;Spare1[2];;INT;0;0;
48.0;Spare1[3];;INT;0;0;
50.0;Spare1[4];;INT;0;0;
52.0;Spare1[5];;INT;0;0;
54.0;Spare1[6];;INT;0;0;
56.0;Spare1[7];;INT;0;0;
58.0;Spare1[8];;INT;0;0;
60.0;Spare1[9];;INT;0;0;
62.0;_RVM301_DeadBand;;REAL;5.000000e-02;5.000000e-02;
66.0;_RVM301_Kp;;REAL;9.000000e+01;9.000000e+01;
70.0;Actual_Recipe_Parameters._Name;;STRING [ 32 ];"'
'";'';
104.0;Actual_Recipe_Parameters._EnProdTemp;;BOOL;FALSE;TRUE;
104.1;Actual_Recipe_Parameters._SyrFlushing;;BOOL;FALSE;FALSE;"Ex_EnDeairea
tion --> DEL ETED - AVP32
0 VALVE OPEN"
104.2;Actual_Recipe_Parameters._GAS2_Injection;;BOOL;FALSE;FALSE;"0 = GAS2 not
present; 1
= GAS2 prese nt"
104.3;Actual_Recipe_Parameters._Eq_Pression_Selected;;BOOL;FALSE;FALSE;
104.4;Actual_Recipe_Parameters._DeoxStripEn;;BOOL;FALSE;FALSE;"******Deaira
tion with St rip Enable"
104.5;Actual_Recipe_Parameters._DeoxVacuumEn;;BOOL;FALSE;TRUE;"******Deaira
tion with Va cuum"
104.6;Actual_Recipe_Parameters._DeoxPreMixed;;BOOL;FALSE;FALSE;"******Deaira
tion of Prem ixed Product"
104.7;Actual_Recipe_Parameters._EnBlowOffProdPipeCO2Fil;;BOOL;FALSE;FALSE;
105.0;Actual_Recipe_Parameters._WaterSelection;;BYTE;B#16#0;B#16#0;
106.0;Actual_Recipe_Parameters._FillerNextRecipeNum;;BYTE;B#16#0;B#16#0;
107.0;Actual_Recipe_Parameters._BottleShape;;BYTE;B#16#0;B#16#0;
108.0;Actual_Recipe_Parameters._Type;;INT;1;2;"1= DIET; 2=
REGULAR; 3=
RATIO; 4= WA TER"
110.0;Actual_Recipe_Parameters._ProdMeterRecipeNum;;INT;0;1;
112.0;Actual_Recipe_Parameters._SyrupBrix;;REAL;5.000000e+01;4.625000e+01;
116.0;Actual_Recipe_Parameters._SyrupDensity;;REAL;1.255800e+00;1.206908e+00;
120.0;Actual_Recipe_Parameters._SyrupFactor;;REAL;1.000000e+00;1.000000e+00;
124.0;Actual_Recipe_Parameters._ProductBrix;;REAL;1.045000e+01;1.000000e+01;
128.0;Actual_Recipe_Parameters._ProductionRate;;REAL;9.000000e+02;3.800000e+02;
132.0;Actual_Recipe_Parameters._Ratio;;REAL;2.000000e+01;4.238896e+00;
136.0;Actual_Recipe_Parameters._ProdBrixOffset;;REAL;0.000000e+00;2.500000e-01;
140.0;Actual_Recipe_Parameters._CO2Vols;;REAL;0.000000e+00;2.550000e+00;
144.0;Actual_Recipe_Parameters._CO2Fact;;REAL;1.000000e+00;9.400000e-01;
148.0;Actual_Recipe_Parameters._ProdTankPress;;REAL;1.000000e+00;4.400000e+00;
152.0;Actual_Recipe_Parameters._SP_ProdTemp;;REAL;1.000000e+01;1.700000e+01;
156.0;Actual_Recipe_Parameters._PrdTankMinLevel;;REAL;1.000000e+01;3.500000e+01;
160.0;Actual_Recipe_Parameters._WaterValveSave;;REAL;0.000000e+00;0.000000e+00;
164.0;Actual_Recipe_Parameters._SyrupValveSave;;REAL;0.000000e+00;0.000000e+00;
168.0;Actual_Recipe_Parameters._CarboCO2ValveSave;;REAL;0.000000e+00;0.000000e+00;
172.0;Actual_Recipe_Parameters._ProdMeterHighBrix;;REAL;0.000000e+00;1.030000e+01;
176.0;Actual_Recipe_Parameters._ProdMeterLowBrix;;REAL;0.000000e+00;9.830000e+00;
180.0;Actual_Recipe_Parameters._ProdMeterHighCO2;;REAL;0.000000e+00;2.900000e+00;
184.0;Actual_Recipe_Parameters._ProdMeterLowCO2;;REAL;0.000000e+00;2.300000e+00;
188.0;Actual_Recipe_Parameters._ProdMeter_ZeroCO2;;REAL;0.000000e+00;0.000000e+00;
192.0;Actual_Recipe_Parameters._ProdMeter_ZeroBrix;;REAL;0.000000e+00;0.000000e+00;
196.0;Actual_Recipe_Parameters._ProdHighCond;;REAL;0.000000e+00;0.000000e+00;
200.0;Actual_Recipe_Parameters._ProdLowCond;;REAL;0.000000e+00;0.000000e+00;
204.0;Actual_Recipe_Parameters._BottleSize;;REAL;0.000000e+00;0.000000e+00;
208.0;Actual_Recipe_Parameters._FillingValveHead_SP;;REAL;0.000000e+00;0.000000e+00;
212.0;Actual_Recipe_Parameters._SyrMeter_ZeroBrix;;REAL;0.000000e+00;0.000000e+00;
216.0;Actual_Recipe_Parameters._FirstProdExtraCO2Fact;;REAL;9.700000e-01;1.020000e+00;
220.0;Actual_Recipe_Parameters._Gas2Vols;;REAL;0.000000e+00;0.000000e+00;
224.0;Actual_Recipe_Parameters._Gas2Fact;;REAL;1.000000e+00;0.000000e+00;
228.0;Actual_Recipe_Parameters._SyrupPumpPressure;;REAL;0.000000e+00;0.000000e+00;"******Syrup
Pump Pressur e SP"
232.0;Actual_Recipe_Parameters._WaterPumpPressure;;REAL;0.000000e+00;0.000000e+00;"******Water
Pump Pressur e SP"
236.0;Actual_Recipe_Parameters._CO2_Air_N2_PressSelect;;INT;0;0;"1=CO2; 2=CO2
+SterilAir; 3=CO2+N2 - P
ressure Tank
Selection"
238.0;Actual_Recipe_Parameters._KFactRVM304BlowOff;;REAL;0.000000e+00;0.000000e+00;
242.0;Actual_Recipe_Parameters._ProdRecircPumpFreq;;REAL;0.000000e+00;0.000000e+00;
246.0;Actual_Recipe_Parameters._ProdBoosterPumpPress;;REAL;0.000000e+00;0.000000e+00;
250.0;Actual_Recipe_Parameters._ProdSendPumpFreq;;REAL;0.000000e+00;0.000000e+00;"******Produc
t Sending Pu mp Frequency
SP"
254.0;Spare2[1];;INT;0;0;
256.0;Spare2[2];;INT;0;0;
258.0;Spare2[3];;INT;0;0;
260.0;Spare2[4];;INT;0;0;
262.0;Spare2[5];;INT;0;0;
264.0;Next_Recipe_Name;;STRING [ 32 ];"'
'";"'cambio 1$00$00$
00$00$00$00$00$0
0$00$00$00$00$00
$00$00$00$00$00$ 00$00$00$00'";
298.0;Next_Recipe_Number;;INT;0;0;
300.0;Spare3[1];;INT;0;0;
302.0;Spare3[2];;INT;0;0;
304.0;Spare3[3];;INT;0;0;
306.0;Spare3[4];;INT;0;0;
308.0;Spare3[5];;INT;0;0;
310.0;Spare3[6];;INT;0;0;
312.0;Spare3[7];;INT;0;0;
314.0;Spare3[8];;INT;0;0;
316.0;Spare3[9];;INT;0;0;
318.0;Spare3[10];;INT;0;0;
320.0;Spare3[11];;INT;0;0;
322.0;Spare3[12];;INT;0;0;
324.0;Spare3[13];;INT;0;0;
326.0;Spare3[14];;INT;0;0;
328.0;Spare3[15];;INT;0;0;
330.0;Spare3[16];;INT;0;0;
332.0;Spare3[17];;INT;0;0;
334.0;Spare3[18];;INT;0;0;
336.0;ProcessSetup.Spare000;;REAL;0.000000e+00;0.000000e+00;
340.0;ProcessSetup.Spare040;;REAL;0.000000e+00;0.000000e+00;
344.0;ProcessSetup._KWaterLoss;;REAL;1.000000e-03;1.000000e-03;"Friction Los
s Constant i n Serpentine"
348.0;ProcessSetup._KSyrupLoss;;REAL;7.800000e-03;7.800000e-03;"Friction Los
s Constant i n Syrup Pipe"
352.0;ProcessSetup._KProdLoss;;REAL;1.390000e-02;1.390000e-02;"Pressure Los
s Factor"
356.0;ProcessSetup._KPPM303;;REAL;5.700000e+00;5.700000e+00;"Frequency Ov
erpressure P ump P3 Const ant [Hz/mm]"
360.0;ProcessSetup._BaialageRVM301OVMin;;REAL;2.000000e+00;2.000000e+00;"Baialage Min
imum Flow (N m3/h)"
364.0;ProcessSetup._SyrupLinePressure;;REAL;2.200000e+00;2.200000e+00;"Syrup Line p
ressure at V EP2 valve"
368.0;ProcessSetup._CIPRMM301OV;;REAL;1.000000e+01;1.000000e+01;"Water Valve
Opening Duri ng CIP"
372.0;ProcessSetup._CIPRMP302OV;;REAL;1.500000e+01;1.500000e+01;"Syrup Valve
Opening Duri ng CIP"
376.0;ProcessSetup._CIPTM301MinLevel;;REAL;3.500000e+01;3.500000e+01;"Product Tank
Minimum Lev el In CIP"
380.0;ProcessSetup._CIPTM301MaxLevel;;REAL;5.500000e+01;5.500000e+01;"Product Tank
Maximum Lev el In CIP"
384.0;ProcessSetup._CIPPPM303Freq;;REAL;5.000000e+01;5.000000e+01;"CIP frequenc
y Value [Hz]"
388.0;ProcessSetup._CIPTP301MinLevel;;REAL;2.500000e+01;2.500000e+01;"Syrup Tank M
inimum Level In CIP"
392.0;ProcessSetup._CIPTP301MaxLevel;;REAL;4.500000e+01;4.500000e+01;"Syrup Tank M
aximum Level In CIP"
396.0;ProcessSetup._RinseRMM301OV;;REAL;1.000000e+01;1.000000e+01;"Water Valve
Opening Duri ng Rinse"
400.0;ProcessSetup._RinseRMP302OV;;REAL;1.400000e+01;1.400000e+01;"Syrup Valve
Opening Duri ng Rinse"
404.0;ProcessSetup._RinseTM301Press;;REAL;3.000000e-01;3.000000e-01;"Product Tank
Pressure In Rinse"
408.0;ProcessSetup._RinsePPM303Freq;;REAL;5.000000e+01;5.000000e+01;"Rinse freque
ncy Value [H z]"
412.0;ProcessSetup._DrainTM301Press;;REAL;1.000000e+00;1.000000e+00;"Buffer Tank
Draining Pre ssure"
416.0;ProcessSetup._KRecBlendError;;REAL;2.000000e+00;2.000000e+00;"Blend Error
Recovery CON STANT"
420.0;ProcessSetup._KRecCarboCO2Error;;REAL;2.000000e+00;2.000000e+00;"Carbonation
Error Recove ry Constant"
424.0;ProcessSetup._MaxBlendError;;REAL;1.000000e+02;1.000000e+02;"Blend Error
Maximum Valu e"
428.0;ProcessSetup._MaxCarboCO2Error;;REAL;5.000000e+02;5.000000e+02;"Carbonation
Error Maximu m Value"
432.0;ProcessSetup._StartUpBrixExtraWater;;REAL;4.700000e+01;4.700000e+01;
436.0;ProcessSetup._StartUpCO2ExtraWater;;REAL;8.000000e+00;8.000000e+00;
440.0;ProcessSetup._StartUpPPM303Freq;;REAL;2.000000e+01;2.000000e+01;"Start Up fre
quency Value [Hz]"
444.0;ProcessSetup._SyrupRoomTank;;INT;1;1;
446.0;ProcessSetup._SyrupRunOutLiters;;REAL;2.900000e+02;2.900000e+02;
450.0;ProcessSetup._InjCO2Press_Offset;;REAL;5.000000e-01;5.000000e-01;
454.0;ProcessSetup._InjCO2Press_MinFlow;;REAL;4.500000e+02;4.500000e+02;
458.0;ProcessSetup._InjCO2Press_MaxFlow;;REAL;2.500000e+03;2.500000e+03;
462.0;ProcessSetup._CarboCO2Pressure;;REAL;1.250000e+01;1.250000e+01;"CO2 Pressure
Infeed Line"
466.0;ProcessSetup._N2MinPressure;;REAL;1.000000e+00;1.000000e+00;"N2 Minimum P
ressure Infe ed Line"
470.0;ProcessSetup._DiffSensor_Height;;REAL;3.950000e+02;3.950000e+02;"Sensor Heigh
t from Soil [mm]"
474.0;ProcessSetup._DiffSensor_DeltaHeight;;REAL;-2.500000e+01;-2.500000e+01;"Sensor Plate
s Height Dif ference [mm]"
478.0;ProcessSetup._DiffSensor_Offset;;REAL;3.618000e+01;3.618000e+01;"Sensor Offse
t Read with zero pressur e (all valve s open) in [ mm]"
482.0;ProcessSetup._FillingValveHeight;;REAL;1.400000e+03;1.400000e+03;"Filling Valv
e Height fro m soil [mm]"
486.0;ProcessSetup._FillerDiameter;;REAL;2.520000e+03;2.520000e+03;"Filler Carou
sel Diameter [mm]"
490.0;ProcessSetup._FillingValveNum;;INT;91;91;"Filling Valv
es Number"
492.0;ProcessSetup._FillerProdPipeDN;;REAL;1.000000e+02;1.000000e+02;
496.0;ProcessSetup._FillerProdPipeMass;;REAL;1.600000e+02;1.600000e+02;
500.0;ProcessSetup._FillingTime;;REAL;3.200000e+00;3.200000e+00;
504.0;ProcessSetup._TM301Height_0;;REAL;1.050000e+03;1.050000e+03;"Level at 0%
Tank Level Height in mm"
508.0;ProcessSetup._TM301LevelPerc_2;;REAL;4.600000e+01;4.600000e+01;"Second level
percentage"
512.0;ProcessSetup._TM301Height_2;;REAL;1.625000e+03;1.625000e+03;"Second level
Height in m m"
516.0;ProcessSetup._RVN304Factor;;REAL;1.000000e+00;1.000000e+00;"DeareationFl
ow/WaterFlow"
520.0;ProcessSetup._DrainTM301Flushing;;REAL;1.300000e+00;1.300000e+00;
524.0;ProcessSetup._FirstProdExtraBrix;;REAL;5.000000e-02;5.000000e-02;
528.0;ProcessSetup._FirstProdDietExtraSyr;;REAL;1.400000e-03;1.400000e-03;
532.0;ProcessSetup._EndProdLastSyrlt;;REAL;0.000000e+00;0.000000e+00;"End Producti
on Last syru p liters"
536.0;ProcessSetup._TM301DrainSt0Time;;WORD;W#16#A;W#16#A;sec
538.0;ProcessSetup._TM301DrainSt1Time;;WORD;W#16#50;W#16#50;sec
540.0;ProcessSetup._ProdPipeRunOutSt0Time;;WORD;W#16#1;W#16#1;sec
542.0;ProcessSetup._RMM301ProdPipeRunOu;;REAL;3.000000e+01;3.000000e+01;
546.0;ProcessSetup._RMP302ProdPipeRunOu;;REAL;4.000000e+01;4.000000e+01;
550.0;ProcessSetup._ProdPipeRunOutAmount;;REAL;3.000000e+01;3.000000e+01;
554.0;ProcessSetup._TM301RunOutChiller;;REAL;5.000000e+00;5.000000e+00;
558.0;ProcessSetup._MinSpeedNominalProd;;REAL;4.000000e-01;4.000000e-01;"Min Speed fo
r Nominal Pr oduction"
562.0;ProcessSetup._MinSpeedSlowProd;;REAL;3.000000e-01;3.000000e-01;"Min Speed fo
r Very Low P roduction"
566.0;ProcessSetup._FastChgOvrTM301DrnPrss;;REAL;9.000000e-01;9.000000e-01;"Fast Change
Over Product Tank Draini
ng Pressure
in Blendfill"
570.0;ProcessSetup._CIPTN301MinLevel;;REAL;3.500000e+01;3.500000e+01;"Deaireator T
ank Minimum Level In CIP"
574.0;ProcessSetup._CIPTN301MaxLevel;;REAL;6.000000e+01;6.000000e+01;"Deaireator T
ank Maximum Level In CIP"
578.0;ProcessSetup._ProdPPN304Freq;;REAL;5.000000e+01;5.000000e+01;
582.0;ProcessSetup._GAS2InjectionPress;;REAL;4.000000e+00;4.000000e+00;
586.0;ProcessSetup._BaialageRVM301OVMax;;REAL;2.000000e+01;2.000000e+01;"Baialage Pro
duction Flow Multiplier"
590.0;ProcessSetup._RinsePPN301Freq;;REAL;5.000000e+00;5.000000e+00;
594.0;ProcessSetup._CIPPPN301Freq;;REAL;5.000000e+00;5.000000e+00;
598.0;ProcessSetup._RinsePPP302Freq;;REAL;5.000000e+00;5.000000e+00;
602.0;ProcessSetup._CIPPPP302Freq;;REAL;5.000000e+00;5.000000e+00;
606.0;ProcessSetup._PercSyrupBrixSyrStarUp;;REAL;2.500000e+01;2.500000e+01;
610.0;ProcessSetup._RefTempCoolingCTRL;;REAL;0.000000e+00;0.000000e+00;
614.0;ProcessSetup._H2OSerpPrimingVolume;;REAL;1.500000e+02;1.500000e+02;"Water Serpen
tine Volume
+ Water Chil ler Volume"
618.0;ProcessSetup._AVN301_Nozzle_Kv;;REAL;1.650000e+02;1.650000e+02;"AVN301 Nozzl
e Kv"
622.0;ProcessSetup._AVN302_Nozzle_Kv;;REAL;2.600000e+02;2.600000e+02;"AVN302 Nozzl
e Kv"
626.0;ProcessSetup._AVN303_Nozzle_Kv;;REAL;1.650000e+02;1.650000e+02;"AVN303 Nozzl
e Kv"
630.0;ProcessSetup._DeoxSpryball_Kv;;REAL;6.700000e+01;6.700000e+01;"Deox Sprybal
l Kv"
634.0;ProcessSetup._PremixedLineDrainTime;;INT;300;300;"Premixed Pro
duct Line Dr ain Time"
636.0;ProcessSetup._PPN301_H_MaxFlow;;REAL;9.000000e+01;9.000000e+01;"PPN301 Pump
Head with Ma x Flow [m]"
640.0;ProcessSetup._PPN301_H_MinFlow;;REAL;8.700000e+01;8.700000e+01;"PPN301 Pump
Head with Mi n Flow [m]"
644.0;ProcessSetup._PPN301_MaxFlow;;REAL;5.070000e+02;5.070000e+02;"PPN301 Max F
low [l/min]"
648.0;ProcessSetup._PPN301_MinFlow;;REAL;2.110000e+02;2.110000e+02;"PPN301 Min F
low [l/min]"
652.0;ProcessSetup._PPP302_H_MaxFlow;;REAL;8.600000e+01;8.600000e+01;"PPP302 Pump
Head with Ma x Flow [m]"
656.0;ProcessSetup._PPP302_H_MinFlow;;REAL;8.500000e+01;8.500000e+01;"PPP302 Pump
Head with Mi n Flow [m]"
660.0;ProcessSetup._PPP302_MaxFlow;;REAL;1.150000e+02;1.150000e+02;"PPP302 Max F
low [l/min]"
664.0;ProcessSetup._PPP302_MinFlow;;REAL;3.200000e+01;3.200000e+01;"PPP302 Min F
low [l/min]"
668.0;ProcessSetup._RinsePPM306Freq;;REAL;5.000000e+00;5.000000e+00;
672.0;ProcessSetup._CIPPPM306Freq;;REAL;5.000000e+00;5.000000e+00;
676.0;ProcessSetup._PPM307_H_MaxFlow;;REAL;0.000000e+00;0.000000e+00;"PPM307 Pump
Head with Ma x Flow [m]"
680.0;ProcessSetup._PPM307_H_MinFlow;;REAL;0.000000e+00;0.000000e+00;"PPM307 Pump
Head with Mi n Flow [m]"
684.0;ProcessSetup._PPM307_MaxFlow;;REAL;0.000000e+00;0.000000e+00;"PPM307 Max F
low [l/min]"
688.0;ProcessSetup._PPM307_MinFlow;;REAL;0.000000e+00;0.000000e+00;"PPM307 Min F
low [l/min]"
692.0;ProcessSetup._Temp0_VacuumCtrl;;REAL;1.800000e+01;1.800000e+01;"PPN304 Targe
t Temperatur e
- OPTION
PPN304 Sterl ing Type"
696.0;ProcessSetup._Temp1_VacuumCtrl;;REAL;2.000000e+00;2.000000e+00;"PPN304 High
Treshold Tem perature Del ta - OPTION
PPN304 Sterl
ing Type"
700.0;ProcessSetup._Temp2_VacuumCtrl;;REAL;2.000000e+00;2.000000e+00;"PPN304 Low T
reshold Temp erature Delt a - OPTION
PPN304 Sterl
ing Type"
704.0;ProcessSetup._Temp3_VacuumCtrl;;REAL;5.000000e+01;5.000000e+01;"PPN304 Warni
ng Temperatu re
- OPTION
PPN304 Sterl ing Type"
708.0;ProcessSetup._Temp4_VacuumCtrl;;REAL;5.000000e+01;5.000000e+01;"PPN304 Alarm
Temperature
- OPTION
PPN304 Sterl ing Type"
712.0;ProcessSetup._T1_VacuumCtrl;;DINT;L#1500;L#1500;"PPN304 Time
1 [msec]
- OPTION
PPN304 Sterl ing Type"
716.0;ProcessSetup._T2_VacuumCtrl;;DINT;L#1500;L#1500;"PPN304 Time
2 [msec]
- OPTION
PPN304 Sterl ing Type"
720.0;ProcessSetup._T3_VacuumCtrl;;DINT;L#1000;L#1000;"PPN304 Time
3 [msec]
- OPTION
PPN304 Sterl ing Type"
724.0;ProcessSetup._T4_VacuumCtrl;;DINT;L#1000;L#1000;"PPN304 Time
4 [msec]
- OPTION
PPN304 Sterl ing Type"
728.0;ProcessSetup._ICS_VolDosWorkTimePAA;;INT;30;30;"ICS - DS - D
osing Workin g Time [sec]"
730.0;ProcessSetup._ICS_VolPauseTimePAA;;INT;30;30;"ICS - DS - D
osing Pause Time [sec]"
732.0;ProcessSetup._ICS_PAAPulseWeight;;INT;10;10;"ICS - DS - P
AA Pulse Wei ght [(L/Puls e)/100]"
734.0;ProcessSetup._ICS_CausticPulseWeight;;INT;10;10;"ICS - DS - C
austic Pulse Weight [(L/
Pulse)/100]"
736.0;ProcessSetup._ICS_AcidPulseWeight;;INT;10;10;"ICS - DS - A
cid Pulse We ight [(L/Pul se)/100]"
738.0;ProcessSetup._ICS_VolumeRestOfLine;;REAL;3.500000e+02;3.500000e+02;"ICS - DS - V
olume of the Rest of the Line (Fille
r + Piping)
[L]"
742.0;ProcessSetup._ICS_VolDosWorkTimeCaus;;INT;30;30;"ICS - DS - D
osing Workin g Time [sec]"
744.0;ProcessSetup._ICS_VolDosPauseTimeCaus;;INT;30;30;"ICS - DS - D
osing Pause Time [sec]"
746.0;ProcessSetup._ICS_VolDosWorkTimeAcid;;INT;30;30;"ICS - DS - D
osing Workin g Time [sec]"
748.0;ProcessSetup._ICS_VolDosPauseTimeAcid;;INT;30;30;"ICS - DS - D
osing Pause Time [sec]"
750.0;ProcessSetup._ICS_ConcDosWorkTimeCaus;;INT;30;30;"ICS - DS - D
osing Workin g Time [sec]"
752.0;ProcessSetup._ICS_ConcDosPausTimeCaus;;INT;30;30;"ICS - DS - D
osing Pause Time [sec]"
754.0;ProcessSetup._ICS_ConcDosWorkTimeAcid;;INT;30;30;"ICS - DS - D
osing Workin g Time [sec]"
756.0;ProcessSetup._ICS_ConcDosPausTimeAcid;;INT;30;30;"ICS - DS - D
osing Pause Time [sec]"
758.0;ProcessSetup._RinsePPM307Freq;;REAL;3.000000e+01;3.000000e+01;
762.0;ProcessSetup._CIPPPM307Freq;;REAL;3.000000e+01;3.000000e+01;
766.0;ProcessSetup._CIP2StepTN301Lvl;;REAL;0.000000e+00;0.000000e+00;"Local CIP -
2 Step loadi ng TN301 Lev el"
770.0;ProcessSetup._CIP2StepTM301Lvl;;REAL;0.000000e+00;0.000000e+00;"Local CIP -
2 Step loadi ng TM301 Lev el"
774.0;ProcessSetup._CIP2StepTP301Lvl;;REAL;0.000000e+00;0.000000e+00;"Local CIP -
2 Step loadi ng TP301 Lev el"
778.0;ProcessSetup._PumpNominalFreq;;REAL;5.000000e+01;5.000000e+01;"50.0 Hz or 6
0.0 Hz"
782.0;_SwitchOff_DensityOK;;BOOL;FALSE;FALSE;
1 Address Name Type Initial value Actual value Comment
2 0.0 Processor_Options.Blender_OPT._ModelNum INT 6 6
3 2.0 Processor_Options.Blender_OPT._CO2_Offset REAL 4.500000e-01 4.500000e-01
4 6.0 Processor_Options.Blender_OPT._MaxSyrDeltaBrix REAL 8.000000e-01 8.000000e-01
5 10.0 Processor_Options.Blender_OPT._BrixMeter BOOL TRUE TRUE
6 10.1 Processor_Options.Blender_OPT.Spare101 BOOL FALSE FALSE
7 10.2 Processor_Options.Blender_OPT._TrackH2OEnable BOOL FALSE FALSE
8 10.3 Processor_Options.Blender_OPT._PAmPDSType BOOL FALSE FALSE 0)Cobrix 200 0 1)Carbo 2 000
9 10.4 Processor_Options.Blender_OPT._HistoricalTrends BOOL TRUE TRUE 0)Not Presen t 1)Present
10 10.5 Processor_Options.Blender_OPT._PowerMeter BOOL FALSE FALSE 0)Not Presen t 1)Present
11 10.6 Processor_Options.Blender_OPT._Report BOOL TRUE TRUE 0)Not Presen t 1)Present
12 10.7 Processor_Options.Blender_OPT._Balaiage BOOL FALSE FALSE
13 11.0 Processor_Options.Blender_OPT._Valves_FullFeedback BOOL TRUE TRUE Valves contr ol Full feed back
14 11.1 Processor_Options.Blender_OPT._Valves_SingleFeedback BOOL FALSE FALSE Valves contr ol Single fe edback
15 11.2 Processor_Options.Blender_OPT._PumpsSafetySwitches BOOL FALSE FALSE Pumps with S afety Switch es
16 11.3 Processor_Options.Blender_OPT._SurgeProtectionAct BOOL FALSE FALSE
17 11.4 Processor_Options.Blender_OPT._DBC_Type BOOL FALSE FALSE 0) Deox,Carb o,Blend 1)D eox,Blend,Ca rbo
18 11.5 Processor_Options.Blender_OPT._CO2InletMeter BOOL TRUE TRUE 0)Not Presen t 1)Present
19 11.6 Processor_Options.Blender_OPT._ProductO2Meter BOOL FALSE FALSE 0)Not Presen t 1)Present
20 11.7 Processor_Options.Blender_OPT._CopressedAirInletMeter BOOL FALSE FALSE 0)Not Presen t 1)Present
21 12.0 Processor_Options.Blender_OPT._MeterType INT 6 6 1)Maselli 2) AntoonPaar 3 )4-20mA 4)UC 05 UR22 5)mP DSPA 6)MR02
22 14.0 Processor_Options.Blender_OPT._MeterReceiveOnly BOOL FALSE FALSE
23 14.1 Processor_Options.Blender_OPT._SyrBrixMeter BOOL FALSE FALSE
24 14.2 Processor_Options.Blender_OPT._Flooding_Start_Up BOOL FALSE FALSE 0)Not Select ed 1)Sele cted
25 14.3 Processor_Options.Blender_OPT._FastChangeOverEnabled BOOL TRUE TRUE
26 14.4 Processor_Options.Blender_OPT._WaterInletMeter BOOL FALSE FALSE 0)Not Presen t 1)Present
27 14.5 Processor_Options.Blender_OPT._BlendFillSystem BOOL TRUE TRUE
28 14.6 Processor_Options.Blender_OPT._TrackFillerSpeed BOOL TRUE TRUE
29 16.0 Processor_Options.Blender_OPT._SignalExchange INT 1 1 FILLER - 0= Hardwire; 1= Ethernet
30 18.0 Processor_Options.Blender_OPT._CoolerPresent BOOL TRUE TRUE
31 20.0 Processor_Options.Blender_OPT._CoolerControl INT 4 4 0)External 1 )Water 2)Pro duct 3)Water +Product-2 C trl 4)Water+ Product-1 Ct rl
32 22.0 Processor_Options.Blender_OPT._CoolerType INT 0 0 0)Glycol 1)A mmonia
33 24.0 Processor_Options.Blender_OPT._LocalCIP BOOL FALSE FALSE
34 24.1 Processor_Options.Blender_OPT._ICS_CustomerHotWater BOOL FALSE FALSE 0)No Hot Wat er from Cust omer 1)Hot W ater from Cu stomer Avail able
35 24.2 Processor_Options.Blender_OPT._ICS_CustomerChemRecov BOOL FALSE FALSE 0)No Custome r's Chemical s Recovery 1 )Customer's Chemicals Re covery Avail able
36 24.3 Processor_Options.Blender_OPT._CIPSignalExchange BOOL FALSE FALSE CIP - 0= Har dwire; 1= Et hernet
37 24.4 Processor_Options.Blender_OPT._ICS_CustomerChemicals BOOL FALSE FALSE 0)Chemicals from ICS 1)C hemicals fro m Customer
38 24.5 Processor_Options.Blender_OPT._CarboPresent BOOL TRUE TRUE
39 24.6 Processor_Options.Blender_OPT._InverterSyrupPumpPPP302 BOOL FALSE FALSE 0)Not Presen t 1)Present
40 24.7 Processor_Options.Blender_OPT._InverterWaterPumpPPN301 BOOL FALSE FALSE 0)Not Presen t 1)Present
41 25.0 Processor_Options.Blender_OPT._DoubleDeair BOOL TRUE TRUE
42 25.1 Processor_Options.Blender_OPT._DeairPreMixed BOOL FALSE FALSE Deox Premixe d Inlet
43 25.2 Processor_Options.Blender_OPT._Deaireation BOOL TRUE TRUE 0)SAG 1)SAE/ SAF
44 25.3 Processor_Options.Blender_OPT._StillWaterByPass BOOL FALSE FALSE
45 25.4 Processor_Options.Blender_OPT._ManifoldSetting BOOL TRUE TRUE 0)Manual 1)A utomatic
46 25.5 Processor_Options.Blender_OPT._InverterProdPumpPPM303 BOOL FALSE FALSE
47 25.6 Processor_Options.Blender_OPT._SidelCip BOOL FALSE FALSE
48 25.7 Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP BOOL TRUE TRUE 0)Comunicati on with CP 1)Comunicat ion with CPU PN
49 26.0 Processor_Options.Blender_OPT._2ndOutlet INT 0 0 0)No 2nd Out let 1)2nd O utlet No Sta ndalone 2)2 nd Outlet St andalone
50 28.0 Processor_Options.Blender_OPT._Promass INT 2 2
51 30.0 Processor_Options.Blender_OPT._WaterPromass BOOL TRUE TRUE 0)Promag 1)P romass
52 30.1 Processor_Options.Blender_OPT._ProductConductimeter BOOL FALSE FALSE
53 30.2 Processor_Options.Blender_OPT._ICS_CustomerH2ORecov BOOL FALSE FALSE 0)No Custome r's H2O Reco very 1)Custo mer's H2O Re covery Avail able
54 30.3 Processor_Options.Blender_OPT.Spare303 BOOL FALSE FALSE
55 30.4 Processor_Options.Blender_OPT._CO2_GAS2_Injection BOOL FALSE FALSE 0)Only CO2 I njection 1)G AS2 Injectio n
56 30.5 Processor_Options.Blender_OPT._InverterVacuuPumpPPN304 BOOL FALSE FALSE 0)Not Presen t 1)Present
57 30.6 Processor_Options.Blender_OPT._InverterBoostPumpPPM307 BOOL FALSE FALSE 0)Not Presen t 1)Present
58 30.7 Processor_Options.Blender_OPT._RunOut_Water BOOL TRUE TRUE 0)Syrup Runo ut without W ater 1)Syrup runout with Water pushi ng
59 31.0 Processor_Options.Blender_OPT._FlowMeterType BOOL FALSE TRUE 0)Endrees Ha user -- 1)Mi cromotion
60 31.1 Processor_Options.Blender_OPT._SidelFiller BOOL FALSE FALSE 0)Filler Sim onazzi -- 1)Filler Sid el Filling
61 31.2 Processor_Options.Blender_OPT._Simulation BOOL FALSE FALSE
62 31.3 Processor_Options.Blender_OPT._ProductCoolingCTRL BOOL FALSE FALSE 0)none 1) TT M307
63 31.4 Processor_Options.Blender_OPT._ChillerCTRL BOOL FALSE FALSE Chiller Pres sure Cross C ontrol
64 31.5 Processor_Options.Blender_OPT._CO2_SterileFilter BOOL TRUE TRUE CO2 Inlet wi th Steril Fi lter
65 31.6 Processor_Options.Blender_OPT._InverterRecirPumpPPM306 BOOL FALSE FALSE 0)Not Presen t 1)Present
66 31.7 Processor_Options.Blender_OPT._ProdPressReleaseRVM304 BOOL FALSE FALSE 0)Not Presen t 1)Present
67 32.0 Processor_Options.Blender_OPT._VacuumPump INT 1 1 0)None 1)Ste rling 2)Nash Elmo
68 34.0 Processor_Options.Blender_OPT._GAS2InjectionType INT 0 0 0)None 1)N2 2)Steril Air
69 36.0 Processor_Options.Blender_OPT._InjectionPress_Ctrl INT 1 1 0)Manual 1)N orgren v1 2) Norgren v2
70 38.0 Processor_Options.Blender_OPT._ProdPressureType INT 0 0 0)Only CO2 1 )CO2+SterilA ir 2)CO2+N2
71 40.0 Processor_Options.Blender_OPT._CIPHeatType INT 0 0 0)Steam 1)El ectric
72 42.0 Processor_Options.Blender_OPT._EHS_NrRes INT 6 6 Number of He at Resistanc es
73 44.0 Spare1[1] INT 0 0
74 46.0 Spare1[2] INT 0 0
75 48.0 Spare1[3] INT 0 0
76 50.0 Spare1[4] INT 0 0
77 52.0 Spare1[5] INT 0 0
78 54.0 Spare1[6] INT 0 0
79 56.0 Spare1[7] INT 0 0
80 58.0 Spare1[8] INT 0 0
81 60.0 Spare1[9] INT 0 0
82 62.0 _RVM301_DeadBand REAL 5.000000e-02 5.000000e-02
83 66.0 _RVM301_Kp REAL 9.000000e+01 9.000000e+01
84 70.0 Actual_Recipe_Parameters._Name STRING [ 32 ] ' ' ''
85 104.0 Actual_Recipe_Parameters._EnProdTemp BOOL FALSE TRUE
86 104.1 Actual_Recipe_Parameters._SyrFlushing BOOL FALSE FALSE Ex_EnDeairea tion --> DEL ETED - AVP32 0 VALVE OPEN
87 104.2 Actual_Recipe_Parameters._GAS2_Injection BOOL FALSE FALSE 0 = GAS2 not present; 1 = GAS2 prese nt
88 104.3 Actual_Recipe_Parameters._Eq_Pression_Selected BOOL FALSE FALSE
89 104.4 Actual_Recipe_Parameters._DeoxStripEn BOOL FALSE FALSE ******Deaira tion with St rip Enable
90 104.5 Actual_Recipe_Parameters._DeoxVacuumEn BOOL FALSE TRUE ******Deaira tion with Va cuum
91 104.6 Actual_Recipe_Parameters._DeoxPreMixed BOOL FALSE FALSE ******Deaira tion of Prem ixed Product
92 104.7 Actual_Recipe_Parameters._EnBlowOffProdPipeCO2Fil BOOL FALSE FALSE
93 105.0 Actual_Recipe_Parameters._WaterSelection BYTE B#16#0 B#16#0
94 106.0 Actual_Recipe_Parameters._FillerNextRecipeNum BYTE B#16#0 B#16#0
95 107.0 Actual_Recipe_Parameters._BottleShape BYTE B#16#0 B#16#0
96 108.0 Actual_Recipe_Parameters._Type INT 1 2 1= DIET; 2= REGULAR; 3= RATIO; 4= WA TER
97 110.0 Actual_Recipe_Parameters._ProdMeterRecipeNum INT 0 1
98 112.0 Actual_Recipe_Parameters._SyrupBrix REAL 5.000000e+01 4.625000e+01
99 116.0 Actual_Recipe_Parameters._SyrupDensity REAL 1.255800e+00 1.206908e+00
100 120.0 Actual_Recipe_Parameters._SyrupFactor REAL 1.000000e+00 1.000000e+00
101 124.0 Actual_Recipe_Parameters._ProductBrix REAL 1.045000e+01 1.000000e+01
102 128.0 Actual_Recipe_Parameters._ProductionRate REAL 9.000000e+02 3.800000e+02
103 132.0 Actual_Recipe_Parameters._Ratio REAL 2.000000e+01 4.238896e+00
104 136.0 Actual_Recipe_Parameters._ProdBrixOffset REAL 0.000000e+00 2.500000e-01
105 140.0 Actual_Recipe_Parameters._CO2Vols REAL 0.000000e+00 2.550000e+00
106 144.0 Actual_Recipe_Parameters._CO2Fact REAL 1.000000e+00 9.400000e-01
107 148.0 Actual_Recipe_Parameters._ProdTankPress REAL 1.000000e+00 4.400000e+00
108 152.0 Actual_Recipe_Parameters._SP_ProdTemp REAL 1.000000e+01 1.700000e+01
109 156.0 Actual_Recipe_Parameters._PrdTankMinLevel REAL 1.000000e+01 3.500000e+01
110 160.0 Actual_Recipe_Parameters._WaterValveSave REAL 0.000000e+00 0.000000e+00
111 164.0 Actual_Recipe_Parameters._SyrupValveSave REAL 0.000000e+00 0.000000e+00
112 168.0 Actual_Recipe_Parameters._CarboCO2ValveSave REAL 0.000000e+00 0.000000e+00
113 172.0 Actual_Recipe_Parameters._ProdMeterHighBrix REAL 0.000000e+00 1.030000e+01
114 176.0 Actual_Recipe_Parameters._ProdMeterLowBrix REAL 0.000000e+00 9.830000e+00
115 180.0 Actual_Recipe_Parameters._ProdMeterHighCO2 REAL 0.000000e+00 2.900000e+00
116 184.0 Actual_Recipe_Parameters._ProdMeterLowCO2 REAL 0.000000e+00 2.300000e+00
117 188.0 Actual_Recipe_Parameters._ProdMeter_ZeroCO2 REAL 0.000000e+00 0.000000e+00
118 192.0 Actual_Recipe_Parameters._ProdMeter_ZeroBrix REAL 0.000000e+00 0.000000e+00
119 196.0 Actual_Recipe_Parameters._ProdHighCond REAL 0.000000e+00 0.000000e+00
120 200.0 Actual_Recipe_Parameters._ProdLowCond REAL 0.000000e+00 0.000000e+00
121 204.0 Actual_Recipe_Parameters._BottleSize REAL 0.000000e+00 0.000000e+00
122 208.0 Actual_Recipe_Parameters._FillingValveHead_SP REAL 0.000000e+00 0.000000e+00
123 212.0 Actual_Recipe_Parameters._SyrMeter_ZeroBrix REAL 0.000000e+00 0.000000e+00
124 216.0 Actual_Recipe_Parameters._FirstProdExtraCO2Fact REAL 9.700000e-01 1.020000e+00
125 220.0 Actual_Recipe_Parameters._Gas2Vols REAL 0.000000e+00 0.000000e+00
126 224.0 Actual_Recipe_Parameters._Gas2Fact REAL 1.000000e+00 0.000000e+00
127 228.0 Actual_Recipe_Parameters._SyrupPumpPressure REAL 0.000000e+00 0.000000e+00 ******Syrup Pump Pressur e SP
128 232.0 Actual_Recipe_Parameters._WaterPumpPressure REAL 0.000000e+00 0.000000e+00 ******Water Pump Pressur e SP
129 236.0 Actual_Recipe_Parameters._CO2_Air_N2_PressSelect INT 0 0 1=CO2; 2=CO2 +SterilAir; 3=CO2+N2 - P ressure Tank Selection
130 238.0 Actual_Recipe_Parameters._KFactRVM304BlowOff REAL 0.000000e+00 0.000000e+00
131 242.0 Actual_Recipe_Parameters._ProdRecircPumpFreq REAL 0.000000e+00 0.000000e+00
132 246.0 Actual_Recipe_Parameters._ProdBoosterPumpPress REAL 0.000000e+00 0.000000e+00
133 250.0 Actual_Recipe_Parameters._ProdSendPumpFreq REAL 0.000000e+00 0.000000e+00 ******Produc t Sending Pu mp Frequency SP
134 254.0 Spare2[1] INT 0 0
135 256.0 Spare2[2] INT 0 0
136 258.0 Spare2[3] INT 0 0
137 260.0 Spare2[4] INT 0 0
138 262.0 Spare2[5] INT 0 0
139 264.0 Next_Recipe_Name STRING [ 32 ] ' ' 'cambio 1$00$00$ 00$00$00$00$00$0 0$00$00$00$00$00 $00$00$00$00$00$ 00$00$00$00'
140 298.0 Next_Recipe_Number INT 0 0
141 300.0 Spare3[1] INT 0 0
142 302.0 Spare3[2] INT 0 0
143 304.0 Spare3[3] INT 0 0
144 306.0 Spare3[4] INT 0 0
145 308.0 Spare3[5] INT 0 0
146 310.0 Spare3[6] INT 0 0
147 312.0 Spare3[7] INT 0 0
148 314.0 Spare3[8] INT 0 0
149 316.0 Spare3[9] INT 0 0
150 318.0 Spare3[10] INT 0 0
151 320.0 Spare3[11] INT 0 0
152 322.0 Spare3[12] INT 0 0
153 324.0 Spare3[13] INT 0 0
154 326.0 Spare3[14] INT 0 0
155 328.0 Spare3[15] INT 0 0
156 330.0 Spare3[16] INT 0 0
157 332.0 Spare3[17] INT 0 0
158 334.0 Spare3[18] INT 0 0
159 336.0 ProcessSetup.Spare000 REAL 0.000000e+00 0.000000e+00
160 340.0 ProcessSetup.Spare040 REAL 0.000000e+00 0.000000e+00
161 344.0 ProcessSetup._KWaterLoss REAL 1.000000e-03 1.000000e-03 Friction Los s Constant i n Serpentine
162 348.0 ProcessSetup._KSyrupLoss REAL 7.800000e-03 7.800000e-03 Friction Los s Constant i n Syrup Pipe
163 352.0 ProcessSetup._KProdLoss REAL 1.390000e-02 1.390000e-02 Pressure Los s Factor
164 356.0 ProcessSetup._KPPM303 REAL 5.700000e+00 5.700000e+00 Frequency Ov erpressure P ump P3 Const ant [Hz/mm]
165 360.0 ProcessSetup._BaialageRVM301OVMin REAL 2.000000e+00 2.000000e+00 Baialage Min imum Flow (N m3/h)
166 364.0 ProcessSetup._SyrupLinePressure REAL 2.200000e+00 2.200000e+00 Syrup Line p ressure at V EP2 valve
167 368.0 ProcessSetup._CIPRMM301OV REAL 1.000000e+01 1.000000e+01 Water Valve Opening Duri ng CIP
168 372.0 ProcessSetup._CIPRMP302OV REAL 1.500000e+01 1.500000e+01 Syrup Valve Opening Duri ng CIP
169 376.0 ProcessSetup._CIPTM301MinLevel REAL 3.500000e+01 3.500000e+01 Product Tank Minimum Lev el In CIP
170 380.0 ProcessSetup._CIPTM301MaxLevel REAL 5.500000e+01 5.500000e+01 Product Tank Maximum Lev el In CIP
171 384.0 ProcessSetup._CIPPPM303Freq REAL 5.000000e+01 5.000000e+01 CIP frequenc y Value [Hz]
172 388.0 ProcessSetup._CIPTP301MinLevel REAL 2.500000e+01 2.500000e+01 Syrup Tank M inimum Level In CIP
173 392.0 ProcessSetup._CIPTP301MaxLevel REAL 4.500000e+01 4.500000e+01 Syrup Tank M aximum Level In CIP
174 396.0 ProcessSetup._RinseRMM301OV REAL 1.000000e+01 1.000000e+01 Water Valve Opening Duri ng Rinse
175 400.0 ProcessSetup._RinseRMP302OV REAL 1.400000e+01 1.400000e+01 Syrup Valve Opening Duri ng Rinse
176 404.0 ProcessSetup._RinseTM301Press REAL 3.000000e-01 3.000000e-01 Product Tank Pressure In Rinse
177 408.0 ProcessSetup._RinsePPM303Freq REAL 5.000000e+01 5.000000e+01 Rinse freque ncy Value [H z]
178 412.0 ProcessSetup._DrainTM301Press REAL 1.000000e+00 1.000000e+00 Buffer Tank Draining Pre ssure
179 416.0 ProcessSetup._KRecBlendError REAL 2.000000e+00 2.000000e+00 Blend Error Recovery CON STANT
180 420.0 ProcessSetup._KRecCarboCO2Error REAL 2.000000e+00 2.000000e+00 Carbonation Error Recove ry Constant
181 424.0 ProcessSetup._MaxBlendError REAL 1.000000e+02 1.000000e+02 Blend Error Maximum Valu e
182 428.0 ProcessSetup._MaxCarboCO2Error REAL 5.000000e+02 5.000000e+02 Carbonation Error Maximu m Value
183 432.0 ProcessSetup._StartUpBrixExtraWater REAL 4.700000e+01 4.700000e+01
184 436.0 ProcessSetup._StartUpCO2ExtraWater REAL 8.000000e+00 8.000000e+00
185 440.0 ProcessSetup._StartUpPPM303Freq REAL 2.000000e+01 2.000000e+01 Start Up fre quency Value [Hz]
186 444.0 ProcessSetup._SyrupRoomTank INT 1 1
187 446.0 ProcessSetup._SyrupRunOutLiters REAL 2.900000e+02 2.900000e+02
188 450.0 ProcessSetup._InjCO2Press_Offset REAL 5.000000e-01 5.000000e-01
189 454.0 ProcessSetup._InjCO2Press_MinFlow REAL 4.500000e+02 4.500000e+02
190 458.0 ProcessSetup._InjCO2Press_MaxFlow REAL 2.500000e+03 2.500000e+03
191 462.0 ProcessSetup._CarboCO2Pressure REAL 1.250000e+01 1.250000e+01 CO2 Pressure Infeed Line
192 466.0 ProcessSetup._N2MinPressure REAL 1.000000e+00 1.000000e+00 N2 Minimum P ressure Infe ed Line
193 470.0 ProcessSetup._DiffSensor_Height REAL 3.950000e+02 3.950000e+02 Sensor Heigh t from Soil [mm]
194 474.0 ProcessSetup._DiffSensor_DeltaHeight REAL -2.500000e+01 -2.500000e+01 Sensor Plate s Height Dif ference [mm]
195 478.0 ProcessSetup._DiffSensor_Offset REAL 3.618000e+01 3.618000e+01 Sensor Offse t Read with zero pressur e (all valve s open) in [ mm]
196 482.0 ProcessSetup._FillingValveHeight REAL 1.400000e+03 1.400000e+03 Filling Valv e Height fro m soil [mm]
197 486.0 ProcessSetup._FillerDiameter REAL 2.520000e+03 2.520000e+03 Filler Carou sel Diameter [mm]
198 490.0 ProcessSetup._FillingValveNum INT 91 91 Filling Valv es Number
199 492.0 ProcessSetup._FillerProdPipeDN REAL 1.000000e+02 1.000000e+02
200 496.0 ProcessSetup._FillerProdPipeMass REAL 1.600000e+02 1.600000e+02
201 500.0 ProcessSetup._FillingTime REAL 3.200000e+00 3.200000e+00
202 504.0 ProcessSetup._TM301Height_0 REAL 1.050000e+03 1.050000e+03 Level at 0% Tank Level Height in mm
203 508.0 ProcessSetup._TM301LevelPerc_2 REAL 4.600000e+01 4.600000e+01 Second level percentage
204 512.0 ProcessSetup._TM301Height_2 REAL 1.625000e+03 1.625000e+03 Second level Height in m m
205 516.0 ProcessSetup._RVN304Factor REAL 1.000000e+00 1.000000e+00 DeareationFl ow/WaterFlow
206 520.0 ProcessSetup._DrainTM301Flushing REAL 1.300000e+00 1.300000e+00
207 524.0 ProcessSetup._FirstProdExtraBrix REAL 5.000000e-02 5.000000e-02
208 528.0 ProcessSetup._FirstProdDietExtraSyr REAL 1.400000e-03 1.400000e-03
209 532.0 ProcessSetup._EndProdLastSyrlt REAL 0.000000e+00 0.000000e+00 End Producti on Last syru p liters
210 536.0 ProcessSetup._TM301DrainSt0Time WORD W#16#A W#16#A sec
211 538.0 ProcessSetup._TM301DrainSt1Time WORD W#16#50 W#16#50 sec
212 540.0 ProcessSetup._ProdPipeRunOutSt0Time WORD W#16#1 W#16#1 sec
213 542.0 ProcessSetup._RMM301ProdPipeRunOu REAL 3.000000e+01 3.000000e+01
214 546.0 ProcessSetup._RMP302ProdPipeRunOu REAL 4.000000e+01 4.000000e+01
215 550.0 ProcessSetup._ProdPipeRunOutAmount REAL 3.000000e+01 3.000000e+01
216 554.0 ProcessSetup._TM301RunOutChiller REAL 5.000000e+00 5.000000e+00
217 558.0 ProcessSetup._MinSpeedNominalProd REAL 4.000000e-01 4.000000e-01 Min Speed fo r Nominal Pr oduction
218 562.0 ProcessSetup._MinSpeedSlowProd REAL 3.000000e-01 3.000000e-01 Min Speed fo r Very Low P roduction
219 566.0 ProcessSetup._FastChgOvrTM301DrnPrss REAL 9.000000e-01 9.000000e-01 Fast Change Over Product Tank Draini ng Pressure in Blendfill
220 570.0 ProcessSetup._CIPTN301MinLevel REAL 3.500000e+01 3.500000e+01 Deaireator T ank Minimum Level In CIP
221 574.0 ProcessSetup._CIPTN301MaxLevel REAL 6.000000e+01 6.000000e+01 Deaireator T ank Maximum Level In CIP
222 578.0 ProcessSetup._ProdPPN304Freq REAL 5.000000e+01 5.000000e+01
223 582.0 ProcessSetup._GAS2InjectionPress REAL 4.000000e+00 4.000000e+00
224 586.0 ProcessSetup._BaialageRVM301OVMax REAL 2.000000e+01 2.000000e+01 Baialage Pro duction Flow Multiplier
225 590.0 ProcessSetup._RinsePPN301Freq REAL 5.000000e+00 5.000000e+00
226 594.0 ProcessSetup._CIPPPN301Freq REAL 5.000000e+00 5.000000e+00
227 598.0 ProcessSetup._RinsePPP302Freq REAL 5.000000e+00 5.000000e+00
228 602.0 ProcessSetup._CIPPPP302Freq REAL 5.000000e+00 5.000000e+00
229 606.0 ProcessSetup._PercSyrupBrixSyrStarUp REAL 2.500000e+01 2.500000e+01
230 610.0 ProcessSetup._RefTempCoolingCTRL REAL 0.000000e+00 0.000000e+00
231 614.0 ProcessSetup._H2OSerpPrimingVolume REAL 1.500000e+02 1.500000e+02 Water Serpen tine Volume + Water Chil ler Volume
232 618.0 ProcessSetup._AVN301_Nozzle_Kv REAL 1.650000e+02 1.650000e+02 AVN301 Nozzl e Kv
233 622.0 ProcessSetup._AVN302_Nozzle_Kv REAL 2.600000e+02 2.600000e+02 AVN302 Nozzl e Kv
234 626.0 ProcessSetup._AVN303_Nozzle_Kv REAL 1.650000e+02 1.650000e+02 AVN303 Nozzl e Kv
235 630.0 ProcessSetup._DeoxSpryball_Kv REAL 6.700000e+01 6.700000e+01 Deox Sprybal l Kv
236 634.0 ProcessSetup._PremixedLineDrainTime INT 300 300 Premixed Pro duct Line Dr ain Time
237 636.0 ProcessSetup._PPN301_H_MaxFlow REAL 9.000000e+01 9.000000e+01 PPN301 Pump Head with Ma x Flow [m]
238 640.0 ProcessSetup._PPN301_H_MinFlow REAL 8.700000e+01 8.700000e+01 PPN301 Pump Head with Mi n Flow [m]
239 644.0 ProcessSetup._PPN301_MaxFlow REAL 5.070000e+02 5.070000e+02 PPN301 Max F low [l/min]
240 648.0 ProcessSetup._PPN301_MinFlow REAL 2.110000e+02 2.110000e+02 PPN301 Min F low [l/min]
241 652.0 ProcessSetup._PPP302_H_MaxFlow REAL 8.600000e+01 8.600000e+01 PPP302 Pump Head with Ma x Flow [m]
242 656.0 ProcessSetup._PPP302_H_MinFlow REAL 8.500000e+01 8.500000e+01 PPP302 Pump Head with Mi n Flow [m]
243 660.0 ProcessSetup._PPP302_MaxFlow REAL 1.150000e+02 1.150000e+02 PPP302 Max F low [l/min]
244 664.0 ProcessSetup._PPP302_MinFlow REAL 3.200000e+01 3.200000e+01 PPP302 Min F low [l/min]
245 668.0 ProcessSetup._RinsePPM306Freq REAL 5.000000e+00 5.000000e+00
246 672.0 ProcessSetup._CIPPPM306Freq REAL 5.000000e+00 5.000000e+00
247 676.0 ProcessSetup._PPM307_H_MaxFlow REAL 0.000000e+00 0.000000e+00 PPM307 Pump Head with Ma x Flow [m]
248 680.0 ProcessSetup._PPM307_H_MinFlow REAL 0.000000e+00 0.000000e+00 PPM307 Pump Head with Mi n Flow [m]
249 684.0 ProcessSetup._PPM307_MaxFlow REAL 0.000000e+00 0.000000e+00 PPM307 Max F low [l/min]
250 688.0 ProcessSetup._PPM307_MinFlow REAL 0.000000e+00 0.000000e+00 PPM307 Min F low [l/min]
251 692.0 ProcessSetup._Temp0_VacuumCtrl REAL 1.800000e+01 1.800000e+01 PPN304 Targe t Temperatur e - OPTION PPN304 Sterl ing Type
252 696.0 ProcessSetup._Temp1_VacuumCtrl REAL 2.000000e+00 2.000000e+00 PPN304 High Treshold Tem perature Del ta - OPTION PPN304 Sterl ing Type
253 700.0 ProcessSetup._Temp2_VacuumCtrl REAL 2.000000e+00 2.000000e+00 PPN304 Low T reshold Temp erature Delt a - OPTION PPN304 Sterl ing Type
254 704.0 ProcessSetup._Temp3_VacuumCtrl REAL 5.000000e+01 5.000000e+01 PPN304 Warni ng Temperatu re - OPTION PPN304 Sterl ing Type
255 708.0 ProcessSetup._Temp4_VacuumCtrl REAL 5.000000e+01 5.000000e+01 PPN304 Alarm Temperature - OPTION PPN304 Sterl ing Type
256 712.0 ProcessSetup._T1_VacuumCtrl DINT L#1500 L#1500 PPN304 Time 1 [msec] - OPTION PPN304 Sterl ing Type
257 716.0 ProcessSetup._T2_VacuumCtrl DINT L#1500 L#1500 PPN304 Time 2 [msec] - OPTION PPN304 Sterl ing Type
258 720.0 ProcessSetup._T3_VacuumCtrl DINT L#1000 L#1000 PPN304 Time 3 [msec] - OPTION PPN304 Sterl ing Type
259 724.0 ProcessSetup._T4_VacuumCtrl DINT L#1000 L#1000 PPN304 Time 4 [msec] - OPTION PPN304 Sterl ing Type
260 728.0 ProcessSetup._ICS_VolDosWorkTimePAA INT 30 30 ICS - DS - D osing Workin g Time [sec]
261 730.0 ProcessSetup._ICS_VolPauseTimePAA INT 30 30 ICS - DS - D osing Pause Time [sec]
262 732.0 ProcessSetup._ICS_PAAPulseWeight INT 10 10 ICS - DS - P AA Pulse Wei ght [(L/Puls e)/100]
263 734.0 ProcessSetup._ICS_CausticPulseWeight INT 10 10 ICS - DS - C austic Pulse Weight [(L/ Pulse)/100]
264 736.0 ProcessSetup._ICS_AcidPulseWeight INT 10 10 ICS - DS - A cid Pulse We ight [(L/Pul se)/100]
265 738.0 ProcessSetup._ICS_VolumeRestOfLine REAL 3.500000e+02 3.500000e+02 ICS - DS - V olume of the Rest of the Line (Fille r + Piping) [L]
266 742.0 ProcessSetup._ICS_VolDosWorkTimeCaus INT 30 30 ICS - DS - D osing Workin g Time [sec]
267 744.0 ProcessSetup._ICS_VolDosPauseTimeCaus INT 30 30 ICS - DS - D osing Pause Time [sec]
268 746.0 ProcessSetup._ICS_VolDosWorkTimeAcid INT 30 30 ICS - DS - D osing Workin g Time [sec]
269 748.0 ProcessSetup._ICS_VolDosPauseTimeAcid INT 30 30 ICS - DS - D osing Pause Time [sec]
270 750.0 ProcessSetup._ICS_ConcDosWorkTimeCaus INT 30 30 ICS - DS - D osing Workin g Time [sec]
271 752.0 ProcessSetup._ICS_ConcDosPausTimeCaus INT 30 30 ICS - DS - D osing Pause Time [sec]
272 754.0 ProcessSetup._ICS_ConcDosWorkTimeAcid INT 30 30 ICS - DS - D osing Workin g Time [sec]
273 756.0 ProcessSetup._ICS_ConcDosPausTimeAcid INT 30 30 ICS - DS - D osing Pause Time [sec]
274 758.0 ProcessSetup._RinsePPM307Freq REAL 3.000000e+01 3.000000e+01
275 762.0 ProcessSetup._CIPPPM307Freq REAL 3.000000e+01 3.000000e+01
276 766.0 ProcessSetup._CIP2StepTN301Lvl REAL 0.000000e+00 0.000000e+00 Local CIP - 2 Step loadi ng TN301 Lev el
277 770.0 ProcessSetup._CIP2StepTM301Lvl REAL 0.000000e+00 0.000000e+00 Local CIP - 2 Step loadi ng TM301 Lev el
278 774.0 ProcessSetup._CIP2StepTP301Lvl REAL 0.000000e+00 0.000000e+00 Local CIP - 2 Step loadi ng TP301 Lev el
279 778.0 ProcessSetup._PumpNominalFreq REAL 5.000000e+01 5.000000e+01 50.0 Hz or 6 0.0 Hz
280 782.0 _SwitchOff_DensityOK BOOL FALSE FALSE

View File

@ -1,557 +0,0 @@
TYPE "Recipe_Prod"
FAMILY : DataType
VERSION : 0.1
STRUCT
_Name : STRING [32 ] := ' ';
_EnProdTemp : BOOL ;
_SyrFlushing : BOOL ; //Ex_EnDeaireation --> DELETED - AVP320 VALVE OPEN
_GAS2_Injection : BOOL ; //0 = GAS2 not present; 1 = GAS2 present
_Eq_Pression_Selected : BOOL ;
_DeoxStripEn : BOOL ; //******Deairation with Strip Enable
_DeoxVacuumEn : BOOL ; //******Deairation with Vacuum
_DeoxPreMixed : BOOL ; //******Deairation of Premixed Product
_EnBlowOffProdPipeCO2Fil : BOOL ;
_WaterSelection : BYTE ;
_FillerNextRecipeNum : BYTE ;
_BottleShape : BYTE ;
_Type : INT := 1; //1= DIET; 2= REGULAR; 3= RATIO; 4= WATER
_ProdMeterRecipeNum : INT ;
_SyrupBrix : REAL := 5.000000e+01;
_SyrupDensity : REAL := 1.255800e+00;
_SyrupFactor : REAL := 1.000000e+00;
_ProductBrix : REAL := 1.045000e+01;
_ProductionRate : REAL := 9.000000e+02;
_Ratio : REAL := 2.000000e+01;
_ProdBrixOffset : REAL ;
_CO2Vols : REAL ;
_CO2Fact : REAL := 1.000000e+00;
_ProdTankPress : REAL := 1.000000e+00;
_SP_ProdTemp : REAL := 1.000000e+01;
_PrdTankMinLevel : REAL := 1.000000e+01;
_WaterValveSave : REAL ;
_SyrupValveSave : REAL ;
_CarboCO2ValveSave : REAL ;
_ProdMeterHighBrix : REAL ;
_ProdMeterLowBrix : REAL ;
_ProdMeterHighCO2 : REAL ;
_ProdMeterLowCO2 : REAL ;
_ProdMeter_ZeroCO2 : REAL ;
_ProdMeter_ZeroBrix : REAL ;
_ProdHighCond : REAL ;
_ProdLowCond : REAL ;
_BottleSize : REAL ;
_FillingValveHead_SP : REAL ;
_SyrMeter_ZeroBrix : REAL ;
_FirstProdExtraCO2Fact : REAL := 9.700000e-01;
_Gas2Vols : REAL ;
_Gas2Fact : REAL := 1.000000e+00;
_SyrupPumpPressure : REAL ; //******Syrup Pump Pressure SP
_WaterPumpPressure : REAL ; //******Water Pump Pressure SP
_CO2_Air_N2_PressSelect : INT ; //1=CO2; 2=CO2+SterilAir; 3=CO2+N2 - Pressure Tank Selection
_KFactRVM304BlowOff : REAL ;
_ProdRecircPumpFreq : REAL ;
_ProdBoosterPumpPress : REAL ;
_ProdSendPumpFreq : REAL ; //******Product Sending Pump Frequency SP
END_STRUCT ;
END_TYPE
DATA_BLOCK "HMI_Blender_Parameters"
TITLE =
{ S7_language := '28(1) Albanese 15.06.2005 17:07:04' }
FAMILY : Resource
VERSION : 0.0
STRUCT
Processor_Options : STRUCT
Blender_OPT : STRUCT
_ModelNum : INT := 6;
_CO2_Offset : REAL := 4.500000e-01;
_MaxSyrDeltaBrix : REAL := 8.000000e-01;
_BrixMeter : BOOL := TRUE;
Spare101 : BOOL ;
_TrackH2OEnable : BOOL ;
_PAmPDSType : BOOL ; //0)Cobrix 2000 1)Carbo 2000
_HistoricalTrends : BOOL := TRUE; //0)Not Present 1)Present
_PowerMeter : BOOL ; //0)Not Present 1)Present
_Report : BOOL := TRUE; //0)Not Present 1)Present
_Balaiage : BOOL ;
_Valves_FullFeedback : BOOL := TRUE; //Valves control Full feedback
_Valves_SingleFeedback : BOOL ; //Valves control Single feedback
_PumpsSafetySwitches : BOOL ; //Pumps with Safety Switches
_SurgeProtectionAct : BOOL ;
_DBC_Type : BOOL ; //0) Deox,Carbo,Blend 1)Deox,Blend,Carbo
_CO2InletMeter : BOOL := TRUE; //0)Not Present 1)Present
_ProductO2Meter : BOOL ; //0)Not Present 1)Present
_CopressedAirInletMeter : BOOL ; //0)Not Present 1)Present
_MeterType : INT := 6; //1)Maselli 2)AntoonPaar 3)4-20mA 4)UC05 UR22 5)mPDSPA 6)MR02
_MeterReceiveOnly : BOOL ;
_SyrBrixMeter : BOOL ;
_Flooding_Start_Up : BOOL ; //0)Not Selected 1)Selected
_FastChangeOverEnabled : BOOL := TRUE;
_WaterInletMeter : BOOL ; //0)Not Present 1)Present
_BlendFillSystem : BOOL := TRUE;
_TrackFillerSpeed : BOOL := TRUE;
_SignalExchange : INT := 1; //FILLER - 0= Hardwire; 1= Ethernet
_CoolerPresent : BOOL := TRUE;
_CoolerControl : INT := 4; //0)External 1)Water 2)Product 3)Water+Product-2 Ctrl 4)Water+Product-1 Ctrl
_CoolerType : INT ; //0)Glycol 1)Ammonia
_LocalCIP : BOOL ;
_ICS_CustomerHotWater : BOOL ; //0)No Hot Water from Customer 1)Hot Water from Customer Available
_ICS_CustomerChemRecov : BOOL ; //0)No Customer's Chemicals Recovery 1)Customer's Chemicals Recovery Available
_CIPSignalExchange : BOOL ; //CIP - 0= Hardwire; 1= Ethernet
_ICS_CustomerChemicals : BOOL ; //0)Chemicals from ICS 1)Chemicals from Customer
_CarboPresent : BOOL := TRUE;
_InverterSyrupPumpPPP302 : BOOL ; //0)Not Present 1)Present
_InverterWaterPumpPPN301 : BOOL ; //0)Not Present 1)Present
_DoubleDeair : BOOL := TRUE;
_DeairPreMixed : BOOL ; //Deox Premixed Inlet
_Deaireation : BOOL := TRUE; //0)SAG 1)SAE/SAF
_StillWaterByPass : BOOL ;
_ManifoldSetting : BOOL := TRUE; //0)Manual 1)Automatic
_InverterProdPumpPPM303 : BOOL ;
_SidelCip : BOOL ;
_EthernetCom_CpuPN_CP : BOOL := TRUE; //0)Comunication with CP 1)Comunication with CPU PN
_2ndOutlet : INT ; //0)No 2nd Outlet 1)2nd Outlet No Standalone 2)2nd Outlet Standalone
_Promass : INT := 2;
_WaterPromass : BOOL := TRUE; //0)Promag 1)Promass
_ProductConductimeter : BOOL ;
_ICS_CustomerH2ORecov : BOOL ; //0)No Customer's H2O Recovery 1)Customer's H2O Recovery Available
Spare303 : BOOL ;
_CO2_GAS2_Injection : BOOL ; //0)Only CO2 Injection 1)GAS2 Injection
_InverterVacuuPumpPPN304 : BOOL ; //0)Not Present 1)Present
_InverterBoostPumpPPM307 : BOOL ; //0)Not Present 1)Present
_RunOut_Water : BOOL := TRUE; //0)Syrup Runout without Water 1)Syrup runout with Water pushing
_FlowMeterType : BOOL ; //0)Endrees Hauser -- 1)Micromotion
_SidelFiller : BOOL ; //0)Filler Simonazzi -- 1)Filler Sidel Filling
_Simulation : BOOL ;
_ProductCoolingCTRL : BOOL ; //0)none 1) TTM307
_ChillerCTRL : BOOL ; //Chiller Pressure Cross Control
_CO2_SterileFilter : BOOL := TRUE; //CO2 Inlet with Steril Filter
_InverterRecirPumpPPM306 : BOOL ; //0)Not Present 1)Present
_ProdPressReleaseRVM304 : BOOL ; //0)Not Present 1)Present
_VacuumPump : INT := 1; //0)None 1)Sterling 2)Nash Elmo
_GAS2InjectionType : INT ; //0)None 1)N2 2)Steril Air
_InjectionPress_Ctrl : INT := 1; //0)Manual 1)Norgren v1 2)Norgren v2
_ProdPressureType : INT ; //0)Only CO2 1)CO2+SterilAir 2)CO2+N2
_CIPHeatType : INT ; //0)Steam 1)Electric
_EHS_NrRes : INT := 6; //Number of Heat Resistances
END_STRUCT ;
END_STRUCT ;
Spare1 : ARRAY [1 .. 9 ] OF INT ;
_RVM301_DeadBand : REAL := 5.000000e-02;
_RVM301_Kp : REAL := 9.000000e+01;
Actual_Recipe_Parameters : "Recipe_Prod";
Spare2 : ARRAY [1 .. 5 ] OF INT ;
Next_Recipe_Name : STRING [32 ] := ' ';
Next_Recipe_Number : INT ;
Spare3 : ARRAY [1 .. 18 ] OF INT ;
ProcessSetup : STRUCT
Spare000 : REAL ;
Spare040 : REAL ;
_KWaterLoss : REAL := 1.000000e-03; //Friction Loss Constant in Serpentine
_KSyrupLoss : REAL := 7.800000e-03; //Friction Loss Constant in Syrup Pipe
_KProdLoss : REAL := 1.390000e-02; //Pressure Loss Factor
_KPPM303 : REAL := 5.700000e+00; //Frequency Overpressure Pump P3 Constant [Hz/mm]
_BaialageRVM301OVMin : REAL := 2.000000e+00; //Baialage Minimum Flow (Nm3/h)
_SyrupLinePressure : REAL := 2.200000e+00; //Syrup Line pressure at VEP2 valve
_CIPRMM301OV : REAL := 1.000000e+01; //Water Valve Opening During CIP
_CIPRMP302OV : REAL := 1.500000e+01; //Syrup Valve Opening During CIP
_CIPTM301MinLevel : REAL := 3.500000e+01; //Product Tank Minimum Level In CIP
_CIPTM301MaxLevel : REAL := 5.500000e+01; //Product Tank Maximum Level In CIP
_CIPPPM303Freq : REAL := 5.000000e+01; //CIP frequency Value [Hz]
_CIPTP301MinLevel : REAL := 2.500000e+01; //Syrup Tank Minimum Level In CIP
_CIPTP301MaxLevel : REAL := 4.500000e+01; //Syrup Tank Maximum Level In CIP
_RinseRMM301OV : REAL := 1.000000e+01; //Water Valve Opening During Rinse
_RinseRMP302OV : REAL := 1.400000e+01; //Syrup Valve Opening During Rinse
_RinseTM301Press : REAL := 3.000000e-01; //Product Tank Pressure In Rinse
_RinsePPM303Freq : REAL := 5.000000e+01; //Rinse frequency Value [Hz]
_DrainTM301Press : REAL := 1.000000e+00; //Buffer Tank Draining Pressure
_KRecBlendError : REAL := 2.000000e+00; //Blend Error Recovery CONSTANT
_KRecCarboCO2Error : REAL := 2.000000e+00; //Carbonation Error Recovery Constant
_MaxBlendError : REAL := 1.000000e+02; //Blend Error Maximum Value
_MaxCarboCO2Error : REAL := 5.000000e+02; //Carbonation Error Maximum Value
_StartUpBrixExtraWater : REAL := 4.700000e+01;
_StartUpCO2ExtraWater : REAL := 8.000000e+00;
_StartUpPPM303Freq : REAL := 2.000000e+01; //Start Up frequency Value [Hz]
_SyrupRoomTank : INT := 1;
_SyrupRunOutLiters : REAL := 2.900000e+02;
_InjCO2Press_Offset : REAL := 5.000000e-01;
_InjCO2Press_MinFlow : REAL := 4.500000e+02;
_InjCO2Press_MaxFlow : REAL := 2.500000e+03;
_CarboCO2Pressure : REAL := 1.250000e+01; //CO2 Pressure Infeed Line
_N2MinPressure : REAL := 1.000000e+00; //N2 Minimum Pressure Infeed Line
_DiffSensor_Height : REAL := 3.950000e+02; //Sensor Height from Soil [mm]
_DiffSensor_DeltaHeight : REAL := -2.500000e+01; //Sensor Plates Height Difference [mm]
_DiffSensor_Offset : REAL := 3.618000e+01; //Sensor Offset Read with zero pressure (all valves open) in [mm]
_FillingValveHeight : REAL := 1.400000e+03; //Filling Valve Height from soil [mm]
_FillerDiameter : REAL := 2.520000e+03; //Filler Carousel Diameter [mm]
_FillingValveNum : INT := 91; //Filling Valves Number
_FillerProdPipeDN : REAL := 1.000000e+02;
_FillerProdPipeMass : REAL := 1.600000e+02;
_FillingTime : REAL := 3.200000e+00;
_TM301Height_0 : REAL := 1.050000e+03; //Level at 0% Tank Level Height in mm
_TM301LevelPerc_2 : REAL := 4.600000e+01; //Second level percentage
_TM301Height_2 : REAL := 1.625000e+03; //Second level Height in mm
_RVN304Factor : REAL := 1.000000e+00; //DeareationFlow/WaterFlow
_DrainTM301Flushing : REAL := 1.300000e+00;
_FirstProdExtraBrix : REAL := 5.000000e-02;
_FirstProdDietExtraSyr : REAL := 1.400000e-03;
_EndProdLastSyrlt : REAL ; //End Production Last syrup liters
_TM301DrainSt0Time : WORD := W#16#A; //sec
_TM301DrainSt1Time : WORD := W#16#50; //sec
_ProdPipeRunOutSt0Time : WORD := W#16#1; //sec
_RMM301ProdPipeRunOu : REAL := 3.000000e+01;
_RMP302ProdPipeRunOu : REAL := 4.000000e+01;
_ProdPipeRunOutAmount : REAL := 3.000000e+01;
_TM301RunOutChiller : REAL := 5.000000e+00;
_MinSpeedNominalProd : REAL := 4.000000e-01; //Min Speed for Nominal Production
_MinSpeedSlowProd : REAL := 3.000000e-01; //Min Speed for Very Low Production
_FastChgOvrTM301DrnPrss : REAL := 9.000000e-01; //Fast Change Over Product Tank Draining Pressure in Blendfill
_CIPTN301MinLevel : REAL := 3.500000e+01; //Deaireator Tank Minimum Level In CIP
_CIPTN301MaxLevel : REAL := 6.000000e+01; //Deaireator Tank Maximum Level In CIP
_ProdPPN304Freq : REAL := 5.000000e+01;
_GAS2InjectionPress : REAL := 4.000000e+00;
_BaialageRVM301OVMax : REAL := 2.000000e+01; //Baialage Production Flow Multiplier
_RinsePPN301Freq : REAL := 5.000000e+00;
_CIPPPN301Freq : REAL := 5.000000e+00;
_RinsePPP302Freq : REAL := 5.000000e+00;
_CIPPPP302Freq : REAL := 5.000000e+00;
_PercSyrupBrixSyrStarUp : REAL := 2.500000e+01;
_RefTempCoolingCTRL : REAL ;
_H2OSerpPrimingVolume : REAL := 1.500000e+02; //Water Serpentine Volume + Water Chiller Volume
_AVN301_Nozzle_Kv : REAL := 1.650000e+02; //AVN301 Nozzle Kv
_AVN302_Nozzle_Kv : REAL := 2.600000e+02; //AVN302 Nozzle Kv
_AVN303_Nozzle_Kv : REAL := 1.650000e+02; //AVN303 Nozzle Kv
_DeoxSpryball_Kv : REAL := 6.700000e+01; //Deox Spryball Kv
_PremixedLineDrainTime : INT := 300; //Premixed Product Line Drain Time
_PPN301_H_MaxFlow : REAL := 9.000000e+01; //PPN301 Pump Head with Max Flow [m]
_PPN301_H_MinFlow : REAL := 8.700000e+01; //PPN301 Pump Head with Min Flow [m]
_PPN301_MaxFlow : REAL := 5.070000e+02; //PPN301 Max Flow [l/min]
_PPN301_MinFlow : REAL := 2.110000e+02; //PPN301 Min Flow [l/min]
_PPP302_H_MaxFlow : REAL := 8.600000e+01; //PPP302 Pump Head with Max Flow [m]
_PPP302_H_MinFlow : REAL := 8.500000e+01; //PPP302 Pump Head with Min Flow [m]
_PPP302_MaxFlow : REAL := 1.150000e+02; //PPP302 Max Flow [l/min]
_PPP302_MinFlow : REAL := 3.200000e+01; //PPP302 Min Flow [l/min]
_RinsePPM306Freq : REAL := 5.000000e+00;
_CIPPPM306Freq : REAL := 5.000000e+00;
_PPM307_H_MaxFlow : REAL ; //PPM307 Pump Head with Max Flow [m]
_PPM307_H_MinFlow : REAL ; //PPM307 Pump Head with Min Flow [m]
_PPM307_MaxFlow : REAL ; //PPM307 Max Flow [l/min]
_PPM307_MinFlow : REAL ; //PPM307 Min Flow [l/min]
_Temp0_VacuumCtrl : REAL := 1.800000e+01; //PPN304 Target Temperature - OPTION PPN304 Sterling Type
_Temp1_VacuumCtrl : REAL := 2.000000e+00; //PPN304 High Treshold Temperature Delta - OPTION PPN304 Sterling Type
_Temp2_VacuumCtrl : REAL := 2.000000e+00; //PPN304 Low Treshold Temperature Delta - OPTION PPN304 Sterling Type
_Temp3_VacuumCtrl : REAL := 5.000000e+01; //PPN304 Warning Temperature - OPTION PPN304 Sterling Type
_Temp4_VacuumCtrl : REAL := 5.000000e+01; //PPN304 Alarm Temperature - OPTION PPN304 Sterling Type
_T1_VacuumCtrl : DINT := L#1500; //PPN304 Time 1 [msec] - OPTION PPN304 Sterling Type
_T2_VacuumCtrl : DINT := L#1500; //PPN304 Time 2 [msec] - OPTION PPN304 Sterling Type
_T3_VacuumCtrl : DINT := L#1000; //PPN304 Time 3 [msec] - OPTION PPN304 Sterling Type
_T4_VacuumCtrl : DINT := L#1000; //PPN304 Time 4 [msec] - OPTION PPN304 Sterling Type
_ICS_VolDosWorkTimePAA : INT := 30; //ICS - DS - Dosing Working Time [sec]
_ICS_VolPauseTimePAA : INT := 30; //ICS - DS - Dosing Pause Time [sec]
_ICS_PAAPulseWeight : INT := 10; //ICS - DS - PAA Pulse Weight [(L/Pulse)/100]
_ICS_CausticPulseWeight : INT := 10; //ICS - DS - Caustic Pulse Weight [(L/Pulse)/100]
_ICS_AcidPulseWeight : INT := 10; //ICS - DS - Acid Pulse Weight [(L/Pulse)/100]
_ICS_VolumeRestOfLine : REAL := 3.500000e+02; //ICS - DS - Volume of the Rest of the Line (Filler + Piping) [L]
_ICS_VolDosWorkTimeCaus : INT := 30; //ICS - DS - Dosing Working Time [sec]
_ICS_VolDosPauseTimeCaus : INT := 30; //ICS - DS - Dosing Pause Time [sec]
_ICS_VolDosWorkTimeAcid : INT := 30; //ICS - DS - Dosing Working Time [sec]
_ICS_VolDosPauseTimeAcid : INT := 30; //ICS - DS - Dosing Pause Time [sec]
_ICS_ConcDosWorkTimeCaus : INT := 30; //ICS - DS - Dosing Working Time [sec]
_ICS_ConcDosPausTimeCaus : INT := 30; //ICS - DS - Dosing Pause Time [sec]
_ICS_ConcDosWorkTimeAcid : INT := 30; //ICS - DS - Dosing Working Time [sec]
_ICS_ConcDosPausTimeAcid : INT := 30; //ICS - DS - Dosing Pause Time [sec]
_RinsePPM307Freq : REAL := 3.000000e+01;
_CIPPPM307Freq : REAL := 3.000000e+01;
_CIP2StepTN301Lvl : REAL ; //Local CIP - 2 Step loading TN301 Level
_CIP2StepTM301Lvl : REAL ; //Local CIP - 2 Step loading TM301 Level
_CIP2StepTP301Lvl : REAL ; //Local CIP - 2 Step loading TP301 Level
_PumpNominalFreq : REAL := 5.000000e+01; //50.0 Hz or 60.0 Hz
END_STRUCT ;
_SwitchOff_DensityOK : BOOL ;
END_STRUCT ;
BEGIN
Processor_Options.Blender_OPT._ModelNum := 6;
Processor_Options.Blender_OPT._CO2_Offset := 4.500000e-01;
Processor_Options.Blender_OPT._MaxSyrDeltaBrix := 8.000000e-01;
Processor_Options.Blender_OPT._BrixMeter := TRUE;
Processor_Options.Blender_OPT.Spare101 := FALSE;
Processor_Options.Blender_OPT._TrackH2OEnable := FALSE;
Processor_Options.Blender_OPT._PAmPDSType := FALSE;
Processor_Options.Blender_OPT._HistoricalTrends := TRUE;
Processor_Options.Blender_OPT._PowerMeter := FALSE;
Processor_Options.Blender_OPT._Report := TRUE;
Processor_Options.Blender_OPT._Balaiage := FALSE;
Processor_Options.Blender_OPT._Valves_FullFeedback := TRUE;
Processor_Options.Blender_OPT._Valves_SingleFeedback := FALSE;
Processor_Options.Blender_OPT._PumpsSafetySwitches := FALSE;
Processor_Options.Blender_OPT._SurgeProtectionAct := FALSE;
Processor_Options.Blender_OPT._DBC_Type := FALSE;
Processor_Options.Blender_OPT._CO2InletMeter := TRUE;
Processor_Options.Blender_OPT._ProductO2Meter := FALSE;
Processor_Options.Blender_OPT._CopressedAirInletMeter := FALSE;
Processor_Options.Blender_OPT._MeterType := 6;
Processor_Options.Blender_OPT._MeterReceiveOnly := FALSE;
Processor_Options.Blender_OPT._SyrBrixMeter := FALSE;
Processor_Options.Blender_OPT._Flooding_Start_Up := FALSE;
Processor_Options.Blender_OPT._FastChangeOverEnabled := TRUE;
Processor_Options.Blender_OPT._WaterInletMeter := FALSE;
Processor_Options.Blender_OPT._BlendFillSystem := TRUE;
Processor_Options.Blender_OPT._TrackFillerSpeed := TRUE;
Processor_Options.Blender_OPT._SignalExchange := 1;
Processor_Options.Blender_OPT._CoolerPresent := TRUE;
Processor_Options.Blender_OPT._CoolerControl := 4;
Processor_Options.Blender_OPT._CoolerType := 0;
Processor_Options.Blender_OPT._LocalCIP := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerHotWater := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerChemRecov := FALSE;
Processor_Options.Blender_OPT._CIPSignalExchange := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerChemicals := FALSE;
Processor_Options.Blender_OPT._CarboPresent := TRUE;
Processor_Options.Blender_OPT._InverterSyrupPumpPPP302 := FALSE;
Processor_Options.Blender_OPT._InverterWaterPumpPPN301 := FALSE;
Processor_Options.Blender_OPT._DoubleDeair := TRUE;
Processor_Options.Blender_OPT._DeairPreMixed := FALSE;
Processor_Options.Blender_OPT._Deaireation := TRUE;
Processor_Options.Blender_OPT._StillWaterByPass := FALSE;
Processor_Options.Blender_OPT._ManifoldSetting := TRUE;
Processor_Options.Blender_OPT._InverterProdPumpPPM303 := FALSE;
Processor_Options.Blender_OPT._SidelCip := FALSE;
Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP := TRUE;
Processor_Options.Blender_OPT._2ndOutlet := 0;
Processor_Options.Blender_OPT._Promass := 2;
Processor_Options.Blender_OPT._WaterPromass := TRUE;
Processor_Options.Blender_OPT._ProductConductimeter := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerH2ORecov := FALSE;
Processor_Options.Blender_OPT.Spare303 := FALSE;
Processor_Options.Blender_OPT._CO2_GAS2_Injection := FALSE;
Processor_Options.Blender_OPT._InverterVacuuPumpPPN304 := FALSE;
Processor_Options.Blender_OPT._InverterBoostPumpPPM307 := FALSE;
Processor_Options.Blender_OPT._RunOut_Water := TRUE;
Processor_Options.Blender_OPT._FlowMeterType := TRUE;
Processor_Options.Blender_OPT._SidelFiller := FALSE;
Processor_Options.Blender_OPT._Simulation := FALSE;
Processor_Options.Blender_OPT._ProductCoolingCTRL := FALSE;
Processor_Options.Blender_OPT._ChillerCTRL := FALSE;
Processor_Options.Blender_OPT._CO2_SterileFilter := TRUE;
Processor_Options.Blender_OPT._InverterRecirPumpPPM306 := FALSE;
Processor_Options.Blender_OPT._ProdPressReleaseRVM304 := FALSE;
Processor_Options.Blender_OPT._VacuumPump := 1;
Processor_Options.Blender_OPT._GAS2InjectionType := 0;
Processor_Options.Blender_OPT._InjectionPress_Ctrl := 1;
Processor_Options.Blender_OPT._ProdPressureType := 0;
Processor_Options.Blender_OPT._CIPHeatType := 0;
Processor_Options.Blender_OPT._EHS_NrRes := 6;
Spare1[1] := 0;
Spare1[2] := 0;
Spare1[3] := 0;
Spare1[4] := 0;
Spare1[5] := 0;
Spare1[6] := 0;
Spare1[7] := 0;
Spare1[8] := 0;
Spare1[9] := 0;
_RVM301_DeadBand := 5.000000e-02;
_RVM301_Kp := 9.000000e+01;
Actual_Recipe_Parameters._Name := '';
Actual_Recipe_Parameters._EnProdTemp := TRUE;
Actual_Recipe_Parameters._SyrFlushing := FALSE;
Actual_Recipe_Parameters._GAS2_Injection := FALSE;
Actual_Recipe_Parameters._Eq_Pression_Selected := FALSE;
Actual_Recipe_Parameters._DeoxStripEn := FALSE;
Actual_Recipe_Parameters._DeoxVacuumEn := TRUE;
Actual_Recipe_Parameters._DeoxPreMixed := FALSE;
Actual_Recipe_Parameters._EnBlowOffProdPipeCO2Fil := FALSE;
Actual_Recipe_Parameters._WaterSelection := B#16#0;
Actual_Recipe_Parameters._FillerNextRecipeNum := B#16#0;
Actual_Recipe_Parameters._BottleShape := B#16#0;
Actual_Recipe_Parameters._Type := 2;
Actual_Recipe_Parameters._ProdMeterRecipeNum := 1;
Actual_Recipe_Parameters._SyrupBrix := 4.625000e+01;
Actual_Recipe_Parameters._SyrupDensity := 1.206908e+00;
Actual_Recipe_Parameters._SyrupFactor := 1.000000e+00;
Actual_Recipe_Parameters._ProductBrix := 1.000000e+01;
Actual_Recipe_Parameters._ProductionRate := 3.800000e+02;
Actual_Recipe_Parameters._Ratio := 4.238896e+00;
Actual_Recipe_Parameters._ProdBrixOffset := 2.500000e-01;
Actual_Recipe_Parameters._CO2Vols := 2.550000e+00;
Actual_Recipe_Parameters._CO2Fact := 9.400000e-01;
Actual_Recipe_Parameters._ProdTankPress := 4.400000e+00;
Actual_Recipe_Parameters._SP_ProdTemp := 1.700000e+01;
Actual_Recipe_Parameters._PrdTankMinLevel := 3.500000e+01;
Actual_Recipe_Parameters._WaterValveSave := 0.000000e+00;
Actual_Recipe_Parameters._SyrupValveSave := 0.000000e+00;
Actual_Recipe_Parameters._CarboCO2ValveSave := 0.000000e+00;
Actual_Recipe_Parameters._ProdMeterHighBrix := 1.030000e+01;
Actual_Recipe_Parameters._ProdMeterLowBrix := 9.830000e+00;
Actual_Recipe_Parameters._ProdMeterHighCO2 := 2.900000e+00;
Actual_Recipe_Parameters._ProdMeterLowCO2 := 2.300000e+00;
Actual_Recipe_Parameters._ProdMeter_ZeroCO2 := 0.000000e+00;
Actual_Recipe_Parameters._ProdMeter_ZeroBrix := 0.000000e+00;
Actual_Recipe_Parameters._ProdHighCond := 0.000000e+00;
Actual_Recipe_Parameters._ProdLowCond := 0.000000e+00;
Actual_Recipe_Parameters._BottleSize := 0.000000e+00;
Actual_Recipe_Parameters._FillingValveHead_SP := 0.000000e+00;
Actual_Recipe_Parameters._SyrMeter_ZeroBrix := 0.000000e+00;
Actual_Recipe_Parameters._FirstProdExtraCO2Fact := 1.020000e+00;
Actual_Recipe_Parameters._Gas2Vols := 0.000000e+00;
Actual_Recipe_Parameters._Gas2Fact := 0.000000e+00;
Actual_Recipe_Parameters._SyrupPumpPressure := 0.000000e+00;
Actual_Recipe_Parameters._WaterPumpPressure := 0.000000e+00;
Actual_Recipe_Parameters._CO2_Air_N2_PressSelect := 0;
Actual_Recipe_Parameters._KFactRVM304BlowOff := 0.000000e+00;
Actual_Recipe_Parameters._ProdRecircPumpFreq := 0.000000e+00;
Actual_Recipe_Parameters._ProdBoosterPumpPress := 0.000000e+00;
Actual_Recipe_Parameters._ProdSendPumpFreq := 0.000000e+00;
Spare2[1] := 0;
Spare2[2] := 0;
Spare2[3] := 0;
Spare2[4] := 0;
Spare2[5] := 0;
Next_Recipe_Name := 'cambio 1$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00';
Next_Recipe_Number := 0;
Spare3[1] := 0;
Spare3[2] := 0;
Spare3[3] := 0;
Spare3[4] := 0;
Spare3[5] := 0;
Spare3[6] := 0;
Spare3[7] := 0;
Spare3[8] := 0;
Spare3[9] := 0;
Spare3[10] := 0;
Spare3[11] := 0;
Spare3[12] := 0;
Spare3[13] := 0;
Spare3[14] := 0;
Spare3[15] := 0;
Spare3[16] := 0;
Spare3[17] := 0;
Spare3[18] := 0;
ProcessSetup.Spare000 := 0.000000e+00;
ProcessSetup.Spare040 := 0.000000e+00;
ProcessSetup._KWaterLoss := 1.000000e-03;
ProcessSetup._KSyrupLoss := 7.800000e-03;
ProcessSetup._KProdLoss := 1.390000e-02;
ProcessSetup._KPPM303 := 5.700000e+00;
ProcessSetup._BaialageRVM301OVMin := 2.000000e+00;
ProcessSetup._SyrupLinePressure := 2.200000e+00;
ProcessSetup._CIPRMM301OV := 1.000000e+01;
ProcessSetup._CIPRMP302OV := 1.500000e+01;
ProcessSetup._CIPTM301MinLevel := 3.500000e+01;
ProcessSetup._CIPTM301MaxLevel := 5.500000e+01;
ProcessSetup._CIPPPM303Freq := 5.000000e+01;
ProcessSetup._CIPTP301MinLevel := 2.500000e+01;
ProcessSetup._CIPTP301MaxLevel := 4.500000e+01;
ProcessSetup._RinseRMM301OV := 1.000000e+01;
ProcessSetup._RinseRMP302OV := 1.400000e+01;
ProcessSetup._RinseTM301Press := 3.000000e-01;
ProcessSetup._RinsePPM303Freq := 5.000000e+01;
ProcessSetup._DrainTM301Press := 1.000000e+00;
ProcessSetup._KRecBlendError := 2.000000e+00;
ProcessSetup._KRecCarboCO2Error := 2.000000e+00;
ProcessSetup._MaxBlendError := 1.000000e+02;
ProcessSetup._MaxCarboCO2Error := 5.000000e+02;
ProcessSetup._StartUpBrixExtraWater := 4.700000e+01;
ProcessSetup._StartUpCO2ExtraWater := 8.000000e+00;
ProcessSetup._StartUpPPM303Freq := 2.000000e+01;
ProcessSetup._SyrupRoomTank := 1;
ProcessSetup._SyrupRunOutLiters := 2.900000e+02;
ProcessSetup._InjCO2Press_Offset := 5.000000e-01;
ProcessSetup._InjCO2Press_MinFlow := 4.500000e+02;
ProcessSetup._InjCO2Press_MaxFlow := 2.500000e+03;
ProcessSetup._CarboCO2Pressure := 1.250000e+01;
ProcessSetup._N2MinPressure := 1.000000e+00;
ProcessSetup._DiffSensor_Height := 3.950000e+02;
ProcessSetup._DiffSensor_DeltaHeight := -2.500000e+01;
ProcessSetup._DiffSensor_Offset := 3.618000e+01;
ProcessSetup._FillingValveHeight := 1.400000e+03;
ProcessSetup._FillerDiameter := 2.520000e+03;
ProcessSetup._FillingValveNum := 91;
ProcessSetup._FillerProdPipeDN := 1.000000e+02;
ProcessSetup._FillerProdPipeMass := 1.600000e+02;
ProcessSetup._FillingTime := 3.200000e+00;
ProcessSetup._TM301Height_0 := 1.050000e+03;
ProcessSetup._TM301LevelPerc_2 := 4.600000e+01;
ProcessSetup._TM301Height_2 := 1.625000e+03;
ProcessSetup._RVN304Factor := 1.000000e+00;
ProcessSetup._DrainTM301Flushing := 1.300000e+00;
ProcessSetup._FirstProdExtraBrix := 5.000000e-02;
ProcessSetup._FirstProdDietExtraSyr := 1.400000e-03;
ProcessSetup._EndProdLastSyrlt := 0.000000e+00;
ProcessSetup._TM301DrainSt0Time := W#16#A;
ProcessSetup._TM301DrainSt1Time := W#16#50;
ProcessSetup._ProdPipeRunOutSt0Time := W#16#1;
ProcessSetup._RMM301ProdPipeRunOu := 3.000000e+01;
ProcessSetup._RMP302ProdPipeRunOu := 4.000000e+01;
ProcessSetup._ProdPipeRunOutAmount := 3.000000e+01;
ProcessSetup._TM301RunOutChiller := 5.000000e+00;
ProcessSetup._MinSpeedNominalProd := 4.000000e-01;
ProcessSetup._MinSpeedSlowProd := 3.000000e-01;
ProcessSetup._FastChgOvrTM301DrnPrss := 9.000000e-01;
ProcessSetup._CIPTN301MinLevel := 3.500000e+01;
ProcessSetup._CIPTN301MaxLevel := 6.000000e+01;
ProcessSetup._ProdPPN304Freq := 5.000000e+01;
ProcessSetup._GAS2InjectionPress := 4.000000e+00;
ProcessSetup._BaialageRVM301OVMax := 2.000000e+01;
ProcessSetup._RinsePPN301Freq := 5.000000e+00;
ProcessSetup._CIPPPN301Freq := 5.000000e+00;
ProcessSetup._RinsePPP302Freq := 5.000000e+00;
ProcessSetup._CIPPPP302Freq := 5.000000e+00;
ProcessSetup._PercSyrupBrixSyrStarUp := 2.500000e+01;
ProcessSetup._RefTempCoolingCTRL := 0.000000e+00;
ProcessSetup._H2OSerpPrimingVolume := 1.500000e+02;
ProcessSetup._AVN301_Nozzle_Kv := 1.650000e+02;
ProcessSetup._AVN302_Nozzle_Kv := 2.600000e+02;
ProcessSetup._AVN303_Nozzle_Kv := 1.650000e+02;
ProcessSetup._DeoxSpryball_Kv := 6.700000e+01;
ProcessSetup._PremixedLineDrainTime := 300;
ProcessSetup._PPN301_H_MaxFlow := 9.000000e+01;
ProcessSetup._PPN301_H_MinFlow := 8.700000e+01;
ProcessSetup._PPN301_MaxFlow := 5.070000e+02;
ProcessSetup._PPN301_MinFlow := 2.110000e+02;
ProcessSetup._PPP302_H_MaxFlow := 8.600000e+01;
ProcessSetup._PPP302_H_MinFlow := 8.500000e+01;
ProcessSetup._PPP302_MaxFlow := 1.150000e+02;
ProcessSetup._PPP302_MinFlow := 3.200000e+01;
ProcessSetup._RinsePPM306Freq := 5.000000e+00;
ProcessSetup._CIPPPM306Freq := 5.000000e+00;
ProcessSetup._PPM307_H_MaxFlow := 0.000000e+00;
ProcessSetup._PPM307_H_MinFlow := 0.000000e+00;
ProcessSetup._PPM307_MaxFlow := 0.000000e+00;
ProcessSetup._PPM307_MinFlow := 0.000000e+00;
ProcessSetup._Temp0_VacuumCtrl := 1.800000e+01;
ProcessSetup._Temp1_VacuumCtrl := 2.000000e+00;
ProcessSetup._Temp2_VacuumCtrl := 2.000000e+00;
ProcessSetup._Temp3_VacuumCtrl := 5.000000e+01;
ProcessSetup._Temp4_VacuumCtrl := 5.000000e+01;
ProcessSetup._T1_VacuumCtrl := L#1500;
ProcessSetup._T2_VacuumCtrl := L#1500;
ProcessSetup._T3_VacuumCtrl := L#1000;
ProcessSetup._T4_VacuumCtrl := L#1000;
ProcessSetup._ICS_VolDosWorkTimePAA := 30;
ProcessSetup._ICS_VolPauseTimePAA := 30;
ProcessSetup._ICS_PAAPulseWeight := 10;
ProcessSetup._ICS_CausticPulseWeight := 10;
ProcessSetup._ICS_AcidPulseWeight := 10;
ProcessSetup._ICS_VolumeRestOfLine := 3.500000e+02;
ProcessSetup._ICS_VolDosWorkTimeCaus := 30;
ProcessSetup._ICS_VolDosPauseTimeCaus := 30;
ProcessSetup._ICS_VolDosWorkTimeAcid := 30;
ProcessSetup._ICS_VolDosPauseTimeAcid := 30;
ProcessSetup._ICS_ConcDosWorkTimeCaus := 30;
ProcessSetup._ICS_ConcDosPausTimeCaus := 30;
ProcessSetup._ICS_ConcDosWorkTimeAcid := 30;
ProcessSetup._ICS_ConcDosPausTimeAcid := 30;
ProcessSetup._RinsePPM307Freq := 3.000000e+01;
ProcessSetup._CIPPPM307Freq := 3.000000e+01;
ProcessSetup._CIP2StepTN301Lvl := 0.000000e+00;
ProcessSetup._CIP2StepTM301Lvl := 0.000000e+00;
ProcessSetup._CIP2StepTP301Lvl := 0.000000e+00;
ProcessSetup._PumpNominalFreq := 5.000000e+01;
_SwitchOff_DensityOK := FALSE;
END_DATA_BLOCK

View File

@ -1,208 +0,0 @@
# Documentación para DB: HMI_Blender_Parameters
| Address | Name | Type | Initial Value | Actual Value | Comment |
|---|---|---|---|---|---|
| 0.0 | Processor_Options | STRUCT | | | |
| 0.0 | Processor_Options.Blender_OPT | STRUCT | | | |
| 0.0 | Processor_Options.Blender_OPT._ModelNum | INT | 6 | 6 | |
| 2.0 | Processor_Options.Blender_OPT._CO2_Offset | REAL | 4.500000e-01 | 4.500000e-01 | |
| 6.0 | Processor_Options.Blender_OPT._MaxSyrDeltaBrix | REAL | 8.000000e-01 | 8.000000e-01 | |
| 10.0 | Processor_Options.Blender_OPT._BrixMeter | BOOL | TRUE | TRUE | |
| 10.1 | Processor_Options.Blender_OPT.Spare101 | BOOL | | FALSE | |
| 10.2 | Processor_Options.Blender_OPT._TrackH2OEnable | BOOL | | FALSE | |
| 10.3 | Processor_Options.Blender_OPT._PAmPDSType | BOOL | | FALSE | 0)Cobrix 2000 1)Carbo 2000 |
| 10.4 | Processor_Options.Blender_OPT._HistoricalTrends | BOOL | TRUE | TRUE | 0)Not Present 1)Present |
| 10.5 | Processor_Options.Blender_OPT._PowerMeter | BOOL | | FALSE | 0)Not Present 1)Present |
| 10.6 | Processor_Options.Blender_OPT._Report | BOOL | TRUE | TRUE | 0)Not Present 1)Present |
| 10.7 | Processor_Options.Blender_OPT._Balaiage | BOOL | | FALSE | |
| 11.0 | Processor_Options.Blender_OPT._Valves_FullFeedback | BOOL | TRUE | TRUE | Valves control Full feedback |
| 11.1 | Processor_Options.Blender_OPT._Valves_SingleFeedback | BOOL | | FALSE | Valves control Single feedback |
| 11.2 | Processor_Options.Blender_OPT._PumpsSafetySwitches | BOOL | | FALSE | Pumps with Safety Switches |
| 11.3 | Processor_Options.Blender_OPT._SurgeProtectionAct | BOOL | | FALSE | |
| 11.4 | Processor_Options.Blender_OPT._DBC_Type | BOOL | | FALSE | 0) Deox,Carbo,Blend 1)Deox,Blend,Carbo |
| 11.5 | Processor_Options.Blender_OPT._CO2InletMeter | BOOL | TRUE | TRUE | 0)Not Present 1)Present |
| 11.6 | Processor_Options.Blender_OPT._ProductO2Meter | BOOL | | FALSE | 0)Not Present 1)Present |
| 11.7 | Processor_Options.Blender_OPT._CopressedAirInletMeter | BOOL | | FALSE | 0)Not Present 1)Present |
| 12.0 | Processor_Options.Blender_OPT._MeterType | INT | 6 | 6 | 1)Maselli 2)AntoonPaar 3)4-20mA 4)UC05 UR22 5)mPDSPA 6)MR02 |
| 14.0 | Processor_Options.Blender_OPT._MeterReceiveOnly | BOOL | | FALSE | |
| 14.1 | Processor_Options.Blender_OPT._SyrBrixMeter | BOOL | | FALSE | |
| 14.2 | Processor_Options.Blender_OPT._Flooding_Start_Up | BOOL | | FALSE | 0)Not Selected 1)Selected |
| 14.3 | Processor_Options.Blender_OPT._FastChangeOverEnabled | BOOL | TRUE | TRUE | |
| 14.4 | Processor_Options.Blender_OPT._WaterInletMeter | BOOL | | FALSE | 0)Not Present 1)Present |
| 14.5 | Processor_Options.Blender_OPT._BlendFillSystem | BOOL | TRUE | TRUE | |
| 14.6 | Processor_Options.Blender_OPT._TrackFillerSpeed | BOOL | TRUE | TRUE | |
| 16.0 | Processor_Options.Blender_OPT._SignalExchange | INT | 1 | 1 | FILLER - 0= Hardwire; 1= Ethernet |
| 18.0 | Processor_Options.Blender_OPT._CoolerPresent | BOOL | TRUE | TRUE | |
| 20.0 | Processor_Options.Blender_OPT._CoolerControl | INT | 4 | 4 | 0)External 1)Water 2)Product 3)Water+Product-2 Ctrl 4)Water+Product-1 Ctrl |
| 22.0 | Processor_Options.Blender_OPT._CoolerType | INT | | 0 | 0)Glycol 1)Ammonia |
| 24.0 | Processor_Options.Blender_OPT._LocalCIP | BOOL | | FALSE | |
| 24.1 | Processor_Options.Blender_OPT._ICS_CustomerHotWater | BOOL | | FALSE | 0)No Hot Water from Customer 1)Hot Water from Customer Available |
| 24.2 | Processor_Options.Blender_OPT._ICS_CustomerChemRecov | BOOL | | FALSE | 0)No Customer's Chemicals Recovery 1)Customer's Chemicals Recovery Available |
| 24.3 | Processor_Options.Blender_OPT._CIPSignalExchange | BOOL | | FALSE | CIP - 0= Hardwire; 1= Ethernet |
| 24.4 | Processor_Options.Blender_OPT._ICS_CustomerChemicals | BOOL | | FALSE | 0)Chemicals from ICS 1)Chemicals from Customer |
| 24.5 | Processor_Options.Blender_OPT._CarboPresent | BOOL | TRUE | TRUE | |
| 24.6 | Processor_Options.Blender_OPT._InverterSyrupPumpPPP302 | BOOL | | FALSE | 0)Not Present 1)Present |
| 24.7 | Processor_Options.Blender_OPT._InverterWaterPumpPPN301 | BOOL | | FALSE | 0)Not Present 1)Present |
| 25.0 | Processor_Options.Blender_OPT._DoubleDeair | BOOL | TRUE | TRUE | |
| 25.1 | Processor_Options.Blender_OPT._DeairPreMixed | BOOL | | FALSE | Deox Premixed Inlet |
| 25.2 | Processor_Options.Blender_OPT._Deaireation | BOOL | TRUE | TRUE | 0)SAG 1)SAE/SAF |
| 25.3 | Processor_Options.Blender_OPT._StillWaterByPass | BOOL | | FALSE | |
| 25.4 | Processor_Options.Blender_OPT._ManifoldSetting | BOOL | TRUE | TRUE | 0)Manual 1)Automatic |
| 25.5 | Processor_Options.Blender_OPT._InverterProdPumpPPM303 | BOOL | | FALSE | |
| 25.6 | Processor_Options.Blender_OPT._SidelCip | BOOL | | FALSE | |
| 25.7 | Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP | BOOL | TRUE | TRUE | 0)Comunication with CP 1)Comunication with CPU PN |
| 26.0 | Processor_Options.Blender_OPT._2ndOutlet | INT | | 0 | 0)No 2nd Outlet 1)2nd Outlet No Standalone 2)2nd Outlet Standalone |
| 28.0 | Processor_Options.Blender_OPT._Promass | INT | 2 | 2 | |
| 30.0 | Processor_Options.Blender_OPT._WaterPromass | BOOL | TRUE | TRUE | 0)Promag 1)Promass |
| 30.1 | Processor_Options.Blender_OPT._ProductConductimeter | BOOL | | FALSE | |
| 30.2 | Processor_Options.Blender_OPT._ICS_CustomerH2ORecov | BOOL | | FALSE | 0)No Customer's H2O Recovery 1)Customer's H2O Recovery Available |
| 30.3 | Processor_Options.Blender_OPT.Spare303 | BOOL | | FALSE | |
| 30.4 | Processor_Options.Blender_OPT._CO2_GAS2_Injection | BOOL | | FALSE | 0)Only CO2 Injection 1)GAS2 Injection |
| 30.5 | Processor_Options.Blender_OPT._InverterVacuuPumpPPN304 | BOOL | | FALSE | 0)Not Present 1)Present |
| 30.6 | Processor_Options.Blender_OPT._InverterBoostPumpPPM307 | BOOL | | FALSE | 0)Not Present 1)Present |
| 30.7 | Processor_Options.Blender_OPT._RunOut_Water | BOOL | TRUE | TRUE | 0)Syrup Runout without Water 1)Syrup runout with Water pushing |
| 31.0 | Processor_Options.Blender_OPT._FlowMeterType | BOOL | | TRUE | 0)Endrees Hauser -- 1)Micromotion |
| 31.1 | Processor_Options.Blender_OPT._SidelFiller | BOOL | | FALSE | 0)Filler Simonazzi -- 1)Filler Sidel Filling |
| 31.2 | Processor_Options.Blender_OPT._Simulation | BOOL | | FALSE | |
| 31.3 | Processor_Options.Blender_OPT._ProductCoolingCTRL | BOOL | | FALSE | 0)none 1) TTM307 |
| 31.4 | Processor_Options.Blender_OPT._ChillerCTRL | BOOL | | FALSE | Chiller Pressure Cross Control |
| 31.5 | Processor_Options.Blender_OPT._CO2_SterileFilter | BOOL | TRUE | TRUE | CO2 Inlet with Steril Filter |
| 31.6 | Processor_Options.Blender_OPT._InverterRecirPumpPPM306 | BOOL | | FALSE | 0)Not Present 1)Present |
| 31.7 | Processor_Options.Blender_OPT._ProdPressReleaseRVM304 | BOOL | | FALSE | 0)Not Present 1)Present |
| 32.0 | Processor_Options.Blender_OPT._VacuumPump | INT | 1 | 1 | 0)None 1)Sterling 2)Nash Elmo |
| 34.0 | Processor_Options.Blender_OPT._GAS2InjectionType | INT | | 0 | 0)None 1)N2 2)Steril Air |
| 36.0 | Processor_Options.Blender_OPT._InjectionPress_Ctrl | INT | 1 | 1 | 0)Manual 1)Norgren v1 2)Norgren v2 |
| 38.0 | Processor_Options.Blender_OPT._ProdPressureType | INT | | 0 | 0)Only CO2 1)CO2+SterilAir 2)CO2+N2 |
| 40.0 | Processor_Options.Blender_OPT._CIPHeatType | INT | | 0 | 0)Steam 1)Electric |
| 42.0 | Processor_Options.Blender_OPT._EHS_NrRes | INT | 6 | 6 | Number of Heat Resistances |
| 44.0 | Spare1 | ARRAY [1..9] OF INT | | | |
| 62.0 | _RVM301_DeadBand | REAL | 5.000000e-02 | 5.000000e-02 | |
| 66.0 | _RVM301_Kp | REAL | 9.000000e+01 | 9.000000e+01 | |
| 70.0 | Actual_Recipe_Parameters | "Recipe_Prod" | | | |
| 254.0 | Spare2 | ARRAY [1..5] OF INT | | | |
| 264.0 | Next_Recipe_Name | STRING[32] | ' ' | 'cambio 1$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00' | |
| 298.0 | Next_Recipe_Number | INT | | 0 | |
| 300.0 | Spare3 | ARRAY [1..18] OF INT | | | |
| 336.0 | ProcessSetup | STRUCT | | | |
| 336.0 | ProcessSetup.Spare000 | REAL | | 0.000000e+00 | |
| 340.0 | ProcessSetup.Spare040 | REAL | | 0.000000e+00 | |
| 344.0 | ProcessSetup._KWaterLoss | REAL | 1.000000e-03 | 1.000000e-03 | Friction Loss Constant in Serpentine |
| 348.0 | ProcessSetup._KSyrupLoss | REAL | 7.800000e-03 | 7.800000e-03 | Friction Loss Constant in Syrup Pipe |
| 352.0 | ProcessSetup._KProdLoss | REAL | 1.390000e-02 | 1.390000e-02 | Pressure Loss Factor |
| 356.0 | ProcessSetup._KPPM303 | REAL | 5.700000e+00 | 5.700000e+00 | Frequency Overpressure Pump P3 Constant [Hz/mm] |
| 360.0 | ProcessSetup._BaialageRVM301OVMin | REAL | 2.000000e+00 | 2.000000e+00 | Baialage Minimum Flow (Nm3/h) |
| 364.0 | ProcessSetup._SyrupLinePressure | REAL | 2.200000e+00 | 2.200000e+00 | Syrup Line pressure at VEP2 valve |
| 368.0 | ProcessSetup._CIPRMM301OV | REAL | 1.000000e+01 | 1.000000e+01 | Water Valve Opening During CIP |
| 372.0 | ProcessSetup._CIPRMP302OV | REAL | 1.500000e+01 | 1.500000e+01 | Syrup Valve Opening During CIP |
| 376.0 | ProcessSetup._CIPTM301MinLevel | REAL | 3.500000e+01 | 3.500000e+01 | Product Tank Minimum Level In CIP |
| 380.0 | ProcessSetup._CIPTM301MaxLevel | REAL | 5.500000e+01 | 5.500000e+01 | Product Tank Maximum Level In CIP |
| 384.0 | ProcessSetup._CIPPPM303Freq | REAL | 5.000000e+01 | 5.000000e+01 | CIP frequency Value [Hz] |
| 388.0 | ProcessSetup._CIPTP301MinLevel | REAL | 2.500000e+01 | 2.500000e+01 | Syrup Tank Minimum Level In CIP |
| 392.0 | ProcessSetup._CIPTP301MaxLevel | REAL | 4.500000e+01 | 4.500000e+01 | Syrup Tank Maximum Level In CIP |
| 396.0 | ProcessSetup._RinseRMM301OV | REAL | 1.000000e+01 | 1.000000e+01 | Water Valve Opening During Rinse |
| 400.0 | ProcessSetup._RinseRMP302OV | REAL | 1.400000e+01 | 1.400000e+01 | Syrup Valve Opening During Rinse |
| 404.0 | ProcessSetup._RinseTM301Press | REAL | 3.000000e-01 | 3.000000e-01 | Product Tank Pressure In Rinse |
| 408.0 | ProcessSetup._RinsePPM303Freq | REAL | 5.000000e+01 | 5.000000e+01 | Rinse frequency Value [Hz] |
| 412.0 | ProcessSetup._DrainTM301Press | REAL | 1.000000e+00 | 1.000000e+00 | Buffer Tank Draining Pressure |
| 416.0 | ProcessSetup._KRecBlendError | REAL | 2.000000e+00 | 2.000000e+00 | Blend Error Recovery CONSTANT |
| 420.0 | ProcessSetup._KRecCarboCO2Error | REAL | 2.000000e+00 | 2.000000e+00 | Carbonation Error Recovery Constant |
| 424.0 | ProcessSetup._MaxBlendError | REAL | 1.000000e+02 | 1.000000e+02 | Blend Error Maximum Value |
| 428.0 | ProcessSetup._MaxCarboCO2Error | REAL | 5.000000e+02 | 5.000000e+02 | Carbonation Error Maximum Value |
| 432.0 | ProcessSetup._StartUpBrixExtraWater | REAL | 4.700000e+01 | 4.700000e+01 | |
| 436.0 | ProcessSetup._StartUpCO2ExtraWater | REAL | 8.000000e+00 | 8.000000e+00 | |
| 440.0 | ProcessSetup._StartUpPPM303Freq | REAL | 2.000000e+01 | 2.000000e+01 | Start Up frequency Value [Hz] |
| 444.0 | ProcessSetup._SyrupRoomTank | INT | 1 | 1 | |
| 446.0 | ProcessSetup._SyrupRunOutLiters | REAL | 2.900000e+02 | 2.900000e+02 | |
| 450.0 | ProcessSetup._InjCO2Press_Offset | REAL | 5.000000e-01 | 5.000000e-01 | |
| 454.0 | ProcessSetup._InjCO2Press_MinFlow | REAL | 4.500000e+02 | 4.500000e+02 | |
| 458.0 | ProcessSetup._InjCO2Press_MaxFlow | REAL | 2.500000e+03 | 2.500000e+03 | |
| 462.0 | ProcessSetup._CarboCO2Pressure | REAL | 1.250000e+01 | 1.250000e+01 | CO2 Pressure Infeed Line |
| 466.0 | ProcessSetup._N2MinPressure | REAL | 1.000000e+00 | 1.000000e+00 | N2 Minimum Pressure Infeed Line |
| 470.0 | ProcessSetup._DiffSensor_Height | REAL | 3.950000e+02 | 3.950000e+02 | Sensor Height from Soil [mm] |
| 474.0 | ProcessSetup._DiffSensor_DeltaHeight | REAL | -2.500000e+01 | -2.500000e+01 | Sensor Plates Height Difference [mm] |
| 478.0 | ProcessSetup._DiffSensor_Offset | REAL | 3.618000e+01 | 3.618000e+01 | Sensor Offset Read with zero pressure (all valves open) in [mm] |
| 482.0 | ProcessSetup._FillingValveHeight | REAL | 1.400000e+03 | 1.400000e+03 | Filling Valve Height from soil [mm] |
| 486.0 | ProcessSetup._FillerDiameter | REAL | 2.520000e+03 | 2.520000e+03 | Filler Carousel Diameter [mm] |
| 490.0 | ProcessSetup._FillingValveNum | INT | 91 | 91 | Filling Valves Number |
| 492.0 | ProcessSetup._FillerProdPipeDN | REAL | 1.000000e+02 | 1.000000e+02 | |
| 496.0 | ProcessSetup._FillerProdPipeMass | REAL | 1.600000e+02 | 1.600000e+02 | |
| 500.0 | ProcessSetup._FillingTime | REAL | 3.200000e+00 | 3.200000e+00 | |
| 504.0 | ProcessSetup._TM301Height_0 | REAL | 1.050000e+03 | 1.050000e+03 | Level at 0% Tank Level Height in mm |
| 508.0 | ProcessSetup._TM301LevelPerc_2 | REAL | 4.600000e+01 | 4.600000e+01 | Second level percentage |
| 512.0 | ProcessSetup._TM301Height_2 | REAL | 1.625000e+03 | 1.625000e+03 | Second level Height in mm |
| 516.0 | ProcessSetup._RVN304Factor | REAL | 1.000000e+00 | 1.000000e+00 | DeareationFlow/WaterFlow |
| 520.0 | ProcessSetup._DrainTM301Flushing | REAL | 1.300000e+00 | 1.300000e+00 | |
| 524.0 | ProcessSetup._FirstProdExtraBrix | REAL | 5.000000e-02 | 5.000000e-02 | |
| 528.0 | ProcessSetup._FirstProdDietExtraSyr | REAL | 1.400000e-03 | 1.400000e-03 | |
| 532.0 | ProcessSetup._EndProdLastSyrlt | REAL | | 0.000000e+00 | End Production Last syrup liters |
| 536.0 | ProcessSetup._TM301DrainSt0Time | WORD | W#16#A | W#16#A | sec |
| 538.0 | ProcessSetup._TM301DrainSt1Time | WORD | W#16#50 | W#16#50 | sec |
| 540.0 | ProcessSetup._ProdPipeRunOutSt0Time | WORD | W#16#1 | W#16#1 | sec |
| 542.0 | ProcessSetup._RMM301ProdPipeRunOu | REAL | 3.000000e+01 | 3.000000e+01 | |
| 546.0 | ProcessSetup._RMP302ProdPipeRunOu | REAL | 4.000000e+01 | 4.000000e+01 | |
| 550.0 | ProcessSetup._ProdPipeRunOutAmount | REAL | 3.000000e+01 | 3.000000e+01 | |
| 554.0 | ProcessSetup._TM301RunOutChiller | REAL | 5.000000e+00 | 5.000000e+00 | |
| 558.0 | ProcessSetup._MinSpeedNominalProd | REAL | 4.000000e-01 | 4.000000e-01 | Min Speed for Nominal Production |
| 562.0 | ProcessSetup._MinSpeedSlowProd | REAL | 3.000000e-01 | 3.000000e-01 | Min Speed for Very Low Production |
| 566.0 | ProcessSetup._FastChgOvrTM301DrnPrss | REAL | 9.000000e-01 | 9.000000e-01 | Fast Change Over Product Tank Draining Pressure in Blendfill |
| 570.0 | ProcessSetup._CIPTN301MinLevel | REAL | 3.500000e+01 | 3.500000e+01 | Deaireator Tank Minimum Level In CIP |
| 574.0 | ProcessSetup._CIPTN301MaxLevel | REAL | 6.000000e+01 | 6.000000e+01 | Deaireator Tank Maximum Level In CIP |
| 578.0 | ProcessSetup._ProdPPN304Freq | REAL | 5.000000e+01 | 5.000000e+01 | |
| 582.0 | ProcessSetup._GAS2InjectionPress | REAL | 4.000000e+00 | 4.000000e+00 | |
| 586.0 | ProcessSetup._BaialageRVM301OVMax | REAL | 2.000000e+01 | 2.000000e+01 | Baialage Production Flow Multiplier |
| 590.0 | ProcessSetup._RinsePPN301Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 594.0 | ProcessSetup._CIPPPN301Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 598.0 | ProcessSetup._RinsePPP302Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 602.0 | ProcessSetup._CIPPPP302Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 606.0 | ProcessSetup._PercSyrupBrixSyrStarUp | REAL | 2.500000e+01 | 2.500000e+01 | |
| 610.0 | ProcessSetup._RefTempCoolingCTRL | REAL | | 0.000000e+00 | |
| 614.0 | ProcessSetup._H2OSerpPrimingVolume | REAL | 1.500000e+02 | 1.500000e+02 | Water Serpentine Volume + Water Chiller Volume |
| 618.0 | ProcessSetup._AVN301_Nozzle_Kv | REAL | 1.650000e+02 | 1.650000e+02 | AVN301 Nozzle Kv |
| 622.0 | ProcessSetup._AVN302_Nozzle_Kv | REAL | 2.600000e+02 | 2.600000e+02 | AVN302 Nozzle Kv |
| 626.0 | ProcessSetup._AVN303_Nozzle_Kv | REAL | 1.650000e+02 | 1.650000e+02 | AVN303 Nozzle Kv |
| 630.0 | ProcessSetup._DeoxSpryball_Kv | REAL | 6.700000e+01 | 6.700000e+01 | Deox Spryball Kv |
| 634.0 | ProcessSetup._PremixedLineDrainTime | INT | 300 | 300 | Premixed Product Line Drain Time |
| 636.0 | ProcessSetup._PPN301_H_MaxFlow | REAL | 9.000000e+01 | 9.000000e+01 | PPN301 Pump Head with Max Flow [m] |
| 640.0 | ProcessSetup._PPN301_H_MinFlow | REAL | 8.700000e+01 | 8.700000e+01 | PPN301 Pump Head with Min Flow [m] |
| 644.0 | ProcessSetup._PPN301_MaxFlow | REAL | 5.070000e+02 | 5.070000e+02 | PPN301 Max Flow [l/min] |
| 648.0 | ProcessSetup._PPN301_MinFlow | REAL | 2.110000e+02 | 2.110000e+02 | PPN301 Min Flow [l/min] |
| 652.0 | ProcessSetup._PPP302_H_MaxFlow | REAL | 8.600000e+01 | 8.600000e+01 | PPP302 Pump Head with Max Flow [m] |
| 656.0 | ProcessSetup._PPP302_H_MinFlow | REAL | 8.500000e+01 | 8.500000e+01 | PPP302 Pump Head with Min Flow [m] |
| 660.0 | ProcessSetup._PPP302_MaxFlow | REAL | 1.150000e+02 | 1.150000e+02 | PPP302 Max Flow [l/min] |
| 664.0 | ProcessSetup._PPP302_MinFlow | REAL | 3.200000e+01 | 3.200000e+01 | PPP302 Min Flow [l/min] |
| 668.0 | ProcessSetup._RinsePPM306Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 672.0 | ProcessSetup._CIPPPM306Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 676.0 | ProcessSetup._PPM307_H_MaxFlow | REAL | | 0.000000e+00 | PPM307 Pump Head with Max Flow [m] |
| 680.0 | ProcessSetup._PPM307_H_MinFlow | REAL | | 0.000000e+00 | PPM307 Pump Head with Min Flow [m] |
| 684.0 | ProcessSetup._PPM307_MaxFlow | REAL | | 0.000000e+00 | PPM307 Max Flow [l/min] |
| 688.0 | ProcessSetup._PPM307_MinFlow | REAL | | 0.000000e+00 | PPM307 Min Flow [l/min] |
| 692.0 | ProcessSetup._Temp0_VacuumCtrl | REAL | 1.800000e+01 | 1.800000e+01 | PPN304 Target Temperature - OPTION PPN304 Sterling Type |
| 696.0 | ProcessSetup._Temp1_VacuumCtrl | REAL | 2.000000e+00 | 2.000000e+00 | PPN304 High Treshold Temperature Delta - OPTION PPN304 Sterling Type |
| 700.0 | ProcessSetup._Temp2_VacuumCtrl | REAL | 2.000000e+00 | 2.000000e+00 | PPN304 Low Treshold Temperature Delta - OPTION PPN304 Sterling Type |
| 704.0 | ProcessSetup._Temp3_VacuumCtrl | REAL | 5.000000e+01 | 5.000000e+01 | PPN304 Warning Temperature - OPTION PPN304 Sterling Type |
| 708.0 | ProcessSetup._Temp4_VacuumCtrl | REAL | 5.000000e+01 | 5.000000e+01 | PPN304 Alarm Temperature - OPTION PPN304 Sterling Type |
| 712.0 | ProcessSetup._T1_VacuumCtrl | DINT | L#1500 | L#1500 | PPN304 Time 1 [msec] - OPTION PPN304 Sterling Type |
| 716.0 | ProcessSetup._T2_VacuumCtrl | DINT | L#1500 | L#1500 | PPN304 Time 2 [msec] - OPTION PPN304 Sterling Type |
| 720.0 | ProcessSetup._T3_VacuumCtrl | DINT | L#1000 | L#1000 | PPN304 Time 3 [msec] - OPTION PPN304 Sterling Type |
| 724.0 | ProcessSetup._T4_VacuumCtrl | DINT | L#1000 | L#1000 | PPN304 Time 4 [msec] - OPTION PPN304 Sterling Type |
| 728.0 | ProcessSetup._ICS_VolDosWorkTimePAA | INT | 30 | 30 | ICS - DS - Dosing Working Time [sec] |
| 730.0 | ProcessSetup._ICS_VolPauseTimePAA | INT | 30 | 30 | ICS - DS - Dosing Pause Time [sec] |
| 732.0 | ProcessSetup._ICS_PAAPulseWeight | INT | 10 | 10 | ICS - DS - PAA Pulse Weight [(L/Pulse)/100] |
| 734.0 | ProcessSetup._ICS_CausticPulseWeight | INT | 10 | 10 | ICS - DS - Caustic Pulse Weight [(L/Pulse)/100] |
| 736.0 | ProcessSetup._ICS_AcidPulseWeight | INT | 10 | 10 | ICS - DS - Acid Pulse Weight [(L/Pulse)/100] |
| 738.0 | ProcessSetup._ICS_VolumeRestOfLine | REAL | 3.500000e+02 | 3.500000e+02 | ICS - DS - Volume of the Rest of the Line (Filler + Piping) [L] |
| 742.0 | ProcessSetup._ICS_VolDosWorkTimeCaus | INT | 30 | 30 | ICS - DS - Dosing Working Time [sec] |
| 744.0 | ProcessSetup._ICS_VolDosPauseTimeCaus | INT | 30 | 30 | ICS - DS - Dosing Pause Time [sec] |
| 746.0 | ProcessSetup._ICS_VolDosWorkTimeAcid | INT | 30 | 30 | ICS - DS - Dosing Working Time [sec] |
| 748.0 | ProcessSetup._ICS_VolDosPauseTimeAcid | INT | 30 | 30 | ICS - DS - Dosing Pause Time [sec] |
| 750.0 | ProcessSetup._ICS_ConcDosWorkTimeCaus | INT | 30 | 30 | ICS - DS - Dosing Working Time [sec] |
| 752.0 | ProcessSetup._ICS_ConcDosPausTimeCaus | INT | 30 | 30 | ICS - DS - Dosing Pause Time [sec] |
| 754.0 | ProcessSetup._ICS_ConcDosWorkTimeAcid | INT | 30 | 30 | ICS - DS - Dosing Working Time [sec] |
| 756.0 | ProcessSetup._ICS_ConcDosPausTimeAcid | INT | 30 | 30 | ICS - DS - Dosing Pause Time [sec] |
| 758.0 | ProcessSetup._RinsePPM307Freq | REAL | 3.000000e+01 | 3.000000e+01 | |
| 762.0 | ProcessSetup._CIPPPM307Freq | REAL | 3.000000e+01 | 3.000000e+01 | |
| 766.0 | ProcessSetup._CIP2StepTN301Lvl | REAL | | 0.000000e+00 | Local CIP - 2 Step loading TN301 Level |
| 770.0 | ProcessSetup._CIP2StepTM301Lvl | REAL | | 0.000000e+00 | Local CIP - 2 Step loading TM301 Level |
| 774.0 | ProcessSetup._CIP2StepTP301Lvl | REAL | | 0.000000e+00 | Local CIP - 2 Step loading TP301 Level |
| 778.0 | ProcessSetup._PumpNominalFreq | REAL | 5.000000e+01 | 5.000000e+01 | 50.0 Hz or 60.0 Hz |
| 782.0 | _SwitchOff_DensityOK | BOOL | | FALSE | |

View File

@ -1,51 +1,30 @@
--- Log de Ejecución: x3.py --- --- Log de Ejecución: x3.py ---
Grupo: S7_DB_Utils Grupo: S7_DB_Utils
Directorio de Trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001 Directorio de Trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Inicio: 2025-05-16 20:15:59 Inicio: 2025-05-17 21:31:24
Fin: 2025-05-16 20:16:00 Fin: 2025-05-17 21:31:25
Duración: 0:00:00.897567 Duración: 0:00:00.136451
Estado: ERROR (Código de Salida: 1) Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) --- --- SALIDA ESTÁNDAR (STDOUT) ---
Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Los archivos JSON de salida se guardarán en: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json
Archivos encontrados para procesar: 3
--- Procesando archivo: db1001_data.db ---
Parseo completo. Intentando serializar a JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_data.json
Resultado guardado en: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_data.json
--- Procesando archivo: db1001_format.db ---
Parseo completo. Intentando serializar a JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format.json
Resultado guardado en: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format.json
--- Procesando archivo: db1001_format_updated.db ---
Parseo completo. Intentando serializar a JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format_updated.json
Resultado guardado en: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format_updated.json
--- Proceso completado ---
--- ERRORES (STDERR) --- --- ERRORES (STDERR) ---
2025-05-16 20:16:00,228 - db_mapper - INFO - Iniciando mapeo de DBs por dirección absoluta Ninguno
2025-05-16 20:16:00,309 - db_mapper - INFO - Directorio de trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
2025-05-16 20:16:00,310 - db_mapper - INFO - Encontrados 3 archivos para procesar
2025-05-16 20:16:00,310 - db_mapper - INFO - Procesando: db1001_data.db
2025-05-16 20:16:00,310 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db
2025-05-16 20:16:00,310 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db: module 'DB_Parser' has no attribute 'parse_db_definition'
Traceback (most recent call last):
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 76, in process_db_file
db_node, db_number, db_name, family, version = DB_Parser.parse_db_definition(db_content, udt_definitions)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'DB_Parser' has no attribute 'parse_db_definition'
2025-05-16 20:16:00,312 - db_mapper - INFO - Procesando: db1001_format.db
2025-05-16 20:16:00,312 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db
2025-05-16 20:16:00,313 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db: module 'DB_Parser' has no attribute 'parse_udt_definition'
Traceback (most recent call last):
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 64, in process_db_file
udt_name, udt_node = DB_Parser.parse_udt_definition(udt_content)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'DB_Parser' has no attribute 'parse_udt_definition'
2025-05-16 20:16:00,316 - db_mapper - INFO - Procesando: db1001_format_updated.db
2025-05-16 20:16:00,316 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format_updated.db
2025-05-16 20:16:00,316 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format_updated.db: module 'DB_Parser' has no attribute 'parse_udt_definition'
Traceback (most recent call last):
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 64, in process_db_file
udt_name, udt_node = DB_Parser.parse_udt_definition(udt_content)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'DB_Parser' has no attribute 'parse_udt_definition'
Traceback (most recent call last):
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 444, in <module>
main()
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 430, in main
processed_files, mapped_pairs = process_all_files_in_directory()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 372, in process_all_files_in_directory
"timestamp": import_datetime().now().isoformat()
^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'datetime' has no attribute 'now'
--- FIN DEL LOG --- --- FIN DEL LOG ---

View File

@ -0,0 +1,36 @@
--- Log de Ejecución: x4.py ---
Grupo: S7_DB_Utils
Directorio de Trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Inicio: 2025-05-17 21:37:42
Fin: 2025-05-17 21:37:42
Duración: 0:00:00.131741
Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) ---
Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Los archivos de documentación generados se guardarán en: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation
Archivos JSON encontrados para procesar: 3
--- Procesando archivo JSON: db1001_data.json ---
Archivo JSON 'db1001_data.json' cargado correctamente.
INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
Archivo S7 reconstruido generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_data.txt
Archivo Markdown de documentación generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_data.md
--- Procesando archivo JSON: db1001_format.json ---
Archivo JSON 'db1001_format.json' cargado correctamente.
INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
Archivo S7 reconstruido generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format.txt
Archivo Markdown de documentación generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format.md
--- Procesando archivo JSON: db1001_format_updated.json ---
Archivo JSON 'db1001_format_updated.json' cargado correctamente.
INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
Archivo S7 reconstruido generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format_updated.txt
Archivo Markdown de documentación generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format_updated.md
--- Proceso de generación de documentación completado ---
--- ERRORES (STDERR) ---
Ninguno
--- FIN DEL LOG ---

View File

@ -0,0 +1,30 @@
--- Log de Ejecución: x5.py ---
Grupo: S7_DB_Utils
Directorio de Trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Inicio: 2025-05-17 21:51:25
Fin: 2025-05-17 21:51:25
Duración: 0:00:00.099104
Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) ---
Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Los archivos Markdown de descripción se guardarán en: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation
Archivos JSON encontrados para procesar: 3
--- Procesando archivo JSON para descripción: db1001_data.json ---
Archivo JSON 'db1001_data.json' cargado correctamente.
Documentación Markdown completa generada: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_data_description.md
--- Procesando archivo JSON para descripción: db1001_format.json ---
Archivo JSON 'db1001_format.json' cargado correctamente.
Documentación Markdown completa generada: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format_description.md
--- Procesando archivo JSON para descripción: db1001_format_updated.json ---
Archivo JSON 'db1001_format_updated.json' cargado correctamente.
Documentación Markdown completa generada: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format_updated_description.md
--- Proceso de generación de descripciones Markdown completado ---
--- ERRORES (STDERR) ---
Ninguno
--- FIN DEL LOG ---

View File

@ -0,0 +1,33 @@
--- Log de Ejecución: x6.py ---
Grupo: S7_DB_Utils
Directorio de Trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Inicio: 2025-05-17 22:05:32
Fin: 2025-05-17 22:05:33
Duración: 0:00:00.614471
Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) ---
Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Los archivos Excel de documentación se guardarán en: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation
Archivos JSON encontrados para procesar: 3
--- Procesando archivo JSON para Excel: db1001_data.json ---
Archivo JSON 'db1001_data.json' cargado correctamente.
Generando documentación Excel para DB: 'HMI_Blender_Parameters' (desde db1001_data.json) -> C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_data.json.xlsx
Excel documentation generated: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_data.json.xlsx
--- Procesando archivo JSON para Excel: db1001_format.json ---
Archivo JSON 'db1001_format.json' cargado correctamente.
Generando documentación Excel para DB: 'HMI_Blender_Parameters' (desde db1001_format.json) -> C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format.json.xlsx
Excel documentation generated: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format.json.xlsx
--- Procesando archivo JSON para Excel: db1001_format_updated.json ---
Archivo JSON 'db1001_format_updated.json' cargado correctamente.
Generando documentación Excel para DB: 'HMI_Blender_Parameters' (desde db1001_format_updated.json) -> C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format_updated.json.xlsx
Excel documentation generated: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format_updated.json.xlsx
--- Proceso de generación de documentación Excel completado ---
--- ERRORES (STDERR) ---
Ninguno
--- FIN DEL LOG ---

View File

@ -0,0 +1,29 @@
--- Log de Ejecución: x7_value_updater.py ---
Grupo: S7_DB_Utils
Directorio de Trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Inicio: 2025-05-17 23:48:43
Fin: 2025-05-17 23:48:43
Duración: 0:00:00.106052
Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) ---
Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Found _data file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db
Found _format file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db
Parsing S7 file: db1001_data.db...
Serializing to JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_data_data.json
JSON saved: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_data_data.json
Parsing S7 file: db1001_format.db...
Serializing to JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format_format.json
JSON saved: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format_format.json
Comparing structure of DB: HMI_Blender_Parameters
La estructura del DB 'HMI_Blender_Parameters' es compatible.
All DB structures are compatible. Proceeding to generate _updated file.
INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
Successfully generated _updated S7 file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_updated.db
--- ERRORES (STDERR) ---
Ninguno
--- FIN DEL LOG ---

File diff suppressed because it is too large Load Diff

View File

@ -1,521 +0,0 @@
TYPE "Recipe_Prod"
FAMILY : DataType;
VERSION : 0.1;
STRUCT
_Name : STRING[32] := ' ';
_EnProdTemp : BOOL;
_SyrFlushing : BOOL; // Ex_EnDeaireation --> DELETED - AVP320 VALVE OPEN
_GAS2_Injection : BOOL; // 0 = GAS2 not present; 1 = GAS2 present
_Eq_Pression_Selected : BOOL;
_DeoxStripEn : BOOL; // ******Deairation with Strip Enable
_DeoxVacuumEn : BOOL; // ******Deairation with Vacuum
_DeoxPreMixed : BOOL; // ******Deairation of Premixed Product
_EnBlowOffProdPipeCO2Fil : BOOL;
_WaterSelection : BYTE;
_FillerNextRecipeNum : BYTE;
_BottleShape : BYTE;
_Type : INT := 1; // 1= DIET; 2= REGULAR; 3= RATIO; 4= WATER
_ProdMeterRecipeNum : INT;
_SyrupBrix : REAL := 5.000000e+01;
_SyrupDensity : REAL := 1.255800e+00;
_SyrupFactor : REAL := 1.000000e+00;
_ProductBrix : REAL := 1.045000e+01;
_ProductionRate : REAL := 9.000000e+02;
_Ratio : REAL := 2.000000e+01;
_ProdBrixOffset : REAL;
_CO2Vols : REAL;
_CO2Fact : REAL := 1.000000e+00;
_ProdTankPress : REAL := 1.000000e+00;
_SP_ProdTemp : REAL := 1.000000e+01;
_PrdTankMinLevel : REAL := 1.000000e+01;
_WaterValveSave : REAL;
_SyrupValveSave : REAL;
_CarboCO2ValveSave : REAL;
_ProdMeterHighBrix : REAL;
_ProdMeterLowBrix : REAL;
_ProdMeterHighCO2 : REAL;
_ProdMeterLowCO2 : REAL;
_ProdMeter_ZeroCO2 : REAL;
_ProdMeter_ZeroBrix : REAL;
_ProdHighCond : REAL;
_ProdLowCond : REAL;
_BottleSize : REAL;
_FillingValveHead_SP : REAL;
_SyrMeter_ZeroBrix : REAL;
_FirstProdExtraCO2Fact : REAL := 9.700000e-01;
_Gas2Vols : REAL;
_Gas2Fact : REAL := 1.000000e+00;
_SyrupPumpPressure : REAL; // ******Syrup Pump Pressure SP
_WaterPumpPressure : REAL; // ******Water Pump Pressure SP
_CO2_Air_N2_PressSelect : INT; // 1=CO2; 2=CO2+SterilAir; 3=CO2+N2 - Pressure Tank Selection
_KFactRVM304BlowOff : REAL;
_ProdRecircPumpFreq : REAL;
_ProdBoosterPumpPress : REAL;
_ProdSendPumpFreq : REAL; // ******Product Sending Pump Frequency SP
END_STRUCT;
END_TYPE;
DATA_BLOCK "HMI_Blender_Parameters"
FAMILY : Resource;
VERSION : 0.0;
STRUCT
Processor_Options : STRUCT;
Blender_OPT : STRUCT;
_ModelNum : INT := 6;
_CO2_Offset : REAL := 4.500000e-01;
_MaxSyrDeltaBrix : REAL := 8.000000e-01;
_BrixMeter : BOOL := TRUE;
Spare101 : BOOL;
_TrackH2OEnable : BOOL;
_PAmPDSType : BOOL; // 0)Cobrix 2000 1)Carbo 2000
_HistoricalTrends : BOOL := TRUE; // 0)Not Present 1)Present
_PowerMeter : BOOL; // 0)Not Present 1)Present
_Report : BOOL := TRUE; // 0)Not Present 1)Present
_Balaiage : BOOL;
_Valves_FullFeedback : BOOL := TRUE; // Valves control Full feedback
_Valves_SingleFeedback : BOOL; // Valves control Single feedback
_PumpsSafetySwitches : BOOL; // Pumps with Safety Switches
_SurgeProtectionAct : BOOL;
_DBC_Type : BOOL; // 0) Deox,Carbo,Blend 1)Deox,Blend,Carbo
_CO2InletMeter : BOOL := TRUE; // 0)Not Present 1)Present
_ProductO2Meter : BOOL; // 0)Not Present 1)Present
_CopressedAirInletMeter : BOOL; // 0)Not Present 1)Present
_MeterType : INT := 6; // 1)Maselli 2)AntoonPaar 3)4-20mA 4)UC05 UR22 5)mPDSPA 6)MR02
_MeterReceiveOnly : BOOL;
_SyrBrixMeter : BOOL;
_Flooding_Start_Up : BOOL; // 0)Not Selected 1)Selected
_FastChangeOverEnabled : BOOL := TRUE;
_WaterInletMeter : BOOL; // 0)Not Present 1)Present
_BlendFillSystem : BOOL := TRUE;
_TrackFillerSpeed : BOOL := TRUE;
_SignalExchange : INT := 1; // FILLER - 0= Hardwire; 1= Ethernet
_CoolerPresent : BOOL := TRUE;
_CoolerControl : INT := 4; // 0)External 1)Water 2)Product 3)Water+Product-2 Ctrl 4)Water+Product-1 Ctrl
_CoolerType : INT; // 0)Glycol 1)Ammonia
_LocalCIP : BOOL;
_ICS_CustomerHotWater : BOOL; // 0)No Hot Water from Customer 1)Hot Water from Customer Available
_ICS_CustomerChemRecov : BOOL; // 0)No Customer's Chemicals Recovery 1)Customer's Chemicals Recovery Available
_CIPSignalExchange : BOOL; // CIP - 0= Hardwire; 1= Ethernet
_ICS_CustomerChemicals : BOOL; // 0)Chemicals from ICS 1)Chemicals from Customer
_CarboPresent : BOOL := TRUE;
_InverterSyrupPumpPPP302 : BOOL; // 0)Not Present 1)Present
_InverterWaterPumpPPN301 : BOOL; // 0)Not Present 1)Present
_DoubleDeair : BOOL := TRUE;
_DeairPreMixed : BOOL; // Deox Premixed Inlet
_Deaireation : BOOL := TRUE; // 0)SAG 1)SAE/SAF
_StillWaterByPass : BOOL;
_ManifoldSetting : BOOL := TRUE; // 0)Manual 1)Automatic
_InverterProdPumpPPM303 : BOOL;
_SidelCip : BOOL;
_EthernetCom_CpuPN_CP : BOOL := TRUE; // 0)Comunication with CP 1)Comunication with CPU PN
_2ndOutlet : INT; // 0)No 2nd Outlet 1)2nd Outlet No Standalone 2)2nd Outlet Standalone
_Promass : INT := 2;
_WaterPromass : BOOL := TRUE; // 0)Promag 1)Promass
_ProductConductimeter : BOOL;
_ICS_CustomerH2ORecov : BOOL; // 0)No Customer's H2O Recovery 1)Customer's H2O Recovery Available
Spare303 : BOOL;
_CO2_GAS2_Injection : BOOL; // 0)Only CO2 Injection 1)GAS2 Injection
_InverterVacuuPumpPPN304 : BOOL; // 0)Not Present 1)Present
_InverterBoostPumpPPM307 : BOOL; // 0)Not Present 1)Present
_RunOut_Water : BOOL := TRUE; // 0)Syrup Runout without Water 1)Syrup runout with Water pushing
_FlowMeterType : BOOL; // 0)Endrees Hauser -- 1)Micromotion
_SidelFiller : BOOL; // 0)Filler Simonazzi -- 1)Filler Sidel Filling
_Simulation : BOOL;
_ProductCoolingCTRL : BOOL; // 0)none 1) TTM307
_ChillerCTRL : BOOL; // Chiller Pressure Cross Control
_CO2_SterileFilter : BOOL := TRUE; // CO2 Inlet with Steril Filter
_InverterRecirPumpPPM306 : BOOL; // 0)Not Present 1)Present
_ProdPressReleaseRVM304 : BOOL; // 0)Not Present 1)Present
_VacuumPump : INT := 1; // 0)None 1)Sterling 2)Nash Elmo
_GAS2InjectionType : INT; // 0)None 1)N2 2)Steril Air
_InjectionPress_Ctrl : INT := 1; // 0)Manual 1)Norgren v1 2)Norgren v2
_ProdPressureType : INT; // 0)Only CO2 1)CO2+SterilAir 2)CO2+N2
_CIPHeatType : INT; // 0)Steam 1)Electric
_EHS_NrRes : INT := 6; // Number of Heat Resistances
END_STRUCT;
END_STRUCT;
Spare1 : ARRAY [1..9] OF INT;
_RVM301_DeadBand : REAL := 5.000000e-02;
_RVM301_Kp : REAL := 9.000000e+01;
Actual_Recipe_Parameters : "Recipe_Prod";
Spare2 : ARRAY [1..5] OF INT;
Next_Recipe_Name : STRING[32] := ' ';
Next_Recipe_Number : INT;
Spare3 : ARRAY [1..18] OF INT;
ProcessSetup : STRUCT;
Spare000 : REAL;
Spare040 : REAL;
_KWaterLoss : REAL := 1.000000e-03; // Friction Loss Constant in Serpentine
_KSyrupLoss : REAL := 7.800000e-03; // Friction Loss Constant in Syrup Pipe
_KProdLoss : REAL := 1.390000e-02; // Pressure Loss Factor
_KPPM303 : REAL := 5.700000e+00; // Frequency Overpressure Pump P3 Constant [Hz/mm]
_BaialageRVM301OVMin : REAL := 2.000000e+00; // Baialage Minimum Flow (Nm3/h)
_SyrupLinePressure : REAL := 2.200000e+00; // Syrup Line pressure at VEP2 valve
_CIPRMM301OV : REAL := 1.000000e+01; // Water Valve Opening During CIP
_CIPRMP302OV : REAL := 1.500000e+01; // Syrup Valve Opening During CIP
_CIPTM301MinLevel : REAL := 3.500000e+01; // Product Tank Minimum Level In CIP
_CIPTM301MaxLevel : REAL := 5.500000e+01; // Product Tank Maximum Level In CIP
_CIPPPM303Freq : REAL := 5.000000e+01; // CIP frequency Value [Hz]
_CIPTP301MinLevel : REAL := 2.500000e+01; // Syrup Tank Minimum Level In CIP
_CIPTP301MaxLevel : REAL := 4.500000e+01; // Syrup Tank Maximum Level In CIP
_RinseRMM301OV : REAL := 1.000000e+01; // Water Valve Opening During Rinse
_RinseRMP302OV : REAL := 1.400000e+01; // Syrup Valve Opening During Rinse
_RinseTM301Press : REAL := 3.000000e-01; // Product Tank Pressure In Rinse
_RinsePPM303Freq : REAL := 5.000000e+01; // Rinse frequency Value [Hz]
_DrainTM301Press : REAL := 1.000000e+00; // Buffer Tank Draining Pressure
_KRecBlendError : REAL := 2.000000e+00; // Blend Error Recovery CONSTANT
_KRecCarboCO2Error : REAL := 2.000000e+00; // Carbonation Error Recovery Constant
_MaxBlendError : REAL := 1.000000e+02; // Blend Error Maximum Value
_MaxCarboCO2Error : REAL := 5.000000e+02; // Carbonation Error Maximum Value
_StartUpBrixExtraWater : REAL := 4.700000e+01;
_StartUpCO2ExtraWater : REAL := 8.000000e+00;
_StartUpPPM303Freq : REAL := 2.000000e+01; // Start Up frequency Value [Hz]
_SyrupRoomTank : INT := 1;
_SyrupRunOutLiters : REAL := 2.900000e+02;
_InjCO2Press_Offset : REAL := 5.000000e-01;
_InjCO2Press_MinFlow : REAL := 4.500000e+02;
_InjCO2Press_MaxFlow : REAL := 2.500000e+03;
_CarboCO2Pressure : REAL := 1.250000e+01; // CO2 Pressure Infeed Line
_N2MinPressure : REAL := 1.000000e+00; // N2 Minimum Pressure Infeed Line
_DiffSensor_Height : REAL := 3.950000e+02; // Sensor Height from Soil [mm]
_DiffSensor_DeltaHeight : REAL := -2.500000e+01; // Sensor Plates Height Difference [mm]
_DiffSensor_Offset : REAL := 3.618000e+01; // Sensor Offset Read with zero pressure (all valves open) in [mm]
_FillingValveHeight : REAL := 1.400000e+03; // Filling Valve Height from soil [mm]
_FillerDiameter : REAL := 2.520000e+03; // Filler Carousel Diameter [mm]
_FillingValveNum : INT := 91; // Filling Valves Number
_FillerProdPipeDN : REAL := 1.000000e+02;
_FillerProdPipeMass : REAL := 1.600000e+02;
_FillingTime : REAL := 3.200000e+00;
_TM301Height_0 : REAL := 1.050000e+03; // Level at 0% Tank Level Height in mm
_TM301LevelPerc_2 : REAL := 4.600000e+01; // Second level percentage
_TM301Height_2 : REAL := 1.625000e+03; // Second level Height in mm
_RVN304Factor : REAL := 1.000000e+00; // DeareationFlow/WaterFlow
_DrainTM301Flushing : REAL := 1.300000e+00;
_FirstProdExtraBrix : REAL := 5.000000e-02;
_FirstProdDietExtraSyr : REAL := 1.400000e-03;
_EndProdLastSyrlt : REAL; // End Production Last syrup liters
_TM301DrainSt0Time : WORD := W#16#A; // sec
_TM301DrainSt1Time : WORD := W#16#50; // sec
_ProdPipeRunOutSt0Time : WORD := W#16#1; // sec
_RMM301ProdPipeRunOu : REAL := 3.000000e+01;
_RMP302ProdPipeRunOu : REAL := 4.000000e+01;
_ProdPipeRunOutAmount : REAL := 3.000000e+01;
_TM301RunOutChiller : REAL := 5.000000e+00;
_MinSpeedNominalProd : REAL := 4.000000e-01; // Min Speed for Nominal Production
_MinSpeedSlowProd : REAL := 3.000000e-01; // Min Speed for Very Low Production
_FastChgOvrTM301DrnPrss : REAL := 9.000000e-01; // Fast Change Over Product Tank Draining Pressure in Blendfill
_CIPTN301MinLevel : REAL := 3.500000e+01; // Deaireator Tank Minimum Level In CIP
_CIPTN301MaxLevel : REAL := 6.000000e+01; // Deaireator Tank Maximum Level In CIP
_ProdPPN304Freq : REAL := 5.000000e+01;
_GAS2InjectionPress : REAL := 4.000000e+00;
_BaialageRVM301OVMax : REAL := 2.000000e+01; // Baialage Production Flow Multiplier
_RinsePPN301Freq : REAL := 5.000000e+00;
_CIPPPN301Freq : REAL := 5.000000e+00;
_RinsePPP302Freq : REAL := 5.000000e+00;
_CIPPPP302Freq : REAL := 5.000000e+00;
_PercSyrupBrixSyrStarUp : REAL := 2.500000e+01;
_RefTempCoolingCTRL : REAL;
_H2OSerpPrimingVolume : REAL := 1.500000e+02; // Water Serpentine Volume + Water Chiller Volume
_AVN301_Nozzle_Kv : REAL := 1.650000e+02; // AVN301 Nozzle Kv
_AVN302_Nozzle_Kv : REAL := 2.600000e+02; // AVN302 Nozzle Kv
_AVN303_Nozzle_Kv : REAL := 1.650000e+02; // AVN303 Nozzle Kv
_DeoxSpryball_Kv : REAL := 6.700000e+01; // Deox Spryball Kv
_PremixedLineDrainTime : INT := 300; // Premixed Product Line Drain Time
_PPN301_H_MaxFlow : REAL := 9.000000e+01; // PPN301 Pump Head with Max Flow [m]
_PPN301_H_MinFlow : REAL := 8.700000e+01; // PPN301 Pump Head with Min Flow [m]
_PPN301_MaxFlow : REAL := 5.070000e+02; // PPN301 Max Flow [l/min]
_PPN301_MinFlow : REAL := 2.110000e+02; // PPN301 Min Flow [l/min]
_PPP302_H_MaxFlow : REAL := 8.600000e+01; // PPP302 Pump Head with Max Flow [m]
_PPP302_H_MinFlow : REAL := 8.500000e+01; // PPP302 Pump Head with Min Flow [m]
_PPP302_MaxFlow : REAL := 1.150000e+02; // PPP302 Max Flow [l/min]
_PPP302_MinFlow : REAL := 3.200000e+01; // PPP302 Min Flow [l/min]
_RinsePPM306Freq : REAL := 5.000000e+00;
_CIPPPM306Freq : REAL := 5.000000e+00;
_PPM307_H_MaxFlow : REAL; // PPM307 Pump Head with Max Flow [m]
_PPM307_H_MinFlow : REAL; // PPM307 Pump Head with Min Flow [m]
_PPM307_MaxFlow : REAL; // PPM307 Max Flow [l/min]
_PPM307_MinFlow : REAL; // PPM307 Min Flow [l/min]
_Temp0_VacuumCtrl : REAL := 1.800000e+01; // PPN304 Target Temperature - OPTION PPN304 Sterling Type
_Temp1_VacuumCtrl : REAL := 2.000000e+00; // PPN304 High Treshold Temperature Delta - OPTION PPN304 Sterling Type
_Temp2_VacuumCtrl : REAL := 2.000000e+00; // PPN304 Low Treshold Temperature Delta - OPTION PPN304 Sterling Type
_Temp3_VacuumCtrl : REAL := 5.000000e+01; // PPN304 Warning Temperature - OPTION PPN304 Sterling Type
_Temp4_VacuumCtrl : REAL := 5.000000e+01; // PPN304 Alarm Temperature - OPTION PPN304 Sterling Type
_T1_VacuumCtrl : DINT := L#1500; // PPN304 Time 1 [msec] - OPTION PPN304 Sterling Type
_T2_VacuumCtrl : DINT := L#1500; // PPN304 Time 2 [msec] - OPTION PPN304 Sterling Type
_T3_VacuumCtrl : DINT := L#1000; // PPN304 Time 3 [msec] - OPTION PPN304 Sterling Type
_T4_VacuumCtrl : DINT := L#1000; // PPN304 Time 4 [msec] - OPTION PPN304 Sterling Type
_ICS_VolDosWorkTimePAA : INT := 30; // ICS - DS - Dosing Working Time [sec]
_ICS_VolPauseTimePAA : INT := 30; // ICS - DS - Dosing Pause Time [sec]
_ICS_PAAPulseWeight : INT := 10; // ICS - DS - PAA Pulse Weight [(L/Pulse)/100]
_ICS_CausticPulseWeight : INT := 10; // ICS - DS - Caustic Pulse Weight [(L/Pulse)/100]
_ICS_AcidPulseWeight : INT := 10; // ICS - DS - Acid Pulse Weight [(L/Pulse)/100]
_ICS_VolumeRestOfLine : REAL := 3.500000e+02; // ICS - DS - Volume of the Rest of the Line (Filler + Piping) [L]
_ICS_VolDosWorkTimeCaus : INT := 30; // ICS - DS - Dosing Working Time [sec]
_ICS_VolDosPauseTimeCaus : INT := 30; // ICS - DS - Dosing Pause Time [sec]
_ICS_VolDosWorkTimeAcid : INT := 30; // ICS - DS - Dosing Working Time [sec]
_ICS_VolDosPauseTimeAcid : INT := 30; // ICS - DS - Dosing Pause Time [sec]
_ICS_ConcDosWorkTimeCaus : INT := 30; // ICS - DS - Dosing Working Time [sec]
_ICS_ConcDosPausTimeCaus : INT := 30; // ICS - DS - Dosing Pause Time [sec]
_ICS_ConcDosWorkTimeAcid : INT := 30; // ICS - DS - Dosing Working Time [sec]
_ICS_ConcDosPausTimeAcid : INT := 30; // ICS - DS - Dosing Pause Time [sec]
_RinsePPM307Freq : REAL := 3.000000e+01;
_CIPPPM307Freq : REAL := 3.000000e+01;
_CIP2StepTN301Lvl : REAL; // Local CIP - 2 Step loading TN301 Level
_CIP2StepTM301Lvl : REAL; // Local CIP - 2 Step loading TM301 Level
_CIP2StepTP301Lvl : REAL; // Local CIP - 2 Step loading TP301 Level
_PumpNominalFreq : REAL := 5.000000e+01; // 50.0 Hz or 60.0 Hz
END_STRUCT;
_SwitchOff_DensityOK : BOOL;
END_STRUCT;
BEGIN
Processor_Options.Blender_OPT._ModelNum := 6;
Processor_Options.Blender_OPT._CO2_Offset := 4.500000e-01;
Processor_Options.Blender_OPT._MaxSyrDeltaBrix := 8.000000e-01;
Processor_Options.Blender_OPT._BrixMeter := TRUE;
Processor_Options.Blender_OPT.Spare101 := FALSE;
Processor_Options.Blender_OPT._TrackH2OEnable := FALSE;
Processor_Options.Blender_OPT._PAmPDSType := FALSE;
Processor_Options.Blender_OPT._HistoricalTrends := TRUE;
Processor_Options.Blender_OPT._PowerMeter := FALSE;
Processor_Options.Blender_OPT._Report := TRUE;
Processor_Options.Blender_OPT._Balaiage := FALSE;
Processor_Options.Blender_OPT._Valves_FullFeedback := TRUE;
Processor_Options.Blender_OPT._Valves_SingleFeedback := FALSE;
Processor_Options.Blender_OPT._PumpsSafetySwitches := FALSE;
Processor_Options.Blender_OPT._SurgeProtectionAct := FALSE;
Processor_Options.Blender_OPT._DBC_Type := FALSE;
Processor_Options.Blender_OPT._CO2InletMeter := TRUE;
Processor_Options.Blender_OPT._ProductO2Meter := FALSE;
Processor_Options.Blender_OPT._CopressedAirInletMeter := FALSE;
Processor_Options.Blender_OPT._MeterType := 6;
Processor_Options.Blender_OPT._MeterReceiveOnly := FALSE;
Processor_Options.Blender_OPT._SyrBrixMeter := FALSE;
Processor_Options.Blender_OPT._Flooding_Start_Up := FALSE;
Processor_Options.Blender_OPT._FastChangeOverEnabled := TRUE;
Processor_Options.Blender_OPT._WaterInletMeter := FALSE;
Processor_Options.Blender_OPT._BlendFillSystem := TRUE;
Processor_Options.Blender_OPT._TrackFillerSpeed := TRUE;
Processor_Options.Blender_OPT._SignalExchange := 1;
Processor_Options.Blender_OPT._CoolerPresent := TRUE;
Processor_Options.Blender_OPT._CoolerControl := 4;
Processor_Options.Blender_OPT._CoolerType := 0;
Processor_Options.Blender_OPT._LocalCIP := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerHotWater := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerChemRecov := FALSE;
Processor_Options.Blender_OPT._CIPSignalExchange := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerChemicals := FALSE;
Processor_Options.Blender_OPT._CarboPresent := TRUE;
Processor_Options.Blender_OPT._InverterSyrupPumpPPP302 := FALSE;
Processor_Options.Blender_OPT._InverterWaterPumpPPN301 := FALSE;
Processor_Options.Blender_OPT._DoubleDeair := TRUE;
Processor_Options.Blender_OPT._DeairPreMixed := FALSE;
Processor_Options.Blender_OPT._Deaireation := TRUE;
Processor_Options.Blender_OPT._StillWaterByPass := FALSE;
Processor_Options.Blender_OPT._ManifoldSetting := TRUE;
Processor_Options.Blender_OPT._InverterProdPumpPPM303 := FALSE;
Processor_Options.Blender_OPT._SidelCip := FALSE;
Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP := TRUE;
Processor_Options.Blender_OPT._2ndOutlet := 0;
Processor_Options.Blender_OPT._Promass := 2;
Processor_Options.Blender_OPT._WaterPromass := TRUE;
Processor_Options.Blender_OPT._ProductConductimeter := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerH2ORecov := FALSE;
Processor_Options.Blender_OPT.Spare303 := FALSE;
Processor_Options.Blender_OPT._CO2_GAS2_Injection := FALSE;
Processor_Options.Blender_OPT._InverterVacuuPumpPPN304 := FALSE;
Processor_Options.Blender_OPT._InverterBoostPumpPPM307 := FALSE;
Processor_Options.Blender_OPT._RunOut_Water := TRUE;
Processor_Options.Blender_OPT._FlowMeterType := TRUE;
Processor_Options.Blender_OPT._SidelFiller := FALSE;
Processor_Options.Blender_OPT._Simulation := FALSE;
Processor_Options.Blender_OPT._ProductCoolingCTRL := FALSE;
Processor_Options.Blender_OPT._ChillerCTRL := FALSE;
Processor_Options.Blender_OPT._CO2_SterileFilter := TRUE;
Processor_Options.Blender_OPT._InverterRecirPumpPPM306 := FALSE;
Processor_Options.Blender_OPT._ProdPressReleaseRVM304 := FALSE;
Processor_Options.Blender_OPT._VacuumPump := 1;
Processor_Options.Blender_OPT._GAS2InjectionType := 0;
Processor_Options.Blender_OPT._InjectionPress_Ctrl := 1;
Processor_Options.Blender_OPT._ProdPressureType := 0;
Processor_Options.Blender_OPT._CIPHeatType := 0;
Processor_Options.Blender_OPT._EHS_NrRes := 6;
_RVM301_DeadBand := 5.000000e-02;
_RVM301_Kp := 9.000000e+01;
Actual_Recipe_Parameters._Name := '';
Actual_Recipe_Parameters._EnProdTemp := TRUE;
Actual_Recipe_Parameters._SyrFlushing := FALSE;
Actual_Recipe_Parameters._GAS2_Injection := FALSE;
Actual_Recipe_Parameters._Eq_Pression_Selected := FALSE;
Actual_Recipe_Parameters._DeoxStripEn := FALSE;
Actual_Recipe_Parameters._DeoxVacuumEn := TRUE;
Actual_Recipe_Parameters._DeoxPreMixed := FALSE;
Actual_Recipe_Parameters._EnBlowOffProdPipeCO2Fil := FALSE;
Actual_Recipe_Parameters._WaterSelection := B#16#0;
Actual_Recipe_Parameters._FillerNextRecipeNum := B#16#0;
Actual_Recipe_Parameters._BottleShape := B#16#0;
Actual_Recipe_Parameters._Type := 2;
Actual_Recipe_Parameters._ProdMeterRecipeNum := 1;
Actual_Recipe_Parameters._SyrupBrix := 4.625000e+01;
Actual_Recipe_Parameters._SyrupDensity := 1.206908e+00;
Actual_Recipe_Parameters._SyrupFactor := 1.000000e+00;
Actual_Recipe_Parameters._ProductBrix := 1.000000e+01;
Actual_Recipe_Parameters._ProductionRate := 3.800000e+02;
Actual_Recipe_Parameters._Ratio := 4.238896e+00;
Actual_Recipe_Parameters._ProdBrixOffset := 2.500000e-01;
Actual_Recipe_Parameters._CO2Vols := 2.550000e+00;
Actual_Recipe_Parameters._CO2Fact := 9.400000e-01;
Actual_Recipe_Parameters._ProdTankPress := 4.400000e+00;
Actual_Recipe_Parameters._SP_ProdTemp := 1.700000e+01;
Actual_Recipe_Parameters._PrdTankMinLevel := 3.500000e+01;
Actual_Recipe_Parameters._WaterValveSave := 0.000000e+00;
Actual_Recipe_Parameters._SyrupValveSave := 0.000000e+00;
Actual_Recipe_Parameters._CarboCO2ValveSave := 0.000000e+00;
Actual_Recipe_Parameters._ProdMeterHighBrix := 1.030000e+01;
Actual_Recipe_Parameters._ProdMeterLowBrix := 9.830000e+00;
Actual_Recipe_Parameters._ProdMeterHighCO2 := 2.900000e+00;
Actual_Recipe_Parameters._ProdMeterLowCO2 := 2.300000e+00;
Actual_Recipe_Parameters._ProdMeter_ZeroCO2 := 0.000000e+00;
Actual_Recipe_Parameters._ProdMeter_ZeroBrix := 0.000000e+00;
Actual_Recipe_Parameters._ProdHighCond := 0.000000e+00;
Actual_Recipe_Parameters._ProdLowCond := 0.000000e+00;
Actual_Recipe_Parameters._BottleSize := 0.000000e+00;
Actual_Recipe_Parameters._FillingValveHead_SP := 0.000000e+00;
Actual_Recipe_Parameters._SyrMeter_ZeroBrix := 0.000000e+00;
Actual_Recipe_Parameters._FirstProdExtraCO2Fact := 1.020000e+00;
Actual_Recipe_Parameters._Gas2Vols := 0.000000e+00;
Actual_Recipe_Parameters._Gas2Fact := 0.000000e+00;
Actual_Recipe_Parameters._SyrupPumpPressure := 0.000000e+00;
Actual_Recipe_Parameters._WaterPumpPressure := 0.000000e+00;
Actual_Recipe_Parameters._CO2_Air_N2_PressSelect := 0;
Actual_Recipe_Parameters._KFactRVM304BlowOff := 0.000000e+00;
Actual_Recipe_Parameters._ProdRecircPumpFreq := 0.000000e+00;
Actual_Recipe_Parameters._ProdBoosterPumpPress := 0.000000e+00;
Actual_Recipe_Parameters._ProdSendPumpFreq := 0.000000e+00;
Next_Recipe_Name := 'cambio 1$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00';
Next_Recipe_Number := 0;
ProcessSetup.Spare000 := 0.000000e+00;
ProcessSetup.Spare040 := 0.000000e+00;
ProcessSetup._KWaterLoss := 1.000000e-03;
ProcessSetup._KSyrupLoss := 7.800000e-03;
ProcessSetup._KProdLoss := 1.390000e-02;
ProcessSetup._KPPM303 := 5.700000e+00;
ProcessSetup._BaialageRVM301OVMin := 2.000000e+00;
ProcessSetup._SyrupLinePressure := 2.200000e+00;
ProcessSetup._CIPRMM301OV := 1.000000e+01;
ProcessSetup._CIPRMP302OV := 1.500000e+01;
ProcessSetup._CIPTM301MinLevel := 3.500000e+01;
ProcessSetup._CIPTM301MaxLevel := 5.500000e+01;
ProcessSetup._CIPPPM303Freq := 5.000000e+01;
ProcessSetup._CIPTP301MinLevel := 2.500000e+01;
ProcessSetup._CIPTP301MaxLevel := 4.500000e+01;
ProcessSetup._RinseRMM301OV := 1.000000e+01;
ProcessSetup._RinseRMP302OV := 1.400000e+01;
ProcessSetup._RinseTM301Press := 3.000000e-01;
ProcessSetup._RinsePPM303Freq := 5.000000e+01;
ProcessSetup._DrainTM301Press := 1.000000e+00;
ProcessSetup._KRecBlendError := 2.000000e+00;
ProcessSetup._KRecCarboCO2Error := 2.000000e+00;
ProcessSetup._MaxBlendError := 1.000000e+02;
ProcessSetup._MaxCarboCO2Error := 5.000000e+02;
ProcessSetup._StartUpBrixExtraWater := 4.700000e+01;
ProcessSetup._StartUpCO2ExtraWater := 8.000000e+00;
ProcessSetup._StartUpPPM303Freq := 2.000000e+01;
ProcessSetup._SyrupRoomTank := 1;
ProcessSetup._SyrupRunOutLiters := 2.900000e+02;
ProcessSetup._InjCO2Press_Offset := 5.000000e-01;
ProcessSetup._InjCO2Press_MinFlow := 4.500000e+02;
ProcessSetup._InjCO2Press_MaxFlow := 2.500000e+03;
ProcessSetup._CarboCO2Pressure := 1.250000e+01;
ProcessSetup._N2MinPressure := 1.000000e+00;
ProcessSetup._DiffSensor_Height := 3.950000e+02;
ProcessSetup._DiffSensor_DeltaHeight := -2.500000e+01;
ProcessSetup._DiffSensor_Offset := 3.618000e+01;
ProcessSetup._FillingValveHeight := 1.400000e+03;
ProcessSetup._FillerDiameter := 2.520000e+03;
ProcessSetup._FillingValveNum := 91;
ProcessSetup._FillerProdPipeDN := 1.000000e+02;
ProcessSetup._FillerProdPipeMass := 1.600000e+02;
ProcessSetup._FillingTime := 3.200000e+00;
ProcessSetup._TM301Height_0 := 1.050000e+03;
ProcessSetup._TM301LevelPerc_2 := 4.600000e+01;
ProcessSetup._TM301Height_2 := 1.625000e+03;
ProcessSetup._RVN304Factor := 1.000000e+00;
ProcessSetup._DrainTM301Flushing := 1.300000e+00;
ProcessSetup._FirstProdExtraBrix := 5.000000e-02;
ProcessSetup._FirstProdDietExtraSyr := 1.400000e-03;
ProcessSetup._EndProdLastSyrlt := 0.000000e+00;
ProcessSetup._TM301DrainSt0Time := W#16#A;
ProcessSetup._TM301DrainSt1Time := W#16#50;
ProcessSetup._ProdPipeRunOutSt0Time := W#16#1;
ProcessSetup._RMM301ProdPipeRunOu := 3.000000e+01;
ProcessSetup._RMP302ProdPipeRunOu := 4.000000e+01;
ProcessSetup._ProdPipeRunOutAmount := 3.000000e+01;
ProcessSetup._TM301RunOutChiller := 5.000000e+00;
ProcessSetup._MinSpeedNominalProd := 4.000000e-01;
ProcessSetup._MinSpeedSlowProd := 3.000000e-01;
ProcessSetup._FastChgOvrTM301DrnPrss := 9.000000e-01;
ProcessSetup._CIPTN301MinLevel := 3.500000e+01;
ProcessSetup._CIPTN301MaxLevel := 6.000000e+01;
ProcessSetup._ProdPPN304Freq := 5.000000e+01;
ProcessSetup._GAS2InjectionPress := 4.000000e+00;
ProcessSetup._BaialageRVM301OVMax := 2.000000e+01;
ProcessSetup._RinsePPN301Freq := 5.000000e+00;
ProcessSetup._CIPPPN301Freq := 5.000000e+00;
ProcessSetup._RinsePPP302Freq := 5.000000e+00;
ProcessSetup._CIPPPP302Freq := 5.000000e+00;
ProcessSetup._PercSyrupBrixSyrStarUp := 2.500000e+01;
ProcessSetup._RefTempCoolingCTRL := 0.000000e+00;
ProcessSetup._H2OSerpPrimingVolume := 1.500000e+02;
ProcessSetup._AVN301_Nozzle_Kv := 1.650000e+02;
ProcessSetup._AVN302_Nozzle_Kv := 2.600000e+02;
ProcessSetup._AVN303_Nozzle_Kv := 1.650000e+02;
ProcessSetup._DeoxSpryball_Kv := 6.700000e+01;
ProcessSetup._PremixedLineDrainTime := 300;
ProcessSetup._PPN301_H_MaxFlow := 9.000000e+01;
ProcessSetup._PPN301_H_MinFlow := 8.700000e+01;
ProcessSetup._PPN301_MaxFlow := 5.070000e+02;
ProcessSetup._PPN301_MinFlow := 2.110000e+02;
ProcessSetup._PPP302_H_MaxFlow := 8.600000e+01;
ProcessSetup._PPP302_H_MinFlow := 8.500000e+01;
ProcessSetup._PPP302_MaxFlow := 1.150000e+02;
ProcessSetup._PPP302_MinFlow := 3.200000e+01;
ProcessSetup._RinsePPM306Freq := 5.000000e+00;
ProcessSetup._CIPPPM306Freq := 5.000000e+00;
ProcessSetup._PPM307_H_MaxFlow := 0.000000e+00;
ProcessSetup._PPM307_H_MinFlow := 0.000000e+00;
ProcessSetup._PPM307_MaxFlow := 0.000000e+00;
ProcessSetup._PPM307_MinFlow := 0.000000e+00;
ProcessSetup._Temp0_VacuumCtrl := 1.800000e+01;
ProcessSetup._Temp1_VacuumCtrl := 2.000000e+00;
ProcessSetup._Temp2_VacuumCtrl := 2.000000e+00;
ProcessSetup._Temp3_VacuumCtrl := 5.000000e+01;
ProcessSetup._Temp4_VacuumCtrl := 5.000000e+01;
ProcessSetup._T1_VacuumCtrl := L#1500;
ProcessSetup._T2_VacuumCtrl := L#1500;
ProcessSetup._T3_VacuumCtrl := L#1000;
ProcessSetup._T4_VacuumCtrl := L#1000;
ProcessSetup._ICS_VolDosWorkTimePAA := 30;
ProcessSetup._ICS_VolPauseTimePAA := 30;
ProcessSetup._ICS_PAAPulseWeight := 10;
ProcessSetup._ICS_CausticPulseWeight := 10;
ProcessSetup._ICS_AcidPulseWeight := 10;
ProcessSetup._ICS_VolumeRestOfLine := 3.500000e+02;
ProcessSetup._ICS_VolDosWorkTimeCaus := 30;
ProcessSetup._ICS_VolDosPauseTimeCaus := 30;
ProcessSetup._ICS_VolDosWorkTimeAcid := 30;
ProcessSetup._ICS_VolDosPauseTimeAcid := 30;
ProcessSetup._ICS_ConcDosWorkTimeCaus := 30;
ProcessSetup._ICS_ConcDosPausTimeCaus := 30;
ProcessSetup._ICS_ConcDosWorkTimeAcid := 30;
ProcessSetup._ICS_ConcDosPausTimeAcid := 30;
ProcessSetup._RinsePPM307Freq := 3.000000e+01;
ProcessSetup._CIPPPM307Freq := 3.000000e+01;
ProcessSetup._CIP2StepTN301Lvl := 0.000000e+00;
ProcessSetup._CIP2StepTM301Lvl := 0.000000e+00;
ProcessSetup._CIP2StepTP301Lvl := 0.000000e+00;
ProcessSetup._PumpNominalFreq := 5.000000e+01;
_SwitchOff_DensityOK := FALSE;
END_DATA_BLOCK;

View File

@ -18,7 +18,31 @@
"hidden": true "hidden": true
}, },
"x3.py": { "x3.py": {
"display_name": "x3", "display_name": "03: Parse DB/AWL",
"short_description": "Crear archivos json haciendo parsing de los archivos .db o .awl",
"long_description": "",
"hidden": false
},
"x4.py": {
"display_name": "04: Generar S7 Source y MD",
"short_description": "Genera código S7 (.txt) y Markdown (.md) desde JSON.",
"long_description": "Procesa archivos JSON (generados por x3.py) para reconstruir el código fuente S7 en formato .txt y generar documentación detallada en formato Markdown para cada Bloque de Datos (DB) contenido en el JSON.",
"hidden": false
},
"x5.py": {
"display_name": "05: Generar Descripción MD del JSON",
"short_description": "Genera documentación descriptiva de archivos JSON en Markdown.",
"long_description": "Crea un archivo Markdown que documenta la estructura interna de los archivos JSON (generados por x3.py). Detalla UDTs y DBs, incluyendo sus miembros, offsets, tipos de datos, y valores iniciales/actuales, facilitando la comprensión del contenido del JSON.",
"hidden": false
},
"x6.py": {
"display_name": "06: Generar Excel desde JSON",
"short_description": "Genera documentación de DBs en formato Excel (.xlsx) desde JSON.",
"long_description": "Procesa archivos JSON (generados por x3.py) y exporta la información de cada Bloque de Datos (DB) a un archivo Excel (.xlsx). La hoja de cálculo incluye detalles como direcciones, nombres de variables, tipos de datos, valores iniciales, valores actuales y comentarios.",
"hidden": false
},
"x7_value_updater.py": {
"display_name": "x7_value_updater",
"short_description": "Sin descripción corta.", "short_description": "Sin descripción corta.",
"long_description": "", "long_description": "",
"hidden": false "hidden": false

View File

@ -6,7 +6,7 @@ import pandas as pd # For Excel writing
# --- Functions for script operation --- # --- Functions for script operation ---
def find_working_directory_from_x1(): def find_working_directory():
""" """
Finds the working directory. Finds the working directory.
Defaults to current directory. Adapt if specific configuration is needed. Defaults to current directory. Adapt if specific configuration is needed.
@ -317,7 +317,7 @@ def generate_excel_comparison(data_file, format_file, updated_file, output_excel
def main_comparator(): def main_comparator():
print("S7 Data Block Comparator to Excel (Multi-Sheet)") print("S7 Data Block Comparator to Excel (Multi-Sheet)")
print("==============================================") print("==============================================")
working_dir = find_working_directory_from_x1() working_dir = find_working_directory()
print(f"Using working directory: {working_dir}") print(f"Using working directory: {working_dir}")
data_f, format_f, updated_f = find_comparison_files_detailed(working_dir) data_f, format_f, updated_f = find_comparison_files_detailed(working_dir)

View File

@ -1,533 +1,409 @@
# --- x3.py (Modificaciones v_final_4 - Incluye 'count' para ArrayDimension y ajuste debug) ---
import re import re
import json import json
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import List, Dict, Optional, Union, Tuple, Any from typing import List, Dict, Optional, Union, Tuple, Any
import os # Asegurarse de que os está importado
import glob # Para buscar archivos
import copy import copy
import sys
script_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
)
sys.path.append(script_root)
from backend.script_utils import load_configuration
def find_working_directory():
configs = load_configuration()
working_directory = configs.get("working_directory")
if not working_directory:
print("No working directory specified in the configuration file.")
sys.exit(1)
return working_directory
# --- Estructuras de Datos ---
@dataclass @dataclass
class ArrayDimension: class ArrayDimension:
lower_bound: int lower_bound: int
upper_bound: int upper_bound: int
@property @property
def count(self) -> int: def count(self) -> int: # La propiedad 'count' se calculará
return self.upper_bound - self.lower_bound + 1 return self.upper_bound - self.lower_bound + 1
@dataclass @dataclass
class VariableInfo: class VariableInfo: # Sin cambios respecto a v_final_3
name: str name: str
data_type: str data_type: str
byte_offset: float byte_offset: float
size_in_bytes: int # For BOOL arrays, this is the number of bytes spanned. For single BOOL, 0. size_in_bytes: int
bit_size: int = 0 # For BOOL, this is 1. For others, usually 0 unless it's a bitfield type. bit_size: int = 0
udt_source_name: Optional[str] = None udt_source_name: Optional[str] = None
string_length: Optional[int] = None string_length: Optional[int] = None
array_dimensions: List[ArrayDimension] = field(default_factory=list) array_dimensions: List[ArrayDimension] = field(default_factory=list)
initial_value: Optional[str] = None initial_value: Optional[str] = None
current_value: Optional[str] = None current_value: Optional[str] = None
comment: Optional[str] = None comment: Optional[str] = None
children: List['VariableInfo'] = field(default_factory=list) children: List['VariableInfo'] = field(default_factory=list)
is_udt_expanded_member: bool = False is_udt_expanded_member: bool = False
current_element_values: Optional[Dict[str, str]] = None
@dataclass @dataclass
class UdtInfo: class UdtInfo: # Sin cambios respecto a v_final_3
name: str name: str
family: Optional[str] = None family: Optional[str] = None
version: Optional[str] = None version: Optional[str] = None
members: List[VariableInfo] = field(default_factory=list) members: List[VariableInfo] = field(default_factory=list)
total_size_in_bytes: int = 0 total_size_in_bytes: int = 0
@dataclass @dataclass
class DbInfo: class DbInfo: # Sin cambios respecto a v_final_3
name: str name: str
title: Optional[str] = None title: Optional[str] = None
family: Optional[str] = None family: Optional[str] = None
version: Optional[str] = None version: Optional[str] = None
members: List[VariableInfo] = field(default_factory=list) members: List[VariableInfo] = field(default_factory=list)
total_size_in_bytes: int = 0 total_size_in_bytes: int = 0
_begin_block_assignments_ordered: List[Tuple[str, str]] = field(default_factory=list)
_initial_values_from_begin_block: Dict[str, str] = field(default_factory=dict) _initial_values_from_begin_block: Dict[str, str] = field(default_factory=dict)
@dataclass @dataclass
class ParsedData: class ParsedData: # Sin cambios
udts: List[UdtInfo] = field(default_factory=list) udts: List[UdtInfo] = field(default_factory=list)
dbs: List[DbInfo] = field(default_factory=list) dbs: List[DbInfo] = field(default_factory=list)
@dataclass @dataclass
class OffsetContext: class OffsetContext: # Sin cambios
byte_offset: int = 0 byte_offset: int = 0
bit_offset: int = 0 # 0-7 bit_offset: int = 0
def get_combined_offset(self) -> float: def get_combined_offset(self) -> float:
if self.bit_offset == 0: if self.bit_offset == 0: return float(self.byte_offset)
return float(self.byte_offset)
return float(self.byte_offset * 10 + self.bit_offset) / 10.0 return float(self.byte_offset * 10 + self.bit_offset) / 10.0
def advance_bits(self, num_bits: int): def advance_bits(self, num_bits: int):
self.bit_offset += num_bits self.bit_offset += num_bits; self.byte_offset += self.bit_offset // 8; self.bit_offset %= 8
self.byte_offset += self.bit_offset // 8
self.bit_offset %= 8
def align_to_byte(self): def align_to_byte(self):
if self.bit_offset > 0: if self.bit_offset > 0: self.byte_offset += 1; self.bit_offset = 0
self.byte_offset += 1
self.bit_offset = 0
def align_to_word(self): def align_to_word(self):
self.align_to_byte() self.align_to_byte()
if self.byte_offset % 2 != 0: if self.byte_offset % 2 != 0: self.byte_offset += 1
self.byte_offset += 1 # --- Fin Estructuras de Datos ---
S7_PRIMITIVE_SIZES = { S7_PRIMITIVE_SIZES = { # Sin cambios
# type_name: (size_in_bytes, alignment_in_bytes_for_start, is_bool_type)
"BOOL": (0, 1, True), "BYTE": (1, 1, False), "CHAR": (1, 1, False), "BOOL": (0, 1, True), "BYTE": (1, 1, False), "CHAR": (1, 1, False),
"SINT": (1, 1, False), "USINT": (1, 1, False), "WORD": (2, 2, False), "SINT": (1, 1, False), "USINT": (1, 1, False), "WORD": (2, 2, False),
"INT": (2, 2, False), "UINT": (2, 2, False), "S5TIME": (2, 2, False), "INT": (2, 2, False), "UINT": (2, 2, False), "S5TIME": (2, 2, False),
"DATE": (2, 2, False), "DWORD": (4, 2, False), "DINT": (4, 2, False), "DATE": (2, 2, False), "DWORD": (4, 2, False), "DINT": (4, 2, False),
"UDINT": (4, 2, False), "REAL": (4, 2, False), "TIME": (4, 2, False), "UDINT": (4, 2, False), "REAL": (4, 2, False), "TIME": (4, 2, False),
"TIME_OF_DAY": (4, 2, False), "TOD": (4, 2, False), # TOD is alias for TIME_OF_DAY "TIME_OF_DAY": (4, 2, False), "TOD": (4, 2, False),
"LREAL": (8, 2, False), "LINT": (8, 2, False), "ULINT": (8, 2, False), "LREAL": (8, 2, False), "LINT": (8, 2, False), "ULINT": (8, 2, False),
"LWORD": (8, 2, False), "DATE_AND_TIME": (8, 2, False), "DT": (8, 2, False), # DT is alias for DATE_AND_TIME "LWORD": (8, 2, False), "DATE_AND_TIME": (8, 2, False), "DT": (8, 2, False),
# STRING is handled specially due to its length component
} }
class S7Parser: class S7Parser: # Sin cambios en __init__ respecto a v_final_3
def __init__(self): def __init__(self):
self.parsed_data = ParsedData() self.parsed_data = ParsedData()
self.known_udts: Dict[str, UdtInfo] = {} self.known_udts: Dict[str, UdtInfo] = {}
self.type_start_regex = re.compile(r'^\s*TYPE\s+"([^"]+)"', re.IGNORECASE) self.type_start_regex = re.compile(r'^\s*TYPE\s+"([^"]+)"', re.IGNORECASE)
self.db_start_regex = re.compile(r'^\s*DATA_BLOCK\s+"([^"]+)"', re.IGNORECASE) self.db_start_regex = re.compile(r'^\s*DATA_BLOCK\s+"([^"]+)"', re.IGNORECASE)
self.property_regex = re.compile(r'^\s*([A-Z_]+)\s*:\s*(.+?)(?:\s*;)?\s*(?://.*)?$', re.IGNORECASE) self.property_regex = re.compile(r'^\s*([A-Z_]+)\s*:\s*(.+?)\s*(?://.*)?$', re.IGNORECASE)
self.struct_start_regex = re.compile(r'^\s*STRUCT\b', re.IGNORECASE) self.struct_start_regex = re.compile(r'^\s*STRUCT\b', re.IGNORECASE)
self.end_struct_regex = re.compile(r'^\s*END_STRUCT\b', re.IGNORECASE) self.end_struct_regex = re.compile(r'^\s*END_STRUCT\b', re.IGNORECASE)
self.end_type_regex = re.compile(r'^\s*END_TYPE\b', re.IGNORECASE) self.end_type_regex = re.compile(r'^\s*END_TYPE\b', re.IGNORECASE)
self.end_db_regex = re.compile(r'^\s*END_DATA_BLOCK\b', re.IGNORECASE) self.end_db_regex = re.compile(r'^\s*END_DATA_BLOCK\b', re.IGNORECASE)
self.begin_regex = re.compile(r'^\s*BEGIN\b', re.IGNORECASE) self.begin_regex = re.compile(r'^\s*BEGIN\b', re.IGNORECASE)
self.var_regex_simplified = re.compile( self.var_regex_simplified = re.compile(
r'^\s*(?P<name>[a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*' r'^\s*(?P<name>[a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*'
r'(?P<typefull>' r'(?P<typefull>'
r'(?:ARRAY\s*\[(?P<arraydims>[^\]]+?)\]\s*OF\s*)?' r'(?:ARRAY\s*\[(?P<arraydims>[^\]]+?)\]\s*OF\s*)?'
r'(?P<basetype>(?:"[^"]+"|[a-zA-Z_][a-zA-Z0-9_]*))' # UDTs in quotes, primitives without r'(?P<basetype>(?:"[^"]+"|[a-zA-Z_][a-zA-Z0-9_]*))'
r'(?:\s*\[\s*(?P<stringlength>\d+)\s*\])?' # Optional string length r'(?:\s*\[\s*(?P<stringlength>\d+)\s*\])?'
r')' r')'
r'(?:\s*:=\s*(?P<initval>[^;]*?))??\s*' # Initial value: non-greedy, does not cross a semicolon r'(?:\s*:=\s*(?P<initval>[^;]*?))??\s*'
r';?\s*$', # Optional semicolon at the end of the declaration r';?\s*$',
re.IGNORECASE re.IGNORECASE
) )
self.array_dim_regex = re.compile(r'(\d+)\s*\.\.\s*(\d+)') self.array_dim_regex = re.compile(r'(\d+)\s*\.\.\s*(\d+)')
def _get_type_details(self, type_name_raw_cleaned: str) -> Tuple[int, int, bool, str]: # Sin cambios
def _get_type_details(self, type_name_raw: str) -> Tuple[int, int, bool, str]: type_name_upper = type_name_raw_cleaned.upper()
type_name_cleaned = type_name_raw.strip('"').upper() if type_name_upper in S7_PRIMITIVE_SIZES:
udt_original_case_name = type_name_raw.strip('"') size, align, is_bool = S7_PRIMITIVE_SIZES[type_name_upper]
return size, align, is_bool, type_name_upper
if type_name_cleaned in S7_PRIMITIVE_SIZES: elif type_name_raw_cleaned in self.known_udts:
size, align, is_bool = S7_PRIMITIVE_SIZES[type_name_cleaned] udt = self.known_udts[type_name_raw_cleaned]
return size, align, is_bool, type_name_cleaned return udt.total_size_in_bytes, 2, False, type_name_raw_cleaned
elif udt_original_case_name in self.known_udts: elif type_name_upper == "STRUCT":
udt = self.known_udts[udt_original_case_name] return 0, 2, False, "STRUCT"
return udt.total_size_in_bytes, 2, False, udt_original_case_name # UDTs align like structs (word) raise ValueError(f"Tipo de dato desconocido o UDT no definido: '{type_name_raw_cleaned}'")
elif type_name_cleaned == "STRUCT": # For explicit STRUCT members
return 0, 2, False, "STRUCT" # Size determined by members, aligns to word
raise ValueError(f"Unknown data type or UDT not defined: '{type_name_raw}' (Cleaned: '{type_name_cleaned}', Original UDT: '{udt_original_case_name}')")
@staticmethod @staticmethod
def _adjust_children_offsets(children: List[VariableInfo], base_offset_add: float): def _adjust_children_offsets(children: List[VariableInfo], base_offset_add: float): # Sin cambios
for child in children: for child in children:
child.byte_offset += base_offset_add child.byte_offset += base_offset_add
if child.byte_offset == float(int(child.byte_offset)): if child.byte_offset == float(int(child.byte_offset)):
child.byte_offset = float(int(child.byte_offset)) child.byte_offset = float(int(child.byte_offset))
if child.children: if child.children:
S7Parser._adjust_children_offsets(child.children, base_offset_add) # Pass the original base_offset_add S7Parser._adjust_children_offsets(child.children, base_offset_add)
def _parse_struct_members(self, lines: List[str], current_line_idx: int, def _parse_struct_members(self, lines: List[str], current_line_idx: int,
parent_members_list: List[VariableInfo], parent_members_list: List[VariableInfo],
active_context: OffsetContext, active_context: OffsetContext,
is_top_level_struct_in_block: bool = False) -> int: is_top_level_struct_in_block: bool = False) -> int: # Ajuste en depuración
idx_to_process = current_line_idx idx_to_process = current_line_idx
while idx_to_process < len(lines): while idx_to_process < len(lines):
original_line_text_with_leading_space = lines[idx_to_process] original_line_text = lines[idx_to_process].strip()
original_line_text = original_line_text_with_leading_space.strip()
line_to_parse = original_line_text line_to_parse = original_line_text
line_comment = None line_comment = None
comment_marker_idx = original_line_text.find("//") comment_marker_idx = original_line_text.find("//")
if comment_marker_idx != -1: if comment_marker_idx != -1:
line_to_parse = original_line_text[:comment_marker_idx].strip() line_to_parse = original_line_text[:comment_marker_idx].strip()
line_comment = original_line_text[comment_marker_idx + 2:].strip() line_comment = original_line_text[comment_marker_idx + 2:].strip()
line_index_for_return = idx_to_process
idx_to_process += 1
if not line_to_parse: continue
is_nested_end_struct = self.end_struct_regex.match(line_to_parse) and not is_top_level_struct_in_block
is_main_block_end_struct = self.end_struct_regex.match(line_to_parse) and is_top_level_struct_in_block
is_block_terminator = is_top_level_struct_in_block and \
(self.end_type_regex.match(line_to_parse) or \
self.end_db_regex.match(line_to_parse) or \
self.begin_regex.match(line_to_parse))
if is_nested_end_struct:
active_context.align_to_byte()
if active_context.byte_offset % 2 != 0: active_context.byte_offset += 1
return idx_to_process
if is_block_terminator:
active_context.align_to_byte()
if active_context.byte_offset % 2 != 0: active_context.byte_offset += 1
return line_index_for_return
if is_main_block_end_struct: # Simplemente lo ignoramos aquí, será manejado por END_TYPE/DB
pass
line_index_for_return = idx_to_process # Save index before incrementing
idx_to_process += 1 # Pre-increment for next loop or return
if not line_to_parse: # If line is empty after stripping comments, or was originally empty
continue
# Handle block endings (STRUCT, TYPE, DB, BEGIN) based on line_to_parse
if self.end_struct_regex.match(line_to_parse):
if not is_top_level_struct_in_block: # End of a nested STRUCT member
active_context.align_to_byte() # Ensure current byte is finished
if active_context.byte_offset % 2 != 0: # Struct total size must be even
active_context.byte_offset += 1
return idx_to_process # Return line number AFTER END_STRUCT
# If is_top_level_struct_in_block, END_STRUCT is for the main block, handled by END_TYPE/DB
if is_top_level_struct_in_block and \
(self.end_type_regex.match(line_to_parse) or \
self.end_db_regex.match(line_to_parse) or \
self.begin_regex.match(line_to_parse)):
active_context.align_to_byte() # Finish current byte for the whole UDT/DB declaration part
if active_context.byte_offset % 2 != 0: # Total size must be even
active_context.byte_offset += 1
return line_index_for_return # Return index OF the BEGIN/END_TYPE/END_DB line
# Check for STRUCT start for a member
if self.struct_start_regex.match(line_to_parse): # This is a nested STRUCT member declaration
# This line should be matched by var_regex as a variable of type STRUCT
# If we are here, it means var_regex didn't match it, or it's an anonymous struct.
# For simplicity, we assume named structs are parsed by var_regex.
# This path might need review if anonymous structs are common.
# For now, we assume explicit STRUCT members are named and caught by var_regex
pass # Let var_regex handle it if it's a named struct
var_match = self.var_regex_simplified.match(line_to_parse) var_match = self.var_regex_simplified.match(line_to_parse)
if var_match: if var_match: # Lógica de var_match sin cambios respecto a v_final_3
var_data = var_match.groupdict() var_data = var_match.groupdict()
var_info = VariableInfo(name=var_data['name'], data_type="", byte_offset=0, size_in_bytes=0) raw_base_type_from_regex = var_data['basetype'].strip()
clean_data_type = raw_base_type_from_regex.strip('"')
initial_val_str = var_data.get('initval') udt_source_name_val = raw_base_type_from_regex if raw_base_type_from_regex.startswith('"') else None
if initial_val_str: var_info = VariableInfo(name=var_data['name'],
var_info.initial_value = initial_val_str.strip() data_type=clean_data_type,
if line_comment: byte_offset=0, size_in_bytes=0,
var_info.comment = line_comment udt_source_name=udt_source_name_val)
if var_data.get('initval'): var_info.initial_value = var_data['initval'].strip()
raw_base_type = var_data['basetype'].strip() if line_comment: var_info.comment = line_comment
var_info.data_type = raw_base_type.strip('"') # Store clean type for logic
if raw_base_type.startswith('"') and raw_base_type.endswith('"'):
var_info.udt_source_name = raw_base_type # Store with quotes if UDT
num_array_elements = 1 num_array_elements = 1
if var_data['arraydims']: if var_data['arraydims']:
for dim_match in self.array_dim_regex.finditer(var_data['arraydims']): for dim_match in self.array_dim_regex.finditer(var_data['arraydims']):
var_info.array_dimensions.append(ArrayDimension(int(dim_match.group(1)), int(dim_match.group(2)))) var_info.array_dimensions.append(ArrayDimension(int(dim_match.group(1)), int(dim_match.group(2))))
if var_info.array_dimensions: if var_info.array_dimensions:
for dim in var_info.array_dimensions: for dim in var_info.array_dimensions: num_array_elements *= dim.count
num_array_elements *= dim.count if var_info.data_type.upper() == "STRUCT":
active_context.align_to_word(); var_info.byte_offset = active_context.get_combined_offset()
# --- Offset and Size Calculation --- nested_struct_context = OffsetContext()
if var_info.data_type.upper() == "STRUCT": # Member is explicitly 'STRUCT' idx_after_nested_struct = self._parse_struct_members(lines, idx_to_process, var_info.children, nested_struct_context, False)
active_context.align_to_word() var_info.size_in_bytes = nested_struct_context.byte_offset
var_info.byte_offset = active_context.get_combined_offset()
nested_struct_context = OffsetContext() # Children offsets are relative to this new context
# We need to find the line "STRUCT" and parse from the line AFTER it
# The current idx_to_process is already advanced.
# The _parse_struct_members call will continue from where the var_match line was,
# which is not right for a struct definition that spans multiple lines.
# This means "STRUCT" members need to be handled by the parser finding "STRUCT" keyword,
# not just by var_regex matching "Variable : STRUCT".
# For now, assume if var_regex matched, it's a named struct.
# The call to _parse_struct_members for children should start from the *next line* in the input lines list.
idx_after_nested_struct = self._parse_struct_members(
lines,
idx_to_process, # Start parsing members of this struct from the next available line
var_info.children,
nested_struct_context,
is_top_level_struct_in_block=False # This is a nested struct
)
var_info.size_in_bytes = nested_struct_context.byte_offset # This is the calculated size of the nested struct
# Adjust children offsets to be absolute
# The children's byte_offset are currently relative to the start of the nested_struct_context (0.0)
# They need to be relative to the DB/UDT.
# var_info.byte_offset is the absolute start of this STRUCT member.
for child in var_info.children: for child in var_info.children:
child.byte_offset += var_info.byte_offset child.byte_offset += var_info.byte_offset
if child.byte_offset == float(int(child.byte_offset)): if child.byte_offset == float(int(child.byte_offset)): child.byte_offset = float(int(child.byte_offset))
child.byte_offset = float(int(child.byte_offset)) if child.children: S7Parser._adjust_children_offsets(child.children, var_info.byte_offset)
if child.children: # If UDTs within struct had their own structs active_context.byte_offset += var_info.size_in_bytes; idx_to_process = idx_after_nested_struct
S7Parser._adjust_children_offsets(child.children, var_info.byte_offset)
active_context.byte_offset += var_info.size_in_bytes # Advance parent context
idx_to_process = idx_after_nested_struct # Update main loop's line index
elif var_info.data_type.upper() == "STRING" and var_data['stringlength']: elif var_info.data_type.upper() == "STRING" and var_data['stringlength']:
var_info.string_length = int(var_data['stringlength']) var_info.string_length = int(var_data['stringlength']); unit_size = var_info.string_length + 2
unit_size = var_info.string_length + 2 active_context.align_to_word(); var_info.byte_offset = active_context.get_combined_offset()
active_context.align_to_word() # STRINGs are word-aligned
var_info.byte_offset = active_context.get_combined_offset()
var_info.size_in_bytes = unit_size * num_array_elements var_info.size_in_bytes = unit_size * num_array_elements
active_context.byte_offset += var_info.size_in_bytes active_context.byte_offset += var_info.size_in_bytes
else:
else: # Primitive or UDT instance
# Use var_info.data_type (cleaned name) for _get_type_details
unit_size_bytes, unit_alignment_req, is_bool, type_name_for_udt_lookup = self._get_type_details(var_info.data_type) unit_size_bytes, unit_alignment_req, is_bool, type_name_for_udt_lookup = self._get_type_details(var_info.data_type)
if is_bool: if is_bool:
var_info.bit_size = 1 # A single BOOL is 1 bit var_info.bit_size = 1; var_info.byte_offset = active_context.get_combined_offset()
# For an array of BOOLs, record offset of the first bit active_context.advance_bits(num_array_elements)
var_info.byte_offset = active_context.get_combined_offset() start_byte_abs = int(var_info.byte_offset); start_bit_in_byte = int(round((var_info.byte_offset - start_byte_abs) * 10))
active_context.advance_bits(num_array_elements) # Advance context by total bits if num_array_elements == 1: var_info.size_in_bytes = 0
else:
# Calculate effective byte span for the BOOL or BOOL array bits_rem = num_array_elements; bytes_spanned = 0
start_byte_abs = int(var_info.byte_offset) if start_bit_in_byte > 0:
start_bit_in_byte = int(round((var_info.byte_offset - start_byte_abs) * 10)) bits_in_first = 8 - start_bit_in_byte
if bits_rem <= bits_in_first: bytes_spanned = 1
if num_array_elements == 1: else: bytes_spanned = 1; bits_rem -= bits_in_first; bytes_spanned += (bits_rem + 7) // 8
var_info.size_in_bytes = 0 # Convention for single bit else: bytes_spanned = (bits_rem + 7) // 8
else: # Array of BOOLs
bits_remaining = num_array_elements
bytes_spanned = 0
if start_bit_in_byte > 0: # Starts mid-byte
bits_in_first_byte = 8 - start_bit_in_byte
if bits_remaining <= bits_in_first_byte:
bytes_spanned = 1
else:
bytes_spanned = 1
bits_remaining -= bits_in_first_byte
bytes_spanned += (bits_remaining + 7) // 8 # Ceiling division for remaining full bytes
else: # Starts on a byte boundary
bytes_spanned = (bits_remaining + 7) // 8
var_info.size_in_bytes = bytes_spanned var_info.size_in_bytes = bytes_spanned
else:
else: # Non-BOOL primitive or UDT active_context.align_to_byte()
active_context.align_to_byte() # Finish any pending bits if unit_alignment_req == 2: active_context.align_to_word()
if unit_alignment_req == 2: # WORD, DWORD, REAL, UDT, etc.
active_context.align_to_word()
var_info.byte_offset = active_context.get_combined_offset() var_info.byte_offset = active_context.get_combined_offset()
var_info.size_in_bytes = unit_size_bytes * num_array_elements var_info.size_in_bytes = unit_size_bytes * num_array_elements
active_context.byte_offset += var_info.size_in_bytes active_context.byte_offset += var_info.size_in_bytes
# If it's a UDT instance, expand its members
if type_name_for_udt_lookup in self.known_udts and not is_bool: if type_name_for_udt_lookup in self.known_udts and not is_bool:
udt_def = self.known_udts[type_name_for_udt_lookup] udt_def = self.known_udts[type_name_for_udt_lookup]; udt_instance_abs_start_offset = var_info.byte_offset
udt_instance_absolute_start_offset = var_info.byte_offset
for udt_member_template in udt_def.members: for udt_member_template in udt_def.members:
expanded_member = copy.deepcopy(udt_member_template) expanded_member = copy.deepcopy(udt_member_template); expanded_member.is_udt_expanded_member = True
expanded_member.is_udt_expanded_member = True expanded_member.byte_offset += udt_instance_abs_start_offset
# udt_member_template.byte_offset is relative to UDT start (0.0) if expanded_member.byte_offset == float(int(expanded_member.byte_offset)): expanded_member.byte_offset = float(int(expanded_member.byte_offset))
expanded_member.byte_offset += udt_instance_absolute_start_offset if expanded_member.children: S7Parser._adjust_children_offsets(expanded_member.children, udt_instance_abs_start_offset)
if expanded_member.byte_offset == float(int(expanded_member.byte_offset)):
expanded_member.byte_offset = float(int(expanded_member.byte_offset))
# If the UDT member itself has children (e.g., a struct within the UDT)
# their offsets also need to be made absolute relative to the DB.
# The base_offset_add for _adjust_children_offsets should be the
# absolute start of the current UDT instance.
if expanded_member.children:
S7Parser._adjust_children_offsets(expanded_member.children, udt_instance_absolute_start_offset)
var_info.children.append(expanded_member) var_info.children.append(expanded_member)
parent_members_list.append(var_info) parent_members_list.append(var_info)
else: # Line not matched by var_regex # Ajuste de la condición del mensaje de depuración
# Check if it's a STRUCT definition line that var_regex MISSED elif line_to_parse and \
# This is a fallback / debug for when 'STRUCT' starts a definition block for a member not self.struct_start_regex.match(line_to_parse) and \
struct_keyword_match = self.struct_start_regex.match(line_to_parse) not is_main_block_end_struct and \
if struct_keyword_match and not var_match : # An unnamed struct or parsing issue not is_nested_end_struct and \
print(f"DEBUG: Found 'STRUCT' keyword on line but not parsed by var_regex: '{original_line_text}' | Processed='{line_to_parse}'") not is_block_terminator : # Solo imprimir si no es un terminador conocido
# This case might need more robust handling if anonymous structs are used or if var_regex is too strict for named structs print(f"DEBUG (_parse_struct_members): Line not parsed: Original='{original_line_text}' | Processed='{line_to_parse}'")
elif line_to_parse and \
not self.end_struct_regex.match(line_to_parse) and \
not (is_top_level_struct_in_block and \
(self.end_type_regex.match(line_to_parse) or \
self.end_db_regex.match(line_to_parse) or \
self.begin_regex.match(line_to_parse))):
print(f"DEBUG: Line not parsed as variable or known keyword: Original='{original_line_text}' | Processed='{line_to_parse}'")
# This final padding should ideally be handled when END_STRUCT or END_TYPE/DB is detected
# For is_top_level_struct_in_block, it's handled by BEGIN/END_TYPE/DB detection.
# For nested structs, it's handled by END_STRUCT detection.
return idx_to_process return idx_to_process
def _parse_begin_block(self, lines: List[str], start_idx: int, db_info: DbInfo) -> int: # Sin cambios
def _parse_begin_block(self, lines: List[str], start_idx: int, db_info: DbInfo) -> int:
idx = start_idx idx = start_idx
# Regex for assignment: path := value ; assignment_regex = re.compile(r'^\s*(?P<path>.+?)\s*:=\s*(?P<value>.+?)\s*;?\s*$', re.IGNORECASE)
# Path can contain dots, array indices. Value can be complex.
assignment_regex = re.compile(r'^\s*(?P<path>[a-zA-Z0-9_."\[\],\s]+?)\s*:=\s*(?P<value>.+?)\s*;?\s*$', re.IGNORECASE)
while idx < len(lines): while idx < len(lines):
original_line = lines[idx].strip() original_line = lines[idx].strip(); line_to_parse = original_line
comment_marker = original_line.find("//")
line_to_parse = original_line if comment_marker != -1: line_to_parse = original_line[:comment_marker].strip()
comment_marker_idx = original_line.find("//") if self.end_db_regex.match(line_to_parse): return idx
if comment_marker_idx != -1: idx += 1
line_to_parse = original_line[:comment_marker_idx].strip() if not line_to_parse: continue
# comment = original_line[comment_marker_idx+2:].strip() # Comment in BEGIN usually not stored
if self.end_db_regex.match(line_to_parse): # END_DATA_BLOCK terminates BEGIN section
return idx # Return index of END_DATA_BLOCK
idx += 1 # Advance to next line
if not line_to_parse: continue # Skip empty lines
match = assignment_regex.match(line_to_parse) match = assignment_regex.match(line_to_parse)
if match: if match:
path = match.group("path").strip() path, value = match.group("path").strip(), match.group("value").strip().rstrip(';').strip()
value = match.group("value").strip().rstrip(';').strip() db_info._begin_block_assignments_ordered.append((path, value))
db_info._initial_values_from_begin_block[path] = value db_info._initial_values_from_begin_block[path] = value
# else: # Optional: print lines in BEGIN that don't match assignment raise SyntaxError("Se esperaba END_DATA_BLOCK después de la sección BEGIN.")
# print(f"DEBUG: Line in BEGIN not matched as assignment: '{original_line}'")
raise SyntaxError("Expected END_DATA_BLOCK after BEGIN section, but not found.") def _apply_current_values(self, members: List[VariableInfo], begin_values: Dict[str, str], current_path_prefix: str = ""): # Sin cambios
def _apply_current_values(self, members: List[VariableInfo], begin_values: Dict[str, str], current_path_prefix: str = ""):
for var_info in members: for var_info in members:
# Construct full path, handling array indices if necessary (simplification: not handling array element assignment here)
# For UDTs, the path in BEGIN block directly names the UDT member, e.g., "MyUdtVar._Name"
full_member_path = f"{current_path_prefix}{var_info.name}" full_member_path = f"{current_path_prefix}{var_info.name}"
if var_info.array_dimensions:
if var_info.is_udt_expanded_member: # Path comes from the UDT parent var_info.current_element_values = {}
# This requires careful reconstruction if the assignment path is more complex prefix_for_search = full_member_path + "["
# For now, assume direct member access for expanded UDTs. for key_in_begin, val_in_begin in begin_values.items():
# Example: If parent is "Actual_Recipe", and child is "_Name", path is "Actual_Recipe._Name" if key_in_begin.startswith(prefix_for_search) and key_in_begin.endswith("]"):
# current_path_prefix should be the name of the UDT variable instance. try:
pass # The full_member_path is already constructed above with current_path_prefix indices_str = key_in_begin[len(prefix_for_search):-1]
var_info.current_element_values[indices_str] = val_in_begin
if full_member_path in begin_values: except: print(f"Advertencia: No se pudo parsear el índice para: {key_in_begin}")
var_info.current_value = begin_values[full_member_path] if not var_info.current_element_values: var_info.current_element_values = None
elif var_info.initial_value is not None: # Fallback to declaration initial value if full_member_path in begin_values: var_info.current_value = begin_values[full_member_path]
var_info.current_value = var_info.initial_value elif full_member_path in begin_values: var_info.current_value = begin_values[full_member_path]
elif var_info.initial_value is not None: var_info.current_value = var_info.initial_value
# If this member itself has children (it's a parsed STRUCT or an expanded UDT that contained STRUCTs), if var_info.children and not var_info.is_udt_expanded_member:
# recurse into them.
if var_info.children and not var_info.is_udt_expanded_member: # Recurse for normal structs
self._apply_current_values(var_info.children, begin_values, f"{full_member_path}.") self._apply_current_values(var_info.children, begin_values, f"{full_member_path}.")
# For expanded UDT members (is_udt_expanded_member = True), their values are set directly, elif var_info.udt_source_name and var_info.children:
# and if THEY had children (structs within the UDT def), those are part of the UDT expansion. self._apply_current_values(var_info.children, begin_values, f"{full_member_path}.")
# The BEGIN block paths would typically be like "MyUdtInstance.StructInUdt.Member".
# This simplified _apply_current_values might need enhancement for complex paths into UDTs.
def parse_file(self, filepath: str) -> ParsedData: # Sin cambios respecto a v_final_3
def parse_file(self, filepath: str) -> ParsedData:
try: try:
with open(filepath, 'r', encoding='utf-8-sig') as f: with open(filepath, 'r', encoding='utf-8-sig') as f: lines = f.readlines()
lines = f.readlines() except Exception as e: print(f"Error al leer el archivo {filepath}: {e}"); return self.parsed_data
except Exception as e:
print(f"Error reading file {filepath}: {e}")
return self.parsed_data
current_block_handler: Optional[Union[UdtInfo, DbInfo]] = None current_block_handler: Optional[Union[UdtInfo, DbInfo]] = None
active_block_context = OffsetContext() active_block_context = OffsetContext(); parsing_title_value_next_line = False; idx = 0
idx = 0
while idx < len(lines): while idx < len(lines):
original_line = lines[idx].strip() original_line_text = lines[idx]; stripped_original_line = original_line_text.strip()
line_to_parse = original_line line_to_parse = stripped_original_line; comment_marker = stripped_original_line.find("//")
comment_marker_idx = original_line.find("//") if comment_marker != -1: line_to_parse = stripped_original_line[:comment_marker].strip()
if comment_marker_idx != -1: if parsing_title_value_next_line and isinstance(current_block_handler, DbInfo):
line_to_parse = original_line[:comment_marker_idx].strip() title_value_candidate = original_line_text.strip()
# Top-level comments usually not stored with block definition if title_value_candidate.startswith("{") and title_value_candidate.endswith("}"):
current_block_handler.title = title_value_candidate
type_match = self.type_start_regex.match(line_to_parse) else: print(f"Advertencia: Se esperaba valor de TITLE {{...}} pero se encontró: '{title_value_candidate}'")
db_match = self.db_start_regex.match(line_to_parse) parsing_title_value_next_line = False; idx += 1; continue
type_match = self.type_start_regex.match(line_to_parse); db_match = self.db_start_regex.match(line_to_parse)
if type_match: if type_match:
if current_block_handler: print(f"Warning: Starting new TYPE block for '{type_match.group(1)}' before previous block '{current_block_handler.name}' ended.") udt_name = type_match.group(1); current_block_handler = UdtInfo(name=udt_name)
udt_name = type_match.group(1) self.parsed_data.udts.append(current_block_handler); active_block_context = OffsetContext(); idx +=1; continue
current_block_handler = UdtInfo(name=udt_name)
self.parsed_data.udts.append(current_block_handler)
active_block_context = OffsetContext()
idx += 1; continue
elif db_match: elif db_match:
if current_block_handler: print(f"Warning: Starting new DATA_BLOCK for '{db_match.group(1)}' before previous block '{current_block_handler.name}' ended.") db_name = db_match.group(1); current_block_handler = DbInfo(name=db_name)
db_name = db_match.group(1) self.parsed_data.dbs.append(current_block_handler); active_block_context = OffsetContext(); idx +=1; continue
current_block_handler = DbInfo(name=db_name) if not current_block_handler: idx +=1; continue
self.parsed_data.dbs.append(current_block_handler) if line_to_parse.upper() == "TITLE =":
active_block_context = OffsetContext() if isinstance(current_block_handler, DbInfo): parsing_title_value_next_line = True; idx += 1; continue
idx += 1; continue prop_match = self.property_regex.match(stripped_original_line)
struct_keyword_match = self.struct_start_regex.match(line_to_parse)
if not current_block_handler: if prop_match and not parsing_title_value_next_line:
idx += 1; continue
# Inside a UDT or DB block definition part (before BEGIN for DBs)
prop_match = self.property_regex.match(original_line) # Properties can have comments
struct_keyword_on_line = self.struct_start_regex.match(line_to_parse) # Check for "STRUCT" keyword line
if prop_match:
key, value = prop_match.group(1).upper(), prop_match.group(2).strip() key, value = prop_match.group(1).upper(), prop_match.group(2).strip()
attr_name = key.lower() if value.endswith(';'): value = value[:-1].strip()
if hasattr(current_block_handler, attr_name): attr = key.lower()
setattr(current_block_handler, attr_name, value) if hasattr(current_block_handler, attr):
if attr == 'title' and current_block_handler.title is not None: pass
elif struct_keyword_on_line and not current_block_handler.members: # Start of main STRUCT for UDT/DB else: setattr(current_block_handler, attr, value)
# The line 'STRUCT' itself is consumed. Parsing of members starts from the next line. elif struct_keyword_match and not current_block_handler.members:
idx = self._parse_struct_members( idx = self._parse_struct_members(lines, idx + 1, current_block_handler.members, active_block_context, True); continue
lines, idx + 1, # Start from line AFTER "STRUCT"
current_block_handler.members,
active_block_context,
is_top_level_struct_in_block=True
)
# idx is now the line number of BEGIN, END_TYPE, or END_DB
continue # Let the main loop handle this new line index
elif self.begin_regex.match(line_to_parse) and isinstance(current_block_handler, DbInfo): elif self.begin_regex.match(line_to_parse) and isinstance(current_block_handler, DbInfo):
# Finalize size from declaration part current_block_handler.total_size_in_bytes = active_block_context.byte_offset
current_block_handler.total_size_in_bytes = active_block_context.byte_offset idx = self._parse_begin_block(lines, idx + 1, current_block_handler); continue
idx = self._parse_begin_block(lines, idx + 1, current_block_handler) # idx + 1 to start after BEGIN
# idx is now the line of END_DATA_BLOCK
continue
elif self.end_type_regex.match(line_to_parse) and isinstance(current_block_handler, UdtInfo): elif self.end_type_regex.match(line_to_parse) and isinstance(current_block_handler, UdtInfo):
if not hasattr(current_block_handler, 'total_size_in_bytes') or current_block_handler.total_size_in_bytes == 0: if current_block_handler.total_size_in_bytes == 0: current_block_handler.total_size_in_bytes = active_block_context.byte_offset
current_block_handler.total_size_in_bytes = active_block_context.byte_offset # Size from declarations
self.known_udts[current_block_handler.name] = current_block_handler self.known_udts[current_block_handler.name] = current_block_handler
print(f"Parsed UDT: {current_block_handler.name}, Size: {current_block_handler.total_size_in_bytes} bytes. Members: {len(current_block_handler.members)}") # print(f"Parsed UDT: {current_block_handler.name}, Size: {current_block_handler.total_size_in_bytes}b, Members: {len(current_block_handler.members)}")
current_block_handler = None current_block_handler = None; parsing_title_value_next_line = False
elif self.end_db_regex.match(line_to_parse) and isinstance(current_block_handler, DbInfo): elif self.end_db_regex.match(line_to_parse) and isinstance(current_block_handler, DbInfo):
if not hasattr(current_block_handler, 'total_size_in_bytes') or current_block_handler.total_size_in_bytes == 0: # If no BEGIN block, size is from declarations if current_block_handler.total_size_in_bytes == 0 : current_block_handler.total_size_in_bytes = active_block_context.byte_offset
current_block_handler.total_size_in_bytes = active_block_context.byte_offset
self._apply_current_values(current_block_handler.members, current_block_handler._initial_values_from_begin_block) self._apply_current_values(current_block_handler.members, current_block_handler._initial_values_from_begin_block)
print(f"Parsed DB: {current_block_handler.name}, Decl. Size: {current_block_handler.total_size_in_bytes} bytes. Members: {len(current_block_handler.members)}") # print(f"Parsed DB: {current_block_handler.name}, Decl.Size: {current_block_handler.total_size_in_bytes}b, Members: {len(current_block_handler.members)}, BEGIN assigns: {len(current_block_handler._begin_block_assignments_ordered)}")
current_block_handler = None current_block_handler = None; parsing_title_value_next_line = False
idx += 1 idx += 1
return self.parsed_data return self.parsed_data
def custom_json_serializer(obj: Any) -> Any: def custom_json_serializer(obj: Any) -> Any:
if isinstance(obj, OffsetContext): return None # Don't serialize OffsetContext if isinstance(obj, OffsetContext): return None
# Manejar ArrayDimension explícitamente para incluir 'count'
if isinstance(obj, ArrayDimension):
return {
'lower_bound': obj.lower_bound,
'upper_bound': obj.upper_bound,
'count': obj.count # La propiedad se calcula y se añade aquí
}
if hasattr(obj, '__dict__'): if hasattr(obj, '__dict__'):
# Filter out None values, empty lists, and specific private fields
d = {k: v for k, v in obj.__dict__.items() d = {k: v for k, v in obj.__dict__.items()
if v is not None and \ if not (v is None or (isinstance(v, list) and not v))} # No filtrar _initial_values_from_begin_block
not (isinstance(v, list) and not v) and \
k != '_initial_values_from_begin_block'}
# Ensure 'is_udt_expanded_member' is present even if False (unless explicitly None)
if isinstance(obj, VariableInfo): if isinstance(obj, VariableInfo):
if 'is_udt_expanded_member' not in d and obj.is_udt_expanded_member is False: if not obj.is_udt_expanded_member and 'is_udt_expanded_member' not in d :
d['is_udt_expanded_member'] = False d['is_udt_expanded_member'] = False
# If it was True, it would already be in d or caught by the general v is not None if not obj.current_element_values and 'current_element_values' in d:
elif obj.is_udt_expanded_member is True: del d['current_element_values']
d['is_udt_expanded_member'] = True if isinstance(obj, DbInfo): # Asegurar que las listas vacías no se omitan si el campo existe
if '_begin_block_assignments_ordered' not in d and obj._begin_block_assignments_ordered == []:
d['_begin_block_assignments_ordered'] = [] # Mantener lista vacía si es el caso
if '_initial_values_from_begin_block' not in d and obj._initial_values_from_begin_block == {}:
d['_initial_values_from_begin_block'] = {} # Mantener dict vacío si es el caso
return d return d
raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable") raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable: {type(obj)}")
if __name__ == "__main__": if __name__ == "__main__":
parser = S7Parser() working_dir = find_working_directory()
# IMPORTANT: Ensure this filepath points to your actual source file. print(f"Using working directory: {working_dir}")
# The filename was changed to .txt for upload, adjust if your local file is .db
filepath = "db1001_format.db.txt" # Or "db1001_format.db" if that's the actual name
print(f"Attempting to parse: {filepath}") output_json_dir = os.path.join(working_dir, "json")
parsed_result = parser.parse_file(filepath) os.makedirs(output_json_dir, exist_ok=True)
print(f"Los archivos JSON de salida se guardarán en: {output_json_dir}")
json_output_filename = "parsed_s7_data_expanded.json" # New output filename
print(f"\nParsing complete. Attempting to serialize to JSON.") source_files_db = glob.glob(os.path.join(working_dir, "*.db"))
source_files_awl = glob.glob(os.path.join(working_dir, "*.awl"))
try: all_source_files = source_files_db + source_files_awl
json_output = json.dumps(parsed_result, default=custom_json_serializer, indent=2)
# print(json_output) # Optional: print to console for quick check if not all_source_files:
with open(json_output_filename, "w", encoding='utf-8') as f: print(f"No se encontraron archivos .db o .awl en {working_dir}")
f.write(json_output) else:
print(f"Result saved to {json_output_filename}") print(f"Archivos encontrados para procesar: {len(all_source_files)}")
except Exception as e:
print(f"Error during JSON serialization or file writing: {e}") for filepath in all_source_files:
parser = S7Parser() # Nueva instancia para cada archivo para evitar estados residuales
filename = os.path.basename(filepath)
print(f"\n--- Procesando archivo: {filename} ---")
parsed_result = parser.parse_file(filepath)
output_filename_base = os.path.splitext(filename)[0]
json_output_filename = os.path.join(output_json_dir, f"{output_filename_base}.json")
print(f"Parseo completo. Intentando serializar a JSON: {json_output_filename}")
try:
json_output = json.dumps(parsed_result, default=custom_json_serializer, indent=2)
with open(json_output_filename, "w", encoding='utf-8') as f:
f.write(json_output)
print(f"Resultado guardado en: {json_output_filename}")
except Exception as e:
print(f"Error durante la serialización JSON o escritura del archivo {json_output_filename}: {e}")
print("\n--- Proceso completado ---")

View File

@ -1,303 +1,235 @@
# --- x4.py (Modificaciones v_final_2) ---
import json import json
from typing import List, Dict, Any, Union from typing import List, Dict, Any
import sys
import os
import glob # Para buscar archivos JSON
# Se asume que las dataclasses (VariableInfo, UdtInfo, etc.) del script x3.py script_root = os.path.dirname(
# estarían disponibles si este script fuera parte de un paquete más grande. os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
# Para este script independiente, trabajaremos directamente con los diccionarios del JSON. )
sys.path.append(script_root)
from backend.script_utils import load_configuration
def find_working_directory():
configs = load_configuration()
working_directory = configs.get("working_directory")
if not working_directory:
print("No working directory specified in the configuration file.")
sys.exit(1)
return working_directory
# format_data_type_for_source (sin cambios respecto a la v5 que te di antes)
def format_data_type_for_source(var_info: Dict[str, Any]) -> str: def format_data_type_for_source(var_info: Dict[str, Any]) -> str:
"""Formatea la declaración de tipo completa para la variable en S7 source."""
base_type = var_info.get("udt_source_name") if var_info.get("udt_source_name") else var_info["data_type"] base_type = var_info.get("udt_source_name") if var_info.get("udt_source_name") else var_info["data_type"]
type_str = "" type_str = ""
if var_info.get("array_dimensions"): if var_info.get("array_dimensions"):
dims_str = ",".join([f"{d['lower_bound']}..{d['upper_bound']}" for d in var_info["array_dimensions"]]) dims_str = ",".join([f"{d['lower_bound']}..{d['upper_bound']}" for d in var_info["array_dimensions"]])
type_str += f"ARRAY [{dims_str}] OF " type_str += f"ARRAY [{dims_str}] OF "
type_str += base_type type_str += base_type
if var_info["data_type"].upper() == "STRING" and var_info.get("string_length") is not None: if var_info["data_type"].upper() == "STRING" and var_info.get("string_length") is not None:
type_str += f"[{var_info['string_length']}]" type_str += f"[{var_info['string_length']}]"
return type_str return type_str
def generate_variable_declaration_for_source(var_info: Dict[str, Any], indent_level: int) -> str: def generate_variable_declaration_for_source(var_info: Dict[str, Any], indent_level: int) -> str:
"""Genera una línea de declaración de variable S7."""
indent_str = " " * indent_level indent_str = " " * indent_level
type_declaration_str = format_data_type_for_source(var_info) type_declaration_str = format_data_type_for_source(var_info)
line = f'{indent_str}{var_info["name"]} : {type_declaration_str}' line = f'{indent_str}{var_info["name"]} : {type_declaration_str}'
if var_info.get("initial_value") is not None: if var_info.get("initial_value") is not None:
# Asegurarse de que los booleanos se escriban como TRUE/FALSE
initial_val = var_info["initial_value"] initial_val = var_info["initial_value"]
if isinstance(initial_val, bool): initial_val_str = "TRUE" if isinstance(initial_val, bool) and initial_val else \
initial_val_str = "TRUE" if initial_val else "FALSE" "FALSE" if isinstance(initial_val, bool) and not initial_val else \
else: str(initial_val)
initial_val_str = str(initial_val)
line += f' := {initial_val_str}' line += f' := {initial_val_str}'
line += ';' is_multiline_struct_def = (var_info["data_type"].upper() == "STRUCT" and \
not var_info.get("udt_source_name") and \
var_info.get("children"))
if not is_multiline_struct_def: # Solo añadir ; si no es una cabecera de STRUCT multilínea
line += ';'
if var_info.get("comment"): if var_info.get("comment"):
line += f'\t// {var_info["comment"]}' line += f'\t// {var_info["comment"]}'
return line return line
def generate_struct_members_for_source(members: List[Dict[str, Any]], indent_level: int) -> List[str]: def generate_struct_members_for_source(members: List[Dict[str, Any]], indent_level: int) -> List[str]:
"""Genera recursivamente las declaraciones de miembros para STRUCTs/UDTs."""
lines = [] lines = []
for var_info in members: for var_info in members:
# No expandir UDTs anidados dentro de la sección de declaración de otro UDT o DB. if var_info.get("is_udt_expanded_member"): continue
# Solo declarar la variable del tipo UDT. if var_info["data_type"].upper() == "STRUCT" and \
# La expansión de miembros de UDT solo ocurre en el JSON para análisis, no para la reconstrucción de la fuente. not var_info.get("udt_source_name") and \
if var_info.get("is_udt_expanded_member"): # Estos no se declaran individualmente en el padre. var_info.get("children"):
continue
if var_info["data_type"].upper() == "STRUCT" and not var_info.get("udt_source_name"): # Es una definición de STRUCT anidada
current_indent_str = " " * indent_level current_indent_str = " " * indent_level
lines.append(f'{current_indent_str}{var_info["name"]} : STRUCT;') lines.append(f'{current_indent_str}{var_info["name"]} : STRUCT') # SIN ;
if var_info.get("children"): lines.extend(generate_struct_members_for_source(var_info["children"], indent_level + 1))
lines.extend(generate_struct_members_for_source(var_info["children"], indent_level + 1)) lines.append(f'{current_indent_str}END_STRUCT;') # CON ;
lines.append(f'{current_indent_str}END_STRUCT;') else:
else: # Variable primitiva, String, Array, o instancia de UDT
lines.append(generate_variable_declaration_for_source(var_info, indent_level)) lines.append(generate_variable_declaration_for_source(var_info, indent_level))
return lines return lines
def _generate_assignments_recursive(members: List[Dict[str, Any]], path_prefix: str, indent_str: str) -> List[str]: def generate_begin_block_assignments(db_info: Dict[str, Any], indent_level: int) -> List[str]:
"""Ayudante recursivo para generar asignaciones del bloque BEGIN."""
assignment_lines = []
for var_info in members:
# Construir la ruta actual para esta variable
current_member_name = var_info['name']
current_full_path = f"{path_prefix}{current_member_name}"
# Si es una instancia de UDT, sus 'children' en el JSON son los miembros expandidos.
# Necesitamos iterar sobre estos 'children' para obtener sus 'current_value'.
if var_info.get("udt_source_name") and var_info.get("children"):
# Para la instancia de UDT, recursivamente generar asignaciones para sus miembros.
# El prefijo de ruta para los miembros del UDT será el nombre de la instancia UDT seguido de un punto.
assignment_lines.extend(
_generate_assignments_recursive(var_info["children"], f"{current_full_path}.", indent_str)
)
# Si es un STRUCT definido inline (no una instancia de UDT)
elif var_info["data_type"].upper() == "STRUCT" and not var_info.get("udt_source_name") and var_info.get("children"):
assignment_lines.extend(
_generate_assignments_recursive(var_info["children"], f"{current_full_path}.", indent_str)
)
# Si es un miembro primitivo (o array/string que tiene un current_value directo)
# y tiene un 'current_value'. Los miembros expandidos de UDT (is_udt_expanded_member=True)
# tendrán su current_value y su current_full_path ya incluirá el nombre de la instancia UDT.
elif var_info.get("current_value") is not None:
val_str = var_info["current_value"]
if isinstance(val_str, bool): # Convertir booleanos de JSON a TRUE/FALSE de S7
val_str = "TRUE" if val_str else "FALSE"
assignment_lines.append(f"{indent_str}{current_full_path} := {val_str};")
return assignment_lines
# En x4.py
def generate_begin_block_assignments(db_info: Dict[str, Any], indent_level: int, parsed_json_udts: Dict[str, Dict[str, Any]]) -> List[str]:
indent_str = " " * indent_level indent_str = " " * indent_level
lines = [] lines = []
# Usar la lista ordenada de asignaciones del JSON, que x3.py ahora debería poblar
ordered_assignments = db_info.get("_begin_block_assignments_ordered")
# Utilizar directamente _initial_values_from_begin_block del JSON if ordered_assignments and isinstance(ordered_assignments, list):
# ¡ASEGÚRATE DE QUE x3.py INCLUYA ESTE CAMPO EN EL JSON! print(f"INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB '{db_info['name']}'.")
begin_values_map = db_info.get("_initial_values_from_begin_block") for path, value_obj in ordered_assignments:
value_str = str(value_obj)
if begin_values_map and isinstance(begin_values_map, dict): if value_str.lower() == "true": value_str = "TRUE"
# Intentar un ordenamiento simple por clave para una salida más consistente, elif value_str.lower() == "false": value_str = "FALSE"
# aunque el orden original del bloque BEGIN no se garantiza. lines.append(f"{indent_str}{path} := {value_str};") # Asignaciones siempre con ;
for path, value_str in sorted(begin_values_map.items()):
# Aquí, value_str ya es una cadena. Si necesitáramos convertir booleanos
# necesitaríamos información del tipo del 'path', lo cual es complejo aquí.
# Asumimos que x3.py guardó los valores en el formato correcto (ej. TRUE/FALSE para bools).
# Si x3.py guardó Python bools (true/false), necesitamos convertir.
# Para ser seguro, si el valor es "true" o "false" (strings), convertir.
# Esta conversión es una heurística. Sería mejor si x3.py ya los formateara.
final_value_str = str(value_str) # Asegurar que es string
if final_value_str.lower() == "true":
final_value_str = "TRUE"
elif final_value_str.lower() == "false":
final_value_str = "FALSE"
lines.append(f"{indent_str}{path} := {final_value_str};")
else: else:
# Fallback si _initial_values_from_begin_block no está o está mal formado. print(f"ADVERTENCIA: '_begin_block_assignments_ordered' no encontrado para DB '{db_info['name']}'. "
# Este fallback ahora necesita ser más inteligente o se eliminará si el principal funciona. "El bloque BEGIN puede estar incompleto o desordenado si se usa el fallback.")
# print(f"Advertencia: _initial_values_from_begin_block no encontrado o vacío para DB {db_info['name']}. Reconstrucción de BEGIN puede ser incompleta.") # (Aquí podría ir el fallback a _generate_assignments_recursive_from_current_values si se desea)
# La función _generate_assignments_recursive anterior podría ser un fallback, # fallback_lines = _generate_assignments_recursive_from_current_values(db_info.get("members", []), "", indent_str)
# pero depende de que los `current_value` de los elementos de array estén bien poblados. # if fallback_lines: lines.extend(fallback_lines)
# Si se implementa el `current_element_values` en `VariableInfo` en x3.py:
def generate_recursive_fallback(members, prefix, current_indent):
fallback_lines = []
for v_info in members:
m_name = v_info['name']
m_path = f"{prefix}{m_name}"
if v_info.get("current_element_values") and isinstance(v_info["current_element_values"], dict):
for index_str, val_str_el in sorted(v_info["current_element_values"].items()):
# index_str puede ser "1" o "1,2" etc.
el_path = f"{m_path}[{index_str}]"
f_val_str_el = str(val_str_el)
if f_val_str_el.lower() == "true": f_val_str_el = "TRUE"
elif f_val_str_el.lower() == "false": f_val_str_el = "FALSE"
fallback_lines.append(f"{current_indent}{el_path} := {f_val_str_el};")
elif v_info.get("udt_source_name") and v_info.get("children"):
fallback_lines.extend(generate_recursive_fallback(v_info["children"], f"{m_path}.", current_indent))
elif v_info.get("data_type", "").upper() == "STRUCT" and not v_info.get("udt_source_name") and v_info.get("children"):
fallback_lines.extend(generate_recursive_fallback(v_info["children"], f"{m_path}.", current_indent))
elif v_info.get("current_value") is not None:
val_str_cv = v_info["current_value"]
f_val_str_cv = str(val_str_cv)
if f_val_str_cv.lower() == "true": f_val_str_cv = "TRUE"
elif f_val_str_cv.lower() == "false": f_val_str_cv = "FALSE"
fallback_lines.append(f"{current_indent}{m_path} := {f_val_str_cv};")
return fallback_lines
lines.extend(generate_recursive_fallback(db_info.get("members", []), "", indent_str))
return lines return lines
def generate_s7_source_code_lines(data: Dict[str, Any]) -> List[str]: def generate_s7_source_code_lines(data: Dict[str, Any]) -> List[str]:
"""Genera el código fuente S7 completo (UDTs y DBs) a partir de los datos JSON."""
lines = [] lines = []
# Generar UDTs
for udt in data.get("udts", []): for udt in data.get("udts", []):
lines.append(f'TYPE "{udt["name"]}"') lines.append(f'TYPE "{udt["name"]}"')
if udt.get("family"): lines.append(f' FAMILY : {udt["family"]};') if udt.get("family"): lines.append(f' FAMILY : {udt["family"]}') # SIN ;
if udt.get("version"): lines.append(f' VERSION : {udt["version"]};') if udt.get("version"): lines.append(f' VERSION : {udt["version"]}') # SIN ;
lines.append("") # Línea en blanco lines.append("")
lines.append(" STRUCT") lines.append(" STRUCT") # SIN ;
# Los miembros del UDT están directamente bajo 'members' lines.extend(generate_struct_members_for_source(udt["members"], 2))
lines.extend(generate_struct_members_for_source(udt["members"], 2)) # Indentación 2 para miembros lines.append(" END_STRUCT;") # CON ;
lines.append(" END_STRUCT;") lines.append(f'END_TYPE') # SIN ; según tu último comentario
lines.append(f'END_TYPE;') lines.append("")
lines.append("") # Línea en blanco después de cada UDT
# Generar DBs
for db in data.get("dbs", []): for db in data.get("dbs", []):
lines.append(f'DATA_BLOCK "{db["name"]}"') lines.append(f'DATA_BLOCK "{db["name"]}"')
if db.get("title"): lines.append(f' TITLE = {db["title"]};') # Asumir que el título ya tiene el formato correcto if db.get("title"): # TITLE = { ... } va tal cual y SIN ;
if db.get("family"): lines.append(f' FAMILY : {db["family"]};') lines.append(f' TITLE = {db["title"]}')
if db.get("version"): lines.append(f' VERSION : {db["version"]};') if db.get("family"): lines.append(f' FAMILY : {db["family"]}') # SIN ;
lines.append("") # Línea en blanco if db.get("version"): lines.append(f' VERSION : {db["version"]}') # SIN ;
lines.append(" STRUCT") lines.append("")
lines.extend(generate_struct_members_for_source(db["members"], 2)) # Indentación 2 para miembros lines.append(" STRUCT") # SIN ;
lines.append(" END_STRUCT;") lines.extend(generate_struct_members_for_source(db["members"], 2))
lines.append(" END_STRUCT;") # CON ;
# Generar bloque BEGIN si hay valores actuales (implicando que hubo un bloque BEGIN) begin_assignments = generate_begin_block_assignments(db, 1) # Indentación 1 para las asignaciones
# La forma más fiable es chequear si hay current_values en los miembros. if begin_assignments:
# O, si el parser x3.py guardara una bandera explícita "has_begin_block". lines.append("BEGIN") # SIN ;
# Por ahora, generaremos BEGIN si hay miembros, ya que las asignaciones se basan en current_value. lines.extend(begin_assignments)
if db.get("members"): # Asumimos que si hay miembros, puede haber un bloque BEGIN.
lines.append("BEGIN")
lines.extend(generate_begin_block_assignments(db, 1)) # Indentación 1 para asignaciones
lines.append(f'END_DATA_BLOCK;')
lines.append("") # Línea en blanco después de cada DB
lines.append(f'END_DATA_BLOCK') # SIN ; según tu último comentario
lines.append("")
return lines return lines
# generate_markdown_table (sin cambios respecto a la v5)
def generate_markdown_table(db_info: Dict[str, Any]) -> List[str]: def generate_markdown_table(db_info: Dict[str, Any]) -> List[str]:
"""Genera una tabla Markdown para la documentación de un DB."""
lines = [] lines = []
lines.append(f"# Documentación para DB: {db_info['name']}") lines.append(f"## Documentación para DB: {db_info['name']}") # Cambiado a H2 para múltiples DBs por archivo
lines.append("") lines.append("")
lines.append("| Address | Name | Type | Initial Value | Actual Value | Comment |") lines.append("| Address | Name | Type | Initial Value | Actual Value | Comment |")
lines.append("|---|---|---|---|---|---|") lines.append("|---|---|---|---|---|---|")
processed_expanded_members = set()
def flatten_members_for_markdown(members: List[Dict[str, Any]], prefix: str = "", base_offset: float = 0.0): def flatten_members_for_markdown(members: List[Dict[str, Any]], prefix: str = "", base_offset: float = 0.0, is_expansion: bool = False):
md_lines = [] md_lines = []
for var in members: for var_idx, var in enumerate(members):
if var.get("is_udt_expanded_member"): # No listar miembros expandidos como filas separadas de alto nivel aquí member_id = f"{prefix}{var['name']}_{var_idx}"
continue if is_expansion and member_id in processed_expanded_members: continue
if is_expansion: processed_expanded_members.add(member_id)
name = f"{prefix}{var['name']}" name_for_display = f"{prefix}{var['name']}"
# El offset en el JSON ya debería ser absoluto para los miembros del DB.
# Para miembros dentro de STRUCTs anidados, el JSON también debería tener offsets absolutos.
address = f"{var['byte_offset']:.1f}" if isinstance(var['byte_offset'], float) else str(var['byte_offset']) address = f"{var['byte_offset']:.1f}" if isinstance(var['byte_offset'], float) else str(var['byte_offset'])
if var.get("bit_size", 0) > 0 and isinstance(var['byte_offset'], float) and var['byte_offset'] != int(var['byte_offset']): if var.get("bit_size", 0) > 0 and isinstance(var['byte_offset'], float) and var['byte_offset'] != int(var['byte_offset']): pass
pass # El formato X.Y ya está bien para bools elif var.get("bit_size", 0) > 0 : address = f"{int(var['byte_offset'])}.0"
elif var.get("bit_size", 0) > 0 : # bool en X.0 data_type_str = format_data_type_for_source(var)
address = f"{int(var['byte_offset'])}.0" initial_value = str(var.get("initial_value", "")).replace("|", "\\|").replace("\n", " ")
actual_value = str(var.get("current_value", "")).replace("|", "\\|").replace("\n", " ")
comment = str(var.get("comment", "")).replace("|", "\\|").replace("\n", " ")
data_type_str = format_data_type_for_source(var) # Usar la misma función de formato is_struct_container = var["data_type"].upper() == "STRUCT" and not var.get("udt_source_name") and var.get("children")
initial_value = str(var.get("initial_value", "")) is_udt_instance_container = bool(var.get("udt_source_name")) and var.get("children")
actual_value = str(var.get("current_value", "")) if not is_struct_container and not is_udt_instance_container or var.get("is_udt_expanded_member"):
comment = str(var.get("comment", "")) md_lines.append(f"| {address} | {name_for_display} | {data_type_str} | {initial_value} | {actual_value} | {comment} |")
# Reemplazar pipes en los valores para no romper la tabla Markdown
initial_value = initial_value.replace("|", "\\|")
actual_value = actual_value.replace("|", "\\|")
comment = comment.replace("|", "\\|").replace("\n", " ")
md_lines.append(f"| {address} | {name} | {data_type_str} | {initial_value} | {actual_value} | {comment} |")
# Si es un STRUCT (no UDT) o un UDT, listar sus miembros constitutivos recursivamente para la documentación
if var.get("children"): if var.get("children"):
# Si es una instancia de UDT, los hijos son los miembros expandidos. md_lines.extend(flatten_members_for_markdown(var["children"],
# Si es un STRUCT, los hijos son los miembros directos del STRUCT. f"{name_for_display}.",
# El prefijo para los hijos debe ser el nombre completo del padre (STRUCT/UDT). var['byte_offset'],
md_lines.extend(flatten_members_for_markdown(var["children"], f"{name}.", var['byte_offset'])) is_expansion=bool(var.get("udt_source_name"))))
return md_lines return md_lines
lines.extend(flatten_members_for_markdown(db_info.get("members", []))) lines.extend(flatten_members_for_markdown(db_info.get("members", [])))
return lines return lines
def main(): def main():
json_input_filename = "parsed_s7_data_expanded.json" working_dir = find_working_directory()
s7_output_filename = "reconstructed_s7_source_v2.txt" # Nuevo nombre para la salida S7 print(f"Using working directory: {working_dir}")
try: input_json_dir = os.path.join(working_dir, "json")
with open(json_input_filename, 'r', encoding='utf-8') as f: documentation_dir = os.path.join(working_dir, "documentation")
data_from_json = json.load(f) os.makedirs(documentation_dir, exist_ok=True)
except FileNotFoundError: print(f"Los archivos de documentación generados se guardarán en: {documentation_dir}")
print(f"Error: No se encontró el archivo JSON de entrada: {json_input_filename}")
return json_files_to_process = glob.glob(os.path.join(input_json_dir, "*.json"))
except json.JSONDecodeError:
print(f"Error: El archivo JSON de entrada no es válido: {json_input_filename}") if not json_files_to_process:
return print(f"No se encontraron archivos .json en {input_json_dir}")
except Exception as e:
print(f"Error al leer el archivo JSON {json_input_filename}: {e}")
return return
print(f"Archivo JSON '{json_input_filename}' cargado correctamente.") print(f"Archivos JSON encontrados para procesar: {len(json_files_to_process)}")
# 1. Generar el archivo S7 reconstruido for json_input_filepath in json_files_to_process:
s7_code_lines = generate_s7_source_code_lines(data_from_json) json_filename_base = os.path.splitext(os.path.basename(json_input_filepath))[0]
try: current_json_filename = os.path.basename(json_input_filepath)
with open(s7_output_filename, 'w', encoding='utf-8') as f: print(f"\n--- Procesando archivo JSON: {current_json_filename} ---")
for line in s7_code_lines:
f.write(line + "\n")
print(f"Archivo S7 reconstruido generado: {s7_output_filename}")
except Exception as e:
print(f"Error al escribir el archivo S7 {s7_output_filename}: {e}")
# 2. Generar la documentación Markdown (para cada DB encontrado) s7_output_filename = os.path.join(documentation_dir, f"{json_filename_base}.txt")
if data_from_json.get("dbs"): md_output_filename = os.path.join(documentation_dir, f"{json_filename_base}.md")
for db_to_document in data_from_json["dbs"]:
db_name_safe = db_to_document['name'].replace('"', '').replace(' ', '_') try:
md_filename_specific = f"documentation_db_{db_name_safe}.md" with open(json_input_filepath, 'r', encoding='utf-8') as f:
data_from_json = json.load(f)
print(f"Archivo JSON '{current_json_filename}' cargado correctamente.")
except Exception as e:
print(f"Error al cargar/leer {current_json_filename}: {e}")
continue # Saltar al siguiente archivo JSON
# Generar archivo S7 (.txt)
s7_code_lines = generate_s7_source_code_lines(data_from_json)
try:
with open(s7_output_filename, 'w', encoding='utf-8') as f:
for line in s7_code_lines:
f.write(line + "\n")
print(f"Archivo S7 reconstruido generado: {s7_output_filename}")
except Exception as e:
print(f"Error al escribir el archivo S7 {s7_output_filename}: {e}")
# Generar archivo Markdown (.md) para todos los DBs en este JSON
all_db_markdown_lines = []
if data_from_json.get("dbs"):
all_db_markdown_lines.append(f"# Documentación S7 para {json_filename_base}")
all_db_markdown_lines.append(f"_Fuente JSON: {current_json_filename}_")
all_db_markdown_lines.append("")
for db_index, db_to_document in enumerate(data_from_json["dbs"]):
if db_index > 0:
all_db_markdown_lines.append("\n---\n") # Separador visual entre DBs
markdown_lines_for_one_db = generate_markdown_table(db_to_document)
all_db_markdown_lines.extend(markdown_lines_for_one_db)
all_db_markdown_lines.append("") # Espacio después de cada tabla de DB
print(f"\nGenerando documentación Markdown para DB: {db_to_document['name']}...")
markdown_lines = generate_markdown_table(db_to_document)
try: try:
with open(md_filename_specific, 'w', encoding='utf-8') as f: with open(md_output_filename, 'w', encoding='utf-8') as f:
for line in markdown_lines: for line in all_db_markdown_lines:
f.write(line + "\n") f.write(line + "\n")
print(f"Archivo Markdown de documentación generado: {md_filename_specific}") print(f"Archivo Markdown de documentación generado: {md_output_filename}")
except Exception as e: except Exception as e:
print(f"Error al escribir el archivo Markdown {md_filename_specific}: {e}") print(f"Error al escribir el archivo Markdown {md_output_filename}: {e}")
else: else:
print("No se encontraron DBs en el archivo JSON para generar documentación.") print(f"No se encontraron DBs en {current_json_filename} para generar documentación Markdown.")
# Opcionalmente, crear un archivo MD con un mensaje
with open(md_output_filename, 'w', encoding='utf-8') as f:
f.write(f"# Documentación S7 para {json_filename_base}\n\n_Fuente JSON: {current_json_filename}_\n\nNo se encontraron Bloques de Datos (DBs) en este archivo JSON.\n")
print(f"Archivo Markdown generado (sin DBs): {md_output_filename}")
print("\n--- Proceso de generación de documentación completado ---")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -0,0 +1,231 @@
import json
from typing import List, Dict, Any, Optional
import sys
import os
import glob # Para buscar archivos JSON
from datetime import datetime # Mover import al inicio
script_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
)
sys.path.append(script_root)
from backend.script_utils import load_configuration
def find_working_directory():
configs = load_configuration()
working_directory = configs.get("working_directory")
if not working_directory:
print("No working directory specified in the configuration file.")
sys.exit(1)
return working_directory
def format_data_type_for_display(var_info: Dict[str, Any]) -> str:
"""Formatea la declaración de tipo para visualización en Markdown."""
base_type = var_info.get("udt_source_name") if var_info.get("udt_source_name") else var_info["data_type"]
type_str = ""
if var_info.get("array_dimensions"):
dims_str = ",".join([f"{d['lower_bound']}..{d['upper_bound']}" for d in var_info["array_dimensions"]])
type_str += f"ARRAY [{dims_str}] OF "
type_str += base_type
if var_info["data_type"].upper() == "STRING" and var_info.get("string_length") is not None:
type_str += f"[{var_info['string_length']}]"
return type_str
def format_offset_for_display(byte_offset: float) -> str:
"""Formatea el offset como X.Y o solo X si es .0."""
if byte_offset == float(int(byte_offset)):
return str(int(byte_offset))
return f"{byte_offset:.1f}"
def generate_members_table_md(
members: List[Dict[str, Any]],
path_prefix: str = "",
is_udt_definition: bool = False,
include_current_value: bool = False
) -> List[str]:
"""Genera líneas de tabla Markdown para una lista de miembros."""
md_lines = []
for var_info in members:
name_display = f"{path_prefix}{var_info['name']}"
# Para miembros expandidos de un UDT, su nombre ya está completo en la jerarquía del JSON.
# La recursión ya habrá construido el path_prefix.
# No necesitamos hacer nada especial aquí si `is_udt_expanded_member` es true,
# ya que esta función se llama recursivamente sobre `children`.
data_type_display = format_data_type_for_display(var_info)
offset_display = format_offset_for_display(var_info['byte_offset'])
size_bytes_display = str(var_info['size_in_bytes'])
bit_size_display = str(var_info.get('bit_size', '0')) if var_info.get('bit_size', 0) > 0 else ""
initial_value_display = str(var_info.get('initial_value', '')).replace("|", "\\|").replace("\n", " ")
comment_display = str(var_info.get('comment', '')).replace("|", "\\|").replace("\n", " ")
row = f"| `{name_display}` | `{data_type_display}` | {offset_display} | {size_bytes_display} | {bit_size_display} | `{initial_value_display}` |"
if include_current_value:
current_value_display = ""
# Si es un array y tiene current_element_values
if var_info.get("current_element_values") and isinstance(var_info["current_element_values"], dict):
# Mostrar un resumen o un placeholder para arrays complejos en la tabla principal
# Los valores detallados del array se listarán en la sección BEGIN.
num_elements = sum(dim['count'] for dim in var_info.get('array_dimensions', [])) if var_info.get('array_dimensions') else 1
if num_elements == 0 and var_info.get("array_dimensions"): # Caso de ARRAY [x..y] donde x > y (raro, pero posible)
num_elements = 1 # Para evitar división por cero o lógica extraña.
assigned_elements = len(var_info["current_element_values"])
if assigned_elements > 0:
current_value_display = f"{assigned_elements} elemento(s) asignado(s) en BEGIN"
elif var_info.get("current_value") is not None: # Para arrays con una asignación global (raro en BEGIN)
current_value_display = str(var_info.get("current_value", '')).replace("|", "\\|").replace("\n", " ")
else:
current_value_display = ""
elif var_info.get("current_value") is not None:
current_value_display = str(var_info.get("current_value", '')).replace("|", "\\|").replace("\n", " ")
row += f" `{current_value_display}` |"
row += f" {comment_display} |"
md_lines.append(row)
# Recursión para hijos de STRUCTs o miembros expandidos de UDTs
# `is_udt_expanded_member` en el JSON nos dice si los 'children' son la expansión de un UDT.
if var_info.get("children"):
# El prefijo para los hijos es el nombre completo del padre actual.
# Si el hijo es un miembro expandido de UDT, su propio nombre en 'children' ya es el nombre final del miembro.
# Si el hijo es parte de un STRUCT anidado, su nombre es relativo al STRUCT.
md_lines.extend(generate_members_table_md(
var_info["children"],
f"{name_display}.",
is_udt_definition,
include_current_value
))
return md_lines
def generate_json_documentation(data: Dict[str, Any], output_filename: str):
"""Genera la documentación Markdown completa para el archivo JSON parseado."""
lines = []
lines.append(f"# Documentación del Archivo de Datos S7 Parseado")
current_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
lines.append(f"_Generado el: {current_date}_")
lines.append("")
lines.append("Este documento describe la estructura y el contenido del archivo JSON generado por el parser de fuentes S7 (`x3.py`).")
lines.append("")
# --- Sección UDTs ---
lines.append("## 1. Tipos de Datos de Usuario (UDTs)")
lines.append("")
if data.get("udts"):
for udt in data["udts"]:
lines.append(f'### 1.{data["udts"].index(udt) + 1}. UDT: `{udt["name"]}`')
if udt.get("family"): lines.append(f"- **Familia**: {udt['family']}")
if udt.get("version"): lines.append(f"- **Versión**: {udt['version']}")
lines.append(f"- **Tamaño Total**: {udt['total_size_in_bytes']} bytes")
lines.append("")
lines.append("#### Miembros del UDT:")
lines.append("| Nombre Miembro | Tipo de Dato | Offset (Byte.Bit) | Tamaño (Bytes) | Tamaño (Bits) | Valor Inicial | Comentario |")
lines.append("|---|---|---|---|---|---|---|")
lines.extend(generate_members_table_md(udt.get("members", []), is_udt_definition=True, include_current_value=False))
lines.append("")
else:
lines.append("No se encontraron UDTs en el archivo JSON.")
lines.append("")
# --- Sección DBs ---
lines.append("## 2. Bloques de Datos (DBs)")
lines.append("")
if data.get("dbs"):
for db in data["dbs"]:
lines.append(f'### 2.{data["dbs"].index(db) + 1}. DB: `{db["name"]}`')
if db.get("title"): lines.append(f"- **TITLE**: `{db['title']}`")
if db.get("family"): lines.append(f"- **Familia**: {db['family']}")
if db.get("version"): lines.append(f"- **Versión**: {db['version']}")
lines.append(f"- **Tamaño Declaraciones**: {db['total_size_in_bytes']} bytes")
lines.append("")
lines.append("#### Miembros del DB (Sección de Declaración):")
lines.append("| Nombre Miembro (Ruta) | Tipo de Dato | Offset (Byte.Bit) | Tamaño (Bytes) | Tamaño (Bits) | Valor Inicial (Decl.) | Valor Actual (Efectivo) | Comentario |")
lines.append("|---|---|---|---|---|---|---|---|")
lines.extend(generate_members_table_md(db.get("members", []), include_current_value=True))
lines.append("")
# Sección BEGIN
ordered_assignments = db.get("_begin_block_assignments_ordered")
if ordered_assignments:
lines.append("#### Contenido del Bloque `BEGIN` (Valores Actuales Asignados):")
lines.append("El bloque `BEGIN` define los valores actuales de las variables en el DB. Las siguientes asignaciones fueron encontradas, en orden:")
lines.append("")
lines.append("```scl") # Usar SCL para syntax highlighting si el visualizador Markdown lo soporta
for path, value in ordered_assignments:
val_str = str(value)
if val_str.lower() == "true": val_str = "TRUE"
elif val_str.lower() == "false": val_str = "FALSE"
lines.append(f" {path} := {val_str};")
lines.append("```")
lines.append("")
else:
lines.append("No se encontraron asignaciones en el bloque `BEGIN` (o no fue parseado).")
lines.append("")
else:
lines.append("No se encontraron DBs en el archivo JSON.")
# Guardar el archivo Markdown
try:
with open(output_filename, 'w', encoding='utf-8') as f:
for line in lines:
f.write(line + "\n")
print(f"Documentación Markdown completa generada: {output_filename}")
except Exception as e:
print(f"Error al escribir el archivo Markdown de documentación {output_filename}: {e}")
# --- Main ---
if __name__ == "__main__":
working_dir = find_working_directory()
print(f"Using working directory: {working_dir}")
input_json_dir = os.path.join(working_dir, "json")
documentation_dir = os.path.join(working_dir, "documentation")
os.makedirs(documentation_dir, exist_ok=True)
print(f"Los archivos Markdown de descripción se guardarán en: {documentation_dir}")
json_files_to_process = glob.glob(os.path.join(input_json_dir, "*.json"))
if not json_files_to_process:
print(f"No se encontraron archivos .json en {input_json_dir}")
else:
print(f"Archivos JSON encontrados para procesar: {len(json_files_to_process)}")
for json_input_filepath in json_files_to_process:
json_filename_base = os.path.splitext(os.path.basename(json_input_filepath))[0]
current_json_filename = os.path.basename(json_input_filepath)
print(f"\n--- Procesando archivo JSON para descripción: {current_json_filename} ---")
markdown_output_filename = os.path.join(documentation_dir, f"{json_filename_base}_description.md")
try:
with open(json_input_filepath, 'r', encoding='utf-8') as f:
data_from_json = json.load(f)
print(f"Archivo JSON '{current_json_filename}' cargado correctamente.")
except FileNotFoundError:
print(f"Error: No se encontró el archivo JSON de entrada: {json_input_filepath}")
continue
except json.JSONDecodeError:
print(f"Error: El archivo JSON de entrada no es válido: {json_input_filepath}")
continue
except Exception as e:
print(f"Error al leer el archivo JSON {json_input_filepath}: {e}")
continue
try:
generate_json_documentation(data_from_json, markdown_output_filename)
except Exception as e:
print(f"Error al generar la documentación para {current_json_filename}: {e}")
print("\n--- Proceso de generación de descripciones Markdown completado ---")

View File

@ -0,0 +1,166 @@
# --- x6.py ---
import json
from typing import List, Dict, Any
import openpyxl # For Excel export
from openpyxl.utils import get_column_letter
import sys
import os
import glob # Para buscar archivos JSON
script_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
)
sys.path.append(script_root)
from backend.script_utils import load_configuration
def find_working_directory():
configs = load_configuration()
working_directory = configs.get("working_directory")
if not working_directory:
print("No working directory specified in the configuration file.")
sys.exit(1)
return working_directory
# format_data_type_for_source (copied from x4.py as it's needed)
def format_data_type_for_source(var_info: Dict[str, Any]) -> str:
base_type = var_info.get("udt_source_name") if var_info.get("udt_source_name") else var_info["data_type"]
type_str = ""
if var_info.get("array_dimensions"):
dims_str = ",".join([f"{d['lower_bound']}..{d['upper_bound']}" for d in var_info["array_dimensions"]])
type_str += f"ARRAY [{dims_str}] OF "
type_str += base_type
if var_info["data_type"].upper() == "STRING" and var_info.get("string_length") is not None:
type_str += f"[{var_info['string_length']}]"
return type_str
def generate_excel_table(db_info: Dict[str, Any], excel_filename: str):
"""
Generates an Excel file with DB documentation.
"""
workbook = openpyxl.Workbook()
sheet = workbook.active
db_name_safe = db_info['name'].replace('"', '').replace(' ', '_').replace('/','_')
sheet.title = f"DB_{db_name_safe}"[:31] # Sheet names have a length limit
headers = ["Address", "Name", "Type", "Initial Value", "Actual Value", "Comment"]
for col_num, header in enumerate(headers, 1):
cell = sheet.cell(row=1, column=col_num, value=header)
cell.font = openpyxl.styles.Font(bold=True)
current_row = 2
processed_expanded_members = set() # To handle expanded UDT members correctly
def flatten_members_for_excel(members: List[Dict[str, Any]], prefix: str = "", base_offset: float = 0.0, is_expansion: bool = False):
nonlocal current_row
for var_idx, var in enumerate(members):
member_id = f"{prefix}{var['name']}_{var_idx}" # Unique ID for processed check
if is_expansion and member_id in processed_expanded_members:
continue
if is_expansion:
processed_expanded_members.add(member_id)
name_for_display = f"{prefix}{var['name']}"
address = f"{var['byte_offset']:.1f}" if isinstance(var['byte_offset'], float) else str(var['byte_offset'])
# Adjust address formatting for bits as in markdown generation
if var.get("bit_size", 0) > 0 and isinstance(var['byte_offset'], float) and var['byte_offset'] != int(var['byte_offset']):
pass # Already formatted like X.Y
elif var.get("bit_size", 0) > 0 :
address = f"{int(var['byte_offset'])}.0" # Ensure X.0 for bits at the start of a byte
data_type_str = format_data_type_for_source(var)
initial_value = str(var.get("initial_value", ""))
actual_value = str(var.get("current_value", ""))
comment = str(var.get("comment", ""))
is_struct_container = var["data_type"].upper() == "STRUCT" and \
not var.get("udt_source_name") and \
var.get("children")
is_udt_instance_container = bool(var.get("udt_source_name")) and var.get("children")
if not is_struct_container and not is_udt_instance_container or var.get("is_udt_expanded_member"):
row_data = [address, name_for_display, data_type_str, initial_value, actual_value, comment]
for col_num, value in enumerate(row_data, 1):
sheet.cell(row=current_row, column=col_num, value=value)
current_row += 1
if var.get("children"):
flatten_members_for_excel(var["children"],
f"{name_for_display}.",
var['byte_offset'], # Pass the parent's offset
is_expansion=bool(var.get("udt_source_name"))) # Mark if we are expanding a UDT
flatten_members_for_excel(db_info.get("members", []))
# Auto-size columns for better readability
for col_idx, column_cells in enumerate(sheet.columns, 1):
max_length = 0
column = get_column_letter(col_idx)
for cell in column_cells:
try:
if len(str(cell.value)) > max_length:
max_length = len(str(cell.value))
except:
pass
adjusted_width = (max_length + 2)
sheet.column_dimensions[column].width = adjusted_width
try:
workbook.save(excel_filename)
print(f"Excel documentation generated: {excel_filename}")
except Exception as e:
print(f"Error writing Excel file {excel_filename}: {e}")
def main():
working_dir = find_working_directory()
print(f"Using working directory: {working_dir}")
input_json_dir = os.path.join(working_dir, "json")
documentation_dir = os.path.join(working_dir, "documentation")
os.makedirs(documentation_dir, exist_ok=True)
print(f"Los archivos Excel de documentación se guardarán en: {documentation_dir}")
json_files_to_process = glob.glob(os.path.join(input_json_dir, "*.json"))
if not json_files_to_process:
print(f"No se encontraron archivos .json en {input_json_dir}")
return
print(f"Archivos JSON encontrados para procesar: {len(json_files_to_process)}")
for json_input_filepath in json_files_to_process:
current_json_filename = os.path.basename(json_input_filepath)
print(f"\n--- Procesando archivo JSON para Excel: {current_json_filename} ---")
try:
with open(json_input_filepath, 'r', encoding='utf-8') as f:
data_from_json = json.load(f)
print(f"Archivo JSON '{current_json_filename}' cargado correctamente.")
except FileNotFoundError:
print(f"Error: El archivo JSON de entrada '{current_json_filename}' no fue encontrado en {json_input_filepath}.")
continue
except json.JSONDecodeError:
print(f"Error: El archivo JSON '{current_json_filename}' no tiene un formato JSON válido.")
continue
except Exception as e:
print(f"Error al cargar/leer {current_json_filename}: {e}")
continue
if data_from_json.get("dbs"):
for db_to_document in data_from_json["dbs"]:
# Construir el path completo para el archivo Excel de salida
excel_output_filename = os.path.join(documentation_dir, f"{current_json_filename}.xlsx")
print(f"Generando documentación Excel para DB: '{db_to_document['name']}' (desde {current_json_filename}) -> {excel_output_filename}")
try:
generate_excel_table(db_to_document, excel_output_filename)
except Exception as e_excel:
print(f"Error al generar Excel para DB '{db_to_document['name']}': {e_excel}")
else:
print(f"No se encontraron DBs en el archivo JSON '{current_json_filename}' para generar documentación Excel.")
print("\n--- Proceso de generación de documentación Excel completado ---")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,413 @@
import json
import os
import sys
import glob
import copy
import re
from typing import List, Dict, Optional, Tuple, Any
# Assuming x3.py and x4.py are in the same directory or accessible via PYTHONPATH
# Imports from x3.py
from x3 import (
S7Parser,
ParsedData, # Dataclass for top-level structure
# The following dataclasses are defined in x3.py and used by S7Parser.
# We might not need to import them explicitly if we work with dicts from JSON.
# VariableInfo, ArrayDimension, UdtInfo, DbInfo,
custom_json_serializer,
find_working_directory,
)
# Imports from x4.py (or reimplementations if direct import is problematic)
# These functions from x4.py work on dictionary representations of the parsed data.
from x4 import (
format_data_type_for_source,
generate_variable_declaration_for_source,
generate_struct_members_for_source,
generate_begin_block_assignments,
generate_s7_source_code_lines,
)
# --- Helper Functions ---
def find_data_format_files(working_dir: str) -> Tuple[Optional[str], Optional[str]]:
"""Finds _data and _format files in the working directory."""
data_file: Optional[str] = None
format_file: Optional[str] = None
extensions = ["*.db", "*.awl", "*.db.txt", "*.awl.txt"]
all_s7_files = []
for ext_pattern in extensions:
all_s7_files.extend(glob.glob(os.path.join(working_dir, ext_pattern)))
# Prioritize longer extensions first for matching to avoid partial matches like .db when .db.txt exists
all_s7_files.sort(key=len, reverse=True)
for f_path in all_s7_files:
basename = os.path.basename(f_path)
# Check for _data file (and ensure it's not an _updated file from a previous run)
if "_data" in basename and "_updated" not in basename:
# More specific check to avoid matching e.g. "some_other_data_related_file"
# We expect "PREFIX_data.EXT"
name_part, _ = os.path.splitext(
basename
) # For "file.db.txt", this gives "file.db"
if name_part.endswith("_data") or basename.replace(
os.path.splitext(basename)[-1], ""
).endswith(
"_data"
): # Handles single and double extensions
if data_file is None: # Take the first one found (after sorting)
data_file = f_path
# Check for _format file
if "_format" in basename and "_updated" not in basename:
name_part, _ = os.path.splitext(basename)
if name_part.endswith("_format") or basename.replace(
os.path.splitext(basename)[-1], ""
).endswith("_format"):
if format_file is None:
format_file = f_path
if data_file:
print(f"Found _data file: {data_file}")
else:
print("Warning: No _data file found.")
if format_file:
print(f"Found _format file: {format_file}")
else:
print("Warning: No _format file found.")
return data_file, format_file
def parse_s7_to_json_file(s7_filepath: str, json_dir: str) -> Optional[str]:
"""Parses an S7 source file to JSON and saves it."""
parser = S7Parser()
filename = os.path.basename(s7_filepath)
print(f"Parsing S7 file: {filename}...")
try:
parsed_result = parser.parse_file(s7_filepath)
except Exception as e:
print(f"Error parsing {filename}: {e}")
return None
output_filename_base = os.path.splitext(filename)[0]
# Handle double extensions like .db.txt
if ".db" in output_filename_base or ".awl" in output_filename_base:
# A more robust way to get the true base name before multiple extensions
# Example: "file.db.txt" -> "file"
# Example: "file.db" -> "file"
temp_name = filename
known_exts = [
".txt",
".db",
".awl",
] # order might matter if extensions can be part of name
for k_ext in reversed(known_exts): # try removing from right to left
if temp_name.lower().endswith(k_ext):
temp_name = temp_name[: -len(k_ext)]
output_filename_base = temp_name # This is the "true" base
json_output_filename = os.path.join(
json_dir,
f"{output_filename_base}_{os.path.basename(s7_filepath).split('_', 1)[1].split('.')[0]}.json",
) # e.g. base_data.json
print(f"Serializing to JSON: {json_output_filename}")
try:
json_output = json.dumps(
parsed_result, default=custom_json_serializer, indent=2
)
with open(json_output_filename, "w", encoding="utf-8") as f:
f.write(json_output)
print(f"JSON saved: {json_output_filename}")
return json_output_filename
except Exception as e:
print(f"Error during JSON serialization or writing for {filename}: {e}")
return None
def load_json_file(json_filepath: str) -> Optional[Dict[str, Any]]:
"""Loads a JSON file into a Python dictionary."""
try:
with open(json_filepath, "r", encoding="utf-8") as f:
data = json.load(f)
return data
except Exception as e:
print(f"Error loading JSON file {json_filepath}: {e}")
return None
def flatten_db_variables_for_compare(
members_list: List[Dict[str, Any]], parent_path: str = ""
) -> List[Tuple[str, Dict[str, Any]]]:
"""
Flattens DB members for comparison.
Collects all 'leaf' nodes (primitives, arrays of primitives, strings)
and their full paths.
"""
flat_list = []
for var_info in members_list:
var_name_segment = var_info["name"]
current_var_path = (
f"{parent_path}{var_name_segment}" if parent_path else var_name_segment
)
if var_info.get("children"):
flat_list.extend(
flatten_db_variables_for_compare(
var_info["children"], f"{current_var_path}."
)
)
else:
flat_list.append((current_var_path, var_info))
return flat_list
def compare_db_structures(data_db: Dict[str, Any], format_db: Dict[str, Any]) -> bool:
"""
Compares the structure of two DBs (as dicts from JSON).
Returns True if compatible, False otherwise.
"""
db_name = format_db.get("name", "UnknownDB")
print(f"Comparing structure of DB: {db_name}")
flat_data_vars_with_paths = flatten_db_variables_for_compare(
data_db.get("members", [])
)
flat_format_vars_with_paths = flatten_db_variables_for_compare(
format_db.get("members", [])
)
if len(flat_data_vars_with_paths) != len(flat_format_vars_with_paths):
print(f"Error: DB '{db_name}' tiene un número diferente de variables expandidas (hoja).")
print(f" Número de variables en archivo _data: {len(flat_data_vars_with_paths)}")
print(f" Número de variables en archivo _format: {len(flat_format_vars_with_paths)}")
min_len = min(len(flat_data_vars_with_paths), len(flat_format_vars_with_paths))
divergence_found_early = False
# Revisar si hay un tipo de dato o nombre diferente antes del final de la lista más corta
for k in range(min_len):
path_data_k, var_data_k = flat_data_vars_with_paths[k]
path_format_k, var_format_k = flat_format_vars_with_paths[k]
type_str_data_k = format_data_type_for_source(var_data_k)
type_str_format_k = format_data_type_for_source(var_format_k)
# Comparamos tipos. Los nombres pueden diferir si la estructura interna de un UDT/Struct cambió.
# La ruta del _data es aproximada si los nombres de los miembros de structs/UDTs cambiaron.
if type_str_data_k != type_str_format_k:
print(f" Adicionalmente, se encontró una discrepancia de tipo ANTES del final de la lista más corta (índice {k}):")
print(f" _format variable: Path='{path_format_k}', Nombre='{var_format_k['name']}', Tipo='{type_str_format_k}'")
print(f" _data variable: Path='{path_data_k}' (aprox.), Nombre='{var_data_k['name']}', Tipo='{type_str_data_k}'")
divergence_found_early = True
break
if not divergence_found_early:
# Si no hubo discrepancias tempranas, la diferencia es por variables extra al final.
if len(flat_data_vars_with_paths) > len(flat_format_vars_with_paths):
print(f" El archivo _data tiene {len(flat_data_vars_with_paths) - min_len} variable(s) más.")
print(f" Primeras variables extra en _data (path, nombre, tipo) desde el índice {min_len}:")
for j in range(min_len, min(min_len + 5, len(flat_data_vars_with_paths))): # Mostrar hasta 5 extra
path, var = flat_data_vars_with_paths[j]
print(f" - Path: '{path}', Nombre: '{var['name']}', Tipo: '{format_data_type_for_source(var)}'")
else:
print(f" El archivo _format tiene {len(flat_format_vars_with_paths) - min_len} variable(s) más.")
print(f" Primeras variables extra en _format (path, nombre, tipo) desde el índice {min_len}:")
for j in range(min_len, min(min_len + 5, len(flat_format_vars_with_paths))): # Mostrar hasta 5 extra
path, var = flat_format_vars_with_paths[j]
print(f" - Path: '{path}', Nombre: '{var['name']}', Tipo: '{format_data_type_for_source(var)}'")
return False
for i in range(len(flat_format_vars_with_paths)):
path_data, var_data = flat_data_vars_with_paths[i]
path_format, var_format = flat_format_vars_with_paths[i]
type_str_data = format_data_type_for_source(var_data)
type_str_format = format_data_type_for_source(var_format)
if type_str_data != type_str_format:
print(f"Error: Discrepancia de tipo en DB '{db_name}' para la variable en el índice {i} (contando desde 0) de la lista expandida.")
print(f" Comparando:")
print(f" _format variable: Path='{path_format}', Nombre='{var_format['name']}', Tipo Declarado='{type_str_format}'")
print(f" Offset: {var_format.get('byte_offset')}, Tamaño: {var_format.get('size_in_bytes')} bytes")
print(f" _data variable: Path='{path_data}' (aprox.), Nombre='{var_data['name']}', Tipo Declarado='{type_str_data}'")
print(f" Offset: {var_data.get('byte_offset')}, Tamaño: {var_data.get('size_in_bytes')} bytes")
return False
print(f"La estructura del DB '{db_name}' es compatible.")
return True
def update_format_db_members_recursive(
format_members: List[Dict[str, Any]], data_members: List[Dict[str, Any]]
):
"""
Recursively updates 'initial_value', 'current_value', and 'current_element_values'
in format_members using values from data_members.
Assumes structures are compatible and lists have the same length.
"""
for i in range(len(format_members)):
fm_var = format_members[i]
dm_var = data_members[i]
fm_var["initial_value"] = dm_var.get("initial_value")
fm_var["current_value"] = dm_var.get("current_value")
if "current_element_values" in dm_var:
fm_var["current_element_values"] = dm_var["current_element_values"]
elif "current_element_values" in fm_var:
del fm_var["current_element_values"]
if fm_var.get("children") and dm_var.get("children"):
if len(fm_var["children"]) == len(dm_var["children"]):
update_format_db_members_recursive(
fm_var["children"], dm_var["children"]
)
else:
print(
f"Warning: Mismatch in children count for {fm_var['name']} during update. This is unexpected."
)
def get_updated_filename(format_filename_basename: str) -> str:
"""Generates the output filename for the _updated file."""
suffixes_map = {
"_format.db.txt": "_updated.db.txt",
"_format.awl.txt": "_updated.awl.txt",
"_format.db": "_updated.db",
"_format.awl": "_updated.awl",
}
for s_format, s_updated in suffixes_map.items():
if format_filename_basename.lower().endswith(s_format.lower()):
base = format_filename_basename[: -len(s_format)]
return base + s_updated
if "_format" in format_filename_basename:
return format_filename_basename.replace("_format", "_updated")
name, ext = os.path.splitext(format_filename_basename)
return f"{name}_updated{ext}"
# --- Main Script Logic ---
def main():
working_dir = find_working_directory()
print(f"Using working directory: {working_dir}")
data_s7_filepath, format_s7_filepath = find_data_format_files(working_dir)
if not data_s7_filepath or not format_s7_filepath:
print(
"Error: Both _data and _format S7 source files must be present. Aborting."
)
return
json_dir = os.path.join(working_dir, "json")
os.makedirs(json_dir, exist_ok=True)
data_json_filepath = parse_s7_to_json_file(data_s7_filepath, json_dir)
if not data_json_filepath:
print("Failed to parse _data file. Aborting.")
return
data_parsed_dict = load_json_file(data_json_filepath)
if not data_parsed_dict:
print("Failed to load _data JSON. Aborting.")
return
format_json_filepath = parse_s7_to_json_file(format_s7_filepath, json_dir)
if not format_json_filepath:
print("Failed to parse _format file. Aborting.")
return
format_parsed_dict = load_json_file(format_json_filepath)
if not format_parsed_dict:
print("Failed to load _format JSON. Aborting.")
return
data_dbs = data_parsed_dict.get("dbs", [])
format_dbs = format_parsed_dict.get("dbs", [])
if not format_dbs:
print("No Data Blocks found in the _format file. Nothing to update. Aborting.")
return
if len(data_dbs) != len(format_dbs):
print(
f"Error: Mismatch in the number of Data Blocks. "
f"_data file has {len(data_dbs)} DBs, _format file has {len(format_dbs)} DBs. Aborting."
)
return
all_dbs_compatible = True
for i in range(len(format_dbs)):
current_format_db = format_dbs[i]
current_data_db = next(
(db for db in data_dbs if db["name"] == current_format_db["name"]), None
)
if not current_data_db:
print(
f"Error: DB '{current_format_db['name']}' from _format file not found in _data file. Aborting."
)
all_dbs_compatible = False
break
if not compare_db_structures(current_data_db, current_format_db):
all_dbs_compatible = False
break
if not all_dbs_compatible:
print("Comparison failed. Aborting generation of _updated file.")
return
print("\nAll DB structures are compatible. Proceeding to generate _updated file.")
updated_parsed_dict = copy.deepcopy(format_parsed_dict)
updated_parsed_dict["udts"] = format_parsed_dict.get("udts", [])
updated_dbs_list = updated_parsed_dict.get("dbs", [])
for i in range(len(updated_dbs_list)):
updated_db_ref = updated_dbs_list[i]
data_db_original = next(
(db for db in data_dbs if db["name"] == updated_db_ref["name"]), None
)
if not data_db_original:
print(
f"Critical Error: Could not find data DB {updated_db_ref['name']} during update phase. Aborting."
)
return
if "members" in updated_db_ref and "members" in data_db_original:
update_format_db_members_recursive(
updated_db_ref["members"], data_db_original["members"]
)
updated_db_ref["_begin_block_assignments_ordered"] = data_db_original.get(
"_begin_block_assignments_ordered", []
)
updated_db_ref["_initial_values_from_begin_block"] = data_db_original.get(
"_initial_values_from_begin_block", {}
)
s7_output_lines = generate_s7_source_code_lines(updated_parsed_dict)
output_s7_filename_basename = get_updated_filename(
os.path.basename(format_s7_filepath)
)
output_s7_filepath = os.path.join(working_dir, output_s7_filename_basename)
try:
with open(output_s7_filepath, "w", encoding="utf-8") as f:
for line in s7_output_lines:
f.write(line + "\n")
print(f"\nSuccessfully generated _updated S7 file: {output_s7_filepath}")
except Exception as e:
print(f"Error writing _updated S7 file {output_s7_filepath}: {e}")
if __name__ == "__main__":
main()

View File

@ -1,42 +1,17 @@
[20:15:59] Iniciando ejecución de x3.py en C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001... [23:48:43] Iniciando ejecución de x7_value_updater.py en C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001...
[20:16:00] --- ERRORES --- [23:48:43] Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
[20:16:00] 2025-05-16 20:16:00,228 - db_mapper - INFO - Iniciando mapeo de DBs por dirección absoluta [23:48:43] Found _data file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db
[20:16:00] 2025-05-16 20:16:00,309 - db_mapper - INFO - Directorio de trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001 [23:48:43] Found _format file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db
[20:16:00] 2025-05-16 20:16:00,310 - db_mapper - INFO - Encontrados 3 archivos para procesar [23:48:43] Parsing S7 file: db1001_data.db...
[20:16:00] 2025-05-16 20:16:00,310 - db_mapper - INFO - Procesando: db1001_data.db [23:48:43] Serializing to JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_data_data.json
[20:16:00] 2025-05-16 20:16:00,310 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db [23:48:43] JSON saved: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_data_data.json
[20:16:00] 2025-05-16 20:16:00,310 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db: module 'DB_Parser' has no attribute 'parse_db_definition' [23:48:43] Parsing S7 file: db1001_format.db...
[20:16:00] Traceback (most recent call last): [23:48:43] Serializing to JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format_format.json
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 76, in process_db_file [23:48:43] JSON saved: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format_format.json
[20:16:00] db_node, db_number, db_name, family, version = DB_Parser.parse_db_definition(db_content, udt_definitions) [23:48:43] Comparing structure of DB: HMI_Blender_Parameters
[20:16:00] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [23:48:43] La estructura del DB 'HMI_Blender_Parameters' es compatible.
[20:16:00] AttributeError: module 'DB_Parser' has no attribute 'parse_db_definition' [23:48:43] All DB structures are compatible. Proceeding to generate _updated file.
[20:16:00] 2025-05-16 20:16:00,312 - db_mapper - INFO - Procesando: db1001_format.db [23:48:43] INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
[20:16:00] 2025-05-16 20:16:00,312 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db [23:48:43] Successfully generated _updated S7 file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_updated.db
[20:16:00] 2025-05-16 20:16:00,313 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db: module 'DB_Parser' has no attribute 'parse_udt_definition' [23:48:43] Ejecución de x7_value_updater.py finalizada (success). Duración: 0:00:00.106052.
[20:16:00] Traceback (most recent call last): [23:48:43] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\log_x7_value_updater.txt
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 64, in process_db_file
[20:16:00] udt_name, udt_node = DB_Parser.parse_udt_definition(udt_content)
[20:16:00] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[20:16:00] AttributeError: module 'DB_Parser' has no attribute 'parse_udt_definition'
[20:16:00] 2025-05-16 20:16:00,316 - db_mapper - INFO - Procesando: db1001_format_updated.db
[20:16:00] 2025-05-16 20:16:00,316 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format_updated.db
[20:16:00] 2025-05-16 20:16:00,316 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format_updated.db: module 'DB_Parser' has no attribute 'parse_udt_definition'
[20:16:00] Traceback (most recent call last):
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 64, in process_db_file
[20:16:00] udt_name, udt_node = DB_Parser.parse_udt_definition(udt_content)
[20:16:00] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[20:16:00] AttributeError: module 'DB_Parser' has no attribute 'parse_udt_definition'
[20:16:00] Traceback (most recent call last):
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 444, in <module>
[20:16:00] main()
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 430, in main
[20:16:00] processed_files, mapped_pairs = process_all_files_in_directory()
[20:16:00] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 372, in process_all_files_in_directory
[20:16:00] "timestamp": import_datetime().now().isoformat()
[20:16:00] ^^^^^^^^^^^^^^^^^^^^^
[20:16:00] AttributeError: module 'datetime' has no attribute 'now'
[20:16:00] --- FIN ERRORES ---
[20:16:00] Ejecución de x3.py finalizada (error). Duración: 0:00:00.897567. Se detectaron errores (ver log).
[20:16:00] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\log_x3.txt