Shelly Pro EM3 - not refreshing states via Binding, so i Made my own MQTT integration, lets test it out

Hi

I have a balcony solar, so i want to mesaure the export to the grid with openhab so i can utilize all the solar power by trigering smart plugs and sync power consumption with solar.

The issue i have is that connecting Shelly Pro EM3 to Openhab 4 isn’t working as expected.

I installed Shelly binding, added the EM3 Pro to the OH4 with typing in fixed IP of the device and it apears to work, but it stops worrkin in no time at all, like when i turn off EM3 Pro it wont reconect to OH every time, the refresh is not reliable.

I have latest shelly 1.5.1 firmware and openHAB 4.3.2 Release Build.
It appears that either the Shelly API gives trouble or the Binding is not optimized for EM3 Pro yet.
It appears that shelly em3 pro reports reliably to mqtt broker i set up, paralel for testing, but that HTTP API or that interface that the OH uses it seems troublesome, i am unsure on what end the issue persists.

I am thinking of integrating over MQTT, or Modbus if the issue will have to be resolved by binding creator, that seems to be bussy on github with many issues open.

I also tested Shelly Plus S plug that seems to be working fine, so it apears to be EM3 pro related issue mainly.

I also would like to have somewhat active status to see active power in real time whe it changes or at least every 5s, i understand it doesn’t need to send all but heartbeat and active power seem necesarry for our use case.

I have my own meter that only pulls current of 3 phases every 2s and it works for alerting of supply overload.

Thats my current setup with diy EMONLIB meter but it lacks advanced power analisys, that shelly will bring.

Any recomendations on reliable integration appriciated.

Cheers
Matej

Yeah I have the same device and it’s also a bit buggy. By mqtt it seems to work fine though. I upgraded to 1.5.1 after using a matter bridge and at least for now it’s handling it fine. I’ll report back. Maybe use the main Shelly thread for support though?

Hi
Thanks for sharing your experience.
May you share the mqtt.things and items snippet for EM3 pro if you have text based config, that would be really helpfull.
Mainly sharing all your JSON trasnsforms in items, that would help me get running with MQTT.

You said shelly thread, what is the official one is it this one Shelly Binding ?
Thanks a lot
Matej

Yes that thread!
All of my config is ui based though. And I simply used mqtt explorer on windows to see the payloads and topics and copied over to a generic mqtt. Ive since deleted that and moved to a matter bridge. Which stopped sending the payloads some time ago so now im back to the binding.

It’s a mess xD

Oh dear, i see, but shelly seems really good so it deserves to work great on OH.
I mainly streamlined all my setup to text config and MQTT.
Sometimes i wish there would be easier to debug bindings on my own but i have no clue of bindings.
I make my own rules and scripts and write python for more sophisticated stuff.

It feels tedious for manually doing all the fetching of JSON in UI.

I will look into it, and make text config by fetching JSON in items then, it has to woork reliably :grinning_face_with_big_eyes:

I overhauled the whole comms to MQTT and it is working great, no lagging what so ever.
It refershes all the metrics related to energy monitoring by events when the readings change and also every 15s. But not so for system status as it aparentlly tries to save on traffic, so i did a RPC trick described bellow.
And here is my new dasboard, with custom icons, i am so proud of :grinning_face_with_big_eyes:


I imagine there is interest, so i am sharing my integration.
influxdb.persist.txt (404 Bytes)
MQTT.things.txt (1.4 KB)
Shelly3EM.items.txt (8.4 KB)
Shelly3EM.rules.txt (1 KB)
Shelly3EM.sitemap.txt (5.4 KB)

I made it fully back compatible to OH 2.5 also, meanwhile it can be simplified on OH4 by setting items bound to mqtt chanels straight to Number values in items, as there should be on the fly conversion to Number. I did it via the rule by Group item detection for OH2.

My integration can serve as an alternative to native HTTP integration via Shelly Binding that is still a bit buggy.

