This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Smappee inifinity Energy Monitoring to KNX
#1
Hello,

I'm looking for a way to integrate the energy monitoring system from Smappee (www.smappee.com) into my KNX home visualization.
The Smappee device sends its data to a MQTT Broker in a JSON format.
I have tried to modify the existing examples from the forum to get the data out of the MQTT broker.
But I get no where.
Is there anybody around here who can help with this or has done this integration.

Topic for subscription : servicelocation/uuid/config

Sample of the data (this sample has 26 live power values in it) :

{"totalPower":4421,"totalReactivePower":-1827,"totalExportEnergy":3067200,"totalImportEnergy":2775754800,"monitorStatus":0,"utcTimeStamp":1611127010000,"measuredFrequency":50012728,"channelPowers":[{"publishIndex":0,"formula":"$5500013892/0$","power":931,"exportEnergy":46800,"importEnergy":616680000,"phaseId":0,"current":51,"apparentPower":1214,"cosPhi":76},{"publishIndex":1,"formula":"$5500013892/1$","power":3113,"exportEnergy":615600,"importEnergy":545688000,"phaseId":1,"current":136,"apparentPower":3214,"cosPhi":96},{"publishIndex":2,"formula":"$5500013892/2$","power":377,"exportEnergy":2354400,"importEnergy":523616400,"phaseId":2,"current":20,"apparentPower":475,"cosPhi":79},{"publishIndex":3,"formula":"$5500013892/3$","power":15,"exportEnergy":0,"importEnergy":182869200,"phaseId":1,"current":2,"apparentPower":43,"cosPhi":33},{"publishIndex":4,"formula":"$5500013906/0$","power":0,"exportEnergy":43200,"importEnergy":23965200,"phaseId":0,"current":1,"apparentPower":14,"cosPhi":0},{"publishIndex":5,"formula":"$5500013906/1$","power":0,"exportEnergy":7200,"importEnergy":23475600,"phaseId":1,"current":1,"apparentPower":14,"cosPhi":0},{"publishIndex":6,"formula":"$5500013906/2$","power":0,"exportEnergy":0,"importEnergy":23691600,"phaseId":2,"current":1,"apparentPower":15,"cosPhi":0},{"publishIndex":7,"formula":"$5500013906/3$","power":91,"exportEnergy":0,"importEnergy":2113200,"phaseId":1,"current":6,"apparentPower":148,"cosPhi":61},{"publishIndex":11,"formula":"$5500024954/3$","power":281,"exportEnergy":0,"importEnergy":61390800,"phaseId":2,"current":14,"apparentPower":333,"cosPhi":84},{"publishIndex":12,"formula":"$5500024970/0$","power":28,"exportEnergy":0,"importEnergy":11750400,"phaseId":0,"current":3,"apparentPower":74,"cosPhi":37},{"publishIndex":13,"formula":"$5500024970/1$","power":2763,"exportEnergy":0,"importEnergy":153662400,"phaseId":1,"current":122,"apparentPower":2874,"cosPhi":96},{"publishIndex":14,"formula":"$5500024970/2$","power":88,"exportEnergy":0,"importEnergy":216208800,"phaseId":2,"current":6,"apparentPower":135,"cosPhi":65},{"publishIndex":15,"formula":"$5500024970/3$","power":80,"exportEnergy":0,"importEnergy":16171200,"phaseId":1,"current":5,"apparentPower":121,"cosPhi":65},{"publishIndex":16,"formula":"$5500024993/0$","power":0,"exportEnergy":0,"importEnergy":25848000,"phaseId":2,"current":0,"apparentPower":6,"cosPhi":5},{"publishIndex":17,"formula":"$5500024993/3$","power":51,"exportEnergy":0,"importEnergy":72860400,"phaseId":0,"current":2,"apparentPower":54,"cosPhi":93},{"publishIndex":18,"formula":"$5500024993/1$","power":530,"exportEnergy":0,"importEnergy":188485200,"phaseId":0,"current":28,"apparentPower":658,"cosPhi":80},{"publishIndex":19,"formula":"$5500024993/2$","power":140,"exportEnergy":0,"importEnergy":45691200,"phaseId":0,"current":9,"apparentPower":225,"cosPhi":62},{"publishIndex":20,"formula":"$5500024996/0$","power":13,"exportEnergy":0,"importEnergy":1807200,"phaseId":1,"current":2,"apparentPower":36,"cosPhi":35},{"publishIndex":21,"formula":"$5500024996/1$","power":74,"exportEnergy":0,"importEnergy":10317600,"phaseId":1,"current":4,"apparentPower":102,"cosPhi":72},{"publishIndex":22,"formula":"$5500024996/2$","power":6,"exportEnergy":0,"importEnergy":12020400,"phaseId":1,"current":2,"apparentPower":42,"cosPhi":13},{"publishIndex":23,"formula":"$5500024996/3$","power":35,"exportEnergy":0,"importEnergy":6868800,"phaseId":1,"current":3,"apparentPower":81,"cosPhi":42},{"publishIndex":24,"formula":"$5500024954/0$","power":11,"exportEnergy":0,"importEnergy":7365600,"phaseId":1,"current":1,"apparentPower":26,"cosPhi":41},{"publishIndex":25,"formula":"$5500024954/1$","power":24,"exportEnergy":0,"importEnergy":2001600,"phaseId":1,"current":2,"apparentPower":40,"cosPhi":60},{"publishIndex":26,"formula":"$5500024954/2$","power":4,"exportEnergy":0,"importEnergy":1206000,"phaseId":1,"current":0,"apparentPower":11,"cosPhi":30}],"voltages":[{"voltage":238,"phaseId":0},{"voltage":236,"phaseId":1},{"voltage":239,"phaseId":2}]}

Best regards,

Luc
Reply
#2
Have you managed to check if that data is being published to the broker? You can use this application to connect to the broker: http://mqtt-explorer.com/
From the docs it looks like the correct topic for data is servicelocation/<UUID>/realtime where <UUID> must be replaced with the unique ID. Or you can simply subscribe to servicelocation/+/realtime to receive data from all devices.
Reply
#3
(20.01.2021, 07:40)admin Wrote: Have you managed to check if that data is being published to the broker? You can use this application to connect to the broker: http://mqtt-explorer.com/
From the docs it looks like the correct topic for data is servicelocation/<UUID>/realtime where <UUID> must be replaced with the unique ID. Or you can simply subscribe to servicelocation/+/realtime to receive data from all devices.

Yes, I got the sample data from the broker with the app MQTTOOL.

The problem is that I don’t have a clue how to get the Jason data into the logicmachine from the broker.
Reply
#4
Resident script (sleep time = 0), log(msg) will output the received real-time data decoded from JSON.
Code:
if not broker then
  require('json')
  require('socket')

  broker, port = '127.0.0.1', 1883
  mclient = require('mosquitto').new()

  mclient.ON_CONNECT = function(res, rc, msg)
    log('mqtt connect status', res, rc, msg)

    if res then
      mclient:subscribe('servicelocation/+/realtime')
    else
      mclient:disconnect()
    end
  end

  mclient.ON_MESSAGE = function(mid, topic, payload)
    local msg = json.pdecode(payload)
    if type(msg) == 'table' then
      log(msg)
    end
  end

  mclient.ON_DISCONNECT = function(...)
    log('mqtt disconnect', ...)
    mclientfd = nil
  end

  mclient.ON_ERROR = function(...)
    log('callback error', ...)
  end

  function mconnect()
    local fd

    mclient:connect(broker, port)
    fd = mclient:socket()

    -- fd ref is valid
    if fd then
      mclientfd = fd
    end
  end

  mconnect()

  -- run timer every 5 seconds
  timer = require('timerfd').new(5)
  timerfd = socket.fdmaskset(timer:getfd(), 'r')
end

-- mqtt connected
if mclientfd then
  mclientfdset = socket.fdmaskset(mclientfd, mclient:want_write() and 'rw' or 'r')
  res, timerstat, mclientstat = socket.selectfds(10, timerfd, mclientfdset)
-- mqtt not connected
else
  res, timerstat = socket.selectfds(10, timerfd)
end

if res then
  if mclientfd and mclientstat then
    if socket.fdmaskread(mclientstat) then
      mclient:loop_read()
    end

    if socket.fdmaskwrite(mclientstat) then
      mclient:loop_write()
    end
  end

  if timerstat then
    -- clear armed timer
    timer:read()

    if mclientfd then
      mclient:loop_misc()
    else
      mconnect()
    end
  end
end
Reply
#5
(20.01.2021, 09:19)admin Wrote: Resident script (sleep time = 0), log(msg) will output the received real-time data decoded from JSON.
Code:
if not broker then
  require('json')
  require('socket')

  broker, port = '127.0.0.1', 1883
  mclient = require('mosquitto').new()

  mclient.ON_CONNECT = function(res, rc, msg)
    log('mqtt connect status', res, rc, msg)

    if res then
      mclient:subscribe('servicelocation/+/realtime')
    else
      mclient:disconnect()
    end
  end

  mclient.ON_MESSAGE = function(mid, topic, payload)
    local msg = json.pdecode(payload)
    if type(msg) == 'table' then
      log(msg)
    end
  end

  mclient.ON_DISCONNECT = function(...)
    log('mqtt disconnect', ...)
    mclientfd = nil
  end

  mclient.ON_ERROR = function(...)
    log('callback error', ...)
  end

  function mconnect()
    local fd

    mclient:connect(broker, port)
    fd = mclient:socket()

    -- fd ref is valid
    if fd then
      mclientfd = fd
    end
  end

  mconnect()

  -- run timer every 5 seconds
  timer = require('timerfd').new(5)
  timerfd = socket.fdmaskset(timer:getfd(), 'r')
end

-- mqtt connected
if mclientfd then
  mclientfdset = socket.fdmaskset(mclientfd, mclient:want_write() and 'rw' or 'r')
  res, timerstat, mclientstat = socket.selectfds(10, timerfd, mclientfdset)
-- mqtt not connected
else
  res, timerstat = socket.selectfds(10, timerfd)
