Omnik Export Script
Moderators: leecollings, remb0
-
- Posts: 7
- Joined: Friday 19 February 2016 15:50
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Omnik Export Script
Can anybody help me:
I used the script form the wiki Omnik Inverter, but I keep getting errors when I run the script.
traceback (most recent call last):
File "OmnikMessage.py", line 83, in <module>
s.sendall(InverterMsg.generate_string(wifi_serial))
AttributeError: 'module' object has no attribute 'generate_string'
I'm a newbie so it's difficult for me.
Thanx!
I used the script form the wiki Omnik Inverter, but I keep getting errors when I run the script.
traceback (most recent call last):
File "OmnikMessage.py", line 83, in <module>
s.sendall(InverterMsg.generate_string(wifi_serial))
AttributeError: 'module' object has no attribute 'generate_string'
I'm a newbie so it's difficult for me.
Thanx!
-
- Posts: 2
- Joined: Saturday 26 March 2016 15:35
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: Omnik Export Script
Hello Noppy, I'm also struggling to solve this issue. Do you have al solution yet?
I do get the same error when using the OmikExport script:
pi@raspberrypi:~/domoticz/Omnik-Data-Logger$ python OmnikExport.py
Traceback (most recent call last):
File "OmnikExport.py", line 83, in <module>
s.sendall(InverterMsg.generate_string(wifi_serial))
AttributeError: 'module' object has no attribute 'generate_string'
pi@raspberrypi:
Probably something to do with the generate_string not able to find in the script.
Can anybody help????
Thnx
I do get the same error when using the OmikExport script:
pi@raspberrypi:~/domoticz/Omnik-Data-Logger$ python OmnikExport.py
Traceback (most recent call last):
File "OmnikExport.py", line 83, in <module>
s.sendall(InverterMsg.generate_string(wifi_serial))
AttributeError: 'module' object has no attribute 'generate_string'
pi@raspberrypi:
Probably something to do with the generate_string not able to find in the script.
Can anybody help????
Thnx
- sincze
- Posts: 1300
- Joined: Monday 02 June 2014 22:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Location: Netherlands / Breda Area
- Contact:
Re: Omnik Export Script
Can you share the first 3 digits of the serial number of the Omnik inverter?
It seems the script is not always working for all the Omnik inverters.
It seems the script is not always working for all the Omnik inverters.
Pass2php
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
-
- Posts: 20
- Joined: Saturday 17 October 2015 22:23
- Target OS: Linux
- Domoticz version: 4.10659
- Contact:
Re: Omnik Export Script
Also struggling with this particular script.
Since LiveStats.py is functioning properly (generating output), I am not expecting that the following error:
....has anything to do with the device serial number, but rather with the python configuration (more specifically the InverterMsg.py file)
I am running python version 2.7.9 on a RBPi3.
Since LiveStats.py is functioning properly (generating output), I am not expecting that the following error:
Code: Select all
Traceback (most recent call last):
File "Omnik-Export.py", line 83, in <module>
s.sendall(InverterMsg.generate_string(wifi_serial))
AttributeError: 'module' object has no attribute 'generate_string'
I am running python version 2.7.9 on a RBPi3.
Last edited by jbr79 on Wednesday 30 March 2016 15:33, edited 1 time in total.
- sincze
- Posts: 1300
- Joined: Monday 02 June 2014 22:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Location: Netherlands / Breda Area
- Contact:
Re: Omnik Export Script
That would have been indeed my next question.
It is known that Omnik Export script doesn't work for all Omnik Inverter.
However if LiveStats is producing output... the rest should work for you as well.
Mine is on Python version 2.7.3.
I copy pasted the script from the wiki into a temp.py file and executed that one. No Errors.
The code in the wiki is still okay.
Have to keep digging some more.
It is known that Omnik Export script doesn't work for all Omnik Inverter.
However if LiveStats is producing output... the rest should work for you as well.
Mine is on Python version 2.7.3.
Code: Select all
root@PC:/home/domoticz/Omnik-Data-Logger# python OmnikExport.py
root@PC:/home/domoticz/Omnik-Data-Logger#
The code in the wiki is still okay.
Have to keep digging some more.
Pass2php
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
-
- Posts: 20
- Joined: Saturday 17 October 2015 22:23
- Target OS: Linux
- Domoticz version: 4.10659
- Contact:
Re: Omnik Export Script
Curious: I had to do several adjustments to align the variable names in the config.cfg file (which was pulled in via a Git clone of the source files - git clone https://github.com/Woutrrr/Omnik-Data-Logger.git) and the Omnik-export.py (the code in the wiki) file.I copy pasted the script from the wiki into a temp.py file and executed that one. No Errors.
The code in the wiki is still okay.
Were you able to use both files without adjustment?
- sincze
- Posts: 1300
- Joined: Monday 02 June 2014 22:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Location: Netherlands / Breda Area
- Contact:
Re: Omnik Export Script
you got me there.
I did not overwrite the .cfg file indeed. I used my original one.
I did not overwrite the .cfg file indeed. I used my original one.
Code: Select all
################
### Settings ###
################
[inverter]
# IP address of your Omnik inverter
ip = ***.***.***.***
# Default for a Omnik with Wifi module
port = 8899
# S/N of the wifi kit
wifi_sn = 1602******
#use temperature of inverter for pvoutput
use_temperature = true
[mysql]
# Enable for exporting to a mysql database
mysql_enabled = false
# Host where the mysql server is active
mysql_host = 127.0.0.1
mysql_user =
mysql_pass =
mysql_db =
[domoticz]
domoticz_enabled = true
domoticz_host = ***.***.***.***
domoticz_port = 8080
domoticz_url = json.htm
# Provide IDX here of the specific devices
domoticz_temp = ***
domoticz_Input_PV1 = ***
domoticz_Input_PV2 = ***
domoticz_AC_Output = ***
domoticz_Cur_Total = ***
domoticz_AMP_1_2_3 = ***
[pvout]
# Enable or disable uploading to PVoutput
pvout_enabled =false
# These two can be found at http://pvoutput.org/account.jsp
pvout_apikey = NOTAREALAPIKEY86e2258d4e29169fb79cf18b00
pvout_sysid = 12345
[log]
log_enabled = true
log_filename = omnik-export.log
Pass2php
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
-
- Posts: 20
- Joined: Saturday 17 October 2015 22:23
- Target OS: Linux
- Domoticz version: 4.10659
- Contact:
Re: Omnik Export Script
I see you disabled mysql and pv_output - I am wondering if that might change the outcome
I will try this evening.
I will try this evening.
- sincze
- Posts: 1300
- Joined: Monday 02 June 2014 22:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Location: Netherlands / Breda Area
- Contact:
Re: Omnik Export Script
Jups. I don't use MYSQL to separately store the data, so disabled it.
I enabled PVOutput "true" and data is now being exported to PVOutput. Works nicely.
Normally I would have used the wiki for PVOutput upload, but since daylight save change that does not work for me anymore.
http://www.domoticz.com/wiki/Upload_ene ... o_PVoutput
Did not yet figure out why. I do recveive the correct data, however PVOutput doesn't seem to like it anymore.
A well back to the original topic. I issued a python3 command..
root@PC:/home/domoticz/Omnik-Data-Logger# python LiveStats.py
So some errors do occur when using a different python version.
At least so it seams....
Regular python is version: Python 2.7.3, can you try that one as well?
I enabled PVOutput "true" and data is now being exported to PVOutput. Works nicely.
Normally I would have used the wiki for PVOutput upload, but since daylight save change that does not work for me anymore.
http://www.domoticz.com/wiki/Upload_ene ... o_PVoutput
Did not yet figure out why. I do recveive the correct data, however PVOutput doesn't seem to like it anymore.
Code: Select all
2016-03-29 23:25:00.770 LUA: ---- The total generated energy is 14310.0 Wh
2016-03-29 23:25:00.770 LUA: ---- The current generated power is 0 W
2016-03-29 23:25:00.770 LUA: ---- The voltage of the inverter is 0.0 V
2016-03-29 23:25:00.770 LUA: ---- The outside temperature is 9.1 C.
2016-03-29 23:25:00.770 LUA: ---- The total consumed energy is 10761371 Wh
2016-03-29 23:25:00.770 LUA: ---- The current consumed power is 650 W
Code: Select all
root@PC:/home/domoticz/Omnik-Data-Logger# python3 LiveStats.py
File "LiveStats.py", line 52
print 'could not open socket'
^
SyntaxError: invalid syntax
root@PC:/home/domoticz/Omnik-Data-Logger# python LiveStats.py
Code: Select all
connecting to ***.***.***.*** port 8899
ID: NL**************
E Today: 14.03 Total: 6623.6
H Total: 0 Temp: 38.5
PV1 V: 268.6 I: 3.0
PV2 V: 266.4 I: 3.0
PV3 V: 0.0 I: 0.0
L1 P: 1424 V: 238.8 I: 5.9 F: 50.0
L2 P: 0 V: 0.0 I: 0.0 F: 0.0
L3 P: 0 V: 0.0 I: 0.0 F: 0.0
At least so it seams....
Regular python is version: Python 2.7.3, can you try that one as well?
Pass2php
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
-
- Posts: 20
- Joined: Saturday 17 October 2015 22:23
- Target OS: Linux
- Domoticz version: 4.10659
- Contact:
Re: Omnik Export Script
I know from my previous encounter with Python that Python3 is a different ballgame. Anyway, having access to the file contents now that it is evening, disabling mysql and pvoutput obviously did not do the trick.
I am however curious as to what the contents of your InverterMsg.py file is. Mine does not hold any reference to 'generate_string'. With my limited programming experience I would say there is another clue hidden in that file.
I am however curious as to what the contents of your InverterMsg.py file is. Mine does not hold any reference to 'generate_string'. With my limited programming experience I would say there is another clue hidden in that file.
- sincze
- Posts: 1300
- Joined: Monday 02 June 2014 22:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Location: Netherlands / Breda Area
- Contact:
Re: Omnik Export Script
Line 78 generate_string of the file InverterMsg.py
Code: Select all
import struct # Converting bytes to numbers
class InverterMsg:
'Class for Inverter message'
rawmsg = ""
def __init__(self, msg, offset=0):
self.rawmsg = msg
self.offset = offset
def __getString(self, begin, end):
return self.rawmsg[begin:end]
def __getShort(self, begin, devider=10):
num = struct.unpack('!H', self.rawmsg[begin:begin+2])[0]
if num == 65535:
return -1
else:
return float(num)/devider
def __getLong(self, begin, devider=10):
return float(struct.unpack('!I', self.rawmsg[begin:begin+4])[0])/devider
def getID(self):
return self.__getString(15,31)
def getTemp(self):
return self.__getShort(31)
def getPower(self):
print self.__getShort(59)
def getETotal(self):
return self.__getLong(71)
def getVPV(self, i=1):
if i not in range(1, 4):
i = 1
num = 33 + (i-1)*2
return self.__getShort(num)
def getIPV(self, i=1):
if i not in range(1, 4):
i=1
num = 39 + (i-1)*2
return self.__getShort(num)
def getIAC(self, i=1):
if i not in range(1, 4):
i=1
num = 45 + (i-1)*2
return self.__getShort(num)
def getVAC(self, i=1):
if i not in range(1, 4):
i=1
num = 51 + (i-1)*2
return self.__getShort(num)
def getFAC(self, i=1):
if i not in range(1, 4):
i=1
num = 57 + (i-1)*4
return self.__getShort(num, 100)
def getPAC(self, i=1):
if i not in range(1, 4):
i=1
num = 59 + (i-1)*4
return int(self.__getShort(num, 1)) # Don't divide
def getEToday(self):
return self.__getShort(69, 100) # Devide by 100
def getHTotal(self):
return int(self.__getLong(75, 1)) # Don't divide
def generate_string(ser):
'''
The request string is build from several parts. The first part is a
fixed 4 char string; the second part is the reversed hex notation of
the s/n twice; then again a fixed string of two chars; a checksum of
the double s/n with an offset; and finally a fixed ending char.
'''
responseString = '\x68\x02\x40\x30';
doublehex = hex(ser)[2:]*2
hexlist = [ doublehex[i:i+2].decode('hex') for i in
reversed(range(0, len(doublehex), 2))]
cs_count = 115 + sum([ ord(c) for c in hexlist])
cs = hex(cs_count)[-2:].decode('hex')
responseString += ''.join(hexlist) + '\x01\x00'+cs+'\x16'
return responseString
Pass2php
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
-
- Posts: 20
- Joined: Saturday 17 October 2015 22:23
- Target OS: Linux
- Domoticz version: 4.10659
- Contact:
Re: Omnik Export Script
Is that the entire contents?
Mine is different (see below).Where did you get your file from?
pi@raspberrypi:~/Omnik-Data-Logger $ cat InverterMsg.py
Mine is different (see below).Where did you get your file from?
pi@raspberrypi:~/Omnik-Data-Logger $ cat InverterMsg.py
Code: Select all
import struct # Converting bytes to numbers
class InverterMsg(object):
"""Decode the response message from an omniksol inverter."""
raw_msg = ""
def __init__(self, msg, offset=0):
self.raw_msg = msg
self.offset = offset
def __get_string(self, begin, end):
"""Extract string from message.
Args:
begin (int): starting byte index of string
end (int): end byte index of string
Returns:
str: String in the message from start to end
"""
return self.raw_msg[begin:end]
def __get_short(self, begin, divider=10):
"""Extract short from message.
The shorts in the message could actually be a decimal number. This is
done by storing the number multiplied in the message. So by dividing
the short the original decimal number can be retrieved.
Args:
begin (int): index of short in message
divider (int): divider to change short to float. (Default: 10)
Returns:
int or float: Value stored at location `begin`
"""
num = struct.unpack('!H', self.raw_msg[begin:begin + 2])[0]
if num == 65535:
return -1
else:
return float(num) / divider
def __get_long(self, begin, divider=10):
"""Extract long from message.
The longs in the message could actually be a decimal number. By
dividing the long, the original decimal number can be extracted.
Args:
begin (int): index of long in message
divider (int): divider to change long to float. (Default : 10)
Returns:
int or float: Value stored at location `begin`
"""
return float(
struct.unpack('!I', self.raw_msg[begin:begin + 4])[0]) / divider
@property
def id(self):
"""ID of the inverter."""
return self.__get_string(15, 31)
@property
def temperature(self):
"""Temperature recorded by the inverter."""
return self.__get_short(31)
@property
def power(self):
"""Power output"""
print self.__get_short(59)
@property
def e_total(self):
"""Total energy generated by inverter in kWh"""
return self.__get_long(71)
def v_pv(self, i=1):
"""Voltage of PV input channel.
Available channels are 1, 2 or 3; if not in this range the function will
default to channel 1.
Args:
i (int): input channel (valid values: 1, 2, 3)
Returns:
float: PV voltage of channel i
"""
if i not in range(1, 4):
i = 1
num = 33 + (i - 1) * 2
return self.__get_short(num)
def i_pv(self, i=1):
"""Current of PV input channel.
Available channels are 1, 2 or 3; if not in this range the function will
default to channel 1.
Args:
i (int): input channel (valid values: 1, 2, 3)
Returns:
float: PV current of channel i
"""
if i not in range(1, 4):
i = 1
num = 39 + (i - 1) * 2
return self.__get_short(num)
def i_ac(self, i=1):
"""Current of the Inverter output channel
Available channels are 1, 2 or 3; if not in this range the function will
default to channel 1.
Args:
i (int): output channel (valid values: 1, 2, 3)
Returns:
float: AC current of channel i
"""
if i not in range(1, 4):
i = 1
num = 45 + (i - 1) * 2
return self.__get_short(num)
def v_ac(self, i=1):
"""Voltage of the Inverter output channel
Available channels are 1, 2 or 3; if not in this range the function will
default to channel 1.
Args:
i (int): output channel (valid values: 1, 2, 3)
Returns:
float: AC voltage of channel i
"""
if i not in range(1, 4):
i = 1
num = 51 + (i - 1) * 2
return self.__get_short(num)
def f_ac(self, i=1):
"""Frequency of the output channel
Available channels are 1, 2 or 3; if not in this range the function will
default to channel 1.
Args:
i (int): output channel (valid values: 1, 2, 3)
Returns:
float: AC frequency of channel i
"""
if i not in range(1, 4):
i = 1
num = 57 + (i - 1) * 4
return self.__get_short(num, 100)
def p_ac(self, i=1):
"""Power output of the output channel
Available channels are 1, 2 or 3; if no tin this range the function will
default to channel 1.
Args:
i (int): output channel (valid values: 1, 2, 3)
Returns:
float: Power output of channel i
"""
if i not in range(1, 4):
i = 1
num = 59 + (i - 1) * 4
return int(self.__get_short(num, 1)) # Don't divide
@property
def e_today(self):
"""Energy generated by inverter today in kWh"""
return self.__get_short(69, 100) # Divide by 100
@property
def h_total(self):
"""Hours the inverter generated electricity"""
return int(self.__get_long(75, 1)) # Don't divide
- sincze
- Posts: 1300
- Joined: Monday 02 June 2014 22:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Location: Netherlands / Breda Area
- Contact:
Re: Omnik Export Script
Euh indeed that is my entire content of my document indeed.
However it seems to work.
Maybe exchange yours for mine and see what happens ??
However it seems to work.
Maybe exchange yours for mine and see what happens ??
Pass2php
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
-
- Posts: 20
- Joined: Saturday 17 October 2015 22:23
- Target OS: Linux
- Domoticz version: 4.10659
- Contact:
Re: Omnik Export Script
That would have been too easy; failure at first sight:
I did not get around to interchanging the generate_string def from your file pasted above with my own InverterMsg.py - will have to find time somewhere this weekend.
I saw there was a staticmethod available in the original OmnikExport.py module. Tried copying that to the InverterMSg.py file, but without success. Same error message:pi@RPi3:~/domoticz/scripts/python/Omnik-Data-Logger $ python LiveStats.py
Traceback (most recent call last):
File "LiveStats.py", line 7, in <module>
import OmnikExport
ImportError: No module named OmnikExport
Code: Select all
pi@RPi3:~/domoticz/scripts/python/Omnik-Data-Logger $ python Export.py
Traceback (most recent call last):
File "Export.py", line 83, in <module>
s.sendall(InverterMsg.generate_string(wifi_serial))
AttributeError: 'module' object has no attribute 'generate_string'
I did not get around to interchanging the generate_string def from your file pasted above with my own InverterMsg.py - will have to find time somewhere this weekend.
-
- Posts: 20
- Joined: Saturday 17 October 2015 22:23
- Target OS: Linux
- Domoticz version: 4.10659
- Contact:
Re: Omnik Export Script
Seems there is a lot more to be done to get this script up and running. I find myself replacing one function after another, but without success. It keeps producing a new error every time. Call me naive, but I fail to see why there seem to be two versions of the same file out in the open. One being completely incompatible.
-
- Posts: 2
- Joined: Saturday 26 March 2016 15:35
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: Omnik Export Script
I also was struggling to get this InverterMsg.py working. I am not a programmer merely I cutted, pasted, trial and errored a lot and I have now a working solution for my situation. Maybe someone with more python skills can make it work for all situations, because with this script the Livestats do not work anymore. In short I added the config of the old file in the new one
And the virtual sensors are now filled with data.
And the virtual sensors are now filled with data.
Code: Select all
pi@raspberrypi:~/domoticz/Omnik-Data-Logger$ cat InverterMsg.py
import struct # Converting bytes to numbers
class InverterMsg(object):
"""Decode the response message from an omniksol inverter."""
raw_msg = ""
def __init__(self, msg, offset=0):
self.raw_msg = msg
self.offset = offset
def __get_string(self, begin, end):
"""Extract string from message.
Args:
begin (int): starting byte index of string
end (int): end byte index of string
Returns:
str: String in the message from start to end
"""
return self.raw_msg[begin:end]
def __get_short(self, begin, divider=10):
"""Extract short from message.
The shorts in the message could actually be a decimal number. This is
done by storing the number multiplied in the message. So by dividing
the short the original decimal number can be retrieved.
Args:
begin (int): index of short in message
divider (int): divider to change short to float. (Default: 10)
Returns:
int or float: Value stored at location `begin`
"""
num = struct.unpack('!H', self.raw_msg[begin:begin + 2])[0]
if num == 65535:
return -1
else:
return float(num) / divider
def __get_long(self, begin, divider=10):
"""Extract long from message.
The longs in the message could actually be a decimal number. By
dividing the long, the original decimal number can be extracted.
Args:
begin (int): index of long in message
divider (int): divider to change long to float. (Default : 10)
Returns:
int or float: Value stored at location `begin`
"""
return float(
struct.unpack('!I', self.raw_msg[begin:begin + 4])[0]) / divider
@property
def id(self):
"""ID of the inverter."""
return self.__get_string(15, 31)
@property
def temperature(self):
"""Temperature recorded by the inverter."""
return self.__get_short(31)
@property
def power(self):
"""Power output"""
print self.__get_short(59)
@property
def e_total(self):
"""Total energy generated by inverter in kWh"""
return self.__get_long(71)
def v_pv(self, i=1):
"""Voltage of PV input channel.
Available channels are 1, 2 or 3; if not in this range the function will
default to channel 1.
Args:
i (int): input channel (valid values: 1, 2, 3)
Returns:
float: PV voltage of channel i
"""
if i not in range(1, 4):
i = 1
num = 33 + (i - 1) * 2
return self.__get_short(num)
def i_pv(self, i=1):
"""Current of PV input channel.
Available channels are 1, 2 or 3; if not in this range the function will
default to channel 1.
Args:
i (int): input channel (valid values: 1, 2, 3)
Returns:
float: PV current of channel i
"""
if i not in range(1, 4):
i = 1
num = 39 + (i - 1) * 2
return self.__get_short(num)
def i_ac(self, i=1):
"""Current of the Inverter output channel
Available channels are 1, 2 or 3; if not in this range the function will
default to channel 1.
Args:
i (int): output channel (valid values: 1, 2, 3)
Returns:
float: AC current of channel i
"""
if i not in range(1, 4):
i = 1
num = 45 + (i - 1) * 2
return self.__get_short(num)
def v_ac(self, i=1):
"""Voltage of the Inverter output channel
Available channels are 1, 2 or 3; if not in this range the function will
default to channel 1.
Args:
i (int): output channel (valid values: 1, 2, 3)
Returns:
float: AC voltage of channel i
"""
if i not in range(1, 4):
i = 1
num = 51 + (i - 1) * 2
return self.__get_short(num)
def f_ac(self, i=1):
"""Frequency of the output channel
Available channels are 1, 2 or 3; if not in this range the function will
default to channel 1.
Args:
i (int): output channel (valid values: 1, 2, 3)
Returns:
float: AC frequency of channel i
"""
if i not in range(1, 4):
i = 1
num = 57 + (i - 1) * 4
return self.__get_short(num, 100)
def p_ac(self, i=1):
"""Power output of the output channel
Available channels are 1, 2 or 3; if no tin this range the function will
default to channel 1.
Args:
i (int): output channel (valid values: 1, 2, 3)
Returns:
float: Power output of channel i
"""
if i not in range(1, 4):
i = 1
num = 59 + (i - 1) * 4
return int(self.__get_short(num, 1)) # Don't divide
@property
def e_today(self):
"""Energy generated by inverter today in kWh"""
return self.__get_short(69, 100) # Divide by 100
@property
def h_total(self):
"""Hours the inverter generated electricity"""
return int(self.__get_long(75, 1)) # Don't divide
def __init__(self, msg, offset=0):
self.rawmsg = msg
self.offset = offset
def __getString(self, begin, end):
return self.rawmsg[begin:end]
def __getShort(self, begin, devider=10):
num = struct.unpack('!H', self.rawmsg[begin:begin+2])[0]
if num == 65535:
return -1
else:
return float(num)/devider
def __getLong(self, begin, devider=10):
return float(struct.unpack('!I', self.rawmsg[begin:begin+4])[0])/devider
def getID(self):
return self.__getString(15,31)
def getTemp(self):
return self.__getShort(31)
def getPower(self):
print self.__getShort(59)
def getETotal(self):
return self.__getLong(71)
def getVPV(self, i=1):
if i not in range(1, 4):
i = 1
num = 33 + (i-1)*2
return self.__getShort(num)
def getIPV(self, i=1):
if i not in range(1, 4):
i=1
num = 39 + (i-1)*2
return self.__getShort(num)
def getIAC(self, i=1):
if i not in range(1, 4):
i=1
num = 45 + (i-1)*2
return self.__getShort(num)
def getVAC(self, i=1):
if i not in range(1, 4):
i=1
num = 51 + (i-1)*2
return self.__getShort(num)
def getFAC(self, i=1):
if i not in range(1, 4):
i=1
num = 57 + (i-1)*4
return self.__getShort(num, 100)
def getPAC(self, i=1):
if i not in range(1, 4):
i=1
num = 59 + (i-1)*4
return int(self.__getShort(num, 1)) # Don't divide
def getEToday(self):
return self.__getShort(69, 100) # Devide by 100
def getHTotal(self):
return int(self.__getLong(75, 1)) # Don't divide
def generate_string(ser):
'''
The request string is build from several parts. The first part is a
fixed 4 char string; the second part is the reversed hex notation of
the s/n twice; then again a fixed string of two chars; a checksum of
the double s/n with an offset; and finally a fixed ending char.
'''
responseString = '\x68\x02\x40\x30';
doublehex = hex(ser)[2:]*2
hexlist = [ doublehex[i:i+2].decode('hex') for i in
reversed(range(0, len(doublehex), 2))]
cs_count = 115 + sum([ ord(c) for c in hexlist])
cs = hex(cs_count)[-2:].decode('hex')
responseString += ''.join(hexlist) + '\x01\x00'+cs+'\x16'
return responseString
-
- Posts: 20
- Joined: Saturday 17 October 2015 22:23
- Target OS: Linux
- Domoticz version: 4.10659
- Contact:
Re: Omnik Export Script
@sincze: would you be able to share your InverterMsg.py , Export.py and LiveStats.py files?
( or for that matter, your anonimized folder) I wonder if I have any luck with them instead of trying to alter my current ones.
( or for that matter, your anonimized folder) I wonder if I have any luck with them instead of trying to alter my current ones.
- sincze
- Posts: 1300
- Joined: Monday 02 June 2014 22:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Location: Netherlands / Breda Area
- Contact:
Re: Omnik Export Script
No Problem.
Please find attached the files you requested.
Let me know the results please
Please find attached the files you requested.
Let me know the results please
- Attachments
-
- OmnikExport.py.txt
- OmnikExport.py
- (8.63 KiB) Downloaded 145 times
-
- LiveStats.py.txt
- LiveStats.py
- (3.17 KiB) Downloaded 131 times
-
- InverterMsg.py.txt
- InverterMsg.py
- (2.63 KiB) Downloaded 130 times
Pass2php
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
-
- Posts: 20
- Joined: Saturday 17 October 2015 22:23
- Target OS: Linux
- Domoticz version: 4.10659
- Contact:
Re: Omnik Export Script
FINALLY: SUCCESS!!!
Big Thanks goes out to sincze for sharing the files! The solution was not in them alone, but they got me started.
So we've established there were differences in the python files. My starting point was that I could get LiveStats.py to work perfectly in console, but OmnikExport.py would generate new errors every time (so you fix, you fall right in the other).
I found out there are two isolated incidents:
- first, the git cloned files have different function names (especially in InverterMsg.py)
- there is (was - I corrected it to prevent more grey hair) an awfully crappy error in the instructions on the Wiki. The config file holds an extra space that is preventing the correct encoding of the URL!
My final solution:
I can't believe it actually works!
Big Thanks goes out to sincze for sharing the files! The solution was not in them alone, but they got me started.
So we've established there were differences in the python files. My starting point was that I could get LiveStats.py to work perfectly in console, but OmnikExport.py would generate new errors every time (so you fix, you fall right in the other).
I found out there are two isolated incidents:
- first, the git cloned files have different function names (especially in InverterMsg.py)
- there is (was - I corrected it to prevent more grey hair) an awfully crappy error in the instructions on the Wiki. The config file holds an extra space that is preventing the correct encoding of the URL!
My final solution:
- git clone the files from git clone https://github.com/Woutrrr/Omnik-Data-Logger.git
- generate the config.cfg file with my settings, and add the lines from the config in the wiki
- test the LiveStats.py file. This should generate output (otherwise it won't work at all with your Converter)
- Create a file called Export.py with the contents of the instructions for the OmnikExport.py file on the wiki, but initially also added "import OmnikExport" at the top (this was removed later)
- used the InverterMsg.py file from sincze to copy all missing code (so what is not originally in the git clone)
- do a a little cleanup of the InverterMsg.py file. There's functions that expect for example getString while it is called get_string in the file.
I can't believe it actually works!
- sincze
- Posts: 1300
- Joined: Monday 02 June 2014 22:46
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 2024.4
- Location: Netherlands / Breda Area
- Contact:
Re: Omnik Export Script
Nice work.
You updated the wiki as well. tnx.
This will avoid grey hairs for other people.
Pass2php
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave, Sonoff 3
MQTT: ZIgbee2MQTT,
ZWAVE: Zwave-JS-UI
WIFI: Mi-light, Tasmota, Xiaomi Shelly
Solar: Omnik, PVOutput
Video: Kodi, Harmony HUB, Chromecast
Sensors: You name it I got 1.
Who is online
Users browsing this forum: Google Adsense [Bot] and 0 guests