Page 1 of 2

Electricity Current/Ampere 3 Phase IPX800V3 + X400CT

Posted: Friday 27 August 2021 22:19
by laco
current-clamps-for-x400-ct.jpg
current-clamps-for-x400-ct.jpg (7.72 KiB) Viewed 2314 times
x400ct-addon-for-ipx800.jpg
x400ct-addon-for-ipx800.jpg (8.1 KiB) Viewed 2314 times
web-relay-board-control-ipx800-v3.jpg
web-relay-board-control-ipx800-v3.jpg (14.02 KiB) Viewed 2314 times

I would need to convert this LUA script to DzVents.
Can anyone help me?


Code: Select all

-- Odber 3 fázy

--time=os.date("*t")

IDX=44 --virtual CM113, Electrisave
IDX_D=40 --darling

json = (loadfile "/volume1/docker/domoticz/config/scripts/lua/JSON.lua")()  -- For Synology Linux
 
local config=assert(io.popen('/usr/bin/curl "http://login:[email protected]/api/xdevices.json?cmd=30"'))  

local blocjson = config:read('*all')
 config:close()
 -- print (blocjson)
 local jsonValeur = json:decode(blocjson)

commandArray = {}

-- if time.min%2==0 then --[2min  test]--

faza1=(tonumber(jsonValeur.AN6)/310) --faza1 on IPX800V3
faza2=(tonumber(jsonValeur.AN7)/310) --faza2 on IPX800V3
faza3=(tonumber(jsonValeur.AN8)/310) --faza3 on IPX800V3
darling=(tonumber(jsonValeur.AN5)/310) --darling

print ('faza1 : ' .. faza1) --prints a value.
print ('faza2 : ' .. faza2) --prints a value.
print ('faza3 : ' .. faza3) --prints a value.
print ('darling : ' .. darling) --prints a value.

commandArray[1]={['UpdateDevice'] = IDX .."|0|"..faza1..";"..faza2..";"..faza3..";"}
commandArray[2]={['UpdateDevice'] = IDX_D .."|0|"..darling..";"}


--end

return commandArray

Re: Electricity Current/Ampere 3 Phase

Posted: Sunday 29 August 2021 13:10
by waltervl
Could be based on something like this
https://domoticz.com/forum/viewtopic.ph ... 44#p237144

You can reuse your own json parsing logic.

Re: Electricity Current/Ampere 3 Phase

Posted: Monday 30 August 2021 9:04
by laco
Use this command to read data from my IPX800 V3, X400-CT:

http://192.168.1.120/api/xdevices.json?cmd=30

Code: Select all

{"product":"IPX800_V3","AN1":766,"AN2":62,"AN3":190,"AN4":65,"AN5":0,"AN6":823,"AN7":1269,"AN8":1548,"AN9":0,"AN10":0,"AN11":0,"AN12":0,"AN13":0,"AN14":0,"AN15":0,"AN16":0}
I have an analog phase sampling sensor in Amperes there.
AN6 = PHASE1
AN7 = PHASE2
AN8 = PHASE3

I need to write data to the virtual sensor IDX:44 CM113, Electrisave

Thanks for help

Re: Electricity Current/Ampere 3 Phase

Posted: Monday 30 August 2021 9:11
by waltervl
dzVents is based on Lua so some things be the same.
Take the script I referred to and copy the json parsing logic into it.
You need .updateCurrent(current1, current2, current3) to update your 3Phase Current device (idx 44)

What kind of device is the darling? Check the update code for that in https://www.domoticz.com/wiki/DzVents:_ ... _scripting

Re: Electricity Current/Ampere 3 Phase

Posted: Thursday 02 September 2021 15:28
by laco
I can't do it. :-(

Re: Electricity Current/Ampere 3 Phase

Posted: Thursday 02 September 2021 15:47
by waltervl
What do you have now on code and what is the error?

Re: Electricity Current/Ampere 3 Phase

Posted: Thursday 02 September 2021 17:41
by laco
The LUA script above gives me an error:

Code: Select all

