449 self.PythonThreadCondLock.acquire() |
449 self.PythonThreadCondLock.acquire() |
450 self.PythonThreadCmd = cmd |
450 self.PythonThreadCmd = cmd |
451 self.PythonThreadCond.notify() |
451 self.PythonThreadCond.notify() |
452 self.PythonThreadCondLock.release() |
452 self.PythonThreadCondLock.release() |
453 |
453 |
|
454 def _fail(msg): |
|
455 self.LogMessage(0, msg) |
|
456 self.PLCStatus = PlcStatus.Broken |
|
457 self.StatusChange() |
|
458 |
|
459 def PreStartPLC(self): |
|
460 """ |
|
461 Here goes actions to be taken just before PLC starts, |
|
462 with all libraries and python object already created. |
|
463 For example : restore saved proprietary parameters |
|
464 """ |
|
465 pass |
|
466 |
454 @RunInMain |
467 @RunInMain |
455 def StartPLC(self): |
468 def StartPLC(self): |
456 |
|
457 def fail(msg): |
|
458 self.LogMessage(0, msg) |
|
459 self.PLCStatus = PlcStatus.Broken |
|
460 self.StatusChange() |
|
461 |
469 |
462 if self.PLClibraryHandle is None: |
470 if self.PLClibraryHandle is None: |
463 if not self.LoadPLC(): |
471 if not self.LoadPLC(): |
464 fail(_("Problem starting PLC : can't load PLC")) |
472 self._fail(_("Problem starting PLC : can't load PLC")) |
|
473 |
|
474 self.PreStartPLC() |
465 |
475 |
466 if self.CurrentPLCFilename is not None and self.PLCStatus == PlcStatus.Stopped: |
476 if self.CurrentPLCFilename is not None and self.PLCStatus == PlcStatus.Stopped: |
467 c_argv = ctypes.c_char_p * len(self.argv) |
477 c_argv = ctypes.c_char_p * len(self.argv) |
468 res = self._startPLC(len(self.argv), c_argv(*self.argv)) |
478 res = self._startPLC(len(self.argv), c_argv(*self.argv)) |
469 if res == 0: |
479 if res == 0: |
470 self.PLCStatus = PlcStatus.Started |
480 self.PLCStatus = PlcStatus.Started |
471 self.StatusChange() |
481 self.StatusChange() |
472 self.PythonThreadCommand("Activate") |
482 self.PythonThreadCommand("Activate") |
473 self.LogMessage("PLC started") |
483 self.LogMessage("PLC started") |
474 else: |
484 else: |
475 fail(_("Problem starting PLC : error %d" % res)) |
485 self._fail(_("Problem starting PLC : error %d" % res)) |
476 |
486 |
477 @RunInMain |
487 @RunInMain |
478 def StopPLC(self): |
488 def StopPLC(self): |
479 if self.PLCStatus == PlcStatus.Started: |
489 if self.PLCStatus == PlcStatus.Started: |
480 self.LogMessage("PLC stopped") |
490 self.LogMessage("PLC stopped") |
508 os.mkdir(self.tmpdir) |
518 os.mkdir(self.tmpdir) |
509 |
519 |
510 @RunInMain |
520 @RunInMain |
511 def SeedBlob(self, seed): |
521 def SeedBlob(self, seed): |
512 blob = (mkstemp(dir=self.tmpdir) + (hashlib.new('md5'),)) |
522 blob = (mkstemp(dir=self.tmpdir) + (hashlib.new('md5'),)) |
513 _fobj, _path, md5sum = blob |
523 _fd, _path, md5sum = blob |
514 md5sum.update(seed) |
524 md5sum.update(seed) |
515 newBlobID = md5sum.digest() |
525 newBlobID = md5sum.digest() |
516 self.blobs[newBlobID] = blob |
526 self.blobs[newBlobID] = blob |
517 return newBlobID |
527 return newBlobID |
518 |
528 |
521 blob = self.blobs.pop(blobID, None) |
531 blob = self.blobs.pop(blobID, None) |
522 |
532 |
523 if blob is None: |
533 if blob is None: |
524 return None |
534 return None |
525 |
535 |
526 fobj, _path, md5sum = blob |
536 fd, _path, md5sum = blob |
527 md5sum.update(data) |
537 md5sum.update(data) |
528 newBlobID = md5sum.digest() |
538 newBlobID = md5sum.digest() |
529 os.write(fobj, data) |
539 os.write(fd, data) |
530 self.blobs[newBlobID] = blob |
540 self.blobs[newBlobID] = blob |
531 return newBlobID |
541 return newBlobID |
532 |
542 |
533 @RunInMain |
543 @RunInMain |
534 def PurgeBlobs(self): |
544 def PurgeBlobs(self): |
535 for fobj, _path, _md5sum in self.blobs.values(): |
545 for fd, _path, _md5sum in self.blobs.values(): |
536 os.close(fobj) |
546 os.close(fd) |
537 self._init_blobs() |
547 self._init_blobs() |
538 |
548 |
539 def _BlobAsFile(self, blobID, newpath): |
549 def _BlobAsFile(self, blobID, newpath): |
540 blob = self.blobs.pop(blobID, None) |
550 blob = self.blobs.pop(blobID, None) |
541 |
551 |
542 if blob is None: |
552 if blob is None: |
543 raise Exception(_("Missing data to create file: {}").format(newpath)) |
553 raise Exception(_("Missing data to create file: {}").format(newpath)) |
544 |
554 |
545 fobj, path, _md5sum = blob |
555 fd, path, _md5sum = blob |
546 os.close(fobj) |
556 fobj = os.fdopen(fd) |
|
557 fobj.flush() |
|
558 os.fsync(fd) |
|
559 fobj.close() |
547 shutil.move(path, newpath) |
560 shutil.move(path, newpath) |
548 |
561 |
549 def _extra_files_log_path(self): |
562 def _extra_files_log_path(self): |
550 return os.path.join(self.workingdir, "extra_files.txt") |
563 return os.path.join(self.workingdir, "extra_files.txt") |
551 |
564 |
597 |
610 |
598 try: |
611 try: |
599 # Create new PLC file |
612 # Create new PLC file |
600 self._BlobAsFile(plc_object, new_PLC_filename) |
613 self._BlobAsFile(plc_object, new_PLC_filename) |
601 |
614 |
602 # Store new PLC filename based on md5 key |
|
603 open(self._GetMD5FileName(), "w").write(md5sum) |
|
604 |
|
605 # Then write the files |
615 # Then write the files |
606 log = open(extra_files_log, "w") |
616 log = open(extra_files_log, "w") |
607 for fname, blobID in extrafiles: |
617 for fname, blobID in extrafiles: |
608 fpath = os.path.join(self.workingdir, fname) |
618 fpath = os.path.join(self.workingdir, fname) |
609 self._BlobAsFile(blobID, fpath) |
619 self._BlobAsFile(blobID, fpath) |
610 log.write(fname+'\n') |
620 log.write(fname+'\n') |
|
621 |
|
622 # Store new PLC filename based on md5 key |
|
623 with open(self._GetMD5FileName(), "w") as f: |
|
624 f.write(md5sum) |
|
625 f.flush() |
|
626 os.fsync(f.fileno()) |
611 |
627 |
612 # Store new PLC filename |
628 # Store new PLC filename |
613 self.CurrentPLCFilename = NewFileName |
629 self.CurrentPLCFilename = NewFileName |
614 except Exception: |
630 except Exception: |
615 self.PLCStatus = PlcStatus.Broken |
631 self.PLCStatus = PlcStatus.Broken |