Widget for TP-Link Smart Plug (HS110) with Energy Monitoring

off course we can add the switch also.
the biggest problem to think about is how big it is al going to get.

now it is time for me to switch off and i dont have much time on fridays and saturdays, but sunday i will look in to how we can use the attributes from the switch instead of 5 sensors.

still this done work is very good.
i (or we) can easy make a widget from this where you can show the state from up to 5 sensors.
all that is left is make the vars more general, and use vars for the text before the state and after.

and as i see with what speed you picked this up, you learned a lot from it and will be able in the future to create other widgets and others will benifit from that also.

i think the best way to go forward is:

  1. create a new widget based on the switch widget
  2. add the parts that we already have in the html to the switch html (keep the icon part, but change the statetext part to our attributes)
  3. connect the switch attributes to the html in the js file

if you want to try it yourself before i get to it:
in basedisplay i find this line:

value = state.attributes[self.entity_attribute]

that show that state contains the values from all attributes:
so to get the Amp from the switch we can use state.attributes[“current_a”]

in the switch widget there is the option to show the state as text.
in the set_view function there you find:

        if ("state_text" in self.parameters && self.parameters.state_text == 1)
        {
            self.set_field(self, "state_text", self.map_state(self, state))
        }

the if statement can go, and then you can add the 5 set_field lines you need like this:

            self.set_field(self, "amps", self.format_number(self,state.attributes["current_a"]))

have fun :wink:

With what we currently have I did a proof of concept. It is ugly because I do not understand css and html, but the important thing is it works. I made the whole widget the switch, but I’m sure it could be centre area only too. the way I see it the box widget could be a light trasnparent yellow, orange, red… hue when it is on. I also have a setview error.

basetester.js

function basetester(widget_id, url, skin, parameters)
{

    self = this;


    self.widget_id = widget_id;

    self.parameters = parameters;

    self.toggle = toggle;

    self.OnButtonClick = OnButtonClick;

    if ("enable" in self.parameters && self.parameters.enable == 1)
    {
        var callbacks =
            [
                {"selector": '#' + widget_id + ' > span', "action": "click", "callback": self.OnButtonClick},
            ]
    }
    else
    {
        var callbacks = []
    }

    self.OnStateAvailable = OnStateAvailable
    self.OnStateUpdate = OnStateUpdate
    self.OnWattsStateAvailable = OnWattsStateAvailable;
    self.OnWattsStateUpdate = OnWattsStateUpdate;
    self.OnAmpsStateAvailable = OnAmpsStateAvailable;
    self.OnAmpsStateUpdate = OnAmpsStateUpdate;
    self.OnKWStateAvailable = OnKWStateAvailable;
    self.OnKWStateUpdate = OnKWStateUpdate;
    self.OnKWTodayStateAvailable = OnKWTodayStateAvailable;
    self.OnKWTodayStateUpdate = OnKWTodayStateUpdate;
    self.OnVoltsStateAvailable = OnVoltsStateAvailable;
    self.OnVoltsStateUpdate = OnVoltsStateUpdate;
    // }
    var monitored_entities =

    [
        {"entity": parameters.entity, "initial": self.OnStateAvailable, "update": self.OnStateUpdate},
        {"entity": parameters.watts, "initial": self.OnWattsStateAvailable, "update": self.OnWattsStateUpdate},
        {"entity": parameters.amps, "initial": self.OnAmpsStateAvailable, "update": self.OnAmpsStateUpdate},
        {"entity": parameters.kw, "initial": self.OnKWStateAvailable, "update": self.OnKWStateUpdate},
        {"entity": parameters.kw_today, "initial": self.OnKWTodayStateAvailable, "update": self.OnKWTodayStateUpdate},
        {"entity": parameters.volts, "initial": self.OnVoltsStateAvailable, "update": self.OnVoltsStateUpdate},
    ];

    WidgetBase.call(self, widget_id, url, skin, parameters, monitored_entities, callbacks);

    function OnWattsStateUpdate(self, state)
    {
       self.set_field(self, "watts", self.format_number(self, state.state))
    }

    function OnWattsStateAvailable(self, state)
    {
       self.set_field(self, "watts", self.format_number(self, state.state))
    }

    function OnAmpsStateUpdate(self, state)
    {
       self.set_field(self, "amps", self.format_number(self, state.state))
    }

    function OnAmpsStateAvailable(self, state)
    {
       self.set_field(self, "amps", self.format_number(self, state.state))
    }

    function OnKWStateUpdate(self, state)
    {
       self.set_field(self, "kw", self.format_number(self, state.state))
    }

    function OnKWStateAvailable(self, state)
    {
       self.set_field(self, "kw", self.format_number(self, state.state))
    }
    function OnKWTodayStateUpdate(self, state)
    {
       self.set_field(self, "kw_today", self.format_number(self, state.state))
    }

    function OnKWTodayStateAvailable(self, state)
    {
       self.set_field(self, "kw_today", self.format_number(self, state.state))
    }

    function OnVoltsStateUpdate(self, state)
    {
       self.set_field(self, "volts", self.format_number(self, state.state))
    }

    function OnVoltsStateAvailable(self, state)
    {
       self.set_field(self, "volts", self.format_number(self, state.state))
    }
	
	function OnStateAvailable(self, state)
    {        
        self.state = state.state;
        set_view(self, self.state)
    }
    
	function OnStateUpdate(self, state)
    {
    if (!("ignore_state" in self.parameters) || self.parameters.ignore_state == 0)
    {
        self.state = state.state;
        set_view(self, self.state)
    }
    }

    function OnButtonClick(self)
    {
    if (self.state == self.parameters.state_active)
    {
        args = self.parameters.post_service_inactive
    }
    else
    {
        args = self.parameters.post_service_active
    }
    self.call_service(self, args);
    toggle(self);
    if ("momentary" in self.parameters)
    {
        setTimeout(function() { self.toggle(self) }, self.parameters["momentary"])
    }
    }

    function toggle(self)
    {
    if (self.state == self.parameters.state_active)
    {
        self.state = self.parameters.state_inactive;
    }
    else
    {
        self.state = self.parameters.state_active;
    }
    set_view(self, self.state)
    }
}

