Skip to content

Commit

Permalink
fixed handling of int16 values in RecordedData Model, minor changes i…
Browse files Browse the repository at this point in the history
…n admin

0.7.0b14
- fixed handling of int16 values in RecordedData Model
- added custom admin interface
- added filter to variable state admin view
- added unit column to variable admin
  • Loading branch information
trombastic committed Jan 26, 2017
1 parent 972e33f commit 3fe9c6b
Show file tree
Hide file tree
Showing 16 changed files with 109 additions and 55 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,9 @@
0.7.0b13
- fixed modbus write task
- fixed Event handling

0.7.0b14
- fixed handling of int16 values in RecordedData Model
- added custom admin interface
- added filter to variable state admin view
- added unit column to variable admin
2 changes: 1 addition & 1 deletion pyscada/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#__import__('pkg_resources').declare_namespace('pyscada')

__version__ = '0.7.0b13'
__version__ = '0.7.0b14'
__author__ = 'Martin Schröder'

default_app_config = 'pyscada.apps.PyScadaConfig'
Expand Down
44 changes: 29 additions & 15 deletions pyscada/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,19 @@
from django.contrib.admin import SimpleListFilter
from django import forms
from django.conf import settings
from django.contrib.admin import AdminSite

import datetime


## Custom AdminSite

class PyScadaAdminSite(AdminSite):
site_header = 'PyScada administration'

## rest


# class VariableImportAdminForm(forms.ModelForm):
# json_configuration = forms.CharField(widget=forms.Textarea)
#
Expand Down Expand Up @@ -50,6 +60,7 @@ class Meta:

class VariableStateAdmin(admin.ModelAdmin):
list_display = ('name','last_value')
list_filter = ('device__short_name', 'active','unit__unit','value_class')
list_display_links = ()
list_per_page = 10
actions = None
Expand Down Expand Up @@ -124,15 +135,17 @@ def render_option_color(self,selected_choices, option_value, option_label):
w.widget.render_option = f # add new method

class VarieblesAdmin(admin.ModelAdmin):
list_display = ('id','name','description','device_name','value_class','active','writeable',)
list_display = ('id','name','description','unit','device_name','value_class','active','writeable',)
list_editable = ('active','writeable',)
list_display_links = ('name',)
list_filter = ('device__short_name', 'active','writeable')
list_filter = ('device__short_name', 'active','writeable','unit__unit','value_class')
search_fields = ['name',]
form = VarieblesAdminFrom
def device_name(self, instance):
return instance.device.short_name

def unit(self, instance):
return instance.unit.unit


class DeviceWriteTaskAdmin(admin.ModelAdmin):
list_display = ('id','name','value','user_name','start_time','done','failed',)
Expand Down Expand Up @@ -205,16 +218,17 @@ class EventAdmin(admin.ModelAdmin):
filter_horizontal = ('mail_recipients',)

raw_id_fields = ('variable',)

admin.site.register(Device,DeviceAdmin)
admin.site.register(Variable,VarieblesAdmin)
admin.site.register(Scaling)

admin_site = PyScadaAdminSite(name='pyscada_admin')
admin_site.register(Device,DeviceAdmin)
admin_site.register(Variable,VarieblesAdmin)
admin_site.register(Scaling)
# admin.site.register(VariableConfigFileImport,VariableImportAdmin)
admin.site.register(Unit)
admin.site.register(Event,EventAdmin)
admin.site.register(RecordedEvent,RecordedEventAdmin)
admin.site.register(Mail,MailAdmin)
admin.site.register(DeviceWriteTask,DeviceWriteTaskAdmin)
admin.site.register(Log,LogAdmin)
admin.site.register(BackgroundTask,BackgroundTaskAdmin)
admin.site.register(VariableState,VariableStateAdmin)
admin_site.register(Unit)
admin_site.register(Event,EventAdmin)
admin_site.register(RecordedEvent,RecordedEventAdmin)
admin_site.register(Mail,MailAdmin)
admin_site.register(DeviceWriteTask,DeviceWriteTaskAdmin)
admin_site.register(Log,LogAdmin)
admin_site.register(BackgroundTask,BackgroundTaskAdmin)
admin_site.register(VariableState,VariableStateAdmin)
6 changes: 4 additions & 2 deletions pyscada/export/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from pyscada.admin import admin_site

from pyscada.export.models import ScheduledExportTask, ExportTask
from django import forms
from django.contrib import admin
Expand All @@ -17,5 +19,5 @@ class ExportTaskAdmin(admin.ModelAdmin):
list_display = ('id','label','datetime_start','datetime_fineshed',\
'mean_value_period','file_format','done','busy','failed',)

admin.site.register(ScheduledExportTask,ScheduledExportTaskAdmin)
admin.site.register(ExportTask,ExportTaskAdmin)
admin_site.register(ScheduledExportTask,ScheduledExportTaskAdmin)
admin_site.register(ExportTask,ExportTaskAdmin)
26 changes: 14 additions & 12 deletions pyscada/hmi/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from pyscada.admin import admin_site

from pyscada.models import Variable
from pyscada.hmi.models import ControlItem
from pyscada.hmi.models import Chart
Expand Down Expand Up @@ -92,15 +94,15 @@ class ProcessFlowDiagramItemAdmin(admin.ModelAdmin):
class ProcessFlowDiagramAdmin(admin.ModelAdmin):
filter_horizontal = ('process_flow_diagram_items',)

admin.site.register(ControlItem,ControlItemAdmin)
admin.site.register(Chart,ChartAdmin)
admin.site.register(SlidingPanelMenu,SlidingPanelMenuAdmin)
admin.site.register(Page,PageAdmin)
admin.site.register(GroupDisplayPermission,GroupDisplayPermissionAdmin)

admin.site.register(ControlPanel,ControlPanelAdmin)
admin.site.register(CustomHTMLPanel,CustomHTMLPanelAdmin)
admin.site.register(Widget,WidgetAdmin)
admin.site.register(View,ViewAdmin)
admin.site.register(ProcessFlowDiagram,ProcessFlowDiagramAdmin)
admin.site.register(ProcessFlowDiagramItem,ProcessFlowDiagramItemAdmin)
admin_site.register(ControlItem,ControlItemAdmin)
admin_site.register(Chart,ChartAdmin)
admin_site.register(SlidingPanelMenu,SlidingPanelMenuAdmin)
admin_site.register(Page,PageAdmin)
admin_site.register(GroupDisplayPermission,GroupDisplayPermissionAdmin)

admin_site.register(ControlPanel,ControlPanelAdmin)
admin_site.register(CustomHTMLPanel,CustomHTMLPanelAdmin)
admin_site.register(Widget,WidgetAdmin)
admin_site.register(View,ViewAdmin)
admin_site.register(ProcessFlowDiagram,ProcessFlowDiagramAdmin)
admin_site.register(ProcessFlowDiagramItem,ProcessFlowDiagramItemAdmin)
Binary file removed pyscada/hmi/static/pyscada/img/admin_logo.gif
Binary file not shown.
Binary file added pyscada/hmi/static/pyscada/img/admin_logo.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion pyscada/hmi/templates/control_element.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
</div>
{% endif %}
{% elif item.type == 6 %}<!-- display value -->
<div class="input-group control_label"><span class="type-label">{ item.label }}<span class="type-unit"><span class="type-numeric var-{{ item.variable.name }}">NaN</span> {{ item.variable.unit.unit }}</span></span></div>
<div class="input-group control_label"><span class="type-label">{{ item.label }}<span class="type-unit"><span class="type-numeric var-{{ item.variable.name }}">NaN</span> {{ item.variable.unit.unit }}</span></span></div>
{% endif %}
{% endif %}
4 changes: 2 additions & 2 deletions pyscada/hmi/templates/view_overview.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ <h3 class="panel-title"><a href="{% url 'main-view' view.link_title %}" target="
<div class="col-sm-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><a href="{% url 'admin:index' %}" target="_blank">Admin</a></h3>
<h3 class="panel-title"><a href="{% url 'pyscada_admin:index' %}" target="_blank">Admin</a></h3>
</div>
<div class="panel-body">
<a href="{% url 'admin:index' %}" class="thumbnail" target="_blank"><img src="{% static "pyscada/img/admin_logo.gif" %}" alt="The Admin Panel" width="100%"></a>
<a href="{% url 'pyscada_admin:index' %}" class="thumbnail" target="_blank"><img src="{% static "pyscada/img/admin_logo.jpg" %}" alt="The Admin Panel" width="100%"></a>
</div>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions pyscada/hmi/urls.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# -*- coding: utf-8 -*-
from django.conf.urls import url, include
from . import views
from pyscada.admin import admin_site
from django.contrib.auth import views as auth_views