Regarding Shelly 3 EM Pro, it seems it is a bit lazy about reporting system metrics, it takes few hours to refresh, so i enabled RPC in shellys Mqtt menu and used RPC command Shelly.GetStatus to retrive fresh metrics about wifi signal, uptime, temperature, and some more by request every 10s.

I have a question tho, why openhab does not have native MQTT JSON integration, i supose the majority of devices are or should be using this notation, so there is place and probablly demand for JSON auto discovery in openhab binding.

As an side idea, openhab could take advantage of mqtt explorer design and have ability to select new devices on the device tree, and topics that need to be imported could be connected via JSON.

One other thing is found out that JSON messages from Shelly or Tasmota… can vary so JSON detection fails with errors when tere is no entity that is being parsed, is there a way to catch that to have no unnecessary errors logged.

In my config only this error catching item, catches fire, and breaks when no error messages arrive from shelly as error entity in MQTT message disapears. :rofl:

String Shelly3EM_Napake_Meritev "Napake Meritev [%s ]" (Shelly3EM) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.errors"] }

1 Like

hehe i have made JS transform for that naughty error entity and i supose it should work fine.

shelly_errors.js

(function(json){
  var data = JSON.parse(json);
  return data.errors || "ni napak";
})(input)

and in Shelly3EM.items

String Shelly3EM_Napake_Meritev "Napake Meritev [%s]" (Shelly3EM) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JS", function="shelly_errors.js"] }

And it has a fallback state now :grinning_face_with_big_eyes:

It apears i am learning new way of integrating with JSON and JS today, as i just foud out that all the conversion i did and twice the items string and then number is not the proper way around limitation of JSON not parsing from String channel to Number in items, as transformation in MQTT.things can parse on the fly even in OH 2.5, i also have OH4 running newer stuff.

Here i wrote it for Shelly Plug in MQTT.things and it works beautifully, just bound to number channels that connect straight to items.

Thing mqtt:topic:shellyS1 "Shelly S1" {
  Channels:
    Type string : rpc_command   "RPC Command"   [ commandTopic="Vticnice/Shelly-S1/rpc" ]
    Type string : rpc_response  "RPC Response"  [ stateTopic="Vticnice/Shelly-S1/Shelly.GetStatus/rpc" ]

    Type switch : power "Switch Output" [stateTopic="Vticnice/Shelly-S1/status/switch:0", commandTopic="Vticnice/Shelly-S1/rpc",
                          transformationPattern="JSONPATH:$.output", transformationPatternOut="JS:shelly_switch.js", on="true", off="false" ] 

    Type number : apower          [ stateTopic="Vticnice/Shelly-S1/status/switch:0", transformationPattern="JSONPATH:$.apower" ]
    Type number : voltage         [ stateTopic="Vticnice/Shelly-S1/status/switch:0", transformationPattern="JSONPATH:$.voltage" ]
    Type number : current         [ stateTopic="Vticnice/Shelly-S1/status/switch:0", transformationPattern="JSONPATH:$.current" ]
    Type number : aenergy_total   [ stateTopic="Vticnice/Shelly-S1/status/switch:0", transformationPattern="JSONPATH:$.aenergy.total" ]
    Type number : temperature     [ stateTopic="Vticnice/Shelly-S1/status/switch:0", transformationPattern="JSONPATH:$.temperature.tC" ]

}

and the JS business for shelly_switch.js

(function(x) {
  return JSON.stringify({
    id: 1,
    src: "Vticnice/Shelly-S1/Switch.Set",
    method: "Switch.Set",
    params: {
      id: 0,
      on:  x == "true"
    }
  });
})(input)

/*
(function(x) {
  return "INPUT: " + typeof x + " = " + x;
})(input)
*/

How amazing is that, and its the cleanest setup i did so far :sweat_smile:

1 Like

I see you’re having fun, and I’m having fun reading through your accomplishments:D keep it up and keep sharing!

Yea, thanks for feedback Pedro_Liberal, :grinning_face_with_big_eyes: it feels great when we learn a more efficient way of doing something.

Thats my up to date integration V2, being cleaned up and more focused on OH4, i workd on OH4 for testing, while OH2 setup is left working in poduction, bsically it could work on OH2 also if transform would be done in things.

But i didn’t bother making so many channels like for smart plug in MQTT.things for ShellyEM3Pro in OH4 as it is capable of on the fly conversion in items, so it takes less space in things alongside other devices, so i moved as much to items as posible to have clean setup.

MQTT.things

Thing mqtt:topic:shelly3em "Shelly 3EM Pro" {
        Channels:
            Type string : em_status     "EM Status"     [ stateTopic="Shelly-3EM/status/em:0" ]
            Type string : emdata        "EM Data"       [ stateTopic="Shelly-3EM/status/emdata:0" ]
            //Type string : rpc           "RPC Events"    [ stateTopic="Shelly-3EM/events/rpc" ]
            Type string : online        "Online"        [ stateTopic="Shelly-3EM/online" ]
            Type string : rpc_command   "RPC Command"   [ commandTopic="Shelly-3EM/rpc" ]
            Type string : rpc_response  "RPC Response"  [ stateTopic="Shelly-3EM/OH_Shelly.GetStatus/rpc" ]
            Type string : errors          [ stateTopic="Shelly-3EM/status/em:0", transformationPattern="JS:shelly_errors.js" ]


            
    }

Shelly_EM3_V2.items

Group Shelly3EM
Group gShelly3EM_Number (Shelly3EM)
Group Shelly_Moc_3F (Shelly3EM)
Group Shelly_Tok_3F (Shelly3EM) 
Group Shelly_Napetost_3F (Shelly3EM)

// === FAZA A ===
Number Shelly3EM_A_Current "1.F tok [%s A]" (gShelly3EM_Number, Shelly_Tok_3F) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.a_current"] }
Number Shelly3EM_A_Voltage "1.F napetost [%s V]" (gShelly3EM_Number, Shelly_Napetost_3F) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.a_voltage"] }
Number Shelly3EM_A_ActPower "1.F moč (W) [%s W]" (gShelly3EM_Number, Shelly_Moc_3F) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.a_act_power"] }
Number Shelly3EM_A_PowerFactor "1.F faktor moči [cos φ ~ %s]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.a_pf"] }

// === FAZA B ===
Number Shelly3EM_B_Current "2.F tok [%s A]" (gShelly3EM_Number, Shelly_Tok_3F) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.b_current"] }
Number Shelly3EM_B_Voltage "2.F napetost [%s V]" (gShelly3EM_Number, Shelly_Napetost_3F) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.b_voltage"] }
Number Shelly3EM_B_ActPower "2.F moč (W) [%s W]" (gShelly3EM_Number, Shelly_Moc_3F) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.b_act_power"] }
Number Shelly3EM_B_PowerFactor "2.F faktor moči [cos φ ~ %s]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.b_pf"] }

// === FAZA C ===
Number Shelly3EM_C_Current "3.F tok [%s A]" (gShelly3EM_Number, Shelly_Tok_3F) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.c_current"] }
Number Shelly3EM_C_Voltage "3.F napetost [%s V]" (gShelly3EM_Number, Shelly_Napetost_3F) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.c_voltage"] }
Number Shelly3EM_C_ActPower "3.F moč (W) [%s W]" (gShelly3EM_Number, Shelly_Moc_3F) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.c_act_power"] }
Number Shelly3EM_C_PowerFactor "3.F faktor moči [cos φ ~ %s]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.c_pf"] }

