Skip to content

Commit

Permalink
Add dedicated co2 tariff (evcc-io#8089)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Michael Geers <[email protected]>
  • Loading branch information
andig and naltatis authored May 31, 2023
1 parent 15b6086 commit 7c3ca53
Show file tree
Hide file tree
Showing 39 changed files with 264 additions and 212 deletions.
18 changes: 1 addition & 17 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,26 +201,10 @@ type Resurrector interface {
WakeUp() error
}

// Rate is a grid tariff rate
type Rate struct {
Start time.Time `json:"start"`
End time.Time `json:"end"`
Price float64 `json:"price"`
}

// IsEmpty returns is the rate is the zero value
func (r Rate) IsEmpty() bool {
return r.Start.IsZero() && r.End.IsZero() && r.Price == 0
}

// Rates is a slice of (future) tariff rates
type Rates []Rate

// Tariff is a tariff capable of retrieving tariff rates
type Tariff interface {
Unit() string
Rates() (Rates, error)
IsDynamic() bool
Type() TariffType
}

// AuthProvider is the ability to provide OAuth authentication through the ui
Expand Down
15 changes: 15 additions & 0 deletions api/rates.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ import (
"time"
)

// Rate is a grid tariff rate
type Rate struct {
Start time.Time `json:"start"`
End time.Time `json:"end"`
Price float64 `json:"price"`
}

// IsEmpty returns is the rate is the zero value
func (r Rate) IsEmpty() bool {
return r.Start.IsZero() && r.End.IsZero() && r.Price == 0
}

// Rates is a slice of (future) tariff rates
type Rates []Rate

// Current returns the rates current rate or error
func (r Rates) Current(now time.Time) (Rate, error) {
for _, rr := range r {
Expand Down
12 changes: 12 additions & 0 deletions api/tariff.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package api

//go:generate enumer -type TariffType -trimprefix TariffType -transform=lower

type TariffType int

const (
_ TariffType = iota
TariffTypePriceStatic
TariffTypePriceDynamic
TariffTypeCo2
)
83 changes: 83 additions & 0 deletions api/tarifftype_enumer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 15 additions & 3 deletions assets/js/components/ChargingPlan.story.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,25 @@ const hoursFromNow = function (hours) {
<ChargingPlan id="1" :targetTime="hoursFromNow(14)" />
</Variant>
<Variant title="price EUR limit">
<ChargingPlan id="1" :smartCostLimit="0.13" smartCostUnit="EUR" :tariffGrid="0.3" />
<ChargingPlan
id="1"
:smartCostLimit="0.13"
smartCostType="price"
currency="EUR"
:tariffGrid="0.3"
/>
</Variant>
<Variant title="price SEK limit">
<ChargingPlan id="1" :smartCostLimit="0.43" smartCostUnit="SEK" :tariffGrid="0.32" />
<ChargingPlan
id="1"
:smartCostLimit="0.43"
smartCostType="price"
currency="SEK"
:tariffGrid="0.32"
/>
</Variant>
<Variant title="co2 limit">
<ChargingPlan id="1" :smartCostLimit="400" smartCostUnit="gCO2eq" :tariffCo2="623" />
<ChargingPlan id="1" :smartCostLimit="400" smartCostType="co2" :tariffCo2="623" />
</Variant>
<Variant title="min soc">
<ChargingPlan id="1" :minSoc="30" :vehicleSoc="25" />
Expand Down
3 changes: 2 additions & 1 deletion assets/js/components/ChargingPlan.vue
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ export default {
vehicleSoc: Number,
vehicleName: String,
smartCostLimit: Number,
smartCostUnit: String,
smartCostType: String,
currency: String,
},
emits: ["target-time-updated", "target-time-removed", "minsoc-updated"],
data: function () {
Expand Down
4 changes: 2 additions & 2 deletions assets/js/components/Energyflow/Energyflow.story.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Energyflow from "./Energyflow.vue";
:tariffGrid="0.25"
:tariffFeedIn="0.08"
:tariffEffectivePrice="0.08"
smartCostUnit="EUR"
smartCostType="price"
smartCostAvailable
currency="EUR"
siteTitle="Home"
Expand Down Expand Up @@ -147,7 +147,7 @@ import Energyflow from "./Energyflow.vue";
:tariffEffectivePrice="0.08"
:tariffCo2="723"
:tariffEffectiveCo2="0"
smartCostUnit="gCO2eq"
smartCostType="co2"
smartCostAvailable
currency="EUR"
siteTitle="Home"
Expand Down
10 changes: 6 additions & 4 deletions assets/js/components/Energyflow/Energyflow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ import GridSettingsModal from "../GridSettingsModal.vue";
import formatter from "../../mixins/formatter";
import AnimatedNumber from "../AnimatedNumber.vue";
import settings from "../../settings";
import { CO2_UNIT } from "../../units";
import { CO2_TYPE, PRICE_DYNAMIC_TYPE } from "../../units";
import collector from "../../mixins/collector";
import BatterySettingsModal from "../BatterySettingsModal.vue";
Expand Down Expand Up @@ -197,9 +197,8 @@ export default {
tariffEffectivePrice: { type: Number },
tariffCo2: { type: Number },
tariffEffectiveCo2: { type: Number },
smartCostAvailable: { type: Boolean },
smartCostLimit: { type: Number },
smartCostUnit: { type: String },
smartCostType: { type: String },
currency: { type: String },
prioritySoc: { type: Number },
bufferSoc: { type: Number },
Expand All @@ -209,6 +208,9 @@ export default {
return { detailsOpen: false, detailsCompleteHeight: null, gridSettingsModal: null };
},
computed: {
smartCostAvailable: function () {
return [CO2_TYPE, PRICE_DYNAMIC_TYPE].includes(this.smartCostType);
},
gridImport: function () {
return Math.max(0, this.gridPower);
},
Expand Down Expand Up @@ -257,7 +259,7 @@ export default {
return this.collectProps(BatterySettingsModal);
},
co2Available() {
return this.smartCostUnit === CO2_UNIT;
return this.smartCostType === CO2_TYPE;
},
},
mounted() {
Expand Down
15 changes: 8 additions & 7 deletions assets/js/components/GridSettingsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
<script>
import formatter from "../mixins/formatter";
import TariffChart from "./TariffChart.vue";
import { CO2_UNIT } from "../units";
import { CO2_TYPE } from "../units";
import api from "../api";
export default {
Expand All @@ -113,7 +113,8 @@ export default {
mixins: [formatter],
props: {
smartCostLimit: Number,
smartCostUnit: String,
smartCostType: String,
currency: String,
},
data: function () {
return {
Expand All @@ -126,7 +127,7 @@ export default {
},
computed: {
isCo2() {
return this.smartCostUnit === CO2_UNIT;
return this.smartCostType === CO2_TYPE;
},
costOptions() {
const values = [];
Expand All @@ -144,7 +145,7 @@ export default {
const name = `< ${
this.isCo2
? this.fmtCo2Medium(value)
: this.fmtPricePerKWh(value, this.smartCostUnit)
: this.fmtPricePerKWh(value, this.currency)
}`;
return { value, name };
});
Expand Down Expand Up @@ -218,7 +219,7 @@ export default {
if (this.isCo2) {
return this.fmtCo2Medium(price);
}
return this.fmtPricePerKWh(price, this.smartCostUnit);
return this.fmtPricePerKWh(price, this.currency);
},
},
watch: {
Expand Down Expand Up @@ -287,10 +288,10 @@ export default {
fmtCostRange({ min, max }) {
const fmtMin = this.isCo2
? this.fmtCo2Short(min)
: this.fmtPricePerKWh(min, this.smartCostUnit, true);
: this.fmtPricePerKWh(min, this.currency, true);
const fmtMax = this.isCo2
? this.fmtCo2Short(max)
: this.fmtPricePerKWh(max, this.smartCostUnit, true);
: this.fmtPricePerKWh(max, this.currency, true);
return `${fmtMin} - ${fmtMax}`;
},
slotHovered(index) {
Expand Down
2 changes: 1 addition & 1 deletion assets/js/components/Loadpoint.vue
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export default {
guardRemaining: Number,
guardAction: String,
smartCostLimit: Number,
smartCostUnit: String,
smartCostType: String,
tariffGrid: Number,
tariffCo2: Number,
currency: String,
Expand Down
4 changes: 2 additions & 2 deletions assets/js/components/Loadpoints.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
:id="index + 1"
:vehicles="vehicles"
:smartCostLimit="smartCostLimit"
:smartCostUnit="smartCostUnit"
:smartCostType="smartCostType"
:tariffGrid="tariffGrid"
:tariffCo2="tariffCo2"
:currency="currency"
Expand Down Expand Up @@ -49,7 +49,7 @@ export default {
loadpoints: Array,
vehicles: Array,
smartCostLimit: Number,
smartCostUnit: String,
smartCostType: String,
tariffGrid: Number,
tariffCo2: Number,
currency: String,
Expand Down
5 changes: 2 additions & 3 deletions assets/js/components/Site.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
:loadpoints="loadpoints"
:vehicles="vehicles"
:smartCostLimit="smartCostLimit"
:smartCostUnit="smartCostUnit"
:smartCostType="smartCostType"
:tariffGrid="tariffGrid"
:tariffCo2="tariffCo2"
:currency="currency"
Expand Down Expand Up @@ -100,8 +100,7 @@ export default {
sponsor: String,
sponsorTokenExpires: Number,
smartCostLimit: Number,
smartCostUnit: String,
smartCostAvailable: Boolean,
smartCostType: String,
},
computed: {
energyflow: function () {
Expand Down
14 changes: 8 additions & 6 deletions assets/js/components/TargetCharge.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
<script>
import "@h2d2/shopicons/es/filled/plus";
import "@h2d2/shopicons/es/filled/edit";
import { CO2_UNIT } from "../units";
import { CO2_TYPE } from "../units";
import TargetChargePlan from "./TargetChargePlan.vue";
import api from "../api";
Expand All @@ -99,7 +99,8 @@ export default {
socBasedCharging: Boolean,
disabled: Boolean,
smartCostLimit: Number,
smartCostUnit: String,
smartCostType: String,
currency: String,
},
emits: ["target-time-updated", "target-time-removed"],
data: function () {
Expand Down Expand Up @@ -144,8 +145,9 @@ export default {
targetChargePlanProps: function () {
const targetTime = this.selectedTargetTime;
const { rates } = this.tariff;
const { duration, unit, plan } = this.plan;
return rates ? { duration, rates, plan, unit, targetTime } : null;
const { duration, plan } = this.plan;
const { currency, smartCostType } = this;
return rates ? { duration, rates, plan, targetTime, currency, smartCostType } : null;
},
tariffLowest: function () {
return this.tariff?.rates.reduce((res, slot) => {
Expand All @@ -167,11 +169,11 @@ export default {
});
}
return this.$t("main.targetCharge.priceLimit", {
price: this.fmtPricePerKWh(this.smartCostLimit, this.smartCostUnit, true),
price: this.fmtPricePerKWh(this.smartCostLimit, this.currency, true),
});
},
isCo2() {
return this.smartCostUnit === CO2_UNIT;
return this.smartCostType === CO2_TYPE;
},
},
watch: {
Expand Down
Loading

0 comments on commit 7c3ca53

Please sign in to comment.