urlpatterns = [
# Public pages
url(r'^$', views.index ,name="view-overview"),
url(r'^pyscada_admin/', admin_site.urls),
url(r'^accounts/logout/$', views.logout_view),
url(r'^accounts/login/$', auth_views.login,{'template_name': 'login.html'},name='login_view'),
url(r'^accounts/password_change/$', auth_views.password_change,{'template_name': 'password_change.html'},name='password_change'),
Expand Down
6 changes: 4 additions & 2 deletions pyscada/modbus/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from pyscada.admin import admin_site

from pyscada.modbus.models import ModbusDevice
from pyscada.modbus.models import ModbusVariable

Expand All @@ -20,5 +22,5 @@ def name(self, instance):
def value_class(self, instance):
return instance.modbus_variable.value_class

admin.site.register(ModbusDevice,ModbusDeviceAdmin)
admin.site.register(ModbusVariable,ModbusVariableAdmin)
admin_site.register(ModbusDevice,ModbusDeviceAdmin)
admin_site.register(ModbusVariable,ModbusVariableAdmin)
44 changes: 31 additions & 13 deletions pyscada/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,12 @@ def update_value(self,value = None,timestamp=None):
return self.store_value

def decode_value(self,value):
#
if self.byte_order == 'default':
byte_order = self.device.byte_order
else:
byte_order = self.byte_order

if self.value_class.upper() in ['FLOAT32','SINGLE','REAL','UNIXTIMEF32']:
target_format = 'f'
source_format = '2H'
Expand All @@ -528,18 +534,20 @@ def decode_value(self,value):
elif self.value_class.upper() in ['INT64','UNIXTIMEI64']:
target_format = 'q'
source_format = '4H'

elif self.value_class.upper() in ['BCD32','BCD24','BCD16']:
elif self.value_class.upper() in ['INT16','INT']:
if byte_order in ['1-0-3-2','3-2-1-0']:
# only convert to from uint to int
return unpack('h',pack('H',value[0]))[0]
else:
# swap bytes
return unpack('>h',pack('<H',value[0]))[0]
elif self.value_class.upper() in ['BCD32','BCD24','BCD16']:
target_format = 'f'
source_format = '2H'
return value[0]
else:
return value[0]
#
if self.byte_order == 'default':
byte_order = self.device.byte_order
else:
byte_order = self.byte_order

#
if source_format == '2H':
if byte_order == '1-0-3-2':
Expand Down Expand Up @@ -666,17 +674,27 @@ def __init__(self, *args, **kwargs):
kwargs['id'] = int(int(int(timestamp*1000)*2097152)+variable_id)
if kwargs.has_key('variable') and kwargs.has_key('value'):
if kwargs['variable'].value_class.upper() in ['FLOAT','FLOAT64','DOUBLE','FLOAT32','SINGLE','REAL']:
kwargs['value_float64'] = kwargs.pop('value')
kwargs['value_float64'] = float(kwargs.pop('value'))
elif kwargs['variable'].scaling and not kwargs['variable'].value_class.upper() in ['BOOL','BOOLEAN']:
kwargs['value_float64'] = kwargs.pop('value')
kwargs['value_float64'] = float(kwargs.pop('value'))
elif kwargs['variable'].value_class.upper() in ['INT64','UINT32','DWORD']:
kwargs['value_int64'] = kwargs.pop('value')
kwargs['value_int64'] = int(kwargs.pop('value'))
if kwargs['value_int64'].bit_length() > 64:
#todo throw exeption or do anything
pass
elif kwargs['variable'].value_class.upper() in ['WORD','UINT','UINT16','INT32']:
kwargs['value_int32'] = kwargs.pop('value')
kwargs['value_int32'] = int(kwargs.pop('value'))
if kwargs['value_int32'].bit_length() > 32:
#todo throw exeption or do anything
pass
elif kwargs['variable'].value_class.upper() in ['INT16','INT8','UINT8','INT']:
kwargs['value_int16'] = kwargs.pop('value')
kwargs['value_int16'] = int(kwargs.pop('value'))
if kwargs['value_int16'].bit_length() > 15:
#todo throw exeption or do anything
pass

elif kwargs['variable'].value_class.upper() in ['BOOL','BOOLEAN']:
kwargs['value_boolean'] = kwargs.pop('value')
kwargs['value_boolean'] = bool(kwargs.pop('value'))

# call the django model __init__
super(RecordedData, self).__init__(*args, **kwargs)
Expand Down
4 changes: 3 additions & 1 deletion pyscada/phant/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
from pyscada.admin import admin_site

from pyscada.phant.models import PhantDevice

from django.contrib import admin


admin.site.register(PhantDevice)
admin_site.register(PhantDevice)
6 changes: 4 additions & 2 deletions pyscada/smbus/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from pyscada.admin import admin_site

from pyscada.smbus.models import SMbusDevice
from pyscada.smbus.models import SMbusVariable

Expand All @@ -20,5 +22,5 @@ def name(self, instance):
def value_class(self, instance):
return instance.smbus_variable.value_class

admin.site.register(SMbusDevice,SMbusDeviceAdmin)
admin.site.register(SMbusVariable,SMbusVariableAdmin)
admin_site.register(SMbusDevice,SMbusDeviceAdmin)
admin_site.register(SMbusVariable,SMbusVariableAdmin)
4 changes: 3 additions & 1 deletion pyscada/systemstat/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from pyscada.admin import admin_site

from pyscada.systemstat.models import SystemStatVariable

from django.contrib import admin
Expand All @@ -13,4 +15,4 @@ def name(self, instance):
def value_class(self, instance):
return instance.system_stat_variable.value_class

admin.site.register(SystemStatVariable,SystemStatVariableAdmin)
admin_site.register(SystemStatVariable,SystemStatVariableAdmin)
8 changes: 5 additions & 3 deletions pyscada/visa/admin.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from pyscada.admin import admin_site

from pyscada.visa.models import *

from django.contrib import admin


admin.site.register(VISAVariable)
admin.site.register(VISADevice)
admin.site.register(VISADeviceHandler)
admin_site.register(VISAVariable)
admin_site.register(VISADevice)
admin_site.register(VISADeviceHandler)

0 comments on commit 3fe9c6b

Please sign in to comment.