OWL Intuition decode using tcp/udp binding

Hi,

I’ve manage to capture and parse the owl messages into openhab2. The result is something link this:

I’ve used regexp because xpath isn’t working. The items are this:

String owlTimeStamp     "TimeStamp [%s]"            <time>      (gOwl)          { udp="<[192.168.1.65:*:'REGEX(.*<timestamp>(.*)</timestamp>.*)']" }
String owlBattery       "Battery [%s]"              <battery>   (gOwl)          { udp="<[192.168.1.65:*:'REGEX(.*<battery level=\'(.*)\'/>.*)']" }
String owlFase1         "Fase 1 [%s w]"             <energy>    (gOwl)          { udp="<[192.168.1.65:*:'REGEX(.*<chan id=\'0\'><curr units=\'w\'>([\\d.]*)</curr>.*)']" }
String owlFase1Agg      "Fase 1 Agregado [%s wh]"   <energy>    (gOwl)          { udp="<[192.168.1.65:*:'REGEX(.*<chan id=\'0\'>.*<day units=\'wh\'>(.*)</day></chan><chan id='1'>.*)']" }
String owlFase2         "Fase 2 [%s w]"             <energy>    (gOwl)          { udp="<[192.168.1.65:*:'REGEX(.*<chan id=\'1\'><curr units=\'w\'>([\\d.]*)</curr>.*)']" }
String owlFase2Agg      "Fase 2 Agregado [%s wh]"   <energy>    (gOwl)          { udp="<[192.168.1.65:*:'REGEX(.*<chan id=\'1\'>.*<day units=\'wh\'>(.*)</day></chan><chan id='2'>.*)']" }
String owlFase3         "Fase 3 [%s w]"             <energy>    (gOwl)          { udp="<[192.168.1.65:*:'REGEX(.*<chan id=\'2\'><curr units=\'w\'>([\\d.]*)</curr>.*)']" }
String owlFase3Agg      "Fase 3 Agregado [%s wh]"   <energy>    (gOwl)          { udp="<[192.168.1.65:*:'REGEX(.*<chan id=\'2\'>.*<day units=\'wh\'>(.*)</day>.*)']" }

I hope this help somebody.

Best Regards,
Fernando Gomes

2 Likes

This is really interesting, many thanks for sharing, but I’m having a hard time implementing this, could you post the code in *items code fences? Because I think something is getting lost with how you pasted the code, maybe?

The IP address you specify is the IP address of the OWL, correct? Did you have to setup data push for your openhab server or is this just listening for UDP multicast?

Thank you!

Sorry for the big delay… So yeap the ip address is the owl device. In the tcp/udp binding I only need to configure the port:

[root@server openhab2]# head -5 services/tcp.cfg  
# all parameters can be applied to both the TCP and UDP binding unless
# specified otherwise

# Port to listen for incoming connections
udp:port=22601

Hi everyone,

Does anybody make it work this way? If do so, Can give some further details? or a simple howto

Thank you in advance

Hi,

What have you done? You already have the owl configured to send the information to the local network?

Best Regards,
Fernando Gomes

Oh no, I haven’t did that?
how you can do it?

In: https://theowl.zendesk.com/hc/en-gb/articles/201284603-Multicast-UDP-API-Information:

To configure the Network OWL to start pushing the data over UDP:

  1. Ensure Network OWL is online and login to the web dashboard for the unit concerned.
  2. Select the Devices menu option
  3. Select the Network OWL
  4. Select the Upgrade option (if available - Network OWL requires at least version 2.1) & then close Devices window
  5. Wait say 5 mins
  6. Select the Devices menu option again
  7. Check Network OWL is now running the new firmware version
  8. Select the Settings menu
  9. Setup Data Push
  10. Enter IP Address and Port number
  11. Save

When you add the ip address on “Setup Data Push” do you mean your local openhab server IP or a public IP with port forwarding to your openhab?

Screen Shot 2020-12-19 at 21.05.43

Your local openhab server IP.

1 Like

Thank you for the reply,
Still doesn’t work for me

Hi,

As talked, you already manage to get it work.
Some things that is needed:

  • regex transformation installed
  • tcp binding installed
  • configuration in OWL site, to send local data to the openhab server

Best Regards,
Fernando Gomes

1 Like

At this point, I would like to thanks @fapg for his kind help in spending time to adjust the tcp/udp binding / REGEX and finally, make the owl produce data.

