Page 1 of 2

customicon script

Posted: Wednesday 15 April 2020 20:58
by jarmoboy
Can someone help me to make script in LUA which changes icons?
device is general custom sensor with idx 118 and it can have value from 0 to 100.
I want to have for example: if value is > 20 and < 40 than set custom icon 115.
Is it even possible? Iam looking for it for ages but my knowledge of scripts is poor.
Thanks

Re: customicon script

Posted: Thursday 16 April 2020 15:20
by bewo
Hi jarmoboy,

yes that's possible and no big problem, i've done this often. Just give a few informations more please....

Should the custom sensor show percentage? And the icon? Battery load?
How is the device triggered? (At this trigger the icon should be triggered, too.)

See an example here:
devices.png
devices.png (38.55 KiB) Viewed 1789 times
Bildschirmfoto 2020-04-16 um 15.22.10.png
Bildschirmfoto 2020-04-16 um 15.22.10.png (18.58 KiB) Viewed 1789 times

Re: customicon script

Posted: Thursday 16 April 2020 19:15
by jarmoboy
Exactly, is percentage of battery from robot, data are evaluated from nodered and exactly this icons I have already in domoticz. So I need only example for one case and the other cases (percentage state) I can evaluate and edit myself. I need only the main code to change the icon.

Re: customicon script

Posted: Thursday 16 April 2020 20:01
by bewo
Ok... I use the icons for mixed things. One of this is a vacuum robot. See script details (if needed here): https://www.domoticz.com/forum/viewtopi ... 47#p232887

Here's the piece of code for set different icons:

Code: Select all

-- Batteriestatus (Symbol und Stand) aktualisieren:
        
        batterie_device = Roboter.Name..' Batteriestand'
        
        -- Passends Batterie-Icon festlegen:
        if Batterieprozent <= 20 then
            batteriesymbol = '102'
        elseif Batterieprozent > 20 and Batterieprozent <= 50 then
            batteriesymbol = '104'
        elseif Batterieprozent > 50 and Batterieprozent <= 90 then
            batteriesymbol = '101'
        elseif Batterieprozent > 90 then
            batteriesymbol = '103'
        end
        
        -- Batteriestand schreiben
        if Batterieprozent ~= tonumber(otherdevices_svalues[batterie_device]) then
            commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[batterie_device]..'|0|'..Batterieprozent}
            print('Staubsauger-Roboter: '..Roboter.Name..' -> Batteriestand auf '..Batterieprozent..'% aktualisiert.')
            os.execute('curl "http://localhost:8077/json.htm?type=setused&idx='..otherdevices_idx[batterie_device]..'&name='..Roboter.Name..'%20Batteriestand&description=&switchtype=0&customimage='..batteriesymbol..'&devoptions=1;%25&used=true"')
        end
If there's a question - just ask. :-)

Re: customicon script

Posted: Thursday 16 April 2020 20:29
by jarmoboy
Hi Bewo,
this topic iam examination whole month and piece of code you gave me I was trying to use yesterday. There is so many variables and things which I don't understand so I wasn't successful at all. BTW. This piece of code you gave me is depended on the other part of lua which work together with this script. After several issues(koalazak plugin made my domoticz crash once a day) I have decided I don't need to control the robot, I want only read the state so I dismissed the plugin and use only nodered to read from API. Honestly, I need something simple and more user friendly. Thank you

Re: customicon script

Posted: Thursday 16 April 2020 20:39
by bewo
Hi jarmoboy,

you don't have to use any plugin. :-) You've asked for an piece of code for self construct. There it is (was).

You need a kind of trigger to set the icon. So i thought the right moment is, when a new battery value is reported. There you could integrate the code piece.

But if you don't like to or it's not possible...:
It's even possible to trigger the script once a minute (time trigger), in worst case there's a false icon for an minute. :-)
Would that be ok for you? If yes i would write this few lines of code for you, no problem.

Re: customicon script

Posted: Thursday 16 April 2020 20:59
by jarmoboy
If you can.... It would be great

Re: customicon script

Posted: Thursday 16 April 2020 21:51
by bewo
If i don't forget something..... Here it is:

Generate a new Lua-Script, device triggered (So the icon should change immediately. :D )

Please change the variables - try out and report. ;-)

Code: Select all

-- Script to change the icon of a battery device depending it's level

