Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions doc/examples/csv/README.md
Comment thread
Pranav-0440 marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# CSV Import Examples

This directory contains example CSV files for testing the CSV import functionality in EditDor.

## Files

### `valid.csv`

A valid CSV file with correct data types and Modbus entities. This file should import without warnings.

**Valid Types:**

- `number`
- `string`
- `boolean`

**Valid Modbus Entities:**

- `HoldingRegister`
- `InputRegister`
- `Coil`
- `DiscreteInput`

### `invalid.csv`

A CSV file with intentional validation issues to demonstrate the warning system. When imported, this file will trigger the following warnings:

1. **Row 2, type**: `number123` is invalid (should be `number`, `string`, or `boolean`)
2. **Row 2, modbus:entity**: `holdingregister` has incorrect casing (expected `HoldingRegister`)
3. **Row 3, modbus:entity**: `InvalidRegister` is not a recognized Modbus entity
4. **Row 4, type**: `invalid_type` is not a valid type
5. **Row 5, modbus:entity**: `coil` has incorrect casing (expected `Coil`)

## Usage

1. Open EditDor
2. Select "Thing Description" or "Thing Model"
3. Click "Load a CSV File"
4. Select either `valid.csv` or `invalid.csv`
5. Observe the results:
- `valid.csv`: Should load successfully without warnings
- `invalid.csv`: Should display validation warnings but still load the data

## CSV Format

Required columns:

- `name`: Property name (required)
- `type`: Data type (number, string, or boolean)
- `modbus:entity`: Modbus entity type
- `modbus:address`: Modbus address (required)
- `modbus:unitID`: Modbus unit ID
- `modbus:quantity`: Number of registers
- `modbus:zeroBasedAddressing`: Boolean (true/false)
- `modbus:function`: Modbus function code
- `modbus:mostSignificantByte`: Boolean (true/false)
- `modbus:mostSignificantWord`: Boolean (true/false)
- `href`: Property endpoint path

Note: Modbus entity validation is case-insensitive for recognition purposes, but incorrect casing will produce a warning. For example, `coil` and `Coil` are treated as the same entity, but `coil` will generate a casing warning.
6 changes: 6 additions & 0 deletions doc/examples/csv/invalid.csv
Comment thread
Pranav-0440 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name,type,modbus:entity,modbus:address,modbus:unitID,modbus:quantity,modbus:zeroBasedAddressing,modbus:function,modbus:mostSignificantByte,modbus:mostSignificantWord,href
temp1,number123,holdingregister,40001,1,1,false,03,true,false,/temp
humidity,number,InvalidRegister,40002,1,1,false,04,false,false,/humidity
pressure,invalid_type,HoldingRegister,40003,1,2,true,03,true,true,/pressure
status,string,coil,00001,1,1,false,01,false,false,/status
alarm,boolean,DiscreteInput,10001,1,1,false,02,false,false,/alarm
6 changes: 6 additions & 0 deletions doc/examples/csv/valid.csv
Comment thread
Pranav-0440 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name,type,modbus:entity,modbus:address,modbus:unitID,modbus:quantity,modbus:zeroBasedAddressing,modbus:function,modbus:mostSignificantByte,modbus:mostSignificantWord,href
temperature,number,HoldingRegister,40001,1,1,false,03,true,false,/temp
humidity,number,InputRegister,40002,1,1,false,04,false,false,/humidity
pressure,number,HoldingRegister,40003,1,2,true,03,true,true,/pressure
status,boolean,Coil,00001,1,1,false,01,false,false,/status
alarm,boolean,DiscreteInput,10001,1,1,false,02,false,false,/alarm
13 changes: 11 additions & 2 deletions src/components/App/CreateTd.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,24 @@ const CreateTd: React.FC<CreateTdProps> = ({
throw new Error("CSV file is empty.");
}

const data = parseCsv(csvContent, true);
const { data, warnings } = parseCsv(csvContent, true);

const parsed = mapCsvToProperties(data);
if (!parsed || Object.keys(parsed).length === 0) {
throw new Error("No valid properties found in the CSV file.");
}

setProperties(parsed);
setError({ open: false, message: "" });

// Display warnings if any
if (warnings.length > 0) {
const warningMessage = warnings
.map((w) => `Row ${w.row}, column "${w.column}": ${w.message}`)
.join("; ");
setError({ open: true, message: `Warnings: ${warningMessage}` });
} else {
setError({ open: false, message: "" });
}
} catch (err) {
setProperties({});
setError({
Expand Down
Loading