I still am testing my voltage bargraph but as rron suggested i made a P1-power bargraph to see what the power usage or delivery of the house is.
So.. if there is more power produced than is used in the house it looks like this: .. and if there is more usage than is being produced in the house it looks like this:
For the textdevice to display everything correct its vital that a monospaced font is used, in my setup this is the case but i heard from rron that this is not the case using firefox, but that is out of my control..
Max value can be set to your needs, the value set is also the minus value.
The bargraph length is adjustable to your setup, for every bar_length extra, of less the total bargraph will grow, or schrink 2 segments..
Code: Select all
-- Bargraph P1 power maker for text device -- RonkA
return {
on = {
-->-->-->- set correct idx number of P1_device
devices = {27}
},
logging = {
level = domoticz.LOG_ERROR,
marker = 'Bargraph',
},
execute = function(domoticz, triggeredItem)
-->-->-->-
local bar_length = 13 -- number of segments in bargraph; resize as you wish
local max_value = 5000 -- max value of Bargraph
local text_device = domoticz.devices(339) -- the right idx HAS to be set
local P1_device = domoticz.devices(27) -- set correct idx number of P1_device, also at beginning of script!!
-->-->-->- also read line 104
local mid_value = 0
local initial_value = -(max_value)
local one_segment = (max_value) / (bar_length) -- calculate value of 1 segment
local raw_value_usage = P1_device.usage
local raw_value_delivered = P1_device.usageDelivered -- is a positive value
local raw_value_tot = raw_value_usage - raw_value_delivered -- calculating the 'total'
local round_value = domoticz.utils.round(raw_value_tot, 0) -- rounding the raw_value_tot to whole numbers
-- restrain raw_value_tot to initial_value if to low
if raw_value_tot < initial_value then
raw_value_tot = initial_value end
-- restrain raw_value_tot to max_value if to high
if raw_value_tot > max_value then
raw_value_tot = max_value end
-- helper function to format a number with a specified number of decimal places and aligned decimal points
-- value--> the number, decimalPlaces--> number of decimalplaces, wholeNumbers--> total characters used for value including the comma.
-- usage= formatWithDecimalPlaces(100, 2, 8) gives " 100.00"
local function formatWithDecimalPlaces(value, decimalPlaces, wholeNumbers)
wholeNumbers = wholeNumbers or 0 -- default value for wholeNumbers parameter is 0 if not provided
local formatString = string.format('%%.%df', decimalPlaces)
local formattedValue = string.format(formatString, value)
local numDigits = string.len(formattedValue)
local numSpaces = math.max(0, wholeNumbers - numDigits) -- adjust the number of spaces for whole numbers
local spaces = string.rep(' ', numSpaces) -- unicode character ' ' (U+2000) for extra spaces
return spaces .. formattedValue
end
-- calculating the segments
local green_zone = 0
local red_zone = 0
local fill_zone_green = 0
local fill_zone_red = 0
local segment_count = 0
if raw_value_tot == initial_value then
green_zone = bar_length
fill_zone_green = 0
fill_zone_red = bar_length
segment_count = fill_zone_green
elseif raw_value_tot < mid_value then
green_zone = math.floor((mid_value - raw_value_tot) / one_segment)
fill_zone_green = bar_length - green_zone
fill_zone_red = bar_length
segment_count = fill_zone_green
elseif raw_value_tot == mid_value then
fill_zone_green = bar_length
fill_zone_red = bar_length
red_zone = 0
segment_count = bar_length + red_zone
elseif raw_value_tot > mid_value then
fill_zone_green = bar_length
fill_zone_red = math.floor((max_value - raw_value_tot) / one_segment)
red_zone = bar_length - fill_zone_red
segment_count = bar_length + red_zone
end
-- building the separate bar segments
local green_bar = '<span style="color: #CCFDA9;">' .. string.rep('█', fill_zone_green) .. '</span>' ..
'<span style="color: green;">' .. string.rep('█', green_zone) .. '</span>'
local red_bar = '<span style="color: Red;">' .. string.rep('█', red_zone) .. '</span>' ..
'<span style="color: #FDD2A9;">' .. string.rep('█', fill_zone_red) .. '</span>'
-- building the bar
-- the minus- and maximal (round_value) that is displayed correctly is from -99999W til 999999W.. should be enough..
local bar = '<span style="font-family: Consolas; font-weight: bold; font-size: 14px;">' ..
initial_value .. 'W' .. '▐' .. green_bar .. '<span style="color: Gray;">█</span>' .. red_bar .. '▌' .. max_value .. 'W\n' ..
string.rep(' ', segment_count + 7) .. '▲\n' ..
string.rep(' ', segment_count) .. formatWithDecimalPlaces(round_value, 0, 6) .. 'W⁞' .. '</span>'
-- check if the current message is the 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 port number accordingly to your setup
domoticz.openURL('http:/127.17.0.2:80/json.htm?type=command¶m=clearlightlog&idx=339')
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!!
EDIT, the fill colors where imho to white, they are now slightly more green and red..