2021-09-02 17:35:00.770 Error: EventSystem: in Script #11 Odber 3 fázy: [string "-- Odber 3 fázy ..."]:8: attempt to call a nil value
I have Domoticz running in DOCKER https://hub.docker.com/r/domoticz/domoticz

Re: Electricity Current/Ampere 3 Phase

Posted: Thursday 02 September 2021 23:46
by waltervl
It could be something like this.
Not tested!!!

Code: Select all

local scriptVar = '3PhaseCurrent'

return 
{
    on = 
    {
        timer = 
        {
            'every 5 minutes',
        },

        httpResponses = 
        {
            scriptVar
        },
    },

    logging =   
    {
        level = domoticz.LOG_DEBUG, -- set to LOG_ERROR when tested and OK
        marker = scriptVar,
    },

    execute = function(dz, item)

        if item.isTimer then
            dz.openURL({
                url = 'http://192.168.1.120/api/xdevices.json?cmd=30',
                callback = scriptVar,
            })
            return
        end
        if (item.isHTTPResponse) then
          if item.ok then
 		--- do the parsing logic here
 		local jsonValeur  = item.json
		faza1=(tonumber(jsonValeur.AN6)/310) --faza1 on IPX800V3
		faza2=(tonumber(jsonValeur.AN7)/310) --faza2 on IPX800V3
		faza3=(tonumber(jsonValeur.AN8)/310) --faza3 on IPX800V3
		darling=(tonumber(jsonValeur.AN5)/310) --darling
		domoticz.log('3 Phase values = ' .. faza1 .. ' , ' .. faza2 .. ' , ' .. faza3, domoticz.LOG_INFO)
 		-- update devices here
 		domoticz.devices(44).updateCurrent(faza1, faza2, faza3) -- update IDX:44 CM113, Electrisave
 		-- domoticz.devices(40).update????(darling)  -- update command depends on device type. See dzVents Wiki
          else
           dz.log('There was a problem handling the request', dz.LOG_ERROR)
           dz.log(item, dz.LOG_ERROR)
          end
       end
    end
}

Re: Electricity Current/Ampere 3 Phase

Posted: Sunday 05 September 2021 18:27
by laco
Prints an error:

Code: Select all

2021-09-05 18:26:00.688 Error: dzVents: Error: (3.1.8) 3PhaseCurrent: An error occurred when calling event handler Odber 3 fazy
2021-09-05 18:26:00.689 Error: dzVents: Error: (3.1.8) 3PhaseCurrent: ...rdata/scripts/dzVents/generated_scripts/Odber 3 fazy.lua:41: attempt to index a nil value (global 'domoticz')

Re: Electricity Current/Ampere 3 Phase

Posted: Tuesday 07 September 2021 9:44
by laco
I enter in a web browser:

http://192.168.1.120/api/xdevices.json?cmd=30

Print this text:

{"product":"IPX800_V3","AN1":805,"AN2":65,"AN3":202,"AN4":65,"AN5":0,"AN6":0,"AN7":14,"AN8":254,"AN9":0,"AN10":0,"AN11":0,"AN12":0,"AN13":0,"AN14":0,"AN15":0,"AN16":0}

Re: Electricity Current/Ampere 3 Phase

Posted: Tuesday 07 September 2021 10:46
by waltervl
As said the script was not tested. There were some inconsistencies in the dz/domoticz calls. I tried to fix them in the code below.

Code: Select all

local scriptVar = '3PhaseCurrent'

return 
{
    on = 
    {
        timer = 
        {
            'every 5 minutes',
        },

        httpResponses = 
        {
            scriptVar
        },
    },

    logging =   
    {
        level = domoticz.LOG_DEBUG, -- set to LOG_ERROR when tested and OK
        marker = scriptVar,
    },

    execute = function(domoticz, item)

        if item.isTimer then
            domoticz.openURL({
                url = 'http://192.168.1.120/api/xdevices.json?cmd=30',
                callback = scriptVar,
            })
            return
        end
        if (item.isHTTPResponse) then
          if item.ok then
			--- do the parsing logic here
			local jsonValeur  = item.json
			faza1=(tonumber(jsonValeur.AN6)/310) --faza1 on IPX800V3
			faza2=(tonumber(jsonValeur.AN7)/310) --faza2 on IPX800V3
			faza3=(tonumber(jsonValeur.AN8)/310) --faza3 on IPX800V3
			darling=(tonumber(jsonValeur.AN5)/310) --darling
			domoticz.log('3 Phase values = ' .. faza1 .. ' , ' .. faza2 .. ' , ' .. faza3, domoticz.LOG_INFO)
			-- update devices here
			domoticz.devices(44).updateCurrent(faza1, faza2, faza3) -- update IDX:44 CM113, Electrisave
			-- domoticz.devices(40).update????(darling)  -- update command depends on device type. See dzVents Wiki
          else
			domoticz.log('There was a problem handling the request', dz.LOG_ERROR)
			domoticz.log(item, dz.LOG_ERROR)
          end
       end
    end
}