What I did:

  1. I logged in to owl-intuition web UI, under "Settings>Advance I added “push data” to my local openhab server through 22601 port

  2. I installed TCP/UDP binding through Paper UI

  3. I went into Services>tcp.cfg and only added udp:port=22601

  4. Then I add the strings in my .items file like above

    //Power Consumption
    Group gOwl “Power Consumption”

    String owlTimeStamp “TimeStamp [%s]” (gOwl) { udp="<[192.168.1.147::'REGEX((.))’]" }
    String owlBattery “Battery [%s]” (gOwl) { udp="<[192.168.1.147::'REGEX(.<battery level=’(.)’/>.)’]" }
    String owlPhase1 “Phase 1 [%s w]” (gOwl) { udp="<[192.168.1.147::'REGEX(.<chan id=‘0’><curr units=‘w’>([\d.]).)’]" }
    String owlPhase1Tot “Phase 1 Total [%s wh]” (gOwl) { udp="<[192.168.1.147::'REGEX(.<chan id=‘0’>.<day units=‘wh’>(.).)’]" }
    String owlPhase2 “Phase 2 [%s w]” (gOwl) { udp="<[192.168.1.147:
    :‘REGEX(.<chan id=‘1’><curr units=‘w’>([\d.]).)’]" }
    String owlPhase2Tot “Phase 2 Total [%s wh]” (gOwl) { udp="<[192.168.1.147:
    :‘REGEX(.<chan id=‘1’>.<day units=‘wh’>(.).)’]" }
    String owlPhase3 “Phase 3 [%s w]” (gOwl) { udp="<[192.168.1.147::'REGEX(.<chan id=‘2’><curr units=‘w’>([\d.]).)’]" }
    String owlPhase3Tot “Phase 3 Total [%s wh]” (gOwl) { udp="<[192.168.1.147::'REGEX(.<chan id=‘2’>.<day units=‘wh’>(.).*)’]" }

After that, I add the items on my sitemap file like above

Frame label="Electricity"
	{
		Group item=gOwl
		{
			Default item=owlTimeStamp
			Default item=owlBattery
			Default item=owlPhase1
			Default item=owlPhase2
			Default item=owlPhase3
			Default item=owlPhase1Tot
			Default item=owlPhase2Tot
			Default item=owlPhase3Tot
		}
	}

Finaly everything worked perfect!

Thank you once again @fapg for saving so much time for me, looking for a solution.

For people that want to upgrade to openhab3, can use this daemon that I just made:

Best Regards,

Well done Fernando!

I was doing it in python too. This was my solution:

import socket
import struct
import json
from bs4 import BeautifulSoup
from openhab import OpenHAB
from datetime import datetime
import time

# OWL definitions
OWL_PORT = 22600
OWL_GROUP = "224.192.32.19"

# OpenHAB definitions
BASE_URL = 'http://localhost:8080/rest'

# OWL connect
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((OWL_GROUP, OWL_PORT))
mreq = struct.pack("=4sl", socket.inet_aton(OWL_GROUP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

# OpenHAB connect
openhab = OpenHAB(BASE_URL)
items = openhab.fetch_all_items()
oh_owl_timestamp = items.get('owl_timestamp')
oh_owl_ph1_act = items.get('owl_ph1_act')
oh_owl_ph1_tot = items.get('owl_ph1_tot')
oh_owl_ph2_act = items.get('owl_ph2_act')
oh_owl_ph2_tot = items.get('owl_ph2_tot')
oh_owl_ph3_act = items.get('owl_ph3_act')
oh_owl_ph3_tot = items.get('owl_ph3_tot')
oh_owl_ph_act = items.get('owl_ph_act')
oh_owl_ph_tot = items.get('owl_ph_tot')

while True:
    # Collect the XML multicast message
    xml, addr = sock.recvfrom(1024)
    # Parse XML soup
    soup = BeautifulSoup(xml,'lxml')
    try:
      # Only process those messages we are interested in
      if soup.electricity.name is not None: #soup.electricity.name == 'electricity':
         ts = soup.electricity.timestamp.get_text()
         dt = datetime.fromtimestamp(int(ts))
         ph1_act = soup.find('chan',{"id": 0}).find('curr').get_text()
         ph1_tot = soup.find('chan',{"id": 0}).find('day').get_text()
         ph2_act = soup.find('chan',{"id": 1}).find('curr').get_text()
         ph2_tot = soup.find('chan',{"id": 1}).find('day').get_text()
         ph3_act = soup.find('chan',{"id": 2}).find('curr').get_text()
         ph3_tot = soup.find('chan',{"id": 2}).find('day').get_text()
         print(ts, dt, ph1_act, ph1_tot, ph2_act, ph2_tot, ph3_act, ph3_tot)
         # print(xml)
         oh_owl_timestamp.update(dt)
         oh_owl_ph1_act.update(float(ph1_act))
         oh_owl_ph1_tot.update(float(ph1_tot)/1000)
         oh_owl_ph2_act.update(float(ph2_act))
         oh_owl_ph2_tot.update(float(ph2_tot)/1000)
         oh_owl_ph3_act.update(float(ph3_act))
         oh_owl_ph3_tot.update(float(ph3_tot)/1000)
         oh_owl_ph_act.update((float(ph1_act)+float(ph2_act)+float(ph3_act))/1000)
         oh_owl_ph_tot.update((float(ph1_tot)+float(ph2_tot)+float(ph3_tot))/1000)
    except:
      print("Something went wrong!")
      time.sleep(30)

BR, Harald