Skip to content

Commit

Permalink
0.7.0rc15
Browse files Browse the repository at this point in the history
- fixed zombi process problem
- fixed migrations with python3
- changed datetime_now to now from django timezone
  • Loading branch information
trombastic committed Apr 29, 2019
1 parent 6f38e7d commit 0a5c215
Show file tree
Hide file tree
Showing 54 changed files with 345 additions and 169 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,9 @@
- fixed WidgetContent not being deleted
- moved signal related methods to dedicated signals.py
- added pyserial to dependency list
- improved hmi <--> db communication to avoid data loss on slow connections
- improved hmi <--> db communication to avoid data loss on slow connections

0.7.0rc15
- fixed zombi process problem
- fixed migrations with python3
- changed datetime_now to now from django timezone
11 changes: 11 additions & 0 deletions docker/mysql/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

## Pull the mysql:5.6 image
FROM mysql:latest

## The maintainer name and email
LABEL maintainer="PyScada | Martin Schröder <info@martin-schroeder.net"

# Install requirement (wget)
#RUN apt-get update && apt-get install -y wget

RUN mysql -e "CREATE DATABASE PyScada_db CHARACTER SET utf8;GRANT ALL PRIVILEGES ON PyScada_db.* TO 'PyScada-user'@'localhost' IDENTIFIED BY 'PyScada-user-password';"
2 changes: 1 addition & 1 deletion docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Dependencies
------------


Debian 8/9, Raspbian
Debian 9, Raspbian
^^^^^^^^^^^^^^^^^^^^

::
Expand Down
39 changes: 38 additions & 1 deletion pyscada/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from django.utils.translation import ugettext_lazy as _

import datetime
import signal
import logging

logger = logging.getLogger(__name__)
Expand All @@ -31,7 +32,42 @@ class PyScadaAdminSite(AdminSite):
site_header = 'PyScada Administration'


# Custom Filters
## admin actions
def restart_process(modeladmin, request, queryset):
"""
restarts a dedicated process
:return:
"""
for process in queryset:
process.restart()


restart_process.short_description = "Restart Processes"

def stop_process(modeladmin, request, queryset):
"""
restarts a dedicated process
:return:
"""
for process in queryset:
process.stop()


stop_process.short_description = "Terminate Processes"


def kill_process(modeladmin, request, queryset):
"""
restarts a dedicated process
:return:
"""
for process in queryset:
process.stop(signum=signal.SIGKILL)


kill_process.short_description = "Kill Processes"

## Custom Filters
class BackgroundProcessFilter(admin.SimpleListFilter):
# Human-readable title which will be displayed in the
# right admin sidebar just above the filter options.
Expand Down Expand Up @@ -185,6 +221,7 @@ class BackgroundProcessAdmin(admin.ModelAdmin):
list_filter = (BackgroundProcessFilter, 'enabled', 'done', 'failed')
list_display_links = ('id', 'label', 'message')
readonly_fields = ('message', 'last_update', 'running_since', 'done', 'failed')
actions = [restart_process, stop_process, kill_process]


class RecordedEventAdmin(admin.ModelAdmin):
Expand Down
18 changes: 10 additions & 8 deletions pyscada/export/export.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# PyScada
from __future__ import unicode_literals

from pyscada.utils import validate_value_class, datetime_now
from pyscada.utils import validate_value_class

from pyscada.models import Variable, RecordedData, BackgroundProcess
from pyscada.export.hdf5_file import MatCompatibleH5
from pyscada.export.hdf5_file import unix_time_stamp_to_matlab_datenum
Expand All @@ -12,6 +13,7 @@

# Django
from django.conf import settings
from django.utils.timezone import now

# other
from datetime import datetime
Expand All @@ -34,7 +36,7 @@ def export_recordeddata_to_file(time_min=None, time_max=None, filename=None, act
if backgroundprocess_id is not None:
tp = BackgroundProcess.objects.get(id=backgroundprocess_id)
tp.message = 'init'
tp.last_update = datetime_now()
tp.last_update = now()
tp.save()
else:
tp = None
Expand All @@ -60,7 +62,7 @@ def export_recordeddata_to_file(time_min=None, time_max=None, filename=None, act
# validate file type
if file_extension not in ['.h5', '.mat', '.csv']:
if tp is not None:
tp.last_update = datetime_now()
tp.last_update = now()
tp.message = 'failed wrong file type'
tp.failed = 1
tp.save()
Expand Down Expand Up @@ -89,7 +91,7 @@ def export_recordeddata_to_file(time_min=None, time_max=None, filename=None, act
db_time_min = RecordedData.objects.first() # todo add RecordedDataOld
if not db_time_min:
if tp is not None:
tp.last_update = datetime_now()
tp.last_update = now()
tp.message = 'no data to export'
tp.failed = 1
tp.save()
Expand All @@ -99,7 +101,7 @@ def export_recordeddata_to_file(time_min=None, time_max=None, filename=None, act
db_time_max = RecordedData.objects.last() # todo add RecordedDataOld
if not db_time_max:
if tp is not None:
tp.last_update = datetime_now()
tp.last_update = now()
tp.message = 'no data to export'
tp.failed = 1
tp.save()
Expand Down Expand Up @@ -195,7 +197,7 @@ def export_recordeddata_to_file(time_min=None, time_max=None, filename=None, act

for var_idx in range(0, active_vars.count(), 10):
if tp is not None:
tp.last_update = datetime_now()
tp.last_update = now()
tp.message = 'reading values from database (%d)' % var_idx
tp.save()
# query data
Expand All @@ -209,7 +211,7 @@ def export_recordeddata_to_file(time_min=None, time_max=None, filename=None, act
for var in var_slice:
# write background task info
if tp is not None:
tp.last_update = datetime_now()
tp.last_update = now()
tp.message = 'writing values for %s (%d) to file' % (var.name, var.pk)
tp.save()
# check if variable is scalled
Expand Down Expand Up @@ -299,7 +301,7 @@ def export_recordeddata_to_file(time_min=None, time_max=None, filename=None, act

bf.close_file()
if tp is not None:
tp.last_update = datetime_now()
tp.last_update = now()
tp.message = 'done'
tp.done = True
tp.save()
Expand Down
12 changes: 6 additions & 6 deletions pyscada/export/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ class Migration(migrations.Migration):
name='ExportJob',
fields=[
('id', models.AutoField(serialize=False, primary_key=True)),
('label', models.CharField(default=b'', max_length=400)),
('day_time', models.PositiveSmallIntegerField(default=0, help_text=b'day time wenn the job will start be started', choices=[(0, b'0:00'), (1, b'1:00'), (2, b'2:00'), (3, b'3:00'), (4, b'4:00'), (5, b'5:00'), (6, b'6:00'), (7, b'7:00'), (8, b'8:00'), (9, b'9:00'), (10, b'10:00'), (11, b'11:00'), (12, b'12:00'), (13, b'13:00'), (14, b'14:00'), (15, b'15:00'), (16, b'16:00'), (17, b'17:00'), (18, b'18:00'), (19, b'19:00'), (20, b'20:00'), (21, b'21:00'), (22, b'22:00'), (23, b'23:00')])),
('mean_value_period', models.PositiveSmallIntegerField(default=0, help_text=b'in Seconds (0 = no mean value)')),
('active', models.BooleanField(default=False, help_text=b'to activate scheduled export')),
('file_format', models.CharField(default=b'', max_length=400)),
('export_period', models.PositiveSmallIntegerField(default=0, help_text=b'', choices=[(1, b'1 Day'), (2, b'2 Days (on every even Day of the year)'), (7, b'7 Days (on Mondays)'), (14, b'14 Days'), (30, b'30 Days')])),
('label', models.CharField(default='', max_length=400)),
('day_time', models.PositiveSmallIntegerField(default=0, help_text='day time wenn the job will start be started', choices=[(0, '0:00'), (1, '1:00'), (2, '2:00'), (3, '3:00'), (4, '4:00'), (5, '5:00'), (6, '6:00'), (7, '7:00'), (8, '8:00'), (9, '9:00'), (10, '10:00'), (11, '11:00'), (12, '12:00'), (13, '13:00'), (14, '14:00'), (15, '15:00'), (16, '16:00'), (17, '17:00'), (18, '18:00'), (19, '19:00'), (20, '20:00'), (21, '21:00'), (22, '22:00'), (23, '23:00')])),
('mean_value_period', models.PositiveSmallIntegerField(default=0, help_text='in Seconds (0 = no mean value)')),
('active', models.BooleanField(default=False, help_text='to activate scheduled export')),
('file_format', models.CharField(default='', max_length=400)),
('export_period', models.PositiveSmallIntegerField(default=0, help_text=b'', choices=[(1, '1 Day'), (2, '2 Days (on every even Day of the year)'), (7, '7 Days (on Mondays)'), (14, '14 Days'), (30, '30 Days')])),
('variables', models.ManyToManyField(to='pyscada.Variable')),
],
),
Expand Down
2 changes: 1 addition & 1 deletion pyscada/export/migrations/0002_auto_20151201_1617.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='exportjob',
name='file_format',
field=models.CharField(default=b'hdf5', max_length=400, choices=[(b'hdf5', b'Hierarchical Data Format Version 5'), (b'mat', b'Matlab\xc2\xae mat v7.3 compatible file'), (b'CSV_EXCEL', b'Microsoft\xc2\xae Excel\xc2\xae compatible csv file')]),
field=models.CharField(default='hdf5', max_length=400, choices=[('hdf5', 'Hierarchical Data Format Version 5'), ('mat', 'Matlab\xc2\xae mat v7.3 compatible file'), ('CSV_EXCEL', 'Microsoft\xc2\xae Excel\xc2\xae compatible csv file')]),
preserve_default=True,
),
]
6 changes: 3 additions & 3 deletions pyscada/export/migrations/0004_exporttask.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class Migration(migrations.Migration):
name='ExportTask',
fields=[
('id', models.AutoField(serialize=False, primary_key=True)),
('label', models.CharField(default=b'', max_length=400)),
('mean_value_period', models.PositiveSmallIntegerField(default=0, help_text=b'in Seconds (0 = no mean value)')),
('file_format', models.CharField(default=b'hdf5', max_length=400, choices=[(b'hdf5', b'Hierarchical Data Format Version 5'), (b'mat', b'Matlab\xc2\xae mat v7.3 compatible file'), (b'CSV_EXCEL', b'Microsoft\xc2\xae Excel\xc2\xae compatible csv file')])),
('label', models.CharField(default='', max_length=400)),
('mean_value_period', models.PositiveSmallIntegerField(default=0, help_text='in Seconds (0 = no mean value)')),
('file_format', models.CharField(default='hdf5', max_length=400, choices=[('hdf5', 'Hierarchical Data Format Version 5'), ('mat', 'Matlab\xc2\xae mat v7.3 compatible file'), ('CSV_EXCEL', 'Microsoft\xc2\xae Excel\xc2\xae compatible csv file')])),
('time_min', models.FloatField(default=None, null=True, blank=True)),
('time_max', models.FloatField(default=None, null=True, blank=True)),
('start', models.FloatField(default=0)),
Expand Down
4 changes: 2 additions & 2 deletions pyscada/export/migrations/0005_auto_20160403_1454.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='exporttask',
name='filename_suffix',
field=models.CharField(default=b'', max_length=400, blank=True),
field=models.CharField(default='', max_length=400, blank=True),
),
migrations.AlterField(
model_name='exporttask',
name='label',
field=models.CharField(default=b'', max_length=400, blank=True),
field=models.CharField(default='', max_length=400, blank=True),
),
migrations.AlterField(
model_name='exporttask',
Expand Down
2 changes: 1 addition & 1 deletion pyscada/export/migrations/0006_auto_20160404_0949.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='exporttask',
name='label',
field=models.CharField(default=b'None', max_length=400, blank=True),
field=models.CharField(default='None', max_length=400, blank=True),
),
migrations.AlterField(
model_name='exporttask',
Expand Down
2 changes: 1 addition & 1 deletion pyscada/export/migrations/0009_auto_20161128_0948.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='scheduledexporttask',
name='day_time',
field=models.PositiveSmallIntegerField(choices=[(0, b'0:00'), (1, b'1:00'), (2, b'2:00'), (3, b'3:00'), (4, b'4:00'), (5, b'5:00'), (6, b'6:00'), (7, b'7:00'), (8, b'8:00'), (9, b'9:00'), (10, b'10:00'), (11, b'11:00'), (12, b'12:00'), (13, b'13:00'), (14, b'14:00'), (15, b'15:00'), (16, b'16:00'), (17, b'17:00'), (18, b'18:00'), (19, b'19:00'), (20, b'20:00'), (21, b'21:00'), (22, b'22:00'), (23, b'23:00')], default=0, help_text=b'day time wenn the job will be started in UTC'),
field=models.PositiveSmallIntegerField(choices=[(0, '0:00'), (1, '1:00'), (2, '2:00'), (3, '3:00'), (4, '4:00'), (5, '5:00'), (6, '6:00'), (7, '7:00'), (8, '8:00'), (9, '9:00'), (10, '10:00'), (11, '11:00'), (12, '12:00'), (13, '13:00'), (14, '14:00'), (15, '15:00'), (16, '16:00'), (17, '17:00'), (18, '18:00'), (19, '19:00'), (20, '20:00'), (21, '21:00'), (22, '22:00'), (23, '23:00')], default=0, help_text='day time wenn the job will be started in UTC'),
),
]
3 changes: 2 additions & 1 deletion pyscada/export/migrations/0010_auto_20161128_1049.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from django.db import migrations, models
import pyscada.export.models
from django.utils.timezone import now


class Migration(migrations.Migration):
Expand All @@ -16,6 +17,6 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='exporttask',
name='datetime_start',
field=models.DateTimeField(default=pyscada.export.models.datetime_now),
field=models.DateTimeField(default=now),
),
]
7 changes: 2 additions & 5 deletions pyscada/export/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@
#
# Model
#


def datetime_now():
return datetime.now(UTC)
from django.utils.timezone import now


@python_2_unicode_compatible
Expand Down Expand Up @@ -64,7 +61,7 @@ class ExportTask(models.Model):
datetime_min = models.DateTimeField(default=None, null=True)
datetime_max = models.DateTimeField(default=None, null=True)
user = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL)
datetime_start = models.DateTimeField(default=datetime_now)
datetime_start = models.DateTimeField(default=now)
datetime_finished = models.DateTimeField(null=True, blank=True)
done = models.BooleanField(default=False, blank=True) # label task has been done
busy = models.BooleanField(default=False, blank=True) # label task is in operation done
Expand Down
6 changes: 3 additions & 3 deletions pyscada/export/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pyscada.export.models import ScheduledExportTask, ExportTask
from pyscada.utils.scheduler import Process as BaseProcess
from pyscada.models import BackgroundProcess
from pyscada.utils import datetime_now
from django.utils.timezone import now

from time import time, gmtime, mktime
from datetime import date, datetime, timedelta
Expand Down Expand Up @@ -79,7 +79,7 @@ def loop(self):

if bp:
bp.done = True
bp.last_update = datetime_now()
bp.last_update = now()
bp.message = 'stopped'
bp.save()

Expand Down Expand Up @@ -176,7 +176,7 @@ def loop(self):
job.save()
continue

if datetime_now() - timedelta(hours=1) > job.backgroundprocess.last_update:
if now() - timedelta(hours=1) > job.backgroundprocess.last_update:
# if the Background Process has been updated in the past 60s wait
continue

Expand Down
Loading

0 comments on commit 0a5c215

Please sign in to comment.