-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathyasdidemon.py
More file actions
98 lines (72 loc) · 4.01 KB
/
Copy pathyasdidemon.py
File metadata and controls
98 lines (72 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#! /usr/bin/env python
# -*- coding: utf-8 -*-
""" A simple demon using the Python wrapper. It searches for SMA inverters and poll the data channels "Pac", "E-Tag", "E-Total" in a loop.
"""
__author__ = "Heiko Prüssing"
__license__ = "MIT License"
__version__ = "0.0.1"
__maintainer__ = "Heiko Prüssing"
# imports
import os
import time
from yasdiwrapper.yasdi import Yasdi, INVALID_HANDLE
from yasdiwrapper.yasdimaster import YasdiMaster, CMD_DEVICE_DETECTION
from yasdiwrapper.sd1channels import CHANNEl_NAME_PAC, CHANNEl_NAME_ETOTAL
# Globals
# Search for YASDI libraries also in the current directory first
os.environ["DYLD_LIBRARY_PATH"] = os.getcwd() # for macOS
os.environ["LD_LIBRARY_PATH"] = os.getcwd() # for Linux/Unix
yasdiMasterLibrary = YasdiMaster()
yasdiLibrary = Yasdi()
# Implementation
class YasdiDemon:
def pollLiveData(self, devicesList, channelsToRequest, outputFile: str="./data.csv"):
"""Polls for live data on given devices and channel names and put it into a csv file."""
# The age of the channel value should not older than 1 second
AGE_OF_VALUE_SECONDS = 1
while True:
outputBuffer = "ChannelName;ChannelUnit;ValueTimestamp;ChannelValue\n"
for deviceHandle in devicesList:
for channelName in channelsToRequest:
channelHandle = yasdiMasterLibrary.FindChannelName(deviceHandle, channelName)
if INVALID_HANDLE == channelHandle:
print(f"Error: Channel {channelName} is missing on device {yasdiMasterLibrary.GetDeviceName(deviceHandle)}. Check your device detection...")
else:
channelValue = yasdiMasterLibrary.GetChannelValue(channelHandle, deviceHandle, AGE_OF_VALUE_SECONDS)
timestamp = yasdiMasterLibrary.GetChannelValueTimeStamp(channelHandle, deviceHandle)
channelUnit = yasdiMasterLibrary.GetChannelUnit(channelHandle)
# print(f"{channelName};{channelUnit};{timestamp};{channelValue}")
outputBuffer = outputBuffer + f"{channelName};{channelUnit};{timestamp};{channelValue}\n"
# Write data to a csv file
with open(outputFile, 'w', encoding="utf-8") as f:
f.write(outputBuffer)
f.close()
time.sleep(2)
def start(self):
try:
driverHandleList = yasdiLibrary.yasdiGetDrivers()
if len(driverHandleList) == 0:
raise Exception("Error: No configured interfaces available! Please check your YASDI configuration try again...")
# Open all interfaces (drivers)
for driverHandle in driverHandleList:
print(f"Open interface driver '{yasdiLibrary.yasdiGetDriverName(driverHandle)}'. Success = {yasdiLibrary.yasdiSetDriverOnline(driverHandle)}" )
# Search for SMA devices (inverters, etc...)
print("Start searching SMA devices...")
COUNT_OF_DEVICES_TO_BE_SEARCHED = 1
if not yasdiMasterLibrary.DoMasterCmdEx(cmd=CMD_DEVICE_DETECTION, param1=COUNT_OF_DEVICES_TO_BE_SEARCHED):
print("Device detection failed for some reason. Maybe not all devices are found as requested.")
# Get the list of found SMA devices
devicesList = yasdiMasterLibrary.GetDeviceHandles()
for deviceHandle in devicesList:
print(f"Found device: {yasdiMasterLibrary.GetDeviceName(deviceHandle)}")
if len(devicesList) == 0:
raise Exception("ERROR: No SMA inverters found! Check your hardware or yasdi configuration and try again...")
# Endless poll for live data from devices:
self.pollLiveData(devicesList, [CHANNEl_NAME_PAC, CHANNEl_NAME_ETOTAL])
#except Exception as e:
# print(f"=> Exception: {e}")
finally:
yasdiMasterLibrary.yasdiMasterShutdown()
if __name__ == "__main__":
yasdiDemon = YasdiDemon()
yasdiDemon.start()