-- Set your devices and variabels here:
Device = 'Example-Name'    -- Name of the Sensor-Device
Icon_Nr_RED = '123'     -- RED = empty
Icon_Nr_ORANGE = '123'  -- ORANGE = low
Icon_Nr_YELLOW = '123'  -- YELLOW = ok
Icon_Nr_GREEN = '123'   -- GREEN = full

-- Your Domoticz Port in URL (default: 8080)
Domoticz_Port = '8080'
-- Load the domoticz LUA library (Change the path only; default at raspberry is /home/pi/domoticz/scripts/lua/JSON.lua)
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() 


-- ###############################################################################################
-- Nothing to do after this line... :-)

commandArray = {}

-- Function we need:
function encodeURI(str)
	if (str) then
		str = string.gsub (str, "\n", "\r\n")
		str = string.gsub (str, "([^%w ])",
			function (c) return string.format ("%%%02X", string.byte(c)) end)
		str = string.gsub (str, " ", "+")
    end
	return str
end

--------------------------------------------------------------------------

BatteryLevel = tonumber(otherdevices_svalues[Device])

if devicechanged[Device] then
    
    -- Look for the icon which is used in the moment:
    json_collect = assert(io.popen('curl "http://localhost:'..Domoticz_Port..'/json.htm?type=devices&rid='..otherdevices_idx[Device]..'"'))
    json_collect_data = json_collect:read('*all')
    json_collect:close()

    Icon_Number = json:decode(json_collect_data).result[1]["CustomImage"]
    Icon = tostring(Icon_Number)

    -- Choose the correct icon
    if BatteryLevel <= 20 then
        battery_icon = Icon_Nr_RED
    elseif BatteryLevel > 20 and BatteryLevel <= 50 then
        battery_icon = Icon_Nr_ORANGE
    elseif BatteryLevel > 50 and BatteryLevel <= 80 then
        battery_icon = Icon_Nr_YELLOW
    elseif BatteryLevel > 80 and BatteryLevel <= 100 then
        battery_icon = Icon_Nr_GREEN
    end

    -- Update the icon if not the correct one is active:
    if battery_icon ~= Icon then
        
        os.execute('curl "http://localhost:'..Domoticz_Port..'/json.htm?type=setused&idx='..otherdevices_idx[Device]..'&name='..encodeURI(Device)..'&description=&switchtype=0&customimage='..battery_icon..'&devoptions=1;%25&used=true"')
        print('Icon of the device '..Device..' was updated.')
        
    end
end


return commandArray

Re: customicon script

Posted: Thursday 16 April 2020 22:36
by jarmoboy
2020-04-16 22:31:00.405 Error: EventSystem: in ikony roza: [string "-- Script to change the icon of a battery dev..."]:36: attempt to index a nil value (global 'devicechanged')
this line is causing problems:
if devicechanged[Device] then
This was a fail with time trigered LUA....my fault
When i changed it to device trigered it says: 2020-04-16 22:45:14.330 Error: EventSystem: in ikony roza: /home/pi/domoticz/scripts/lua/JSON.lua:808: HTML passed to JSON:decode(): <html><head><title>Unauthorized</title></head><body><h1>401 Unauthorized</h1></body></html>
my complete code is:

Code: Select all

-- Script to change the icon of a battery device depending it's level

-- Set your devices and variabels here:
Device = 'Roza baterka'    -- Name of the Sensor-Device
Icon_Nr_RED = '114'     -- RED = empty
Icon_Nr_ORANGE = '116'  -- ORANGE = low
Icon_Nr_YELLOW = '117'  -- YELLOW = ok
Icon_Nr_GREEN = '115'   -- GREEN = full

-- Your Domoticz Port in URL (default: 8080)
Domoticz_Port = '8084'
-- Load the domoticz LUA library (Change the path only; default at raspberry is /home/pi/domoticz/scripts/lua/JSON.lua)
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() 


-- ###############################################################################################
-- Nothing to do after this line... :-)

commandArray = {}

-- Function we need:
function encodeURI(str)
	if (str) then
		str = string.gsub (str, "\n", "\r\n")
		str = string.gsub (str, "([^%w ])",
			function (c) return string.format ("%%%02X", string.byte(c)) end)
		str = string.gsub (str, " ", "+")
    end
	return str
end

--------------------------------------------------------------------------

BatteryLevel = tonumber(otherdevices_svalues[Device])

if devicechanged[Device] then
    
    -- Look for the icon which is used in the moment:
    json_collect = assert(io.popen('curl "http://localhost:'..Domoticz_Port..'/json.htm?type=devices&rid='..otherdevices_idx[Device]..'"'))
    json_collect_data = json_collect:read('*all')
    json_collect:close()

    Icon_Number = json:decode(json_collect_data).result[1]["CustomImage"]
    Icon = tostring(Icon_Number)

    -- Choose the correct icon
    if BatteryLevel <= 20 then
        battery_icon = Icon_Nr_RED
    elseif BatteryLevel > 20 and BatteryLevel <= 50 then
        battery_icon = Icon_Nr_ORANGE
    elseif BatteryLevel > 50 and BatteryLevel <= 80 then
        battery_icon = Icon_Nr_YELLOW
    elseif BatteryLevel > 80 and BatteryLevel <= 100 then
        battery_icon = Icon_Nr_GREEN
    end

    -- Update the icon if not the correct one is active:
    if battery_icon ~= Icon then
        
        os.execute('curl "http://localhost:'..Domoticz_Port..'/json.htm?type=setused&idx='..otherdevices_idx[Device]..'&name='..encodeURI(Device)..'&description=&switchtype=0&customimage='..battery_icon..'&devoptions=1;%25&used=true"')
        print('Icon of the device '..Device..' was updated.')
        
    end
end


return commandArray

Re: customicon script

Posted: Thursday 16 April 2020 22:51
by bewo
Did you set up as device triggered?
Bildschirmfoto 2020-04-16 um 22.51.23.png
Bildschirmfoto 2020-04-16 um 22.51.23.png (4.45 KiB) Viewed 1750 times

Re: customicon script

Posted: Thursday 16 April 2020 22:54
by jarmoboy
Please read again I made edit. Thx

Re: customicon script

Posted: Thursday 16 April 2020 23:01
by bewo
A sorry my bad... I've didn't seen... :D

Make sure that localhost has the rights to collect the json.
Therefore you have to set localhost (127.0.0.1) in your settings under local network:
Bildschirmfoto 2020-04-16 um 22.59.24.png
Bildschirmfoto 2020-04-16 um 22.59.24.png (20.43 KiB) Viewed 1749 times

Re: customicon script

Posted: Thursday 16 April 2020 23:32
by jarmoboy
I have add it but still says the same...

Re: customicon script

Posted: Sunday 19 April 2020 21:52
by jarmoboy
Is there something i can write to command line to find out why is unauthorized?
THX

Re: customicon script

Posted: Monday 20 April 2020 17:33
by bewo
Sorry the delay... :?

Did you restart Domoticz after add 127.0.0.1 in the settings? Sometimes there some network issues... ;-)

Yes, you can test this in CLI. In your case type:

Code: Select all

curl "http://127.0.0.1:8084/json.htm?type=command&param=getversion"
And you should get some information about domoticz version.

Re: customicon script

Posted: Monday 20 April 2020 22:08
by jarmoboy
HI,
No preblem, i've got info about version, so it works.

Re: customicon script

Posted: Monday 20 April 2020 22:33
by bewo
And the script still doesn‘t work?

If not, maybe your network is not well configured.
Please change in my script „localhost“ to „127.0.0.1“. It‘s near under „Look for the icon which is used in the moment“
:-)

Re: customicon script

Posted: Monday 20 April 2020 22:51
by waaren
bewo wrote: Monday 20 April 2020 22:33 And the script still doesn‘t work?
Are you aware that you could use dzVents and apply the method setIcon(iconNumber) ?

Re: customicon script

Posted: Tuesday 21 April 2020 7:31
by jarmoboy
Tadaaaaa, it works,
Problem was "localhost". When i replace it with 127.0.0.1 everything works.
Thanky you Bewo for you magical skills.
So for further use and others iam including working code:

Code: Select all

-- Script to change the icon of a battery device depending it's level

-- Set your devices and variabels here:
Device = 'Roza baterka'    -- Name of the Sensor-Device
Icon_Nr_RED = '114'     -- RED = empty
Icon_Nr_ORANGE = '116'  -- ORANGE = low
Icon_Nr_YELLOW = '117'  -- YELLOW = ok
Icon_Nr_GREEN = '115'   -- GREEN = full

-- Your Domoticz Port in URL (default: 8080)
Domoticz_Port = '8084'
-- Load the domoticz LUA library (Change the path only; default at raspberry is /home/pi/domoticz/scripts/lua/JSON.lua)
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() 


-- ###############################################################################################
-- Nothing to do after this line... :-)

commandArray = {}
-- Function we need:
function encodeURI(str)
	if (str) then
		str = string.gsub (str, "\n", "\r\n")
		str = string.gsub (str, "([^%w ])",
			function (c) return string.format ("%%%02X", string.byte(c)) end)
		str = string.gsub (str, " ", "+")
    end
	return str
end

--------------------------------------------------------------------------

BatteryLevel = tonumber(otherdevices_svalues[Device])

if devicechanged[Device] then
    
    -- Look for the icon which is used in the moment:  
    json_collect = assert(io.popen('curl "http://127.0.0.1:'..Domoticz_Port..'/json.htm?type=devices&rid='..otherdevices_idx[Device]..'"'))
   json_collect_data = json_collect:read('*all')
    json_collect:close()

    Icon_Number = json:decode(json_collect_data).result[1]["CustomImage"]
    Icon = tostring(Icon_Number)

    -- Choose the correct icon
    if BatteryLevel <= 20 then
        battery_icon = Icon_Nr_RED
    elseif BatteryLevel > 20 and BatteryLevel <= 50 then
        battery_icon = Icon_Nr_ORANGE
    elseif BatteryLevel > 50 and BatteryLevel <= 80 then
        battery_icon = Icon_Nr_YELLOW
    elseif BatteryLevel > 80 and BatteryLevel <= 100 then
        battery_icon = Icon_Nr_GREEN
    end

    -- Update the icon if not the correct one is active:
    if battery_icon ~= Icon then
        
        os.execute('curl "http://127.0.0.1:'..Domoticz_Port..'/json.htm?type=setused&idx='..otherdevices_idx[Device]..'&name='..encodeURI(Device)..'&description=&switchtype=0&customimage='..battery_icon..'&devoptions=1;%25&used=true"')
        print('Icon of the device '..Device..' was updated.')
        print('Correct number of icon is '..battery_icon..'')
        
    end
end


return commandArray

Re: customicon script

Posted: Tuesday 21 April 2020 12:37
by jarmoboy
one more thing, iam perfectionist...
ive tried myself to use the code also for text device, ive checked few step with "print" to check if it uses right icon it says it does but it doesnt.
What is wrong there?

Code: Select all

-- Script to change the icon of a text device depending it's announcement

-- Set your devices and variabels here:
Device = 'Roza stav kose'    -- Name of the Sensor-Device
Icon_Nr_RED = '121'     -- RED
Icon_Nr_ORANGE = '120'  -- ORANGE
Icon_Nr_GREEN = '119'   -- GREEN

-- Your Domoticz Port in URL (default: 8080)
Domoticz_Port = '8084'
-- Load the domoticz LUA library (Change the path only; default at raspberry is /home/pi/domoticz/scripts/lua/JSON.lua)
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() 


-- ###############################################################################################
-- Nothing to do after this line... :-)

commandArray = {}
-- Function we need:
function encodeURI(str)
	if (str) then
		str = string.gsub (str, "\n", "\r\n")
		str = string.gsub (str, "([^%w ])",
			function (c) return string.format ("%%%02X", string.byte(c)) end)
		str = string.gsub (str, " ", "+")
    end
	return str
end

--------------------------------------------------------------------------

BatteryLevel = tostring(otherdevices_svalues[Device])

if devicechanged[Device] then
    
    -- Look for the icon which is used in the moment:  
    json_collect = assert(io.popen('curl "http://127.0.0.1:'..Domoticz_Port..'/json.htm?type=devices&rid='..otherdevices_idx[Device]..'"'))
   json_collect_data = json_collect:read('*all')
    json_collect:close()

    Icon_Number = json:decode(json_collect_data).result[1]["CustomImage"]
    Icon = tostring(Icon_Number)
    print('ted tam je ikona pro kos '..Icon..'')

    -- Choose the correct icon
    if BatteryLevel == 'Kos je v poradku' then
        battery_icon = Icon_Nr_GREEN
    elseif BatteryLevel == 'Roza nema kos!'then
        battery_icon = Icon_Nr_RED
    elseif BatteryLevel == 'Roza ma plny kos!'then
        battery_icon = Icon_Nr_YELLOW
    end

    -- Update the icon if not the correct one is active:
    if battery_icon ~= Icon then
        
        os.execute('curl "http://127.0.0.1:'..Domoticz_Port..'/json.htm?type=setused&idx='..otherdevices_idx[Device]..'&name='..encodeURI(Device)..'&description=&switchtype=0&customimage='..battery_icon..'&devoptions=1;%25&used=true"')
        print('Icon of the device '..Device..' was updated.')
        print('Spravne cislo je '..battery_icon..'')
        
    end
end


return commandArray