5500SHAC - Lua to enumerate all group addresses

Discussion in 'C-Bus Automation Controllers' started by Narkov, Jan 1, 2020.

  1. Narkov

    redstorm

    Joined:
    Aug 16, 2021
    Messages:
    18
    Likes Received:
    2
    From GitHub, just did a factory reset and reloaded the CGL file, setup the 3 scripts and tagged the GA with All and still not publishing or subscribing if i manually publish an ON command to a topic GA

    upload_2022-3-27_19-10-5.png

    Nothing in the SHAC error log
     
    redstorm, Mar 27, 2022
    #41
  2. Narkov

    Pie Boy

    Joined:
    Nov 21, 2012
    Messages:
    248
    Likes Received:
    31
    Location:
    New Zealand
    A couple of ideas,

    under system settings network config, do you have dns settings configured?

    also can you try MQTT explorer or similar to see what’s happening at a MQTT level?
     
    Pie Boy, Mar 27, 2022
    #42
  3. Narkov

    redstorm

    Joined:
    Aug 16, 2021
    Messages:
    18
    Likes Received:
    2
    Looking at the objects in the SHAC is this right?
    upload_2022-3-27_19-18-39.png

    Group address 0/56/0?
    Should it be 254/56/0? the network address is set to 254
     
    redstorm, Mar 27, 2022
    #43
  4. Narkov

    redstorm

    Joined:
    Aug 16, 2021
    Messages:
    18
    Likes Received:
    2
    yes DNS is set on the interface, both the local and the remote network routers as DNS resolvers.

    Ping and Trace route from the 192.168.2.4 (SHAC) to the MQTT Broker 192.168.1.12 work both ways.
    No firewall involved.

    In saying that however these two networks are connected via a Wireguard VPN tunnel with routes to each other over the tunnel. both the SHAC logs are saying connected to MQTT and the MQTT logs are seeing the SHAC connection from 192.168.2.4 (the SHAC's DHCP reserved address)

    I'm subscribing to # on MQTT which will subscribe to all topics
     
    redstorm, Mar 27, 2022
    #44
  5. Narkov

    Pie Boy

    Joined:
    Nov 21, 2012
    Messages:
    248
    Likes Received:
    31
    Location:
    New Zealand
    Is the broker in a different location to you (physically) .

    is it positive to put the broker and the shac on the same subnet for testing purposes?
     
    Pie Boy, Mar 27, 2022
    #45
  6. Narkov

    redstorm

    Joined:
    Aug 16, 2021
    Messages:
    18
    Likes Received:
    2
    Looks like its the MQTT end is the issue. Using tcpdump if i press my light switch i get traffic at MQTT from the SHAC (so looks like the scripts are working) but its not getting published. ill take a look in wireshark and see whats going on...
     
    redstorm, Mar 27, 2022
    #46
  7. Narkov

    ZacOlly

    Joined:
    Mar 16, 2019
    Messages:
    6
    Likes Received:
    3
    Hi @redstorm
    I would highly recommend trying an external MQTT broker. I had the same issues - all connected but not publishing.
    I just uses a free online broker to try and it worked seamlessly. Then I setup a separate one once I knew that was the issue.
    Just be aware if you do use a online broker you may get some random entities in HA.
     
    ZacOlly, Mar 27, 2022
    #47
  8. Narkov

    redstorm

    Joined:
    Aug 16, 2021
    Messages:
    18
    Likes Received:
    2
    The SHAC scripts are golden. working as expected.
    The packet capture I can see the messages for the light switch being sent to mqtt from the SHAC but its the HA mosquito broker thats not playing ball. @ZacOlly, ill take your point and try a public MQTT broker first to verify and them make a plan from their to migrate to a different docker image for MQTT.

    upload_2022-3-27_20-25-36.png

    I can as its just down the road, however from what ive seen in the packet capture i dont think it will make a difference.

    Testing to an online MQTT broker works so looks like its the HA Mosquito thats the issue as others have discovered.
    upload_2022-3-27_20-44-26.png

    Ill update once i have a working broker locally.

    Thanks all for you quick response
     
    redstorm, Mar 27, 2022
    #48
  9. Narkov

    redstorm

    Joined:
    Aug 16, 2021
    Messages:
    18
    Likes Received:
    2
    Spun up a local mqtt eclipse docker image and works fine.
     
    redstorm, Mar 28, 2022
    #49
  10. Narkov

    redstorm

    Joined:
    Aug 16, 2021
    Messages:
    18
    Likes Received:
    2
    Found the issue and have made a change to the scripts to fix it.

    The root cause is that the LUA script if you don't specify a client id it randomly generates one and puts a / in the name mosq/randomstring

    New client connected from 192.168.2.4 as mosq/bv]4EmKK1Qx9@^82^R (p1, c1, k60, u'hauser').

    https://github.com/home-assistant/addons/issues/2020

    This post talks about the client id with the / in them being filtered out

    I made this change to both the resident scripts.

    clientid = 'SHAC2MQTT'
    -- create new mqtt client
    client = mqtt.new(clientid)

    Now when it connects it has a client id with out a '/' and publishing now works to the default mqtt addon in home assistant.

    New client connected from 192.168.2.4 as SHAC2MQTT (p1, c1, k60, u'hauser').
    New client connected from 192.168.2.4 as MQTT2SHAC (p1, c1, k60, u'hauser').

    Verified using a debug node in NodeRed
    upload_2022-3-28_20-29-45.png
    Solved by setting a client id in the LUA scripts.
     
    redstorm, Mar 28, 2022
    #50
    ZacOlly and Damaxx like this.
  11. Narkov

    ZacOlly

    Joined:
    Mar 16, 2019
    Messages:
    6
    Likes Received:
    3
    Nice work @redstorm
    I've just tried with the HA add-on and it is working well.
    Monitored it all via mqtt explorer and it's seamless!
    Thanks for that!
     
    ZacOlly, Aug 31, 2022
    #51
  12. Narkov

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    232
    Likes Received:
    31
    Location:
    Melbourne
    @redstorm, I've done a lot of work with CBus and HA, implementing bi-directional sync along with discovery by HomeAssistant of CBus groups via MQTT. Lights, switches, sweep fans, blinds, buttons, selects, sensors, binary sensors and what I call 'bsensors'. And a lot more, including incorporating a few Philips Hue devices at my joint with CBus, like bedside lights and electric blankets, controlled using CBus scenes alongside HA.

    My approach utilises a single MQTT connection from one resident script for both send and receive (using a simple and predicable client ID as you settled on), along with an event-based script for CBus level change detection. Plus adjunctive scripts if desired. Almost everything on the automation controller side relies on keywords added to groups to adjust HA discovery aspects like icon, preferred name, suggested area and more.

    This body of work is freely given to the community, so thought I'd share: https://github.com/autoSteve/acMqtt.

    There are countless hours invested, and its had some great peer review and input. I love it.
     
    ssaunders, Sep 23, 2022
    #52
  13. Narkov

    redstorm

    Joined:
    Aug 16, 2021
    Messages:
    18
    Likes Received:
    2
    @ssaunders, I can see a lot of work has gone into your resident script. I came here today to see if anyone hand implemented Units on the measurement application as the original script has it hard coded to 0 which means degree C
    I am publishing my powerwall charge status to a measurement group address and need to set the unit to % and was about to re write the script to allow the unit to be configured also.

    Knowing the powerwall charge status will be used to trigger loads like heated towel rails and AC/Heating when excess solar is being generated and the battery is charged above a level.

    I see in your code that unit is not specified in the function but further down in your code you are setting a unit variable. did you fully implement the ability to set the unit for the measurement application before i re invent the wheel so to speak.

    Thanks
    Red.
    --[[
    Publish measurement application objects to MQTT
    --]]
    function publishMeasurement(net, app, group, channel, value)
    if value == nil then logger('Warning: Nil CBus measurement value for '..net..'/'..app..'/'..group); do return end end
    local adjust = publishAdj[net..'/'..app..'/'..group..'/'..channel]
    if adjust then v = tonumber(string.format('%.'..adjust.dec..'f', value * adjust.scale)) else v = value end
    client:publish(mqttReadTopic..net..'/'..app..'/'..group..'_'..channel..'/state', v, mqttQoS, RETAIN)
    -- if logging then logger('Publishing measurement '..mqttReadTopic..net..'/'..app..'/'..group..'_'..channel..' to '..v) end
    end
     
    redstorm, Feb 1, 2023
    #53
  14. Narkov

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    232
    Likes Received:
    31
    Location:
    Melbourne
    I only use units in my script for User Parameter/Sensor, @redstorm. It allows the MQTT payload to display with the desired units in Home Assistant. This isn't so for measurement.

    For measurement application would it help if I got the configured units from GetCBusMeasurement to include in the MQTT payload?

    An alternative...

    I use an approach of tagging measurement app groups with 'M2U' to fire an event script. Example: "M2U, up=Pool Temperature, onlyif=0/56/Pool Pump, ", which instructs the NAC to send the measurement value to the User Parameter "Pool Temperature", but only if the pool pump is running.

    The User Parameter then includes a Unit tag, which is included in the MQTT payload. (Example: "MQTT, sensor, sa=Pool, pn=Pool Pool Temperature, unit= °C, dec=1, ")

    The positives are that measurement updates of the same value do not result in repeated MQTT messages, plus I can alter update behaviour based on the state of other group addresses.

    It's more convoluted, but would that work for you?

    If you rathered I tackle including the units for measurement then just ask. I'm free this evening. :)

    Here's M2U...

    Code:
    val = event.getvalue()
    
    prem = storage.get('mes'..event.dst, -99999)
    if prem ~= val then
      storage.set('mes'..event.dst, val)
     
      storage.set('mestag'..event.dst, nil) -- Clear mestag
     
      local onlyif
    
      local tocheck = nil
      local tags = grp.gettags(event.dst)
      local upnet = 0; local up = ''; local tag
      for _, tag in pairs(tags) do
        local parts = string.split(tag, '=')
        if parts[1] == 'up' then up = parts[2]; if #tags == 1 then break end
        elseif parts[1] == 'upnet' then upnet = tonumber(parts[2])
        elseif parts[1] == 'onlyif' then tocheck = parts[2]
        end
      end
      if up == '' then
        log('ERROR: "up" tag not specified for '..event.dst)
        do return end
      end
      mestag = {up=up, upnet=upnet, onlyif=tocheck}
    
      -- Get target decimal places and scale, if any (if none assume dec=3/scale=1). Then compare target value
      -- at required precision. This will avoid unnecessary additional messages being sent (reducing MQTT load)
      mestag.target = mestag.upnet..'/250/'..GetCBusGroupAddress(mestag.upnet, 250, mestag.up)
      tags = grp.gettags(mestag.target)
      local dec = 3; local scale = 1; gotDec = false; gotScale = false
      for _, tag in pairs(tags) do
        local parts = string.split(tag, '=')
        if parts[1] == 'dec' then dec = tonumber(parts[2]); gotDec = true; if gotDec and gotScale then break end
        elseif parts[1] == 'scale' then scale = tonumber(parts[2]); gotScale = true; if gotDec and gotScale then break end
        end
      end
      mestag.dec = dec
      mestag.scale = scale
        
      local comp = string.format('%.'..mestag.dec..'f', val * mestag.scale)
      local pre = storage.get('mestgt'..mestag.target, '')
      if pre ~= comp then
        if mestag.onlyif ~= nil then
          p = string.split(mestag.onlyif, '/')
          onlyif = GetCBusState(p[1],p[2],p[3])
        else
          onlyif = true
        end
        storage.set('mestgt'..mestag.target, comp)
        if onlyif then
          SetUserParam(mestag.upnet, mestag.up, val)
        end
      end
    end
     
    ssaunders, Feb 2, 2023
    #54
  15. Narkov

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    232
    Likes Received:
    31
    Location:
    Melbourne
    I got that wrong @redstorm. You're going from MQTT to the NAC I think.

    I think.

    If you set the units by doing a 'Set value' in the NAC does it persist when the value is updated?
     
    ssaunders, Feb 2, 2023
    #55
  16. Narkov

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    232
    Likes Received:
    31
    Location:
    Melbourne
    Or maybe you are actually going NAC to MQTT @redstorm. :confused:

    This will publish the units configured in the NAC to MQTT along with the value as a string. Replace publishMeasurement:

    Code:
    function publishMeasurement(net, app, group, channel, value)
      local units
      if value == nil then logger('Warning: Nil CBus measurement value for '..net..'/'..app..'/'..group); do return end end
      local adjust = publishAdj[net..'/'..app..'/'..group..'/'..channel]
      if adjust then v = tonumber(string.format('%.'..adjust.dec..'f', value * adjust.scale)) else v = value end
      _, units = GetCBusMeasurement(net, group, channel)
      if units == '$' then
        v = units..tostring(v)
      elseif units == '%' then
        v = v..units
      else
        v = v..' '..units
      end
      client:publish(mqttReadTopic..net..'/'..app..'/'..group..'_'..channel..'/state', v, mqttQoS, RETAIN)
      -- if logging then logger('Publishing measurement '..mqttReadTopic..net..'/'..app..'/'..group..'_'..channel..' to '..v) end
    end
     
    Last edited: Feb 2, 2023
    ssaunders, Feb 2, 2023
    #56
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.