Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
trombastic committed Dec 9, 2019
0 parents commit e3828b4
Show file tree
Hide file tree
Showing 18 changed files with 1,145 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.pyc
/pyscada_gpio.egg-info/*
/.idea/*
/dist/*
/build/*
11 changes: 11 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Current or previous core committers:

* Martin Schröder

Current and previous core designers:

* Martin Schröder

Contributors (in alphabetical order):

* Gregor Kendzierski
1 change: 1 addition & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include AUTHORS
include LICENSE
include README.rst
include CHANGELOG.txt
recursive-include pyscada/pt104 *
36 changes: 36 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
PyScada PT104 Extension
=======================

This is a extension for PyScada to support read measurements from Pico PT104 Devices.


What is Working
---------------

- nothing is test


What is not Working/Missing
---------------------------

- Test with real hardware
- Documentation

Installation
------------

- pip install pyscada-gpio


Contribute
----------

- Issue Tracker: https://github.com/trombastic/PyScada-PT104/issues
- Source Code: https://github.com/trombastic/PyScada-PT104


License
-------

The project is licensed under the _GNU General Public License v3 (GPLv3)_.
-
1 change: 1 addition & 0 deletions pyscada/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__import__('pkg_resources').declare_namespace(__name__)
17 changes: 17 additions & 0 deletions pyscada/pt104/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from pyscada import core

__version__ = core.__version__
__author__ = core.__author__

default_app_config = 'pyscada.pt104.apps.PyScadaPT104Config'

PROTOCOL_ID = 11

parent_process_list = [{'pk':PROTOCOL_ID,
'label': 'pyscada.pt104',
'process_class': 'pyscada.pt104.worker.Process',
'process_class_kwargs': '{"dt_set":30}',
'enabled': True}]
65 changes: 65 additions & 0 deletions pyscada/pt104/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from pyscada.admin import admin_site
from pyscada.models import Device, DeviceProtocol

from pyscada.pt104 import PROTOCOL_ID
from pyscada.pt104.models import PT104Variable, PT104Device, ExtendedPT104Device, ExtendedPT104Variable
from pyscada.admin import DeviceAdmin
from pyscada.admin import VariableAdmin
from django.contrib import admin
import logging

logger = logging.getLogger(__name__)



class PT104DeviceAdminInline(admin.StackedInline):
model = PT104Device


class PT104DeviceAdmin(DeviceAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'protocol':
kwargs['queryset'] = DeviceProtocol.objects.filter(pk=PROTOCOL_ID)
db_field.default = PROTOCOL_ID
return super(PT104DeviceAdmin,self).formfield_for_foreignkey(db_field, request, **kwargs)

def get_queryset(self, request):
"""Limit Pages to those that belong to the request's user."""
qs = super(PT104DeviceAdmin, self).get_queryset(request)
return qs.filter(protocol_id=PROTOCOL_ID)

inlines = [
PT104DeviceAdminInline
]


class PT104VariableAdminInline(admin.StackedInline):
model = PT104Variable


class PT104VariableAdmin(VariableAdmin):
def name(self, instance):
return instance.pt104_variable.name

def value_class(self, instance):
return instance.pt104_variable.value_class

def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'device':
kwargs['queryset'] = Device.objects.filter(protocol=PROTOCOL_ID)
return super(PT104VariableAdmin,self).formfield_for_foreignkey(db_field, request, **kwargs)

def get_queryset(self, request):
"""Limit Pages to those that belong to the request's user."""
qs = super(PT104VariableAdmin, self).get_queryset(request)
return qs.filter(device__protocol_id=PROTOCOL_ID)

inlines = [
PT104VariableAdminInline
]

admin_site.register(ExtendedPT104Variable, PT104VariableAdmin)
admin_site.register(ExtendedPT104Device,PT104DeviceAdmin)
13 changes: 13 additions & 0 deletions pyscada/pt104/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _


class PyScadaPT104Config(AppConfig):
name = 'pyscada.pt104'
verbose_name = _("PyScada PT104")

def ready(self):
import pyscada.pt104.signals
54 changes: 54 additions & 0 deletions pyscada/pt104/device.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from time import time
driver_ok = True
try:
from PT104 import PT104, Channels, DataTypes, Wires
driver_ok = True
except ImportError:
driver_ok = False

import logging

logger = logging.getLogger(__name__)


class Device:
def __init__(self, device):
self.variables = []
self.device = device
if not driver_ok:
logger.debug('not driver_ok')
return
self.unit = PT104()
self.unit.connect(device.pt104device.serial_nb)
if not self.unit.is_connected:
logger.debug('not connected')
return
for item in device.variable_set.filter(active=1):
if not hasattr(item, 'pt104variable'):
continue
self.variables.append(item)
self.unit.set_channel(int(item.pt104variable.channel), int(item.pt104variable.data_type), int(item.pt104variable.wires))

def request_data(self):
"""
"""
if not driver_ok:
return []

output = []
for item in self.variables:
value = None
timeout = time() + 2 # 2 seconds timeout
while value is None:
value = self.unit.get_value(int(item.pt104variable.channel))
timestamp = time()
if time() > timeout:
break
# update variable
if value is not None and item.update_value(value, timestamp):
output.append(item.create_recorded_data_element())
return output
68 changes: 68 additions & 0 deletions pyscada/pt104/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.25 on 2019-11-05 09:28
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
('pyscada', '0056_auto_20190625_1823'),
]

operations = [
migrations.CreateModel(
name='PT104Device',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('serial_nb', models.CharField(default='', max_length=15)),
],
),
migrations.CreateModel(
name='PT104Variable',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('channel', models.CharField(choices=[('1', 'CH1'), ('2', 'CH2'), ('3', 'CH3'), ('4', 'CH4'), ('5', 'CH5'), ('6', 'CH6'), ('7', 'CH7'), ('8', 'CH8')], default='', max_length=10)),
('wires', models.CharField(choices=[('2', '2 Wires'), ('3', '3 Wires'), ('4', '4 Wires')], default='', max_length=10)),
('data_type', models.CharField(choices=[('0', 'OFF'), ('1', 'PT100'), ('2', 'PT1000'), ('3', 'RESISTANCE_TO_375R'), ('4', 'RESISTANCE_TO_10K'), ('5', 'DIFFERENTIAL_TO_115MV'), ('6', 'DIFFERENTIAL_TO_2500MV'), ('7', 'SINGLE_ENDED_TO_115MV'), ('8', 'SINGLE_ENDED_TO_2500MV')], default='', max_length=10)),
],
),
migrations.CreateModel(
name='ExtendedPT104Device',
fields=[
],
options={
'verbose_name': 'PT104 Device',
'verbose_name_plural': 'PT104 Devices',
'proxy': True,
'indexes': [],
},
bases=('pyscada.device',),
),
migrations.CreateModel(
name='ExtendedPT104Variable',
fields=[
],
options={
'verbose_name': 'PT104 Variable',
'verbose_name_plural': 'PT104 Variable',
'proxy': True,
'indexes': [],
},
bases=('pyscada.variable',),
),
migrations.AddField(
model_name='pt104variable',
name='pt104_variable',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='pyscada.Variable'),
),
migrations.AddField(
model_name='pt104device',
name='pt104_device',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='pyscada.Device'),
),
]
42 changes: 42 additions & 0 deletions pyscada/pt104/migrations/0002_add_device_protocol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2017-02-24 12:49
from __future__ import unicode_literals

from pyscada.pt104 import PROTOCOL_ID
from django.db import migrations


def forwards_func(apps, schema_editor):
# We get the model from the versioned app registry;
# if we directly import it, it'll be the wrong version
DeviceProtocol = apps.get_model("pyscada", "DeviceProtocol")
db_alias = schema_editor.connection.alias
DeviceProtocol.objects.using(db_alias).filter(protocol='pt104').delete()
DeviceProtocol.objects.using(db_alias).bulk_create([
DeviceProtocol(pk=PROTOCOL_ID,
protocol='pt104',
description='Pico PT104 Device',
app_name='pyscada.pt104',
device_class='pyscada.pt104.device',
daq_daemon=True,
single_thread=True),
])


def reverse_func(apps, schema_editor):
# forwards_func() creates two Country instances,
# so reverse_func() should delete them.
DeviceProtocol = apps.get_model("pyscada", "DeviceProtocol")
db_alias = schema_editor.connection.alias
DeviceProtocol.objects.using(db_alias).filter(protocol="pt104").delete()


class Migration(migrations.Migration):
dependencies = [
('pt104', '0001_initial'),
('pyscada', '0041_update_protocol_id'),
]

operations = [
migrations.RunPython(forwards_func, reverse_func),
]
Empty file.
62 changes: 62 additions & 0 deletions pyscada/pt104/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from pyscada.models import Variable, Device

from django.db import models
from django.utils.encoding import python_2_unicode_compatible
import logging

logger = logging.getLogger(__name__)


@python_2_unicode_compatible
class PT104Variable(models.Model):
pt104_variable = models.OneToOneField(Variable)
channel_choices = (('1', 'CH1'),
('2', 'CH2'),
('3', 'CH3'),
('4', 'CH4'),
('5', 'CH5'),
('6', 'CH6'),
('7', 'CH7'),
('8', 'CH8'),)
channel = models.CharField(default='', max_length=10, choices=channel_choices)
wires_choices = (('2', '2 Wires'),('3', '3 Wires'),('4', '4 Wires'),)
wires = models.CharField(default='', max_length=10, choices=wires_choices)
data_type_choices = (('0', 'OFF'),
('1', 'PT100'),
('2','PT1000'),
('3', 'RESISTANCE_TO_375R'),
('4', 'RESISTANCE_TO_10K'),
('5', 'DIFFERENTIAL_TO_115MV'),
('6', 'DIFFERENTIAL_TO_2500MV'),
('7', 'SINGLE_ENDED_TO_115MV'),
('8', 'SINGLE_ENDED_TO_2500MV'),)
data_type = models.CharField(default='', max_length=10, choices=data_type_choices)

def __str__(self):
return self.pt104_variable.name


@python_2_unicode_compatible
class PT104Device(models.Model):
pt104_device = models.OneToOneField(Device)
serial_nb = models.CharField(default='', max_length=15)
def __str__(self):
return self.pt104_device.short_name


class ExtendedPT104Device(Device):
class Meta:
proxy = True
verbose_name = 'PT104 Device'
verbose_name_plural = 'PT104 Devices'


class ExtendedPT104Variable(Variable):
class Meta:
proxy = True
verbose_name = 'PT104 Variable'
verbose_name_plural = 'PT104 Variable'

Loading

0 comments on commit e3828b4

Please sign in to comment.