OpenC3 / cosmos

OpenC3 COSMOS
https://openc3.com
Other
111 stars 31 forks source link

How to read csv in a Read Conversion initialization? #1689

Closed mkalin2 closed 2 weeks ago

mkalin2 commented 2 weeks ago

Is there a good way to read a csv file in the initialize method for a read conversion?

Currently I am getting a directory not found error when I upload to COSMOS:

Error. Error processing /tmp/d20241105-334-xh1ft/TARGET_NAME/cmd_tlm/tlm.txt

ENOENT: No such file or directory @ rb_sysopen - targets/TARGET_NAME/lib/csv_files/file.csv

Initially I was assuming the local directory was the target lib directory so I was just using csv_files/file.csv as my path, but I was getting a similar error on build. Changing the path to targets/TARGET_NAME/lib/csv_files/file.csv fixed the error on build, but when I upload to COSMOS I am still getting the same error.

ryanmelt commented 2 weeks ago

When we're parsing config files, the working directory is set to the folder of the config file. I'm not sure where you are reading this CSV file, but you need to control the working directory appropriately.

Wrap your file read like this:

      relative_path_to_other_file = "whatever relative to this file"
      full_path_to_current_file = File.expand_path(File.dirname(__FILE__))
      OpenC3.set_working_dir(File.dirname(full_path_to_current_file)) do
        return File.read(relative_path_to_other_file).force_encoding("UTF-8")
      end
mkalin2 commented 2 weeks ago

Sorry this doesn't seem to be working. I have tried using the relative path from tlm.txt as well as this_conversion.rb and still get the same error for both cases.

Here is the directory structure:

TARGET_NAME
├── cmd_tlm
│   ├── cmd.txt
│   └── tlm.txt
├── lib
│   ├── this_conversion.rb
│   ├── csv_files
│   │   └── file.csv
├── procedures
│   └── procedure.rb
├── public
│   └── README.txt
├── screens
│   ├── status.txt
└── target.txt
ryanmelt commented 2 weeks ago

Please provide the code that reads the file.

mkalin2 commented 2 weeks ago

This function gets called in the initialize function of this_conversion.rb.

file_name = 'file.csv'

def read_csv(file_name)
      relative_path = 'csv_files/' + file_name
      curr_dir = File.expand_path(File.dirname(__FILE__))
      OpenC3.set_working_dir(File.dirname(curr_dir)) do
        return CSV.read(relative_path)
      end
end

I have also tried using File.read() rather than the csv library, but I still get the file not found error.

mkalin2 commented 2 weeks ago

Here is the full stack trace:

Error: Error processing /tmp/d20241106-10-k083cs/TARGET_NAME/cmd_tlm/tlm.txt:

ENOENT : No such file or directory @ rb_sysopen - csv_files/file.csv
/usr/lib/ruby/3.2.0/csv.rb:1593:in `initialize'
/usr/lib/ruby/3.2.0/csv.rb:1593:in `open'
/usr/lib/ruby/3.2.0/csv.rb:1593:in `open'
/usr/lib/ruby/3.2.0/csv.rb:1829:in `read'
/tmp/d20241106-10-lfwb9v/gem/targets/TARGET_NAME/lib/this_conversion.rb:77:in `block in read_csv'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/top_level.rb:483:in `set_working_dir_internal'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/top_level.rb:473:in `block in set_working_dir'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/top_level.rb:472:in `synchronize'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/top_level.rb:472:in `set_working_dir'
/tmp/d20241106-10-lfwb9v/gem/targets/TARGET_NAME/lib/this_conversion.rb:76:in `read_csv'
/tmp/d20241106-10-lfwb9v/gem/targets/TARGET_NAME/lib/this_conversion.rb:27:in `initialize'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/packets/packet_config.rb:578:in `new'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/packets/packet_config.rb:578:in `process_current_item'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/packets/packet_config.rb:238:in `block in process_file'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/config/config_parser.rb:217:in `parse_loop'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/config/config_parser.rb:217:in `parse_file'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/packets/packet_config.rb:144:in `process_file'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/system/system.rb:181:in `block in add_target'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/system/system.rb:180:in `each'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/system/system.rb:180:in `add_target'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/system/system.rb:169:in `block in initialize'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/system/system.rb:169:in `each'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/system/system.rb:169:in `initialize'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/models/target_model.rb:602:in `new'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/models/target_model.rb:602:in `deploy'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/models/plugin_model.rb:251:in `block in install_phase2'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/config/config_parser.rb:217:in `parse_loop'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/config/config_parser.rb:217:in `parse_file'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/openc3/models/plugin_model.rb:243:in `install_phase2'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/../bin/openc3cli:327:in `validate_plugin'
/usr/lib/ruby/gems/3.2.0/gems/openc3-5.19.0/lib/../bin/openc3cli:850:in `<main>'
ryanmelt commented 2 weeks ago

I think my earlier code had one too many dirname calls.

Try this:

def read_csv(file_name)
      relative_path = 'csv_files/' + file_name
      full_file_path = File.expand_path(__FILE__)
      OpenC3.set_working_dir(File.dirname(full_file_path)) do
        return CSV.read(relative_path)
      end
end
mkalin2 commented 2 weeks ago

That seems to have fixed it! Thanks!