Johannes Müller 3 anni fa
parent
commit
f85a90f263

+ 8 - 0
.gitignore

@@ -2,5 +2,13 @@
 *.aux
 *.synctex.gz
 *.out
+
+*.csv
+
 ~$*
 __pycache__/
+
+
+*.Wrk
+*.Sem
+*.ACD.Recovery

+ 25 - 0
box-pc/application/database/csv.py

@@ -0,0 +1,25 @@
+import csv
+
+from structures.measurement import CurrentMeasurement
+
+class Database:
+  lastMeas = [None] * 16
+
+  def __init__(self) -> None:
+      self.file = open("current.csv", "a", newline='')
+      self.writer = csv.writer(self.file, delimiter=' ')
+
+  def write(self, values: list):
+    meas: CurrentMeasurement
+    for i, meas in enumerate(values):
+      prev : CurrentMeasurement = self.lastMeas[meas.channel]
+      if prev == None:
+        self.writer.writerow([meas.timestamp, meas.source, meas.channel, meas.current])
+        meas.saved = True
+      elif prev.current != meas.current:
+        if not prev.saved:
+          self.writer.writerow([prev.timestamp, prev.source, prev.channel, prev.current])
+        self.writer.writerow([meas.timestamp, meas.source, meas.channel, meas.current])
+        meas.saved = True
+
+      self.lastMeas[meas.channel] = meas

+ 7 - 2
box-pc/application/database/influxdb.py

@@ -10,5 +10,10 @@ class Database():
     self.write_api = self.client.write_api(write_options=SYNCHRONOUS)
     self.query_api = self.client.query_api()
 
-  def write(self, point):
-    self.write_api.write(bucket=self.bucket, record=point)
+  def write(self, values):
+    points = []
+    for meas in values:
+      p = Point("24v").time(meas.timestamp).tag("source", meas.source).tag("channel", meas.channel).field("current", meas.current)
+      points.append(p)
+      
+    self.write_api.write(bucket=self.bucket, record=points)

+ 15 - 0
box-pc/application/database/sqlite3.py

@@ -0,0 +1,15 @@
+import sqlite3
+
+from structures.measurement import CurrentMeasurement
+
+class Database():
+  def __init__(self):
+    self.con = sqlite3.connect('sqlite3.db')
+
+    with self.con.cursor() as cur:
+      cur.execute("CREATE TABLE current (timestamp text, source text, channel int, value real")
+      cur.commit()
+
+  def write(self, meas: CurrentMeasurement):
+    with self.con.cursor() as cur:
+      cur.execute("INSERT INTO current VALUES (")

+ 41 - 1
box-pc/application/inputs/allen_bradley_connect.py

@@ -1 +1,41 @@
-from pycomm3 import LogixDriver
+from pylogix import PLC
+from threading import Thread
+import time
+from datetime import datetime
+import struct
+
+from structures.measurement import CurrentMeasurement
+from inputs.common import Input
+
+localtz = datetime.now().astimezone().tzinfo
+
+class AllenBradleyCPU(Input):
+ 
+  def __init__(self):
+    super().__init__(self.read_handler)
+    self.comm = PLC()
+    self.comm.IPAddress = '192.168.10.5'
+    self.tag = "STL"
+    self.port = 0
+    self.E_offset = 12 + self.port * 48
+    self.E_connected_offset = self.E_offset + 32
+    self.E_error_offset = self.E_offset + 33
+
+    self.A_offset = 6 + self.port * 32
+
+    self.interval = 0.02
+
+  def read_handler(self):
+    timestamp = datetime.now(localtz)
+    ret = self.comm.Read(F"{self.tag}:I")
+    raw = ret.Value
+    data = struct.unpack(">" + "B" * 16 + "HHHHHBxH", raw[self.E_offset:self.E_offset+30])
+
+    for i in range(16):
+      self._q.put(CurrentMeasurement(timestamp, "AB", i, data[i]))
+
+if __name__ == "__main__":
+  with AllenBradleyCPU() as cpu:
+    cpu.start()
+    while True:
+      time.sleep(1)

+ 2 - 2
box-pc/application/inputs/balluff_html.py

@@ -3,7 +3,7 @@ import time
 import requests, json
 import re
 
-from structures.measurement import Measurement
+from structures.measurement import CurrentMeasurement
 
 class Balluff():
 
@@ -38,7 +38,7 @@ class Balluff():
     points = []
     for i in range(16):
       if status & (1 << i):
-        points.append(Measurement(timestamp, "balluff_html", i, data[i] / 10))
+        points.append(CurrentMeasurement(timestamp, "IO", i, data[i] / 10))
 
     return points
 

+ 40 - 0
box-pc/application/inputs/common.py

@@ -0,0 +1,40 @@
+from threading import Thread
+from queue import Queue
+import time
+
+class Input:
+  _t = None
+  _stop = False
+  _q = Queue()
+
+  interval = 1
+  _read_cb = None
+
+  def __init__(self, read_cb) -> None:
+      self._read_cb = read_cb
+
+  def start(self):
+    if not self._t:
+      self._stop = False
+      self._t = Thread(target = self._main)
+      self._t.setDaemon(True)
+      self._t.start()
+
+  def stop(self):
+    if self._t:
+      self._stop = True
+      self._t.join()
+      self._t = None
+
+  def read(self):
+    while not self._q.empty():
+      yield self._q.get()
+
+  def _main(self):
+    while not self._stop:
+      start_time = time.monotonic()
+      self._read_cb()
+      end_time = time.monotonic()
+      remaining = self.interval + start_time - end_time
+      if remaining > 0:
+        time.sleep(remaining)

+ 26 - 27
box-pc/application/inputs/snap7_connect.py

@@ -1,13 +1,14 @@
-import snap7
+from snap7.client import Client
 import time
 from datetime import datetime
 import struct
 
-from structures.measurement import Measurement
+from structures.measurement import CurrentMeasurement
+from inputs.common import Input
 
 localtz = datetime.now().astimezone().tzinfo
 
-class SiemensCPU(snap7.client.Client):
+class SiemensCPU(Input):
 
   cpu_start_time = None
   cpu_last_time = None
@@ -17,10 +18,28 @@ class SiemensCPU(snap7.client.Client):
 
   cpu_db_value_count = 50
 
-  def get_ints(self, start, count):
-    raw = self.db_read(self.db, start*4, count*4)
-    data = struct.unpack(">" + "i" * count, raw)
-    return data
+  def __init__(self) -> None:
+    super().__init__(self.read_handler)
+    self.cpu = Client()
+
+  def start(self):
+    self.cpu.connect("10.0.10.1", 0, 0)
+    super().start()
+
+  def read_handler(self):
+    raw = self.cpu.db_read(self.db, 0, (self.cpu_db_value_count + 1)*4)
+    data = struct.unpack(">" + "i" * (self.cpu_db_value_count + 1), raw)
+
+    cpu_time = data[0] / 1000
+    if not self.cpu_last_time:
+      self.cpu_last_time = cpu_time - self.interval
+    if cpu_time == self.cpu_last_time:
+      return
+    inc_time = (cpu_time - self.cpu_last_time) / self.cpu_db_value_count
+    for i, val in enumerate(data[1:]):
+      timestamp = self.get_timestamp(self.cpu_last_time + inc_time * (i+1))
+      self._q.put(CurrentMeasurement(timestamp, "S7", 0, val / 10))
+    self.cpu_last_time = cpu_time
 
   def get_timestamp(self, cpu_time):
     if not self.cpu_start_time:
@@ -46,24 +65,4 @@ class SiemensCPU(snap7.client.Client):
       self.interval = sum(intervals) / len(intervals)
     return self.interval
 
-  def read(self):
-    data = self.get_ints(0, self.cpu_db_value_count + 1)
-    cpu_time = data[0] / 1000
-    if not self.cpu_last_time:
-      self.cpu_last_time = cpu_time - self.interval
-    if cpu_time == self.cpu_last_time:
-      return []
-    inc_time = (cpu_time - self.cpu_last_time) / self.cpu_db_value_count
-    points = []
-    for i, val in enumerate(data[1:]):
-      timestamp = self.get_timestamp(self.cpu_last_time + inc_time * (i+1))
-      points.append(Measurement(timestamp, "siemens_cpu", 0, val / 10))
-    self.cpu_last_time = cpu_time
-    return points
-
-  def read_continous(self):
-    while True:
-      points = self.read()
-      for point in points:
-        yield point
       

+ 9 - 11
box-pc/application/main.py

@@ -1,6 +1,7 @@
 from inputs.snap7_connect import SiemensCPU
 from inputs.balluff_html import Balluff
-from database.influxdb import Point, Database
+from inputs.allen_bradley_connect import AllenBradleyCPU
+from database.csv import Database
 from datetime import datetime
 import time
 
@@ -8,18 +9,15 @@ db = Database()
 
 cpu = SiemensCPU()
 
-cpu.connect("10.0.10.1", 0, 0)
-cpu.get_connected()
-
 #print(cpu.synchronize())
 
 balluff = Balluff()
 
+ab = AllenBradleyCPU()
+ab.start()
+
 while True:
-  values = balluff.read()
-  points = []
-  for meas in values:
-    print(meas)
-    p = Point("24v").time(meas.timestamp).tag("source", meas.source).tag("channel", meas.channel).field("current", meas.current)
-    points.append(p)
-  db.write(points)
+  values = list(ab.read())
+  print(len(values))
+  db.write(values)
+  time.sleep(1)

+ 2 - 1
box-pc/application/structures/measurement.py

@@ -3,8 +3,9 @@ from datetime import datetime
 import string
 
 @dataclass
-class Measurement:
+class CurrentMeasurement:
   timestamp: datetime
   source: string
   channel: int
   current: float
+  saved: bool = False

File diff suppressed because it is too large
+ 518 - 0
projekt-rsLogix/Balluff_IP_Test.ACD


Some files were not shown because too many files changed in this diff