Re: Electricity Current/Ampere 3 Phase

Posted: Wednesday 08 September 2021 8:26
by laco
It's working properly now.
Well thank you.
Is it possible to set it to write more often than 1 minute?

Re: Electricity Current/Ampere 3 Phase

Posted: Wednesday 08 September 2021 9:06
by rrozema
You still have some dz. in that code that needs to be replaced by domoticz.

Code: Select all

local scriptVar = '3PhaseCurrent'

return 
{
    on = 
    {
        timer = 
        {
            'every 5 minutes',
        },

        httpResponses = 
        {
            scriptVar
        },
    },

    logging =   
    {
        level = domoticz.LOG_DEBUG, -- set to LOG_ERROR when tested and OK
        marker = scriptVar,
    },

    execute = function(domoticz, item)

        if item.isTimer then
            domoticz.openURL({
                url = 'http://192.168.1.120/api/xdevices.json?cmd=30',
                callback = scriptVar,
            })
            return
        end
        if (item.isHTTPResponse) then
          if item.ok then
			--- do the parsing logic here
			local jsonValeur  = item.json
			faza1=(tonumber(jsonValeur.AN6)/310) --faza1 on IPX800V3
			faza2=(tonumber(jsonValeur.AN7)/310) --faza2 on IPX800V3
			faza3=(tonumber(jsonValeur.AN8)/310) --faza3 on IPX800V3
			darling=(tonumber(jsonValeur.AN5)/310) --darling
			domoticz.log('3 Phase values = ' .. faza1 .. ' , ' .. faza2 .. ' , ' .. faza3, domoticz.LOG_INFO)
			-- update devices here
			domoticz.devices(44).updateCurrent(faza1, faza2, faza3) -- update IDX:44 CM113, Electrisave
			-- domoticz.devices(40).update????(darling)  -- update command depends on device type. See dzVents Wiki
          else
			domoticz.log('There was a problem handling the request', domoticz.LOG_ERROR)
			domoticz.log(item, domoticz.LOG_ERROR)
          end
       end
    end
}
And no, dzvents timers can't be set faster than once per minute. I think you may be able to do it though using command option .afterSec()), but i haven't tested it so I really don't know if below code actually works. But if it does work, it will query your device and update your device values in domoticz every 15 seconds. I also added .checkFirst() to the update statement, to prevent the values to be updated every 15 seconds even if no new value was read. Again, this is untested: see for yourself if it works. And please do let us know the results :-)

Code: Select all

local scriptVar = '3PhaseCurrent'

return 
{
    on = 
    {
        timer = 
        {
            'every 1 minute',
        },

        httpResponses = 
        {
            scriptVar
        },
    },

    logging =   
    {
        level = domoticz.LOG_DEBUG, -- set to LOG_ERROR when tested and OK
        marker = scriptVar,
    },

    execute = function(domoticz, item)

        if item.isTimer then
            domoticz.openURL({
                url = 'http://192.168.1.120/api/xdevices.json?cmd=30',
                callback = scriptVar,
            })
            domoticz.openURL({
                url = 'http://192.168.1.120/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(15)
            domoticz.openURL({
                url = 'http://192.168.1.120/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(30)
            domoticz.openURL({
                url = 'http://192.168.1.120/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(45)
            return
        elseif (item.isHTTPResponse) then
          if item.ok then
			--- do the parsing logic here
			local jsonValeur  = item.json
			faza1=(tonumber(jsonValeur.AN6)/310) --faza1 on IPX800V3
			faza2=(tonumber(jsonValeur.AN7)/310) --faza2 on IPX800V3
			faza3=(tonumber(jsonValeur.AN8)/310) --faza3 on IPX800V3
			darling=(tonumber(jsonValeur.AN5)/310) --darling
			domoticz.log('3 Phase values = ' .. faza1 .. ' , ' .. faza2 .. ' , ' .. faza3, domoticz.LOG_INFO)
			-- update devices here
			domoticz.devices(44).updateCurrent(faza1, faza2, faza3).checkFirst() -- update IDX:44 CM113, Electrisave
			-- domoticz.devices(40).update????(darling)  -- update command depends on device type. See dzVents Wiki
          else
			domoticz.log('There was a problem handling the request', domoticz.LOG_ERROR)
			domoticz.log(item, domoticz.LOG_ERROR)
          end
       end
    end
}

However, dzvents may still not be the best solution for this, because this is actually an implementation of a hardware device. I think it should be possible to implement this using the http/https poller hardware. Using that method it is possible to trigger the refresh more often than once per minute, for example every 10 seconds is quite normal. An example of how this is done for another device can be found here (site is in Dutch, sorry) : https://www.connectix.nl/watermeter-uit ... -domoticz/

Re: Electricity Current/Ampere 3 Phase

Posted: Thursday 09 September 2021 17:29
by laco
It works properly, writes every 15 seconds.

But it still displays an error in the log.

Code: Select all

2021-09-09 17:23:00.835 Status: dzVents: Debug: - HTTPResponse: 3PhaseCurrent
2021-09-09 17:23:00.860 Status: dzVents: Info: Handling httpResponse-events for: "3PhaseCurrent"
2021-09-09 17:23:00.861 Status: dzVents: Info: 3PhaseCurrent: ------ Start internal script: Odber_phase_15s: HTTPResponse: "3PhaseCurrent"
2021-09-09 17:23:00.862 Status: dzVents: Info: 3PhaseCurrent: 3 Phase values = 0.0 , 0.045161290322581 , 0.75806451612903
2021-09-09 17:23:00.871 Status: dzVents: Debug: 3PhaseCurrent: Processing device-adapter for Fázy: 3-phase Ampere device adapter
2021-09-09 17:23:00.872 Status: dzVents: Info: 3PhaseCurrent: ------ Finished Odber_phase_15s
2021-09-09 17:23:00.872 Status: dzVents: !Info: 3PhaseCurrent: Debug: Writing module summary to /opt/domoticz/userdata/scripts/dzVents/module.log
2021-09-09 17:23:00.872 Error: dzVents: Error: (3.1.8) 3PhaseCurrent: An error occurred when calling event handler Odber_phase_15s
2021-09-09 17:23:00.872 Error: dzVents: Error: (3.1.8) 3PhaseCurrent: ...ta/scripts/dzVents/generated_scripts/Odber_phase_15s.lua:54: attempt to call a nil value (field 'checkFirst')

Re: Electricity Current/Ampere 3 Phase

Posted: Thursday 09 September 2021 20:49
by rrozema
That's the 2nd addition I did: checking if the value has actually changed. Please remove the .checkFirst() from that code and see if works better then.

It should have worked, but apparently something's wrong, so better leave it off for now.

Re: Electricity Current/Ampere 3 Phase IPX800V3 + X400CT

Posted: Friday 10 September 2021 9:01
by laco
Thank you very much.

Now it works perfectly.
I set every 5 seconds to write the value.

Here is my function code:

Code: Select all

local scriptVar = '3PhaseCurrent'

return 
{
    on = 
    {
        timer = 
        {
            'every 1 minutes',
        },

        httpResponses = 
        {
            scriptVar
        },
    },

    logging =   
    {
        level = domoticz.LOG_DEBUG, -- set to LOG_ERROR when tested and OK
        marker = scriptVar,
    },

    execute = function(domoticz, item)

        if item.isTimer then
            domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            })
            domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(5)
             domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(10)
             domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(15)
             domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(20)
             domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(25)
            domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(30)
             domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(35)
             domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(40)
            domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(45)
             domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(50)
             domoticz.openURL({
                url = 'http://login:[email protected]/api/xdevices.json?cmd=30',
                callback = scriptVar,
            }).afterSec(55)
            return
        elseif (item.isHTTPResponse) then
          if item.ok then
			--- do the parsing logic here
			local jsonValeur  = item.json
			phase1=(tonumber(jsonValeur.AN6)/310) --phase1 on IPX800V3
			phase2=(tonumber(jsonValeur.AN7)/310) --phase2 on IPX800V3
			phase3=(tonumber(jsonValeur.AN8)/310) --phase3 on IPX800V3
			darling=(tonumber(jsonValeur.AN5)/310) --darling
			domoticz.log('3 Phase values = ' .. phase1 .. ' , ' .. phase2 .. ' , ' .. phase3, domoticz.LOG_INFO)
			-- update devices here
			domoticz.devices(44).updateCurrent(phase1, phase2, phase3) -- update IDX:44 CM113, Electrisave
			domoticz.devices(40).updateCurrent(darling)  -- update command depends on device type. See dzVents Wiki
          else
			domoticz.log('There was a problem handling the request', domoticz.LOG_ERROR)
			domoticz.log(item, domoticz.LOG_ERROR)
          end
       end
    end
}
last-24-hours.jpeg
last-24-hours.jpeg (48.89 KiB) Viewed 2311 times

Re: Electricity Current/Ampere 3 Phase IPX800V3 + X400CT

Posted: Friday 10 September 2021 11:41
by rrozema
As I said, retrieving the values using dzVents is not the best idea. It works, but it may overload your system. Symptoms of an overloaded system can be: slow response of the domoticz UI site, long delays between clicking a button in Domoticz and the actual response of the device and vice versa, long delays between activating an actuator (f.e. a light switch) and the corresponding device in Domoticz showing the result, high cpu usage, high RAM usage, overheating, etc. And if you really go to far, you could even crash/freeze Domoticz. So I would suggest not to update as often as every 5 seconds. Plus, besides the potential performance issues, adding new values every 5 seconds makes your database grow very fast too.

You're better off implementing your interface using one of the "hardware" methods Domoticz provides. This can for example be the HTTP/HTTPS poller combined with a lua script, or a python hardware implementation. Those can achieve similar results, but they are meant to be run every so-many seconds, so they're probably better optimized for it. I can't give you much pointers how to exactly use those "hardware" methods, as I've myself not done this before either. I just want you to be aware that the way you're doing it now can potentially cause you other/future problems in your system.

Re: Electricity Current/Ampere 3 Phase IPX800V3 + X400CT

Posted: Friday 10 September 2021 12:33
by waltervl
I agree, especially for URL requests they can be high demanding on your system. dzVents luckily now supports asynchronous requests but setting it to 5 seconds is a little bit fast. Why do you need this? Looking at your graph there is no spike of 5 seconds. so 30 sec or 1 minute should be enough in monitoring your 3Phase usage. In the end, in the weekly/monthly/yearly overviews all the values of 1 day are recalculated and summarized to 1 daily value (containing min,max and average). So these 5 sec intervalls are only stored for max 7 days (depends on your Log settings in menu Setup-Settings)

Re: Electricity Current/Ampere 3 Phase IPX800V3 + X400CT

Posted: Friday 10 September 2021 13:08
by laco
My domoticz runs in DOCKER on SYNOLOGY NAS.
I'm testing it so far, but the CPU load and RAM consumption are very low.
The response is fast, there is no sign of slowing down.
It is important for me to know the immediate consumption in Wats.
2021-09-10 (1).png
2021-09-10 (1).png (32.32 KiB) Viewed 2295 times
2021-09-10.png
2021-09-10.png (6.71 KiB) Viewed 2295 times

Re: Electricity Current/Ampere 3 Phase IPX800V3 + X400CT

Posted: Sunday 07 November 2021 12:50
by laco
I have one more question.
Can I modify the script to write only positive data?

For example, if 0 is darling so that it does not write it to the database.

Is it possible to create a separate script for DARLING?