bms

Members
  • Posts

    27
  • Joined

  • Last visited

Everything posted by bms

  1. Another question if you will entertain me. I'm using a DLL at the moment to get around the issue, but it is a bit inconvenient that DF blocks while the function is running (i have to call it fairly regularly, and takes around 5 seconds to compute). Is there a way to call DLL functions asynchronously? "DLLGlue.dll": #include <stdlib.h> extern "C" { __declspec(dllexport) char RunApp(char *command) { return system(command); } } Then in DF: extern(OPT.OptimiserLocation + "DLLGlue.dll", "char RunApp(string)", "OptRunApp", "stdcall") OptRunApp("cmd /C python " + chr(34) + OPT.OptimiserLocation + "query.py" + chr(34))
  2. Still scratching my head here. If I send GET /optimize HTTP/1.1\013\010\013\010 I correctly receive HTTP 200. If I deliberately send something wrong EG GET /abc HTTP/1.1\013\010\013\010 I correctly get a 404 not found. Same for GET HTTP/1.1\013\010\013\010; 404 Not Found But HTTP.Get("127.0.0.1", "/optimize", 5000) gives the "a connection to the server could not be found" error. There is also no traffic captured on wireshark What is strange is HTTP.Get("127.0.0.1", "", 5000) does correctly return a 404 error and I can see it in wireshark. Does HTTP.Get() do any formatting before sending to windows?
  3. Yes, definitely not secure. Via the browser https://localhost:5000/optimize throws an error, but http://localhost:5000/optimize serves correctly.
  4. I have a webserver running locally that I'm trying to hit using HTTP.Get("127.0.0.1", "/optimize", 5000) or HTTP.Get("localhost", "/optimize", 5000), but I keep getting "HTTP Error: A connection with the server could not be established." I can access the server with a web browser (127.0.0.1:5000/optimize or localhost:5000/optimize). Is there a reason why DF can't find localhost, or am I doing something wrong?
  5. bms

    Licensing

    I've got the developer license on a hardware key. The license is used for local editing, and the file is then deployed to remote computers in the field. I occasionally have need to edit the remote files in situ for debugging, where local testing isn't adequate. What is the best way to achieve this? I would want to be able to do the remote editing on multiple different machines, but typically only for a few hours at a time. After that they would go back to runtime.
  6. Finally got this going today, using these credentials: private semail = new(CEMail) semail.strhost = "smtp.gmail.com" semail.port = 587 semail.strUserName = "<gmail_address>" semail.strPassword = "<app_password>" semail.strAuthenticate = "AuthLogin" semail.strBody = "this is a test" semail.strReplyAddress = "<gmail_address>" semail.strReplyName = "<gmail_address>" semail.strSubject = "test subject" semail.strTo = "<gmail_address>" semail.strConnectionType = "STARTTLS" semail.strSSLProtocol = "TLSv1_2" semail.Send() These are my original settings, so it seems there is something else going on beyond just having the right code and account settings. For anyone else reading this, I'd recommend logging out and back in to your google account every day until it starts working. I suspect Google is blocking access for a period of time; I had a similar problem last year (https://support.azeotech.com/topic/4251-twitter-feed-anyone/):
  7. Thanks Steve, but still no luck for me unfortunately. 2 Step verification is on, and I have generated an "app password." private semail = new(CEMail) semail.strhost = "smtp.gmail.com" semail.port = 465 semail.strUserName = "<gmail_address>" semail.strPassword = "<app_password>" semail.strAuthenticate = "AuthLogin" semail.strBody = "this is a test" semail.strReplyAddress = "<gmail_address>" semail.strReplyName = "<gmail_address>" semail.strSubject = "test subject" semail.strTo = "<gmail_address>" semail.strConnectionType = "STARTTLS" semail.strSSLProtocol = "TLSv1_2" semail.Send() Error 80040227 every time. Tried port 25, 465, 587. Help please!
  8. Emails have stopped working (Gmail) in the last couple of days. What does error 80040211 mean when sending?
  9. I have an issue querying a large database where some column names on separate tables are the same. In rare cases the query will include 2 or more of these datasets, and I therefore can't tell them apart using QueryToClass, as they have the same FieldName. EG I have two tables in my database, one for GHI Irradiance, and the other for POA Irradiance. Both have a column name "Irradiance." If the user wishes to graph both against each other: private RO = DB.QueryToClass(SQLTools.MySQLHandle, SQLQuery) RO.FieldNames // contains: {"Time_Stamp", "Irradiance", "Irradiance"} GraphTrace1 = evaluate(format("RO.%s", RO.Fieldnames[1])) GraphTrace2 = evaluate(format("RO.%s", RO.Fieldnames[2])) //Ambigious, always uses data from the first RO.Irradiance Is there a way to access the data some other way than via the FieldNames string array?
  10. We are currently using HTTP.Get() to interface with an API to our work server, but it is about to be depreciated. Is there a HTTPS version available or planned?
  11. When using these comms objects, I can't seem to poll Input or Holding Registers in the 30000 to 50000 range. EG when asking for Input Register 30233: ModbusDevice.ReadInputU16(1,30233,2) The command that actually goes out is for Input Register 232 (00 00 00 00 00 06 02 04 00 e8 00 02). It's as if it is assuming I am using Modicon 30xxx 40xxx convention. Asking for 60232 correctly sends the right command: 00 00 00 00 00 06 01 04 eb 48 00 02. Is there a way to force it to evaluate my data addressing literally?
  12. Please add support for OAuth2 email authentication
  13. Our email server is Microsoft Exchange and only supports OAuth2. For the moment I'm just using Gmail instead, but it seems they are also standardizing on OAuth2; I had to manually enable "unsecure 3rd party access". If you don't send any emails for a while (about 24 hours it seems) then they automatically turn it off again, and I can't send anything. I suspect their long term view is to phase it out completely.
  14. Is there any plan for DF to support OAuth2?
  15. I'm trying to track down what I think is a memory leak. DF runs fine for about a day, then starts to error out that it can't run any sequences. Task Manager shows DF is using over 1GB of memory; up from about 150mb on startup. It looks to be an issue with my logging function, which is called every 10 seconds to write all tags to MySQL. Simplified version: try private MySQLHandle = DB.Open("dfsqlsource", "user", "pass") //for loops to create query, removed here for brevity private string SQLQuery = "INSERT INTO etc etc" DB.Execute(MySQLHandle, SQLQuery) DB.Close(MySQLHandle) catch() System.ErrorMessage("SQL Log All Error: " + strLastError) DB.Close(MySQLHandle) endcatch Am I using DB.Open() and DB.Close() correctly? Or is it something to do with the private variables staying in scope between function calls or something weird like that?
  16. This works OK: private string SQLQuery = "SELECT Data_Manager.Time_Stamp, Inverter.RemoteReady FROM Data_Manager JOIN Inverter ON Inverter.Time_Stamp LIMIT 1000" private FieldHandle = DB.Query(MySQLHandle, SQLQuery) ? DB.Field(FieldHandle, 1) But I get an error "O1004 Unable to run query" for this: private string SQLQuery = "SELECT Data_Manager.Time_Stamp, Inverter.RemoteReady FROM Data_Manager JOIN Inverter ON Inverter.Time_Stamp LIMIT 1000" private RO = DB.QueryToClass(MySQLHandle, SQLQuery) ? RO.FieldNames
  17. +1 for SVG, that would be great. I'm not having any luck getting WMF directly into the symbol component, either from the clipboard, or using the load image button. Is it supported?
  18. Is there a way to import vector graphics directly, or do you have to go via the symbol factory?
  19. Is there a way to dynamically create alarms from sequences, or do they have to be manually added in the alarm summary view?
  20. That's great, thank you. Do these objects also support ModbusTCP Slave? Also, I'm confused with variable scope in a specific situation: class ModbusClass local string IPAddress = "192.168.1.1" local ModbusAddress = 1 local EthernetPort local ModbusDevice function Init() EthernetPort = new (CCommEthernet) EthernetPort.Address = IPAddress EthernetPort.Port = 502 EthernetPort.InitComm() EthernetPort.Purge() ModbusDevice = new (CCommDevice) ModbusDevice.PortObject = EthernetPort ModbusDevice.ProtocolName = "ModbusTCP" endfunction function Read(start, length, string type) ? format("IP Address: %s", ModbusDevice.IPAddress) return evaluate("ModbusDevice." + type + "(" + ModbusAddress + "," + start + "," + length + ")") endfunction endclass class DataManagerClass local Modbus function Init() Modbus = new (ModbusClass) endfunction endclass global DM = new (DataManagerClass) DM.Init() DM.Modbus.IPAddress = "10.0.0.19" DM.Modbus.Init() DM.Modbus.Read(0,125,"ReadInputU16") The output is: 192.168.1.1. The local variable IPAddress holds "10.0.0.19" as I would expect, but why does ModbusDevice.IPAddress print 192.168.1.1? Curiously, I do correctly poll the slave at 10.0.0.19
  21. Is it possible to call a Comm Device by referencing its underlying object? For example, switching between two different Modbus devices using a single wrapper: device.DataManager.Address = "10.0.0.19" device.SafetyEquipment.Address = "10.0.0.20" class ModbusStatsClass local Interface local Address function ReadModbus(start, size) return Interface.ReadHoldingU16(Address, start, size) endfunction endclass class DataManagerClass local WindSpeed local ModbusStats function Init() ModbusStats = new (ModbusStatsClass) ModbusStats.Address = 1 ModbusStats.Interface = device.DataManager endfunction endclass class SafetyEquipmentClass local LocalRemote local ModbusStats function Init() ModbusStats = new (ModbusStatsClass) ModbusStats.Address = 2 ModbusStats.Interface = device.SafetyEquipment endfunction endclass Global DM = new (DataManagerClass) Global SEIO = new (SafetyEquipmentClass) DM.Init() SEIO.Init() Private HoldingRegisters = DM.ModbusStats.ReadModbus(0, 125) // Do some stuff HoldingRegisters = SEIO.ModbusStats.ReadModbus(0, 60) //Do some other stuff
  22. Got it. Thanks for the detailed explanations; much appreciated.
  23. Is there an unsigned set register function? When reading I use ReadHoldingU16() but there doesn't appear to be a corresponding SetRegisterU16()?
  24. Sorry the omitted local is a typo. I am still a little confused by what is happening behind the scenes. Am I right in saying when this runs: class WSCLASS local status local temperature = new (MINMAXCLASS) local windspeed = new (MINMAXCLASS) endclass Then temperature and windspeed hold pointers to MINMAXCLASS, not the objects themselves? Then when I do: global ws = new(wsclass) ws will correctly hold the object wsclass with a copy of the member variable "status"? But the nested members "min" and "max" don't actually exist as copies in ws? So when altering them: ws.temperature.max = 10 This is actually updating the memory that was allocated when the class was first defined, not memory belonging to the object ws? And therefore considered a runtime error with undefined behavior?