// === SKUPNO ===
Number Shelly3EM_Total_Current "Skupni tok [%s A]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.total_current"] }
Number Shelly3EM_Total_ActPower "Skupna moč [%s W]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.total_act_power"] }
Number Shelly3EM_Total_AprtPower "Skupna navidezna moč [%s VA]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:em_status" [profile="transform:JSONPATH", function="$.total_aprt_power"] }

// === ENERGIJA ===
Number Shelly3EM_A_Total_Energy "1.F poraba [%s Wh]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:emdata" [profile="transform:JSONPATH", function="$.a_total_act_energy"] }
Number Shelly3EM_B_Total_Energy "2.F poraba [%s Wh]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:emdata" [profile="transform:JSONPATH", function="$.b_total_act_energy"] }
Number Shelly3EM_C_Total_Energy "3.F poraba [%s Wh]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:emdata" [profile="transform:JSONPATH", function="$.c_total_act_energy"] }
Number Shelly3EM_Total_Act_Energy "Skupna poraba [%s Wh]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:emdata" [profile="transform:JSONPATH", function="$.total_act"] }

// === ODDANA ENERGIJA ===
Number Shelly3EM_A_Total_RetEnergy "1.F povratna energija [%s Wh]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:emdata" [profile="transform:JSONPATH", function="$.a_total_act_ret_energy"] }
Number Shelly3EM_B_Total_RetEnergy "2.F povratna energija [%s Wh]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:emdata" [profile="transform:JSONPATH", function="$.b_total_act_ret_energy"] }
Number Shelly3EM_C_Total_RetEnergy "3.F povratna energija [%s Wh]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:emdata" [profile="transform:JSONPATH", function="$.c_total_act_ret_energy"] }
Number Shelly3EM_Total_Act_RetEnergy "Skupaj oddana energija [%s Wh]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:emdata" [profile="transform:JSONPATH", function="$.total_act_ret"] }

// === SISTEMSKE METRIKE ===

String Shelly3EM_Napake_Meritev "Napake Meritev [%s]" (Shelly3EM) { channel="mqtt:topic:shelly3em:errors"}  // JS tansform dela le v things [profile="transform:js", function="shelly_errors.js"] 
String Shelly3EM_Online1 (Shelly3EM) { channel="mqtt:topic:shelly3em:online" }
String Shelly3EM_Rpc_command (Shelly3EM) { channel="mqtt:topic:shelly3em:rpc_command" }


String Shelly3EM_RPC_WiFi_IP "WiFi IP [%s]" (Shelly3EM) { channel="mqtt:topic:shelly3em:rpc_response" [profile="transform:JSONPATH", function="$.result.wifi.sta_ip"] }
String Shelly3EM_RPC_WiFi_Status "WiFi stanje [%s]" (Shelly3EM) { channel="mqtt:topic:shelly3em:rpc_response" [profile="transform:JSONPATH", function="$.result.wifi.status"] }
Number Shelly3EM_WiFi_RSSI "WiFi signal [%s dBm]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:rpc_response" [profile="transform:JSONPATH", function="$.result.wifi.rssi"] }

String Shelly3EM_RPC_Sys_Time "Ura [%s]" (Shelly3EM) { channel="mqtt:topic:shelly3em:rpc_response" [profile="transform:JSONPATH", function="$.result.sys.time"] }
Number Shelly3EM_Sys_Uptime "Uptime [%s s]" (gShelly3EM_Number) { channel="mqtt:topic:shelly3em:rpc_response" [profile="transform:JSONPATH", function="$.result.sys.uptime"] }
String Shelly3EM_RPC_Cloud_Connected "Cloud povezan [%s]" (Shelly3EM) { channel="mqtt:topic:shelly3em:rpc_response" [profile="transform:JSONPATH", function="$.result.cloud.connected"] }
Number Shelly3EM_Temp_C "Temperatura [%s °C]" (gShelly3EM_Number) {channel="mqtt:topic:shelly3em:rpc_response" [profile="transform:JSONPATH", function="$.result.temperature:0.tC"] }

Shelly_EM3_V2.rules

rule "Poizvedba Shelly Status"
when
    Time cron "0/10 * * * * ?"
then
    Shelly3EM_Rpc_command.sendCommand('{ "id": 2, "src": "Shelly-3EM/OH_Shelly.GetStatus", "method": "Shelly.GetStatus" }')

    //ShellyPlug_S1_Command.sendCommand('{ "id": 2, "src": "Vticnice/Shelly-S1/Shelly.GetStatus", "method": "Shelly.GetStatus" }')
  
end

Shelly sitemap section

Text item=Shelly3EM_C_ActPower label="Shelly - Meritve Energije[(3.F) .. %s W]" icon="shelly_3em_2"
        {
          Frame
          {
            Text item=Shelly3EM_RPC_Sys_Time icon="time" label="Čas Meritve"
            Text item=Shelly3EM_Online1 icon="link" label="Online"
            
          }
          Frame label="Meritve Toka"
          {
          Default item=Shelly3EM_A_Current label="1. Tok" icon="amps3_l1" 
          Default item=Shelly3EM_B_Current label="2. Tok"  icon="amps2_l2"
          Default item=Shelly3EM_C_Current label="3. Tok"  icon="amps2_l3" 
          }
            Frame label="Moč"
          {
          Default item=Shelly3EM_A_ActPower label="1. Aktivna Moč" icon="watts2_l1"
          Default item=Shelly3EM_B_ActPower label="2. Aktivna Moč"  icon="watts2_l2"
          Default item=Shelly3EM_C_ActPower label="3. Aktivna Moč"  icon="watts2_l3"
          }
        
          
          Frame label="Skupaj 3F"
          {
            Default item=Shelly3EM_Total_Current label="Skupni Tok" icon="amps2_ln" 
            Default item=Shelly3EM_Total_ActPower label="Skupna Moč" icon="watts2_ln"
            
            Default item=Shelly3EM_Total_Act_Energy label="Porabljena Energija" icon="energy_use"
            Default item=Shelly3EM_Total_Act_RetEnergy label="Oddana Energija" icon="energy_sun_1"
                  
          
          Text label="Energija in Napetost" icon="energy_detail" labelcolor=["green"]
          {
          Frame label="Energija"
          { 
          Default item=Shelly3EM_A_Total_Energy label="1. Energija" icon="energy_l1"
          Default item=Shelly3EM_B_Total_Energy label="2. Energija" icon="energy_l2"
        
          Default item=Shelly3EM_C_Total_Energy label="3. Energija" icon="energy_l3"
          Default item=Shelly3EM_C_Total_RetEnergy label="3. Povratna Energija" icon="energy_l3sun"
            
          }
          Frame label="Napetost in PF"{
            Default item=Shelly3EM_A_Voltage label="1. Napetost" icon="volts_1_2" 
            Default item=Shelly3EM_B_Voltage label="2. Napetost" icon="volts_2_2"
            Default item=Shelly3EM_C_Voltage label="3. Napetost" icon="volts_3_2" 
          }
          Frame{
            Default item=Shelly3EM_Total_AprtPower label="Navidezna Moč" icon="voltamps2"

            Default item=Shelly3EM_A_PowerFactor label="1. Faktor Moči" icon="cosfi_1" 
            Default item=Shelly3EM_B_PowerFactor label="2. Faktor Moči" icon="cosfi_2" 
            Default item=Shelly3EM_C_PowerFactor label="3. Faktor Moči" icon="cosfi_3" 
            }
          }
          
          }
          Frame label="Grafi"
          {
            Switch item=GrafCas_Meritve label="Časovni Interval" mappings=[h="h",4h="4h",12h="12h",D="D", W="W"]
                  
                  Chart item=Shelly_Moc_3F refresh=10000 period=h legend=true visibility=[GrafCas_Meritve=="h"] 
                  Chart item=Shelly_Moc_3F refresh=10000 period=4h legend=true visibility=[GrafCas_Meritve=="4h"] 
                  Chart item=Shelly_Moc_3F refresh=10000 period=12h legend=true visibility=[GrafCas_Meritve=="12h"] 
                  Chart item=Shelly_Moc_3F refresh=10000 period=D legend=true visibility=[GrafCas_Meritve=="D"] 
                  Chart item=Shelly_Moc_3F refresh=10000 period=W legend=true visibility=[GrafCas_Meritve=="W"] 

                  Chart item=Shelly3EM_C_ActPower refresh=10000 period=h legend=true visibility=[GrafCas_Meritve=="h"] 
                  Chart item=Shelly3EM_C_ActPower refresh=10000 period=4h legend=true visibility=[GrafCas_Meritve=="4h"] 
                  Chart item=Shelly3EM_C_ActPower refresh=10000 period=12h legend=true visibility=[GrafCas_Meritve=="12h"] 
                  Chart item=Shelly3EM_C_ActPower refresh=10000 period=D legend=true visibility=[GrafCas_Meritve=="D"] 
                  Chart item=Shelly3EM_C_ActPower refresh=10000 period=W legend=true visibility=[GrafCas_Meritve=="W"] 


              Text label="Več Grafov" icon="line"
            {
              Switch item=GrafCas_Meritve label="Časovni Interval" mappings=[h="h",4h="4h",12h="12h",D="D", W="W"]
                            

                  Chart item=Shelly_Tok_3F refresh=10000 period=h legend=true visibility=[GrafCas_Meritve=="h"] 
                  Chart item=Shelly_Tok_3F refresh=10000 period=4h legend=true visibility=[GrafCas_Meritve=="4h"] 
                  Chart item=Shelly_Tok_3F refresh=10000 period=12h legend=true visibility=[GrafCas_Meritve=="12h"] 
                  Chart item=Shelly_Tok_3F refresh=10000 period=D legend=true visibility=[GrafCas_Meritve=="D"] 
                  Chart item=Shelly_Tok_3F refresh=10000 period=W legend=true visibility=[GrafCas_Meritve=="W"] 

                  Chart item=Shelly_Napetost_3F refresh=10000 period=h legend=true visibility=[GrafCas_Meritve=="h"] 
                  Chart item=Shelly_Napetost_3F refresh=10000 period=4h legend=true visibility=[GrafCas_Meritve=="4h"] 
                  Chart item=Shelly_Napetost_3F refresh=10000 period=12h legend=true visibility=[GrafCas_Meritve=="12h"] 
                  Chart item=Shelly_Napetost_3F refresh=10000 period=D legend=true visibility=[GrafCas_Meritve=="D"] 
                  Chart item=Shelly_Napetost_3F refresh=10000 period=W legend=true visibility=[GrafCas_Meritve=="W"] 

            }

          }
          Frame label="Sistem"
          {
            Text item=Shelly3EM_Sys_Uptime icon="time"
            
            Text item=Shelly3EM_WiFi_RSSI label="Signal" icon="wifi"
            {
              Default item=Shelly3EM_RPC_WiFi_IP label="WiFi IP" icon="link"
              Default item=Shelly3EM_RPC_WiFi_Status icon="wifi"
              Default item=Shelly3EM_RPC_Cloud_Connected icon="online"
            }
            Default item=Shelly3EM_Temp_C label="Temperatura" icon="therm"
            Text item=Shelly3EM_Napake_Meritev icon="error"
          }
        }

the JS transform for shelly_errors.js i uploaded in previous post, is left the same.

So posibly there could be made an integration into the Shelly binding to support MQTT comms via my code, but that’s not in my capabilities yet, as i run all text based config.

So i weclome new users, to test out my integration and tell me about the experience, customize it and post it back :grinning_face_with_big_eyes:.