basetester.html

<span class="toggle-area" id="switch"></span>
<h1 class="title" data-bind="text: title, attr:{ style: title_style}"></h1>
<div data-bind="attr: {style: watts_style}">
		<p class="primary-info" data-bind="text: watts"></p>
		<p class="secondary-info">&nbsp;W</p>
</div>
<div data-bind="attr: {style: amp_style}">
		<p class="secondary-info">AMPs:&nbsp;</p>
		<p class="secondary-info" data-bind="text: amps"></p>
		<p class="secondary-info">&nbsp;A</p>
</div>
<div data-bind="attr: {style: volts_style}">
		<p class="secondary-info">Volts:&nbsp;</p>
		<p class="secondary-info" data-bind="text: volts"></p>
		<p class="secondary-info">&nbsp;V</p>
</div>
<div data-bind="attr: {style: kw_style}">
		<p class="secondary-info">Current:&nbsp;</p>
		<p class="secondary-info" data-bind="text: kw"></p>
		<p class="secondary-info">&nbsp;kWh</p>
</div>
<div data-bind="attr: {style: kw_today_style}">
		<p class="secondary-info">Since Midnight:&nbsp;</p>
		<p class="secondary-info" data-bind="text: kw_today"></p>
		<p class="secondary-info">&nbsp;KW</p>
</div>

basetester.html

.widget-basetesterer-{{id}} {
		color: white;
}

.widget-basetesterer-{{id}} h1 {
		margin-bottom: 0px;
}

.widget-basetesterer-{{id}} [class^="primary"] {
		display: inline-block;
		vertical-align: middle;
		padding: 0;
		margin-left: 10px;
		margin-right: 10px;
		margin-top: 0px;
		margin-bottom: 0px;
}

.widget-basetesterer-{{id}} [class^="secondary"] {
		display: inline-block;
		vertical-align: middle;
		padding: 0;
		margin-left: 0px;
		margin-right: 0px;
		margin-top: 0px;
		margin-bottom: 0px;
	}

.widget-basetesterer-{{id}} .primary-climacon {
		font-family: "Climacons-Font";
		font-size: 70px;
}

.widget-basetesterer-{{id}} .primary-info {
		font-size: 300%;
		font-weight: 400;
}

.widget-basetesterer-{{id}} .primary-unit {
		font-size: 100%;
		font-weight: 400;
		margin-left: 0;
		margin-top: 20px;
		vertical-align: top;
}

.widget-basetesterer-{{id}} .secondary-icon {
		font-family: "Climacons-Font";
		font-size: 40px;
		margin-left: 10px;
		margin-right: 0px;
}

.widget-basetesterer-{{id}} .secondary-climacon {
		font-family: "Climacons-Font";
		font-size: 55px;
		margin-left: 10px;
		margin-right: 10px;
}

.widget-basetesterer-{{id}} .secondary-info {
		font-size: 125%;
		font-weight: 200;
}

.widget-basetesterer-{{id}} hr {
		width: 90%;
		border: 0;
		height: 1px;
		background: rgba(255, 255, 255, 0.25);
		margin-top: 15px;
		margin-bottom: 15px;
}
.widget-basetesterer-{{id}} {
	position: relative;
}

.widget-basetester-{{id}} .title {
	position: absolute;
	top: 5px;
	width: 100%;
}

.widget-basetester-{{id}} .title2 {
	position: absolute;
	top: 23px;
	width: 100%;
}

.widget-basetester-{{id}} .state_text {
	position: absolute;
	bottom: -3px;
	width: 100%;
}

.widget-basetester-{{id}} .icon {
	position: absolute;
	top: 43px;
	width: 100%;
}

.widget-basetester-{{id}} .toggle-area {
	z-index: 10;
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

tester.yaml

widget_type: basetester
entity: {{entity}}
state_active: "on"
state_inactive: "off"
enable: 1
post_service_active:
    service: homeassistant/turn_on
    entity_id: {{entity}}
post_service_inactive:
    service: homeassistant/turn_off
    entity_id: {{entity}}
fields:
  title: ""
  unit: ""
  dark_sky_icon: ""
  watts: ""
  amps: ""
  kw: ""
  kw_today: ""
  volts: ""

static_icons: []
css: []
  # icon_style_active: $switch_icon_style_active
  # icon_style_inactive: $switch_icon_style_inactive
static_css:
  title_style: $tplink_sub_style
  watts_style: $tplink_watts_style
  amp_style: $tplink_amp_style
  volts_style: $tplink_volts_style
  kw_style: $tplink_kw_style
  kw_today_style: $tplink_kw_today_style
  widget_style: $tplink_widget_style

dashboard

tester1:
  widget_type: tester
  title: TP Large Mining Rig
  entity: switch.granny_kitchen_38    
  watts: sensor.tp_link_watts_2
  amps: sensor.tp_link_amps_2
  kw: sensor.tp_link_kw_2
  kw_today: sensor.tp_link_kw_today_2
  volts: sensor.tp_link_volts_2

you have a typo in your css

widget-basetesterer

and you need to take the js from the switch and DONT make the changes we made in the other widget.
just add the line i gave you to the set_view function.

like i said all the work we did is obsolete.