end

if res then
  if mclientfd and mclientstat then
    if socket.fdmaskread(mclientstat) then
      mclient:loop_read()
    end

    if socket.fdmaskwrite(mclientstat) then
      mclient:loop_write()
    end
  end

  if timerstat then
    -- clear armed timer
    timer:read()

    if mclientfd then
      mclient:loop_misc()
    else
      mconnect()
    end
  end
end

Thanks this works perfect.
Reply
#6
I'm also trying to import the data from the Smappee to the logic machine. I have use the script above, and I think it is working. The output I get is:


Quote:LogicMachine Uitloggen StartpaginaTaal:

Versie: 20211215






CPU/IO: 0.00 0.05 0.07, Geheugen: 16% Schijf: 40%, KNX/TP: OK

* table:
["totalPower"]
  * number: 300
["totalExportEnergy"]
  * number: 500922000
["channelPowers"]
  * table:
  [1]
    * table:
    ["publishIndex"]
      * number: 0
    ["power"]
      * number: -1159
    ["formula"]
      * string: $5500047832/0$
    ["exportEnergy"]
      * number: 237502800
    ["current"]
      * number: 53
    ["apparentPower"]
      * number: 1267
    ["phaseId"]
      * number: 0
    ["cosPhi"]
      * number: -91
    ["importEnergy"]
      * number: 77511600
  [2]
    * table:
    ["publishIndex"]
      * number: 1
    ["power"]
      * number: 2730
    ["formula"]
      * string: $5500047832/1$
    ["exportEnergy"]
      * number: 6998400
    ["current"]
      * number: 227
    ["apparentPower"]
      * number: 5218
    ["phaseId"]
      * number: 1
    ["cosPhi"]
      * number: 52
    ["importEnergy"]
      * number: 590248800
  [3]
    * table:
    ["publishIndex"]
      * number: 2
    ["power"]
      * number: -1414
    ["formula"]
      * string: $5500047832/2$
    ["exportEnergy"]
      * number: 221806800
    ["current"]
      * number: 86
    ["apparentPower"]
      * number: 2097
    ["phaseId"]
      * number: 2
    ["cosPhi"]
      * number: -67
    ["importEnergy"]
      * number: 44172000
  [4]
    * table:
    ["publishIndex"]
      * number: 3
    ["power"]
      * number: 144
    ["formula"]
      * string: $5500047832/3$
    ["exportEnergy"]
      * number: 0
    ["current"]
      * number: 8
    ["apparentPower"]
      * number: 187
    ["phaseId"]
      * number: 1
    ["cosPhi"]
      * number: 76
    ["importEnergy"]
      * number: 72900000
  [5]
    * table:
    ["publishIndex"]
      * number: 4
    ["power"]
      * number: -1169
    ["formula"]
      * string: $5520006145/0$
    ["exportEnergy"]
      * number: 22492800
    ["current"]
      * number: 53
    ["apparentPower"]
      * number: 1282
    ["phaseId"]
      * number: 0
    ["cosPhi"]
      * number: -91
    ["importEnergy"]
      * number: 2746800
  [6]
    * table:
    ["publishIndex"]
      * number: 5
    ["power"]
      * number: 2726
    ["formula"]
      * string: $5520006145/1$
    ["exportEnergy"]
      * number: 6116400
    ["current"]
      * number: 228
    ["apparentPower"]
      * number: 5245
    ["phaseId"]
      * number: 1
    ["cosPhi"]
      * number: 51
    ["importEnergy"]
      * number: 18313200
  [7]
    * table:
    ["publishIndex"]
      * number: 6
    ["power"]
      * number: -1415
    ["formula"]
      * string: $5520006145/2$
    ["exportEnergy"]
      * number: 6004800
    ["current"]
      * number: 83
    ["apparentPower"]
      * number: 2035
    ["phaseId"]
      * number: 2
    ["cosPhi"]
      * number: -69
    ["importEnergy"]
      * number: 1047600
["totalReactivePower"]
  * number: -12977
["monitorStatus"]
  * number: 0
["utcTimeStamp"]
  * number: 1686054839000
["measuredFrequency"]
  * number: 49994600
["voltages"]
  * table:
  [1]
    * table:
    ["voltage"]
      * number: 240
    ["phaseId"]
      * number: 0
  [2]
    * table:
    ["voltage"]
      * number: 230
    ["phaseId"]
      * number: 1
  [3]
    * table:
    ["voltage"]
      * number: 245
    ["phaseId"]
      * number: 2
["totalImportEnergy"]
  * number: 806940000

But, how I nog put a value into an address, so I can use it?
Reply
#7
Put this instead of log(msg). Adjust group addresses and data fields as needed.
Code:
grp.checkupdate('32/1/0', msg.totalPower)
grp.checkupdate('32/1/1', msg.totalImportEnergy)

grp.checkupdate('32/1/2', msg.voltages[1].voltage)
grp.checkupdate('32/1/3', msg.voltages[2].voltage)
grp.checkupdate('32/1/4', msg.voltages[3].voltage)
Reply


Forum Jump: