Bargraph text-device

In this subforum you can show projects you have made, or you are busy with. Please create your own topic.

Moderator: leecollings

Post Reply
User avatar
RonkA
Posts: 96
Joined: Tuesday 14 June 2022 12:57
Target OS: NAS (Synology & others)
Domoticz version: 2023.2
Location: Harlingen
Contact:

Bargraph text-device

Post by RonkA »

I made a dZvents script to display values, its not wat is requested in https://www.domoticz.com/forum/viewtopic.php?t=40765 but wanted show it anyway..

The bargraph is fully customable in length and colorzones by adjusting some values.
To work this script a textdevice has to be created and a source for the value to be displayed.

Right now in the current script i take the value from a temperature device to see how warm the water in my solar-storage tank is.
bar_green.PNG
bar_green.PNG (10.42 KiB) Viewed 1682 times
bar_yellow.PNG
bar_yellow.PNG (10.54 KiB) Viewed 1682 times
bar_red.PNG
bar_red.PNG (10.39 KiB) Viewed 1682 times

Code: Select all

-- Bargraph maker for text device -- RonkA
return {
    on = {
        timer = { 'every minute' },
    },
    logging = {
        level = domoticz.LOG_ERROR,
        marker = 'Bargraph',
    },
    execute = function(domoticz, triggeredItem)

        local bar_length = 30        -- number of segments in bargraph; resize as you wish
        local initial_value = 24     -- initial value to start bargraph at
        local max_value = 75         -- max value of Bargraph
        local bar_length_medium = 50 -- 1st color value yellow
        local bar_length_hot = 60    -- 2nd color value red
        
        local text_device = domoticz.devices('Bargraph')  -- idx 335 --> the right idx HAS to be set in line 76 !!!
        local value_device = domoticz.devices('Boiler gemiddelde temperatuur')  -- this device produces the barvalue
        
        local raw_value = value_device.temperature   -- because value_device comes from a temperature device I use .temperature
        local round_value = domoticz.utils.round(raw_value,0)   -- rounding the raw_value to whole numbers
        
        local one_segment = (max_value - initial_value) / bar_length                        -- calculate value of 1 segment
        local green_zone = math.floor((bar_length_medium - initial_value) / one_segment)    -- calculate the number of segments in the green zone
        local yellow_zone = math.floor((bar_length_hot - initial_value) / one_segment)      -- calculate the number of segments in the yellow zone            
        local red_zone = bar_length                                                         -- the remaining segments are for the red zone      
        
        local segment_count = math.floor((raw_value - initial_value) / one_segment)         -- number of segments to display in bargraph 
  

            -- calculate the percentage value round to the nearest whole number
        local percentage = (raw_value - initial_value) / (max_value - initial_value) * 100
        if percentage < 0 then
            percentage = 0
        elseif percentage > 100 then
            percentage = 100
        end
        local percentage_display = math.floor(percentage + 0.5)


            -- building the separate bar segments
        local green_bar = ''
        local yellow_bar = ''
        local red_bar = ''
        
        if segment_count <= green_zone then
            green_bar = '<span style="color: Green;">' .. string.rep('█', segment_count) .. '</span>' ..
                        '<span style="color: Wheat; background-color: Green;">' .. string.rep('▓', green_zone - segment_count) .. '</span>'
            yellow_bar = '<span style="color: Wheat; background-color: yellow;">' .. string.rep('▓', yellow_zone - green_zone) .. '</span>'
            red_bar = '<span style="color: Wheat; background-color: red;">' .. string.rep('▓', red_zone - yellow_zone) .. '</span>'
        elseif segment_count > green_zone and segment_count <= yellow_zone then
            green_bar = '<span style="color: Green;">' .. string.rep('█', green_zone) .. '</span>'
            yellow_bar = '<span style="color: Yellow;">' .. string.rep('█', segment_count - green_zone) .. '</span>' ..
                         '<span style="color: Wheat; background-color: yellow;">' .. string.rep('▓', yellow_zone - segment_count) .. '</span>'
            red_bar = '<span style="color: Wheat; background-color: red;">' .. string.rep('▓', red_zone - yellow_zone) .. '</span>'            
        elseif segment_count > yellow_zone then
            green_bar = '<span style="color: Green;">' .. string.rep('█', green_zone) .. '</span>'
            yellow_bar = '<span style="color: Yellow;">' .. string.rep('█', yellow_zone - green_zone) .. '</span>'
            red_bar = '<span style="color: Red;">' .. string.rep('█', segment_count - yellow_zone) .. '</span>' ..
                      '<span style="color: Wheat; background-color: red;">' .. string.rep('▓', red_zone - segment_count) .. '</span>'
        end    
        
            -- building the bar
        local bar = '<span style="font-family: Consolas; font-weight: bold; font-size: 14px;">' ..
                    initial_value .. '°C' .. '▐' .. green_bar .. yellow_bar .. red_bar .. '▌' .. max_value .. '°C\n' .. 
                    string.rep(' ', segment_count + 4) ..  '▲\n' .. 
                    string.rep(' ', segment_count) .. round_value .. '°C⁞'.. percentage_display .. '%' .. '</span>' 

            -- check if the current message is same as the new message        
        local current_message = text_device.text
        if (current_message ~= bar) then 
            text_device.updateText(bar)  -- Update the text device
            
 ----------> automatically clear the log of the textdevice; change the ip and portnumber accordingly to your setup..
            domoticz.openURL('http://127.17.0.2:80/json.htm?type=command&param=clearlightlog&idx=335')     
        else
            return -- This will stop the script and no log entry will be made
        end         
    end
}
For me this works fine, i hope for others also..
Enjoy!!
Last edited by RonkA on Wednesday 22 May 2024 17:26, edited 5 times in total.
SolarEdge ModbusTCP - Kaku - Synology NAS - Watermeter - ESPEasy - DS18b20
Work in progress = Life in general..
User avatar
psubiaco
Posts: 205
Joined: Monday 20 August 2018 9:38
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Italy
Contact:

Re: Bargraph text-device

Post by psubiaco »

Wow! That's a nice workaround to the missing bargraph in Domoticz!
Paolo
--
I use DomBus modules to charge EV car, get a full alarm system, control heat pump, fire alarm detection, lights and much more. Video
Facebook page - Youtube channel
lost
Posts: 643
Joined: Thursday 10 November 2016 9:30
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Bargraph text-device

Post by lost »

Clever hack of the text device!
Did not even noticed html could be used in such device for now, this brings a wide range of specific display customizations.
rron
Posts: 246
Joined: Sunday 30 March 2014 15:24
Target OS: Linux
Domoticz version: Beta
Location: Waterland
Contact:

Re: Bargraph text-device

Post by rron »

I like this very much but I want to use it for my power ¨slimme meter". I have adapt some some settings but I think this is not the right way. Can you look at myj adaptions?
Spoiler: show
-- Bargraph maker for text device -- RonkA
return {
on = {
timer = { 'every minute' },
},
logging = {
level = domoticz.LOG_ERROR,
marker = 'Bargraph',
},
execute = function(domoticz, triggeredItem)

local bar_length = 30 -- number of segments in bargraph; resize as you wish
local initial_value = -3000 -- initial value to start bargraph at
local max_value = 3000 -- max value of Bargraph
local bar_length_medium = 50 -- 1st color value yellow
local bar_length_hot = 60 -- 2nd color value red

local text_device = domoticz.devices('Bargraph') -- idx 689 --> the right idx HAS to be set in line 76 !!!
local value_device = domoticz.devices('Slimme meter') -- this device produces the barvalue

local raw_value = value_device.temperature -- because value_device comes from a temperature device I use .temperature
local round_value = domoticz.utils.round(raw_value,0) -- rounding the raw_value to whole numbers

local one_segment = (max_value - initial_value) / bar_length -- calculate value of 1 segment
local green_zone = math.floor((bar_length_medium - initial_value) / one_segment) -- calculate the number of segments in the green zone
local yellow_zone = math.floor((bar_length_hot - initial_value) / one_segment) -- calculate the number of segments in the yellow zone
local red_zone = bar_length -- the remaining segments are for the red zone

local segment_count = math.floor((raw_value - initial_value) / one_segment) -- number of segments to display in bargraph


-- calculate the percentage value round to the nearest whole number
local percentage = (raw_value - initial_value) / (max_value - initial_value) * 100
if percentage < 0 then
percentage = 0
elseif percentage > 100 then
percentage = 100
end
local percentage_display = math.floor(percentage + 0.5)


-- building the separate bar segments
local green_bar = ''
local yellow_bar = ''
local red_bar = ''

if segment_count <= green_zone then
green_bar = '<span style="color: Green;">' .. string.rep('█', segment_count) .. '</span>' ..
'<span style="color: Wheat; background-color: Green;">' .. string.rep('▓', green_zone - segment_count) .. '</span>'
yellow_bar = '<span style="color: Wheat; background-color: yellow;">' .. string.rep('▓', yellow_zone - green_zone) .. '</span>'
red_bar = '<span style="color: Wheat; background-color: red;">' .. string.rep('▓', red_zone - yellow_zone) .. '</span>'
elseif segment_count > green_zone and segment_count <= yellow_zone then
green_bar = '<span style="color: Green;">' .. string.rep('█', green_zone) .. '</span>'
yellow_bar = '<span style="color: Yellow;">' .. string.rep('█', segment_count - green_zone) .. '</span>' ..
'<span style="color: Wheat; background-color: yellow;">' .. string.rep('▓', yellow_zone - segment_count) .. '</span>'
red_bar = '<span style="color: Wheat; background-color: red;">' .. string.rep('▓', red_zone - yellow_zone) .. '</span>'
elseif segment_count > yellow_zone then
green_bar = '<span style="color: Green;">' .. string.rep('█', green_zone) .. '</span>'
yellow_bar = '<span style="color: Yellow;">' .. string.rep('█', yellow_zone - green_zone) .. '</span>'
red_bar = '<span style="color: Red;">' .. string.rep('█', segment_count - yellow_zone) .. '</span>' ..
'<span style="color: Wheat; background-color: red;">' .. string.rep('▓', red_zone - segment_count) .. '</span>'
end

-- building the bar
local bar = '<span style="font-family: Consolas; font-weight: bold; font-size: 14px;">' ..
initial_value .. 'W' .. '▐' .. green_bar .. yellow_bar .. red_bar .. '▌' .. max_value .. 'W\n' ..
string.rep(' ', segment_count + 4) .. '▲\n' ..
string.rep(' ', segment_count) .. round_value .. '°W'.. percentage_display .. '%' .. '</span>'

-- check if the current message is same as the new message
local current_message = text_device.text
if (current_message ~= bar) then
text_device.updateText(bar) -- Update the text device

----------> automatically clear the log of the textdevice; change the ip and portnumber accordingly to your setup..
domoticz.openURL('http://127.17.0.2:80/json.htm?type=comm ... og&idx=689')
else
return -- This will stop the script and no log entry will be made
end
end
}
Rpi, RFXcom, klikaan klikuit switch,thermosmart, z-wave, espeasy, smartevse
User avatar
RonkA
Posts: 96
Joined: Tuesday 14 June 2022 12:57
Target OS: NAS (Synology & others)
Domoticz version: 2023.2
Location: Harlingen
Contact:

