pymscada 0.1.11b7__tar.gz → 0.1.11b9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymscada might be problematic. Click here for more details.
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/PKG-INFO +2 -2
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/pyproject.toml +2 -2
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/bus_server.py +5 -1
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/accuweather.yaml +1 -1
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/openweather.yaml +1 -1
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/tags.yaml +57 -1
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/wwwserver.yaml +46 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/openweather.py +4 -2
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/www_server.py +0 -2
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/LICENSE +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/README.md +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/__init__.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/__main__.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/bus_client.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/checkout.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/config.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/console.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/README.md +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/__init__.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/bus.yaml +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/files.yaml +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/history.yaml +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/logixclient.yaml +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/modbus_plc.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/modbusclient.yaml +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/modbusserver.yaml +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/opnotes.yaml +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/ping.yaml +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-bus.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-demo-modbus_plc.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-files.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-history.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-io-accuweather.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-io-logixclient.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-io-modbusclient.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-io-modbusserver.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-io-ping.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-io-snmpclient.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-opnotes.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/pymscada-wwwserver.service +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/demo/snmpclient.yaml +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/files.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/history.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/__init__.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/accuweather.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/logix_client.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/logix_map.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/modbus_client.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/modbus_map.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/modbus_server.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/ping_client.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/ping_map.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/snmp_client.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/iodrivers/snmp_map.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/main.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/misc.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/module_config.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/opnotes.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/pdf/__init__.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/pdf/one.pdf +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/pdf/two.pdf +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/periodic.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/protocol_constants.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/samplers.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/tag.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/tools/snmp_client2.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/tools/walk.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/src/pymscada/validate.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/__init__.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/bus_echo.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/iodrivers/test_logix.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/iodrivers/test_modbus.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_assets/busserver.yaml +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_assets/db.sqlite +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_assets/hist_tag_0_0.dat +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_assets/hist_tag_0_10_2.dat +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_assets/hist_tag_0_15.dat +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_assets/hist_tag_0_26.dat +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_assets/hist_tag_0_50.dat +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_bus_server.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_config.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_history.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_misc.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_openweather.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_opnotes.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_periodic.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_samplers.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_tag.py +0 -0
- {pymscada-0.1.11b7 → pymscada-0.1.11b9}/tests/test_validate.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pymscada
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.11b9
|
|
4
4
|
Summary: Shared tag value SCADA with python backup and Angular UI
|
|
5
5
|
Author-Email: Jamie Walton <jamie@walton.net.nz>
|
|
6
6
|
License: GPL-3.0-or-later
|
|
@@ -15,7 +15,7 @@ Project-URL: Bug Tracker, https://github.com/jamie0walton/pymscada/issues
|
|
|
15
15
|
Requires-Python: >=3.9
|
|
16
16
|
Requires-Dist: PyYAML>=6.0.1
|
|
17
17
|
Requires-Dist: aiohttp>=3.8.5
|
|
18
|
-
Requires-Dist: pymscada-html>=0.1.
|
|
18
|
+
Requires-Dist: pymscada-html>=0.1.10b5
|
|
19
19
|
Requires-Dist: cerberus>=1.3.5
|
|
20
20
|
Requires-Dist: pycomm3>=1.2.14
|
|
21
21
|
Requires-Dist: pysnmplib>=5.0.24
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pymscada"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.11b9"
|
|
4
4
|
description = "Shared tag value SCADA with python backup and Angular UI"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Jamie Walton", email = "jamie@walton.net.nz" },
|
|
@@ -8,7 +8,7 @@ authors = [
|
|
|
8
8
|
dependencies = [
|
|
9
9
|
"PyYAML>=6.0.1",
|
|
10
10
|
"aiohttp>=3.8.5",
|
|
11
|
-
"pymscada-html>=0.1.
|
|
11
|
+
"pymscada-html>=0.1.10b5",
|
|
12
12
|
"cerberus>=1.3.5",
|
|
13
13
|
"pycomm3>=1.2.14",
|
|
14
14
|
"pysnmplib>=5.0.24",
|
|
@@ -265,7 +265,11 @@ class BusServer:
|
|
|
265
265
|
if len(data) > 300:
|
|
266
266
|
logging.warning(f'process: log message too long from {bus_id}')
|
|
267
267
|
else:
|
|
268
|
-
|
|
268
|
+
log_msg = data.decode()
|
|
269
|
+
logging.warning(log_msg)
|
|
270
|
+
client_addr = self.connections[bus_id].addr
|
|
271
|
+
self.bus_tag.value = f'\x03{client_addr}: {log_msg}'.encode()
|
|
272
|
+
self.bus_tag.time_us = int(time.time() * 1e6)
|
|
269
273
|
else: # consider disconnecting
|
|
270
274
|
logging.warn(f'invalid message {cmd}')
|
|
271
275
|
|
|
@@ -116,4 +116,60 @@ localhost_ping:
|
|
|
116
116
|
google_ping:
|
|
117
117
|
desc: Ping time to google
|
|
118
118
|
type: float
|
|
119
|
-
units: ms
|
|
119
|
+
units: ms
|
|
120
|
+
Murupara_Temp:
|
|
121
|
+
desc: Murupara Temperature
|
|
122
|
+
type: float
|
|
123
|
+
units: '°C'
|
|
124
|
+
dp: 1
|
|
125
|
+
min: -50
|
|
126
|
+
max: 50
|
|
127
|
+
Murupara_WindSpeed:
|
|
128
|
+
desc: Murupara Wind Speed
|
|
129
|
+
type: float
|
|
130
|
+
units: 'm/s'
|
|
131
|
+
dp: 1
|
|
132
|
+
min: 0
|
|
133
|
+
max: 200
|
|
134
|
+
Murupara_WindDir:
|
|
135
|
+
desc: Murupara Wind Direction
|
|
136
|
+
type: float
|
|
137
|
+
units: '°'
|
|
138
|
+
dp: 0
|
|
139
|
+
min: 0
|
|
140
|
+
max: 360
|
|
141
|
+
Murupara_Rain:
|
|
142
|
+
desc: Murupara Rainfall
|
|
143
|
+
type: float
|
|
144
|
+
units: 'mm'
|
|
145
|
+
dp: 1
|
|
146
|
+
min: 0
|
|
147
|
+
max: 1000
|
|
148
|
+
Murupara_Temp_03:
|
|
149
|
+
desc: Murupara Temperature 3-Hour Forecast
|
|
150
|
+
type: float
|
|
151
|
+
units: '°C'
|
|
152
|
+
dp: 1
|
|
153
|
+
min: -50
|
|
154
|
+
max: 50
|
|
155
|
+
Murupara_WindSpeed_03:
|
|
156
|
+
desc: Murupara Wind Speed 3-Hour Forecast
|
|
157
|
+
type: float
|
|
158
|
+
units: 'm/s'
|
|
159
|
+
dp: 1
|
|
160
|
+
min: 0
|
|
161
|
+
max: 200
|
|
162
|
+
Murupara_WindDir_03:
|
|
163
|
+
desc: Murupara Wind Direction 3-Hour Forecast
|
|
164
|
+
type: float
|
|
165
|
+
units: '°'
|
|
166
|
+
dp: 0
|
|
167
|
+
min: 0
|
|
168
|
+
max: 360
|
|
169
|
+
Murupara_Rain_03:
|
|
170
|
+
desc: Murupara Rainfall 3-Hour Forecast
|
|
171
|
+
type: float
|
|
172
|
+
units: 'mm'
|
|
173
|
+
dp: 1
|
|
174
|
+
min: 0
|
|
175
|
+
max: 1000
|
|
@@ -78,3 +78,49 @@ pages:
|
|
|
78
78
|
scale: mS
|
|
79
79
|
color: red
|
|
80
80
|
dp: 1
|
|
81
|
+
- name: Weather
|
|
82
|
+
parent:
|
|
83
|
+
items:
|
|
84
|
+
- type: uplot
|
|
85
|
+
ms:
|
|
86
|
+
desc: Weather
|
|
87
|
+
age: 172800
|
|
88
|
+
legend_pos: left
|
|
89
|
+
time_pos: left
|
|
90
|
+
time_res: m
|
|
91
|
+
axes:
|
|
92
|
+
- scale: x
|
|
93
|
+
range: [-86400, 0] # 24 hours of data
|
|
94
|
+
- scale: temp
|
|
95
|
+
range: [-10, 40] # Temperature in Celsius
|
|
96
|
+
dp: 1
|
|
97
|
+
- scale: wind
|
|
98
|
+
range: [0, 100] # Wind speed in km/h
|
|
99
|
+
dp: 1
|
|
100
|
+
- scale: dir
|
|
101
|
+
range: [0, 360] # Wind direction in degrees
|
|
102
|
+
dp: 0
|
|
103
|
+
- scale: rain
|
|
104
|
+
range: [0, 50] # Rain in mm
|
|
105
|
+
dp: 1
|
|
106
|
+
series:
|
|
107
|
+
- tagname: Murupara_Temp
|
|
108
|
+
label: Temperature
|
|
109
|
+
scale: temp
|
|
110
|
+
color: red
|
|
111
|
+
dp: 1
|
|
112
|
+
- tagname: Murupara_WindSpeed
|
|
113
|
+
label: Wind Speed
|
|
114
|
+
scale: wind
|
|
115
|
+
color: blue
|
|
116
|
+
dp: 1
|
|
117
|
+
- tagname: Murupara_WindDir
|
|
118
|
+
label: Wind Direction
|
|
119
|
+
scale: dir
|
|
120
|
+
color: green
|
|
121
|
+
dp: 0
|
|
122
|
+
- tagname: Murupara_Rain
|
|
123
|
+
label: Rainfall
|
|
124
|
+
scale: rain
|
|
125
|
+
color: lightblue
|
|
126
|
+
dp: 1
|
|
@@ -73,6 +73,7 @@ class OpenWeatherClient:
|
|
|
73
73
|
|
|
74
74
|
async def fetch_current_data(self):
|
|
75
75
|
"""Fetch current weather data for all locations."""
|
|
76
|
+
logging.info('fetching current')
|
|
76
77
|
if self.session is None:
|
|
77
78
|
self.session = aiohttp.ClientSession()
|
|
78
79
|
for location, coords in self.locations.items():
|
|
@@ -92,6 +93,7 @@ class OpenWeatherClient:
|
|
|
92
93
|
|
|
93
94
|
async def fetch_forecast_data(self):
|
|
94
95
|
"""Fetch forecast weather data for all locations."""
|
|
96
|
+
logging.info('fetching forecast')
|
|
95
97
|
if self.session is None:
|
|
96
98
|
self.session = aiohttp.ClientSession()
|
|
97
99
|
for location, coords in self.locations.items():
|
|
@@ -113,9 +115,9 @@ class OpenWeatherClient:
|
|
|
113
115
|
"""Poll OpenWeather APIs every 10 minutes."""
|
|
114
116
|
now = int(time())
|
|
115
117
|
if now % 600 == 0: # Every 10 minutes
|
|
116
|
-
|
|
118
|
+
asyncio.create_task(self.fetch_current_data())
|
|
117
119
|
if now % 10800 == 60: # Every 3 hours, offset by 1 minute
|
|
118
|
-
|
|
120
|
+
asyncio.create_task(self.fetch_forecast_data())
|
|
119
121
|
|
|
120
122
|
async def start(self):
|
|
121
123
|
"""Start bus connection and API polling."""
|
|
@@ -182,8 +182,6 @@ class WSHandler():
|
|
|
182
182
|
if action == 'set': # pc.CMD_SET
|
|
183
183
|
self.tag_by_name[tagname].value = value, time_us, bus
|
|
184
184
|
elif action == 'rta': # pc.CMD_RTA
|
|
185
|
-
if tagname not in self.tag_by_name:
|
|
186
|
-
self.do_sub(tagname)
|
|
187
185
|
if 'File' in value:
|
|
188
186
|
file = await anext(self.ws)
|
|
189
187
|
value['_file_data'] = file.data
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|