358 except KeyError: |
358 except KeyError: |
359 raise KeyError("Try to set unknown shared global variable : %s" % name) |
359 raise KeyError("Try to set unknown shared global variable : %s" % name) |
360 v = parent.python_runtime_vars["_"+name+"_pack"](t, value) |
360 v = parent.python_runtime_vars["_"+name+"_pack"](t, value) |
361 parent.python_runtime_vars["_PySafeSetPLCGlob_"+name](ctypes.byref(v)) |
361 parent.python_runtime_vars["_PySafeSetPLCGlob_"+name](ctypes.byref(v)) |
362 |
362 |
|
363 class OnChangeStateClass(object): |
|
364 def __getattr__(self, name): |
|
365 u = parent.python_runtime_vars["_"+name+"_unpack"] |
|
366 return type("changedesc",(),dict( |
|
367 count = parent.python_runtime_vars["_PyOnChangeCount_"+name].value, |
|
368 first = u(parent.python_runtime_vars["_PyOnChangeFirst_"+name]), |
|
369 last = u(parent.python_runtime_vars["_PyOnChangeLast_"+name]))) |
|
370 |
|
371 |
363 self.python_runtime_vars.update({ |
372 self.python_runtime_vars.update({ |
364 "PLCGlobals": PLCSafeGlobals(), |
373 "PLCGlobals": PLCSafeGlobals(), |
|
374 "OnChange": OnChangeStateClass(), |
365 "WorkingDir": self.workingdir, |
375 "WorkingDir": self.workingdir, |
366 "PLCObject": self, |
376 "PLCObject": self, |
367 "PLCBinary": self.PLClibraryHandle, |
377 "PLCBinary": self.PLClibraryHandle, |
368 "PLCGlobalsDesc": []}) |
378 "PLCGlobalsDesc": []}) |
369 |
379 |
438 self.PythonThreadCmd = "Wait" |
448 self.PythonThreadCmd = "Wait" |
439 self.PythonThreadCondLock.release() |
449 self.PythonThreadCondLock.release() |
440 |
450 |
441 if cmd == "Activate": |
451 if cmd == "Activate": |
442 self.PythonRuntimeCall("start") |
452 self.PythonRuntimeCall("start") |
|
453 self.PreStartPLC() |
443 self.PythonThreadLoop() |
454 self.PythonThreadLoop() |
444 self.PythonRuntimeCall("stop", reverse_order=True) |
455 self.PythonRuntimeCall("stop", reverse_order=True) |
445 else: # "Finish" |
456 else: # "Finish" |
446 break |
457 break |
447 |
458 |
468 def StartPLC(self): |
479 def StartPLC(self): |
469 |
480 |
470 if self.PLClibraryHandle is None: |
481 if self.PLClibraryHandle is None: |
471 if not self.LoadPLC(): |
482 if not self.LoadPLC(): |
472 self._fail(_("Problem starting PLC : can't load PLC")) |
483 self._fail(_("Problem starting PLC : can't load PLC")) |
473 |
|
474 self.PreStartPLC() |
|
475 |
484 |
476 if self.CurrentPLCFilename is not None and self.PLCStatus == PlcStatus.Stopped: |
485 if self.CurrentPLCFilename is not None and self.PLCStatus == PlcStatus.Stopped: |
477 c_argv = ctypes.c_char_p * len(self.argv) |
486 c_argv = ctypes.c_char_p * len(self.argv) |
478 res = self._startPLC(len(self.argv), c_argv(*self.argv)) |
487 res = self._startPLC(len(self.argv), c_argv(*self.argv)) |
479 if res == 0: |
488 if res == 0: |
544 def PurgeBlobs(self): |
553 def PurgeBlobs(self): |
545 for fd, _path, _md5sum in self.blobs.values(): |
554 for fd, _path, _md5sum in self.blobs.values(): |
546 os.close(fd) |
555 os.close(fd) |
547 self._init_blobs() |
556 self._init_blobs() |
548 |
557 |
549 def _BlobAsFile(self, blobID, newpath): |
558 def BlobAsFile(self, blobID, newpath): |
550 blob = self.blobs.pop(blobID, None) |
559 blob = self.blobs.pop(blobID, None) |
551 |
560 |
552 if blob is None: |
561 if blob is None: |
553 raise Exception(_("Missing data to create file: {}").format(newpath)) |
562 raise Exception(_("Missing data to create file: {}").format(newpath)) |
554 |
563 |
|
564 self._BlobAsFile(blob, newpath) |
|
565 |
|
566 def _BlobAsFile(self, blob, newpath): |
555 fd, path, _md5sum = blob |
567 fd, path, _md5sum = blob |
556 fobj = os.fdopen(fd) |
568 fobj = os.fdopen(fd) |
557 fobj.flush() |
569 fobj.flush() |
558 os.fsync(fd) |
570 os.fsync(fd) |
559 fobj.close() |
571 fobj.close() |
608 |
620 |
609 self.LogMessage("NewPLC (%s)" % md5sum) |
621 self.LogMessage("NewPLC (%s)" % md5sum) |
610 |
622 |
611 try: |
623 try: |
612 # Create new PLC file |
624 # Create new PLC file |
613 self._BlobAsFile(plc_object, new_PLC_filename) |
625 self.BlobAsFile(plc_object, new_PLC_filename) |
614 |
626 |
615 # Then write the files |
627 # Then write the files |
616 log = open(extra_files_log, "w") |
628 log = open(extra_files_log, "w") |
617 for fname, blobID in extrafiles: |
629 for fname, blobID in extrafiles: |
618 fpath = os.path.join(self.workingdir, fname) |
630 fpath = os.path.join(self.workingdir, fname) |
619 self._BlobAsFile(blobID, fpath) |
631 self.BlobAsFile(blobID, fpath) |
620 log.write(fname+'\n') |
632 log.write(fname+'\n') |
621 |
633 |
622 # Store new PLC filename based on md5 key |
634 # Store new PLC filename based on md5 key |
623 with open(self._GetMD5FileName(), "w") as f: |
635 with open(self._GetMD5FileName(), "w") as f: |
624 f.write(md5sum) |
636 f.write(md5sum) |