Re: Bargraph text-device

Post by RonkA »

Funny you mention this; now i am making a bargraph to monitor the mains voltage and this has almost the same challenge as what you are attempting.
It is a bargraph that shows a bar to 2 sides, one negative, a 'neutral' point in the middle, and one positive side, so it ranges from 207 volt to 230 volt to 253 volt..
so if the voltage is under 230 volt there is a bargraph on the left and if the voltage is over 230 volt there is a bargraph to the right.
This is almost the same for your wattage bargraph but with much lower values..
I have the right side working (copy paste almost ;) ) and now trying to make the left side working..
The bandwith for the bargraph will be 253-207=46 volts at 30 segments gives a resolution of 1,53 volt per segment..
If it works it wil not be to hard to convert to your power bargraph.
The bandwidth of 6000 watt at 30 segments wil give a resolution 200 watt so it wil not be very accurate.
SolarEdge ModbusTCP - Kaku - Synology NAS - Watermeter - ESPEasy - DS18b20
Work in progress = Life in general..
rron
Posts: 246
Joined: Sunday 30 March 2014 15:24
Target OS: Linux
Domoticz version: Beta
Location: Waterland
Contact:

Re: Bargraph text-device

Post by rron »

Ok I hope you will share it and then I can see what I did wrong. 8-)
Rpi, RFXcom, klikaan klikuit switch,thermosmart, z-wave, espeasy, smartevse
meal
Posts: 106
Joined: Monday 04 March 2019 14:59
Target OS: Raspberry Pi / ODroid
Domoticz version: 2024.7
Location: France
Contact:

Re: Bargraph text-device

Post by meal »

Hello,

The bargraph implementation is a nice feature.

Would it be possible not to store the text log for a text device in order not to overload the domoticz DB ?

BR
meal
janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Bargraph text-device

Post by janpep »

meal wrote: Sunday 26 May 2024 18:14 Would it be possible not to store the text log for a text device in order not to overload the domoticz DB ?
Indeed. Very nicely made. I am still thinking about possible use for myself :-)
About your log: i do not think you quickly overload the DB. How much grow do you expect?
If you are concerned about the amount of data to store you might want to use logging to a separate file?
Or create a function that clears the log for the device from time to time. Something like:

Code: Select all

dz.openURL('http://<IP>:<PORT>/json.htm?type=command&param=clearlightlog&idx=<INDEXNUMBER>')
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
User avatar
RonkA
Posts: 96
Joined: Tuesday 14 June 2022 12:57
Target OS: NAS (Synology & others)
Domoticz version: 2023.2
Location: Harlingen
Contact:

Re: Bargraph text-device

Post by RonkA »

meal wrote: Sunday 26 May 2024 18:14 Would it be possible not to store the text log for a text device in order not to overload the domoticz DB ?
Read line 75!!!!

Code: Select all

 ----------> automatically clear the log of the textdevice; change the ip and portnumber accordingly to your setup..
            domoticz.openURL('http://127.17.0.2:80/json.htm?type=command&param=clearlightlog&idx=335') 
SolarEdge ModbusTCP - Kaku - Synology NAS - Watermeter - ESPEasy - DS18b20
Work in progress = Life in general..
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests