Atomic File Reads and Writes/Calling Python script from app.js
-
Hi all,
I'm currently trying to find a way to save data to and load data from the local disk atomically so as to avoid corruption in the event of a loss of power. I'm running mango 2.8.6 on Windows. Everything is done on localhost so there's no remote access of any kind, I just need some way to store and retrieve the results of tests. As javascript doesn't have a way of writing files transactionally that I'm aware of, the only solution I can think of is to send the data to a python script, which will do the file writes, but I'm not sure how to call a python script using an ajax request in my mango script. I should also note that these file writes will have to happen fairly regularly (~every minute).Lastly, if this isn't a good way to achieve what I want should I instead use the H2 database? If so, I'm having trouble connecting to it. Do I need to change the blank username and password in env.properties file? The sql console works but the sql datasource isn't working for me. I'd also be interested to know how to query and publish to the sql database from code so that I can save and retrieve files, thanks.
-
Hi avilla,
What do you mean, "mango script"? If you are referring to the scripting environments, like the Scripting Data Source or Meta data point, then you can invoke Java code directly to perform that type of task. Or, if you pass the command line argument for Nashorn to be in scripting mode, you can invoke system shell calls from JavaScript. This git issue is related to passing arguments (but won't tell you how, you'll probably need to have an ext-enabled script currently): https://github.com/infiniteautomation/ma-core-public/issues/1107 If you enable the scripting mode it won't be an AJAX method to invoke it.
You can create your own new java.io.FileOutputStream(new java.io.File("/path/to/file")) and write() to it.
Here's an example of someone using Java code in a script to read from a file, https://forum.infiniteautomation.com/topic/2970/is-it-possible-to-read-several-csv-documents-by-scripting
You do not need to change the blank username and password - your username and password are probably blank. Meaning, for the SQL data source you should be able to connect with the right driver (org.h2.Driver), the connection string in a similar syntax to the env.properties db.url as the path to your Mango/databases/mah2
Edit: I see now you probably meant scripting from the front end. The webpage definitely cannot access the file system, and the only way I can think of offhand to execute something like that would be the script-utils endpoint, which should give you the ability to submit a script for execution that could do the things discussed in the first part of this post. Or you can set relevant details to a context point that triggers a script.
Edit again: If all you need to do is trigger a python script, you can use a process event handler and set a value to a point that causes the event. You can use requests and the API in the python script to get the relevant information.
-
@avilla can you explain more what issue you are trying to solve. What kind of corruption are you trying to avoid and what kind of data are you trying to save?
-
Hi thanks for the reply.
I've now decided to use the built in h2 database to save and load my data. To answer your question @JoelHaggar the system is an automated temperature/vacuum chamber that needs to read and save some temperatures and voltages every time it runs a test. It will also need to load data from previous tests. The way I have it set up, each test will get its own row in the jsondata table. I was able to figure out how to insert and modify values into the JSONDATA table so saving files is done, but not how to load.The issue I'm having right now is that I will need to allow the user to load values from previous tests by selecting a file name in a select box that's generated from an sql query. I can't figure out from javascript how to query the "name" column in the jsondata table for all the file names and then once a row based on the "name" column value is selected how to get that rows data (really I only need the "data" column). Is this possible using the sql datapoints? And if so could you possibly provide some quick example code? Sorry, this is all pretty new to me. Thanks for your quick replies!
-
You can do that with the SQL Data Source. If you read the documentation available in the "?" icon it gives good examples of how to use it.
-
@joelhaggar I looked at that documentation and i figured out how to do everything except get a list of values for each row under the name column. I can only get info for the first column, whether I'm doing row or column based query.
For example, I want to get a list in my javascript of everything under the "NAME" column so the result should be [play-area-admin, TC Gauges, custom-user-pages, Profile, hello .. etc].