mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Adopt new electricity tariffs in pvpc hourly pricing (#51789)
This commit is contained in:
parent
d4ac5bf048
commit
b7c1df7864
@ -1,17 +1,38 @@
|
|||||||
"""The pvpc_hourly_pricing integration to collect Spain official electric prices."""
|
"""The pvpc_hourly_pricing integration to collect Spain official electric prices."""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from aiopvpc import DEFAULT_POWER_KW, TARIFFS
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||||
from homeassistant.const import CONF_NAME
|
from homeassistant.const import CONF_NAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant, callback
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.helpers.entity_registry import (
|
||||||
|
EntityRegistry,
|
||||||
|
async_get,
|
||||||
|
async_migrate_entries,
|
||||||
|
)
|
||||||
|
|
||||||
from .const import ATTR_TARIFF, DEFAULT_NAME, DEFAULT_TARIFF, DOMAIN, PLATFORMS, TARIFFS
|
from .const import (
|
||||||
|
ATTR_POWER,
|
||||||
|
ATTR_POWER_P3,
|
||||||
|
ATTR_TARIFF,
|
||||||
|
DEFAULT_NAME,
|
||||||
|
DOMAIN,
|
||||||
|
PLATFORMS,
|
||||||
|
)
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
_DEFAULT_TARIFF = TARIFFS[0]
|
||||||
|
VALID_POWER = vol.All(vol.Coerce(float), vol.Range(min=1.0, max=15.0))
|
||||||
|
VALID_TARIFF = vol.In(TARIFFS)
|
||||||
UI_CONFIG_SCHEMA = vol.Schema(
|
UI_CONFIG_SCHEMA = vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(CONF_NAME, default=DEFAULT_NAME): str,
|
vol.Required(CONF_NAME, default=DEFAULT_NAME): str,
|
||||||
vol.Required(ATTR_TARIFF, default=DEFAULT_TARIFF): vol.In(TARIFFS),
|
vol.Required(ATTR_TARIFF, default=_DEFAULT_TARIFF): VALID_TARIFF,
|
||||||
|
vol.Required(ATTR_POWER, default=DEFAULT_POWER_KW): VALID_POWER,
|
||||||
|
vol.Required(ATTR_POWER_P3, default=DEFAULT_POWER_KW): VALID_POWER,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
CONFIG_SCHEMA = vol.Schema(
|
CONFIG_SCHEMA = vol.Schema(
|
||||||
@ -20,19 +41,8 @@ CONFIG_SCHEMA = vol.Schema(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: dict):
|
async def async_setup(hass: HomeAssistant, config: dict) -> bool:
|
||||||
"""
|
"""Set up the electricity price sensor from configuration.yaml."""
|
||||||
Set up the electricity price sensor from configuration.yaml.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
pvpc_hourly_pricing:
|
|
||||||
- name: PVPC manual ve
|
|
||||||
tariff: electric_car
|
|
||||||
- name: PVPC manual nocturna
|
|
||||||
tariff: discrimination
|
|
||||||
timeout: 3
|
|
||||||
```
|
|
||||||
"""
|
|
||||||
for conf in config.get(DOMAIN, []):
|
for conf in config.get(DOMAIN, []):
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
hass.config_entries.flow.async_init(
|
hass.config_entries.flow.async_init(
|
||||||
@ -45,10 +55,67 @@ async def async_setup(hass: HomeAssistant, config: dict):
|
|||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up pvpc hourly pricing from a config entry."""
|
"""Set up pvpc hourly pricing from a config entry."""
|
||||||
|
if len(entry.data) == 2:
|
||||||
|
defaults = {
|
||||||
|
ATTR_TARIFF: _DEFAULT_TARIFF,
|
||||||
|
ATTR_POWER: DEFAULT_POWER_KW,
|
||||||
|
ATTR_POWER_P3: DEFAULT_POWER_KW,
|
||||||
|
}
|
||||||
|
data = {**entry.data, **defaults}
|
||||||
|
hass.config_entries.async_update_entry(
|
||||||
|
entry, unique_id=_DEFAULT_TARIFF, data=data, options=defaults
|
||||||
|
)
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def update_unique_id(reg_entry):
|
||||||
|
"""Change unique id for sensor entity, pointing to new tariff."""
|
||||||
|
return {"new_unique_id": _DEFAULT_TARIFF}
|
||||||
|
|
||||||
|
try:
|
||||||
|
await async_migrate_entries(hass, entry.entry_id, update_unique_id)
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Migrating PVPC sensor from old tariff '%s' to new '%s'. "
|
||||||
|
"Configure the integration to set your contracted power, "
|
||||||
|
"and select prices for Ceuta/Melilla, "
|
||||||
|
"if that is your case",
|
||||||
|
entry.data[ATTR_TARIFF],
|
||||||
|
_DEFAULT_TARIFF,
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
# there were multiple sensors (with different old tariffs, up to 3),
|
||||||
|
# so we leave just one and remove the others
|
||||||
|
ent_reg: EntityRegistry = async_get(hass)
|
||||||
|
for entity_id, reg_entry in ent_reg.entities.items():
|
||||||
|
if reg_entry.config_entry_id == entry.entry_id:
|
||||||
|
ent_reg.async_remove(entity_id)
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Old PVPC Sensor %s is removed "
|
||||||
|
"(another one already exists, using the same tariff)",
|
||||||
|
entity_id,
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
|
await hass.config_entries.async_remove(entry.entry_id)
|
||||||
|
return False
|
||||||
|
|
||||||
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
||||||
|
entry.async_on_unload(entry.add_update_listener(async_update_options))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
async def async_update_options(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
||||||
|
"""Handle options update."""
|
||||||
|
if any(
|
||||||
|
entry.data.get(attrib) != entry.options.get(attrib)
|
||||||
|
for attrib in (ATTR_TARIFF, ATTR_POWER, ATTR_POWER_P3)
|
||||||
|
):
|
||||||
|
# update entry replacing data with new options
|
||||||
|
hass.config_entries.async_update_entry(
|
||||||
|
entry, data={**entry.data, **entry.options}
|
||||||
|
)
|
||||||
|
await hass.config_entries.async_reload(entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Unload a config entry."""
|
"""Unload a config entry."""
|
||||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
"""Config flow for pvpc_hourly_pricing."""
|
"""Config flow for pvpc_hourly_pricing."""
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from . import CONF_NAME, UI_CONFIG_SCHEMA
|
from . import CONF_NAME, UI_CONFIG_SCHEMA, VALID_POWER, VALID_TARIFF
|
||||||
from .const import ATTR_TARIFF, DOMAIN
|
from .const import ATTR_POWER, ATTR_POWER_P3, ATTR_TARIFF, DOMAIN
|
||||||
|
|
||||||
_DOMAIN_NAME = DOMAIN
|
|
||||||
|
|
||||||
|
|
||||||
class TariffSelectorConfigFlow(config_entries.ConfigFlow, domain=_DOMAIN_NAME):
|
class TariffSelectorConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
"""Handle a config flow for `pvpc_hourly_pricing` to select the tariff."""
|
"""Handle config flow for `pvpc_hourly_pricing`."""
|
||||||
|
|
||||||
VERSION = 1
|
VERSION = 1
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@callback
|
||||||
|
def async_get_options_flow(config_entry):
|
||||||
|
"""Get the options flow for this handler."""
|
||||||
|
return PVPCOptionsFlowHandler(config_entry)
|
||||||
|
|
||||||
async def async_step_user(self, user_input=None):
|
async def async_step_user(self, user_input=None):
|
||||||
"""Handle the initial step."""
|
"""Handle the initial step."""
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
@ -24,3 +31,35 @@ class TariffSelectorConfigFlow(config_entries.ConfigFlow, domain=_DOMAIN_NAME):
|
|||||||
async def async_step_import(self, import_info):
|
async def async_step_import(self, import_info):
|
||||||
"""Handle import from config file."""
|
"""Handle import from config file."""
|
||||||
return await self.async_step_user(import_info)
|
return await self.async_step_user(import_info)
|
||||||
|
|
||||||
|
|
||||||
|
class PVPCOptionsFlowHandler(config_entries.OptionsFlow):
|
||||||
|
"""Handle PVPC options."""
|
||||||
|
|
||||||
|
def __init__(self, config_entry):
|
||||||
|
"""Initialize options flow."""
|
||||||
|
self.config_entry = config_entry
|
||||||
|
|
||||||
|
async def async_step_init(self, user_input=None):
|
||||||
|
"""Manage the options."""
|
||||||
|
if user_input is not None:
|
||||||
|
return self.async_create_entry(title="", data=user_input)
|
||||||
|
|
||||||
|
# Fill options with entry data
|
||||||
|
tariff = self.config_entry.options.get(
|
||||||
|
ATTR_TARIFF, self.config_entry.data[ATTR_TARIFF]
|
||||||
|
)
|
||||||
|
power = self.config_entry.options.get(
|
||||||
|
ATTR_POWER, self.config_entry.data[ATTR_POWER]
|
||||||
|
)
|
||||||
|
power_valley = self.config_entry.options.get(
|
||||||
|
ATTR_POWER_P3, self.config_entry.data[ATTR_POWER_P3]
|
||||||
|
)
|
||||||
|
schema = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(ATTR_TARIFF, default=tariff): VALID_TARIFF,
|
||||||
|
vol.Required(ATTR_POWER, default=power): VALID_POWER,
|
||||||
|
vol.Required(ATTR_POWER_P3, default=power_valley): VALID_POWER,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return self.async_show_form(step_id="init", data_schema=schema)
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
"""Constant values for pvpc_hourly_pricing."""
|
"""Constant values for pvpc_hourly_pricing."""
|
||||||
from aiopvpc import TARIFFS
|
|
||||||
|
|
||||||
DOMAIN = "pvpc_hourly_pricing"
|
DOMAIN = "pvpc_hourly_pricing"
|
||||||
PLATFORMS = ["sensor"]
|
PLATFORMS = ["sensor"]
|
||||||
|
ATTR_POWER = "power"
|
||||||
|
ATTR_POWER_P3 = "power_p3"
|
||||||
ATTR_TARIFF = "tariff"
|
ATTR_TARIFF = "tariff"
|
||||||
DEFAULT_NAME = "PVPC"
|
DEFAULT_NAME = "PVPC"
|
||||||
DEFAULT_TARIFF = TARIFFS[1]
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Spain electricity hourly pricing (PVPC)",
|
"name": "Spain electricity hourly pricing (PVPC)",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/pvpc_hourly_pricing",
|
"documentation": "https://www.home-assistant.io/integrations/pvpc_hourly_pricing",
|
||||||
"requirements": ["aiopvpc==2.1.2"],
|
"requirements": ["aiopvpc==2.2.0"],
|
||||||
"codeowners": ["@azogue"],
|
"codeowners": ["@azogue"],
|
||||||
"quality_scale": "platinum",
|
"quality_scale": "platinum",
|
||||||
"iot_class": "cloud_polling"
|
"iot_class": "cloud_polling"
|
||||||
|
@ -3,19 +3,21 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from random import randint
|
from random import randint
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from aiopvpc import PVPCData
|
from aiopvpc import PVPCData
|
||||||
|
|
||||||
from homeassistant import config_entries
|
|
||||||
from homeassistant.components.sensor import SensorEntity
|
from homeassistant.components.sensor import SensorEntity
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_NAME, CURRENCY_EURO, ENERGY_KILO_WATT_HOUR
|
from homeassistant.const import CONF_NAME, CURRENCY_EURO, ENERGY_KILO_WATT_HOUR
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.event import async_call_later, async_track_time_change
|
from homeassistant.helpers.event import async_call_later, async_track_time_change
|
||||||
from homeassistant.helpers.restore_state import RestoreEntity
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
from .const import ATTR_TARIFF
|
from .const import ATTR_POWER, ATTR_POWER_P3, ATTR_TARIFF
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -27,15 +29,18 @@ _DEFAULT_TIMEOUT = 10
|
|||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant, config_entry: config_entries.ConfigEntry, async_add_entities
|
hass: HomeAssistant,
|
||||||
):
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
"""Set up the electricity price sensor from config_entry."""
|
"""Set up the electricity price sensor from config_entry."""
|
||||||
name = config_entry.data[CONF_NAME]
|
name = config_entry.data[CONF_NAME]
|
||||||
pvpc_data_handler = PVPCData(
|
pvpc_data_handler = PVPCData(
|
||||||
tariff=config_entry.data[ATTR_TARIFF],
|
tariff=config_entry.data[ATTR_TARIFF],
|
||||||
|
power=config_entry.data[ATTR_POWER],
|
||||||
|
power_valley=config_entry.data[ATTR_POWER_P3],
|
||||||
local_timezone=hass.config.time_zone,
|
local_timezone=hass.config.time_zone,
|
||||||
websession=async_get_clientsession(hass),
|
websession=async_get_clientsession(hass),
|
||||||
logger=_LOGGER,
|
|
||||||
timeout=_DEFAULT_TIMEOUT,
|
timeout=_DEFAULT_TIMEOUT,
|
||||||
)
|
)
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
@ -57,15 +62,7 @@ class ElecPriceSensor(RestoreEntity, SensorEntity):
|
|||||||
self._pvpc_data = pvpc_data_handler
|
self._pvpc_data = pvpc_data_handler
|
||||||
self._num_retries = 0
|
self._num_retries = 0
|
||||||
|
|
||||||
self._hourly_tracker = None
|
async def async_added_to_hass(self) -> None:
|
||||||
self._price_tracker = None
|
|
||||||
|
|
||||||
async def async_will_remove_from_hass(self) -> None:
|
|
||||||
"""Cancel listeners for sensor updates."""
|
|
||||||
self._hourly_tracker()
|
|
||||||
self._price_tracker()
|
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
|
||||||
"""Handle entity which will be added."""
|
"""Handle entity which will be added."""
|
||||||
await super().async_added_to_hass()
|
await super().async_added_to_hass()
|
||||||
state = await self.async_get_last_state()
|
state = await self.async_get_last_state()
|
||||||
@ -73,14 +70,18 @@ class ElecPriceSensor(RestoreEntity, SensorEntity):
|
|||||||
self._pvpc_data.state = state.state
|
self._pvpc_data.state = state.state
|
||||||
|
|
||||||
# Update 'state' value in hour changes
|
# Update 'state' value in hour changes
|
||||||
self._hourly_tracker = async_track_time_change(
|
self.async_on_remove(
|
||||||
self.hass, self.update_current_price, second=[0], minute=[0]
|
async_track_time_change(
|
||||||
|
self.hass, self.update_current_price, second=[0], minute=[0]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
# Update prices at random time, 2 times/hour (don't want to upset API)
|
# Update prices at random time, 2 times/hour (don't want to upset API)
|
||||||
random_minute = randint(1, 29)
|
random_minute = randint(1, 29)
|
||||||
mins_update = [random_minute, random_minute + 30]
|
mins_update = [random_minute, random_minute + 30]
|
||||||
self._price_tracker = async_track_time_change(
|
self.async_on_remove(
|
||||||
self.hass, self.async_update_prices, second=[0], minute=mins_update
|
async_track_time_change(
|
||||||
|
self.hass, self.async_update_prices, second=[0], minute=mins_update
|
||||||
|
)
|
||||||
)
|
)
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Setup of price sensor %s (%s) with tariff '%s', "
|
"Setup of price sensor %s (%s) with tariff '%s', "
|
||||||
@ -90,8 +91,9 @@ class ElecPriceSensor(RestoreEntity, SensorEntity):
|
|||||||
self._pvpc_data.tariff,
|
self._pvpc_data.tariff,
|
||||||
mins_update,
|
mins_update,
|
||||||
)
|
)
|
||||||
await self.async_update_prices(dt_util.utcnow())
|
now = dt_util.utcnow()
|
||||||
self.update_current_price(dt_util.utcnow())
|
await self.async_update_prices(now)
|
||||||
|
self.update_current_price(now)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self) -> str | None:
|
def unique_id(self) -> str | None:
|
||||||
@ -99,12 +101,12 @@ class ElecPriceSensor(RestoreEntity, SensorEntity):
|
|||||||
return self._unique_id
|
return self._unique_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self) -> str:
|
||||||
"""Return the name of the sensor."""
|
"""Return the name of the sensor."""
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self) -> float:
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
return self._pvpc_data.state
|
return self._pvpc_data.state
|
||||||
|
|
||||||
@ -114,7 +116,7 @@ class ElecPriceSensor(RestoreEntity, SensorEntity):
|
|||||||
return self._pvpc_data.state_available
|
return self._pvpc_data.state_available
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self):
|
def extra_state_attributes(self) -> dict[str, Any]:
|
||||||
"""Return the state attributes."""
|
"""Return the state attributes."""
|
||||||
return self._pvpc_data.attributes
|
return self._pvpc_data.attributes
|
||||||
|
|
||||||
|
@ -2,16 +2,31 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"step": {
|
"step": {
|
||||||
"user": {
|
"user": {
|
||||||
"title": "Tariff selection",
|
"title": "Sensor setup",
|
||||||
"description": "This sensor uses official API to get [hourly pricing of electricity (PVPC)](https://www.esios.ree.es/es/pvpc) in Spain.\nFor more precise explanation visit the [integration docs](https://www.home-assistant.io/integrations/pvpc_hourly_pricing/).\n\nSelect the contracted rate based on the number of billing periods per day:\n- 1 period: normal\n- 2 periods: discrimination (nightly rate)\n- 3 periods: electric car (nightly rate of 3 periods)",
|
"description": "This sensor uses official API to get [hourly pricing of electricity (PVPC)](https://www.esios.ree.es/es/pvpc) in Spain.\nFor more precise explanation visit the [integration docs](https://www.home-assistant.io/integrations/pvpc_hourly_pricing/).",
|
||||||
"data": {
|
"data": {
|
||||||
"name": "Sensor Name",
|
"name": "Sensor Name",
|
||||||
"tariff": "Contracted tariff (1, 2, or 3 periods)"
|
"tariff": "Applicable tariff by geographic zone",
|
||||||
|
"power": "Contracted power (kW)",
|
||||||
|
"power_p3": "Contracted power for valley period P3 (kW)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]"
|
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"title": "Sensor setup",
|
||||||
|
"description": "This sensor uses official API to get [hourly pricing of electricity (PVPC)](https://www.esios.ree.es/es/pvpc) in Spain.\nFor more precise explanation visit the [integration docs](https://www.home-assistant.io/integrations/pvpc_hourly_pricing/).",
|
||||||
|
"data": {
|
||||||
|
"tariff": "Applicable tariff by geographic zone",
|
||||||
|
"power": "Contracted power (kW)",
|
||||||
|
"power_p3": "Contracted power for valley period P3 (kW)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,25 @@
|
|||||||
"user": {
|
"user": {
|
||||||
"data": {
|
"data": {
|
||||||
"name": "Sensor Name",
|
"name": "Sensor Name",
|
||||||
"tariff": "Contracted tariff (1, 2, or 3 periods)"
|
"power": "Contracted power (kW)",
|
||||||
|
"power_p3": "Contracted power for valley period P3 (kW)",
|
||||||
|
"tariff": "Applicable tariff by geographic zone"
|
||||||
},
|
},
|
||||||
"description": "This sensor uses official API to get [hourly pricing of electricity (PVPC)](https://www.esios.ree.es/es/pvpc) in Spain.\nFor more precise explanation visit the [integration docs](https://www.home-assistant.io/integrations/pvpc_hourly_pricing/).\n\nSelect the contracted rate based on the number of billing periods per day:\n- 1 period: normal\n- 2 periods: discrimination (nightly rate)\n- 3 periods: electric car (nightly rate of 3 periods)",
|
"description": "This sensor uses official API to get [hourly pricing of electricity (PVPC)](https://www.esios.ree.es/es/pvpc) in Spain.\nFor more precise explanation visit the [integration docs](https://www.home-assistant.io/integrations/pvpc_hourly_pricing/).",
|
||||||
"title": "Tariff selection"
|
"title": "Sensor setup"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"data": {
|
||||||
|
"power": "Contracted power (kW)",
|
||||||
|
"power_p3": "Contracted power for valley period P3 (kW)",
|
||||||
|
"tariff": "Applicable tariff by geographic zone"
|
||||||
|
},
|
||||||
|
"description": "This sensor uses official API to get [hourly pricing of electricity (PVPC)](https://www.esios.ree.es/es/pvpc) in Spain.\nFor more precise explanation visit the [integration docs](https://www.home-assistant.io/integrations/pvpc_hourly_pricing/).",
|
||||||
|
"title": "Sensor setup"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ aiopulse==0.4.2
|
|||||||
aiopvapi==1.6.14
|
aiopvapi==1.6.14
|
||||||
|
|
||||||
# homeassistant.components.pvpc_hourly_pricing
|
# homeassistant.components.pvpc_hourly_pricing
|
||||||
aiopvpc==2.1.2
|
aiopvpc==2.2.0
|
||||||
|
|
||||||
# homeassistant.components.webostv
|
# homeassistant.components.webostv
|
||||||
aiopylgtv==0.4.0
|
aiopylgtv==0.4.0
|
||||||
|
@ -146,7 +146,7 @@ aiopulse==0.4.2
|
|||||||
aiopvapi==1.6.14
|
aiopvapi==1.6.14
|
||||||
|
|
||||||
# homeassistant.components.pvpc_hourly_pricing
|
# homeassistant.components.pvpc_hourly_pricing
|
||||||
aiopvpc==2.1.2
|
aiopvpc==2.2.0
|
||||||
|
|
||||||
# homeassistant.components.webostv
|
# homeassistant.components.webostv
|
||||||
aiopylgtv==0.4.0
|
aiopylgtv==0.4.0
|
||||||
|
@ -14,6 +14,7 @@ from tests.test_util.aiohttp import AiohttpClientMocker
|
|||||||
FIXTURE_JSON_DATA_2019_10_26 = "PVPC_CURV_DD_2019_10_26.json"
|
FIXTURE_JSON_DATA_2019_10_26 = "PVPC_CURV_DD_2019_10_26.json"
|
||||||
FIXTURE_JSON_DATA_2019_10_27 = "PVPC_CURV_DD_2019_10_27.json"
|
FIXTURE_JSON_DATA_2019_10_27 = "PVPC_CURV_DD_2019_10_27.json"
|
||||||
FIXTURE_JSON_DATA_2019_10_29 = "PVPC_CURV_DD_2019_10_29.json"
|
FIXTURE_JSON_DATA_2019_10_29 = "PVPC_CURV_DD_2019_10_29.json"
|
||||||
|
FIXTURE_JSON_DATA_2021_06_01 = "PVPC_CURV_DD_2021_06_01.json"
|
||||||
|
|
||||||
|
|
||||||
def check_valid_state(state, tariff: str, value=None, key_attr=None):
|
def check_valid_state(state, tariff: str, value=None, key_attr=None):
|
||||||
@ -60,4 +61,10 @@ def pvpc_aioclient_mock(aioclient_mock: AiohttpClientMocker):
|
|||||||
text=load_fixture(f"{DOMAIN}/{FIXTURE_JSON_DATA_2019_10_29}"),
|
text=load_fixture(f"{DOMAIN}/{FIXTURE_JSON_DATA_2019_10_29}"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# new format for prices >= 2021-06-01
|
||||||
|
aioclient_mock.get(
|
||||||
|
"https://api.esios.ree.es/archives/70/download_json?locale=es&date=2021-06-01",
|
||||||
|
text=load_fixture(f"{DOMAIN}/{FIXTURE_JSON_DATA_2021_06_01}"),
|
||||||
|
)
|
||||||
|
|
||||||
return aioclient_mock
|
return aioclient_mock
|
||||||
|
@ -3,7 +3,13 @@ from datetime import datetime
|
|||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from homeassistant import config_entries, data_entry_flow
|
from homeassistant import config_entries, data_entry_flow
|
||||||
from homeassistant.components.pvpc_hourly_pricing import ATTR_TARIFF, DOMAIN
|
from homeassistant.components.pvpc_hourly_pricing import (
|
||||||
|
ATTR_POWER,
|
||||||
|
ATTR_POWER_P3,
|
||||||
|
ATTR_TARIFF,
|
||||||
|
DOMAIN,
|
||||||
|
TARIFFS,
|
||||||
|
)
|
||||||
from homeassistant.const import CONF_NAME
|
from homeassistant.const import CONF_NAME
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
@ -20,13 +26,20 @@ async def test_config_flow(
|
|||||||
"""
|
"""
|
||||||
Test config flow for pvpc_hourly_pricing.
|
Test config flow for pvpc_hourly_pricing.
|
||||||
|
|
||||||
- Create a new entry with tariff "normal"
|
- Create a new entry with tariff "2.0TD (Ceuta/Melilla)"
|
||||||
- Check state and attributes
|
- Check state and attributes
|
||||||
- Check abort when trying to config another with same tariff
|
- Check abort when trying to config another with same tariff
|
||||||
- Check removal and add again to check state restoration
|
- Check removal and add again to check state restoration
|
||||||
|
- Configure options to change power and tariff to "2.0TD"
|
||||||
"""
|
"""
|
||||||
hass.config.time_zone = dt_util.get_time_zone("Europe/Madrid")
|
hass.config.time_zone = dt_util.get_time_zone("Europe/Madrid")
|
||||||
mock_data = {"return_time": datetime(2019, 10, 26, 14, 0, tzinfo=date_util.UTC)}
|
tst_config = {
|
||||||
|
CONF_NAME: "test",
|
||||||
|
ATTR_TARIFF: TARIFFS[1],
|
||||||
|
ATTR_POWER: 4.6,
|
||||||
|
ATTR_POWER_P3: 5.75,
|
||||||
|
}
|
||||||
|
mock_data = {"return_time": datetime(2021, 6, 1, 12, 0, tzinfo=date_util.UTC)}
|
||||||
|
|
||||||
def mock_now():
|
def mock_now():
|
||||||
return mock_data["return_time"]
|
return mock_data["return_time"]
|
||||||
@ -38,13 +51,13 @@ async def test_config_flow(
|
|||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], {CONF_NAME: "test", ATTR_TARIFF: "normal"}
|
result["flow_id"], tst_config
|
||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get("sensor.test")
|
state = hass.states.get("sensor.test")
|
||||||
check_valid_state(state, tariff="normal")
|
check_valid_state(state, tariff=TARIFFS[1])
|
||||||
assert pvpc_aioclient_mock.call_count == 1
|
assert pvpc_aioclient_mock.call_count == 1
|
||||||
|
|
||||||
# Check abort when configuring another with same tariff
|
# Check abort when configuring another with same tariff
|
||||||
@ -53,7 +66,7 @@ async def test_config_flow(
|
|||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], {CONF_NAME: "test", ATTR_TARIFF: "normal"}
|
result["flow_id"], tst_config
|
||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
assert pvpc_aioclient_mock.call_count == 1
|
assert pvpc_aioclient_mock.call_count == 1
|
||||||
@ -70,11 +83,38 @@ async def test_config_flow(
|
|||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], {CONF_NAME: "test", ATTR_TARIFF: "normal"}
|
result["flow_id"], tst_config
|
||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get("sensor.test")
|
state = hass.states.get("sensor.test")
|
||||||
check_valid_state(state, tariff="normal")
|
check_valid_state(state, tariff=TARIFFS[1])
|
||||||
|
price_pbc = state.state
|
||||||
assert pvpc_aioclient_mock.call_count == 2
|
assert pvpc_aioclient_mock.call_count == 2
|
||||||
|
assert state.attributes["period"] == "P2"
|
||||||
|
assert state.attributes["next_period"] == "P1"
|
||||||
|
assert state.attributes["available_power"] == 4600
|
||||||
|
|
||||||
|
# check options flow
|
||||||
|
current_entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
|
assert len(current_entries) == 1
|
||||||
|
config_entry = current_entries[0]
|
||||||
|
|
||||||
|
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == "init"
|
||||||
|
|
||||||
|
result = await hass.config_entries.options.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={ATTR_TARIFF: TARIFFS[0], ATTR_POWER: 3.0, ATTR_POWER_P3: 4.6},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get("sensor.test")
|
||||||
|
price_cym = state.state
|
||||||
|
check_valid_state(state, tariff=TARIFFS[0])
|
||||||
|
assert pvpc_aioclient_mock.call_count == 3
|
||||||
|
assert state.attributes["period"] == "P2"
|
||||||
|
assert state.attributes["next_period"] == "P1"
|
||||||
|
assert state.attributes["available_power"] == 3000
|
||||||
|
assert price_cym < price_pbc
|
||||||
|
@ -3,15 +3,20 @@ from datetime import datetime, timedelta
|
|||||||
import logging
|
import logging
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from homeassistant.components.pvpc_hourly_pricing import ATTR_TARIFF, DOMAIN
|
from homeassistant.components.pvpc_hourly_pricing import (
|
||||||
|
ATTR_POWER,
|
||||||
|
ATTR_POWER_P3,
|
||||||
|
ATTR_TARIFF,
|
||||||
|
DOMAIN,
|
||||||
|
TARIFFS,
|
||||||
|
)
|
||||||
from homeassistant.const import CONF_NAME
|
from homeassistant.const import CONF_NAME
|
||||||
from homeassistant.core import ATTR_NOW, EVENT_TIME_CHANGED
|
from homeassistant.core import ATTR_NOW, EVENT_TIME_CHANGED
|
||||||
from homeassistant.setup import async_setup_component
|
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from .conftest import check_valid_state
|
from .conftest import check_valid_state
|
||||||
|
|
||||||
from tests.common import date_util
|
from tests.common import MockConfigEntry, date_util, mock_registry
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
|
|
||||||
@ -32,14 +37,27 @@ async def test_sensor_availability(
|
|||||||
):
|
):
|
||||||
"""Test sensor availability and handling of cloud access."""
|
"""Test sensor availability and handling of cloud access."""
|
||||||
hass.config.time_zone = dt_util.get_time_zone("Europe/Madrid")
|
hass.config.time_zone = dt_util.get_time_zone("Europe/Madrid")
|
||||||
config = {DOMAIN: [{CONF_NAME: "test_dst", ATTR_TARIFF: "discrimination"}]}
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN, data={CONF_NAME: "test_dst", ATTR_TARIFF: "discrimination"}
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||||
mock_data = {"return_time": datetime(2019, 10, 27, 20, 0, 0, tzinfo=date_util.UTC)}
|
mock_data = {"return_time": datetime(2019, 10, 27, 20, 0, 0, tzinfo=date_util.UTC)}
|
||||||
|
|
||||||
def mock_now():
|
def mock_now():
|
||||||
return mock_data["return_time"]
|
return mock_data["return_time"]
|
||||||
|
|
||||||
with patch("homeassistant.util.dt.utcnow", new=mock_now):
|
with patch("homeassistant.util.dt.utcnow", new=mock_now):
|
||||||
assert await async_setup_component(hass, DOMAIN, config)
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
|
||||||
|
# check migration
|
||||||
|
current_entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
|
assert len(current_entries) == 1
|
||||||
|
migrated_entry = current_entries[0]
|
||||||
|
assert migrated_entry.version == 1
|
||||||
|
assert migrated_entry.data[ATTR_POWER] == migrated_entry.data[ATTR_POWER_P3]
|
||||||
|
assert migrated_entry.data[ATTR_TARIFF] == TARIFFS[0]
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert pvpc_aioclient_mock.call_count == 2
|
assert pvpc_aioclient_mock.call_count == 2
|
||||||
@ -85,3 +103,64 @@ async def test_sensor_availability(
|
|||||||
assert pvpc_aioclient_mock.call_count == 33
|
assert pvpc_aioclient_mock.call_count == 33
|
||||||
assert len(caplog.messages) == 1
|
assert len(caplog.messages) == 1
|
||||||
assert caplog.records[0].levelno == logging.WARNING
|
assert caplog.records[0].levelno == logging.WARNING
|
||||||
|
|
||||||
|
|
||||||
|
async def test_multi_sensor_migration(
|
||||||
|
hass, caplog, legacy_patchable_time, pvpc_aioclient_mock: AiohttpClientMocker
|
||||||
|
):
|
||||||
|
"""Test tariff migration when there are >1 old sensors."""
|
||||||
|
entity_reg = mock_registry(hass)
|
||||||
|
hass.config.time_zone = dt_util.get_time_zone("Europe/Madrid")
|
||||||
|
uid_1 = "discrimination"
|
||||||
|
uid_2 = "normal"
|
||||||
|
old_conf_1 = {CONF_NAME: "test_pvpc_1", ATTR_TARIFF: uid_1}
|
||||||
|
old_conf_2 = {CONF_NAME: "test_pvpc_2", ATTR_TARIFF: uid_2}
|
||||||
|
|
||||||
|
config_entry_1 = MockConfigEntry(domain=DOMAIN, data=old_conf_1, unique_id=uid_1)
|
||||||
|
config_entry_1.add_to_hass(hass)
|
||||||
|
entity1 = entity_reg.async_get_or_create(
|
||||||
|
domain="sensor",
|
||||||
|
platform=DOMAIN,
|
||||||
|
unique_id=uid_1,
|
||||||
|
config_entry=config_entry_1,
|
||||||
|
suggested_object_id="test_pvpc_1",
|
||||||
|
)
|
||||||
|
|
||||||
|
config_entry_2 = MockConfigEntry(domain=DOMAIN, data=old_conf_2, unique_id=uid_2)
|
||||||
|
config_entry_2.add_to_hass(hass)
|
||||||
|
entity2 = entity_reg.async_get_or_create(
|
||||||
|
domain="sensor",
|
||||||
|
platform=DOMAIN,
|
||||||
|
unique_id=uid_2,
|
||||||
|
config_entry=config_entry_2,
|
||||||
|
suggested_object_id="test_pvpc_2",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(hass.config_entries.async_entries(DOMAIN)) == 2
|
||||||
|
assert len(entity_reg.entities) == 2
|
||||||
|
|
||||||
|
mock_data = {"return_time": datetime(2019, 10, 27, 20, tzinfo=date_util.UTC)}
|
||||||
|
|
||||||
|
def mock_now():
|
||||||
|
return mock_data["return_time"]
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
with caplog.at_level(logging.WARNING):
|
||||||
|
with patch("homeassistant.util.dt.utcnow", new=mock_now):
|
||||||
|
assert await hass.config_entries.async_setup(config_entry_1.entry_id)
|
||||||
|
assert len(caplog.messages) == 2
|
||||||
|
|
||||||
|
# check migration with removal of extra sensors
|
||||||
|
assert len(entity_reg.entities) == 1
|
||||||
|
assert entity1.entity_id in entity_reg.entities
|
||||||
|
assert entity2.entity_id not in entity_reg.entities
|
||||||
|
|
||||||
|
current_entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
|
assert len(current_entries) == 1
|
||||||
|
migrated_entry = current_entries[0]
|
||||||
|
assert migrated_entry.version == 1
|
||||||
|
assert migrated_entry.data[ATTR_POWER] == migrated_entry.data[ATTR_POWER_P3]
|
||||||
|
assert migrated_entry.data[ATTR_TARIFF] == TARIFFS[0]
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert pvpc_aioclient_mock.call_count == 2
|
||||||
|
604
tests/fixtures/pvpc_hourly_pricing/PVPC_CURV_DD_2021_06_01.json
vendored
Normal file
604
tests/fixtures/pvpc_hourly_pricing/PVPC_CURV_DD_2021_06_01.json
vendored
Normal file
@ -0,0 +1,604 @@
|
|||||||
|
{
|
||||||
|
"PVPC": [
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "00-01",
|
||||||
|
"PCB": "116,33",
|
||||||
|
"CYM": "116,33",
|
||||||
|
"COF2TD": "0,000088075182000000",
|
||||||
|
"PMHPCB": "104,00",
|
||||||
|
"PMHCYM": "104,00",
|
||||||
|
"SAHPCB": "3,56",
|
||||||
|
"SAHCYM": "3,56",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,00",
|
||||||
|
"PCAPCYM": "0,00",
|
||||||
|
"TEUPCB": "6,00",
|
||||||
|
"TEUCYM": "6,00",
|
||||||
|
"CCVPCB": "2,57",
|
||||||
|
"CCVCYM": "2,57",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "01-02",
|
||||||
|
"PCB": "115,95",
|
||||||
|
"CYM": "115,95",
|
||||||
|
"COF2TD": "0,000073094842000000",
|
||||||
|
"PMHPCB": "103,18",
|
||||||
|
"PMHCYM": "103,18",
|
||||||
|
"SAHPCB": "3,99",
|
||||||
|
"SAHCYM": "3,99",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,00",
|
||||||
|
"PCAPCYM": "0,00",
|
||||||
|
"TEUPCB": "6,00",
|
||||||
|
"TEUCYM": "6,00",
|
||||||
|
"CCVPCB": "2,58",
|
||||||
|
"CCVCYM": "2,58",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "02-03",
|
||||||
|
"PCB": "114,89",
|
||||||
|
"CYM": "114,89",
|
||||||
|
"COF2TD": "0,000065114032000000",
|
||||||
|
"PMHPCB": "101,87",
|
||||||
|
"PMHCYM": "101,87",
|
||||||
|
"SAHPCB": "4,25",
|
||||||
|
"SAHCYM": "4,25",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,00",
|
||||||
|
"PCAPCYM": "0,00",
|
||||||
|
"TEUPCB": "6,00",
|
||||||
|
"TEUCYM": "6,00",
|
||||||
|
"CCVPCB": "2,56",
|
||||||
|
"CCVCYM": "2,56",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "03-04",
|
||||||
|
"PCB": "114,96",
|
||||||
|
"CYM": "114,96",
|
||||||
|
"COF2TD": "0,000061272596000000",
|
||||||
|
"PMHPCB": "102,01",
|
||||||
|
"PMHCYM": "102,01",
|
||||||
|
"SAHPCB": "4,19",
|
||||||
|
"SAHCYM": "4,19",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,00",
|
||||||
|
"PCAPCYM": "0,00",
|
||||||
|
"TEUPCB": "6,00",
|
||||||
|
"TEUCYM": "6,00",
|
||||||
|
"CCVPCB": "2,57",
|
||||||
|
"CCVCYM": "2,57",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "04-05",
|
||||||
|
"PCB": "114,84",
|
||||||
|
"CYM": "114,84",
|
||||||
|
"COF2TD": "0,000059563056000000",
|
||||||
|
"PMHPCB": "101,87",
|
||||||
|
"PMHCYM": "101,87",
|
||||||
|
"SAHPCB": "4,21",
|
||||||
|
"SAHCYM": "4,21",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,00",
|
||||||
|
"PCAPCYM": "0,00",
|
||||||
|
"TEUPCB": "6,00",
|
||||||
|
"TEUCYM": "6,00",
|
||||||
|
"CCVPCB": "2,56",
|
||||||
|
"CCVCYM": "2,56",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "05-06",
|
||||||
|
"PCB": "116,03",
|
||||||
|
"CYM": "116,03",
|
||||||
|
"COF2TD": "0,000059907686000000",
|
||||||
|
"PMHPCB": "103,14",
|
||||||
|
"PMHCYM": "103,14",
|
||||||
|
"SAHPCB": "4,11",
|
||||||
|
"SAHCYM": "4,11",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,00",
|
||||||
|
"PCAPCYM": "0,00",
|
||||||
|
"TEUPCB": "6,00",
|
||||||
|
"TEUCYM": "6,00",
|
||||||
|
"CCVPCB": "2,58",
|
||||||
|
"CCVCYM": "2,58",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "06-07",
|
||||||
|
"PCB": "116,29",
|
||||||
|
"CYM": "116,29",
|
||||||
|
"COF2TD": "0,000062818713000000",
|
||||||
|
"PMHPCB": "103,64",
|
||||||
|
"PMHCYM": "103,64",
|
||||||
|
"SAHPCB": "3,88",
|
||||||
|
"SAHCYM": "3,88",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,00",
|
||||||
|
"PCAPCYM": "0,00",
|
||||||
|
"TEUPCB": "6,00",
|
||||||
|
"TEUCYM": "6,00",
|
||||||
|
"CCVPCB": "2,57",
|
||||||
|
"CCVCYM": "2,57",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "07-08",
|
||||||
|
"PCB": "115,70",
|
||||||
|
"CYM": "115,70",
|
||||||
|
"COF2TD": "0,000072575564000000",
|
||||||
|
"PMHPCB": "103,85",
|
||||||
|
"PMHCYM": "103,85",
|
||||||
|
"SAHPCB": "3,10",
|
||||||
|
"SAHCYM": "3,10",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,00",
|
||||||
|
"PCAPCYM": "0,00",
|
||||||
|
"TEUPCB": "6,00",
|
||||||
|
"TEUCYM": "6,00",
|
||||||
|
"CCVPCB": "2,55",
|
||||||
|
"CCVCYM": "2,55",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "08-09",
|
||||||
|
"PCB": "152,89",
|
||||||
|
"CYM": "152,89",
|
||||||
|
"COF2TD": "0,000086825264000000",
|
||||||
|
"PMHPCB": "105,65",
|
||||||
|
"PMHCYM": "105,65",
|
||||||
|
"SAHPCB": "2,36",
|
||||||
|
"SAHCYM": "2,36",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,34",
|
||||||
|
"PCAPCYM": "0,34",
|
||||||
|
"TEUPCB": "41,77",
|
||||||
|
"TEUCYM": "41,77",
|
||||||
|
"CCVPCB": "2,57",
|
||||||
|
"CCVCYM": "2,57",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "09-10",
|
||||||
|
"PCB": "150,83",
|
||||||
|
"CYM": "150,83",
|
||||||
|
"COF2TD": "0,000095768317000000",
|
||||||
|
"PMHPCB": "103,77",
|
||||||
|
"PMHCYM": "103,77",
|
||||||
|
"SAHPCB": "2,24",
|
||||||
|
"SAHCYM": "2,24",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,34",
|
||||||
|
"PCAPCYM": "0,34",
|
||||||
|
"TEUPCB": "41,77",
|
||||||
|
"TEUCYM": "41,77",
|
||||||
|
"CCVPCB": "2,53",
|
||||||
|
"CCVCYM": "2,53",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "10-11",
|
||||||
|
"PCB": "242,62",
|
||||||
|
"CYM": "149,28",
|
||||||
|
"COF2TD": "0,000102672431000000",
|
||||||
|
"PMHPCB": "102,38",
|
||||||
|
"PMHCYM": "102,11",
|
||||||
|
"SAHPCB": "2,38",
|
||||||
|
"SAHCYM": "2,37",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "2,01",
|
||||||
|
"PCAPCYM": "0,34",
|
||||||
|
"TEUPCB": "133,12",
|
||||||
|
"TEUCYM": "41,77",
|
||||||
|
"CCVPCB": "2,54",
|
||||||
|
"CCVCYM": "2,51",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "11-12",
|
||||||
|
"PCB": "240,50",
|
||||||
|
"CYM": "240,50",
|
||||||
|
"COF2TD": "0,000105691470000000",
|
||||||
|
"PMHPCB": "100,14",
|
||||||
|
"PMHCYM": "100,14",
|
||||||
|
"SAHPCB": "2,52",
|
||||||
|
"SAHCYM": "2,52",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "2,02",
|
||||||
|
"PCAPCYM": "2,02",
|
||||||
|
"TEUPCB": "133,12",
|
||||||
|
"TEUCYM": "133,12",
|
||||||
|
"CCVPCB": "2,51",
|
||||||
|
"CCVCYM": "2,51",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "12-13",
|
||||||
|
"PCB": "238,09",
|
||||||
|
"CYM": "238,09",
|
||||||
|
"COF2TD": "0,000110462952000000",
|
||||||
|
"PMHPCB": "97,58",
|
||||||
|
"PMHCYM": "97,58",
|
||||||
|
"SAHPCB": "2,71",
|
||||||
|
"SAHCYM": "2,71",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "2,02",
|
||||||
|
"PCAPCYM": "2,02",
|
||||||
|
"TEUPCB": "133,12",
|
||||||
|
"TEUCYM": "133,12",
|
||||||
|
"CCVPCB": "2,47",
|
||||||
|
"CCVCYM": "2,47",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "13-14",
|
||||||
|
"PCB": "235,30",
|
||||||
|
"CYM": "235,30",
|
||||||
|
"COF2TD": "0,000119052052000000",
|
||||||
|
"PMHPCB": "94,65",
|
||||||
|
"PMHCYM": "94,65",
|
||||||
|
"SAHPCB": "2,89",
|
||||||
|
"SAHCYM": "2,89",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "2,02",
|
||||||
|
"PCAPCYM": "2,02",
|
||||||
|
"TEUPCB": "133,12",
|
||||||
|
"TEUCYM": "133,12",
|
||||||
|
"CCVPCB": "2,43",
|
||||||
|
"CCVCYM": "2,43",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "14-15",
|
||||||
|
"PCB": "137,96",
|
||||||
|
"CYM": "231,28",
|
||||||
|
"COF2TD": "0,000117990009000000",
|
||||||
|
"PMHPCB": "89,95",
|
||||||
|
"PMHCYM": "90,19",
|
||||||
|
"SAHPCB": "3,37",
|
||||||
|
"SAHCYM": "3,38",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,34",
|
||||||
|
"PCAPCYM": "2,03",
|
||||||
|
"TEUPCB": "41,77",
|
||||||
|
"TEUCYM": "133,12",
|
||||||
|
"CCVPCB": "2,34",
|
||||||
|
"CCVCYM": "2,37",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "15-16",
|
||||||
|
"PCB": "132,88",
|
||||||
|
"CYM": "132,88",
|
||||||
|
"COF2TD": "0,000108598330000000",
|
||||||
|
"PMHPCB": "84,43",
|
||||||
|
"PMHCYM": "84,43",
|
||||||
|
"SAHPCB": "3,89",
|
||||||
|
"SAHCYM": "3,89",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,34",
|
||||||
|
"PCAPCYM": "0,34",
|
||||||
|
"TEUPCB": "41,77",
|
||||||
|
"TEUCYM": "41,77",
|
||||||
|
"CCVPCB": "2,26",
|
||||||
|
"CCVCYM": "2,26",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "16-17",
|
||||||
|
"PCB": "131,93",
|
||||||
|
"CYM": "131,93",
|
||||||
|
"COF2TD": "0,000104114191000000",
|
||||||
|
"PMHPCB": "83,66",
|
||||||
|
"PMHCYM": "83,66",
|
||||||
|
"SAHPCB": "3,73",
|
||||||
|
"SAHCYM": "3,73",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,34",
|
||||||
|
"PCAPCYM": "0,34",
|
||||||
|
"TEUPCB": "41,77",
|
||||||
|
"TEUCYM": "41,77",
|
||||||
|
"CCVPCB": "2,25",
|
||||||
|
"CCVCYM": "2,25",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "17-18",
|
||||||
|
"PCB": "135,99",
|
||||||
|
"CYM": "135,99",
|
||||||
|
"COF2TD": "0,000105171071000000",
|
||||||
|
"PMHPCB": "88,07",
|
||||||
|
"PMHCYM": "88,07",
|
||||||
|
"SAHPCB": "3,31",
|
||||||
|
"SAHCYM": "3,31",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,34",
|
||||||
|
"PCAPCYM": "0,34",
|
||||||
|
"TEUPCB": "41,77",
|
||||||
|
"TEUCYM": "41,77",
|
||||||
|
"CCVPCB": "2,31",
|
||||||
|
"CCVCYM": "2,31",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "18-19",
|
||||||
|
"PCB": "231,44",
|
||||||
|
"CYM": "138,13",
|
||||||
|
"COF2TD": "0,000106417649000000",
|
||||||
|
"PMHPCB": "90,57",
|
||||||
|
"PMHCYM": "90,33",
|
||||||
|
"SAHPCB": "3,16",
|
||||||
|
"SAHCYM": "3,15",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,16",
|
||||||
|
"FOSCYM": "0,16",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "2,02",
|
||||||
|
"PCAPCYM": "0,34",
|
||||||
|
"TEUPCB": "133,12",
|
||||||
|
"TEUCYM": "41,77",
|
||||||
|
"CCVPCB": "2,37",
|
||||||
|
"CCVCYM": "2,34",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "19-20",
|
||||||
|
"PCB": "240,40",
|
||||||
|
"CYM": "240,40",
|
||||||
|
"COF2TD": "0,000108017615000000",
|
||||||
|
"PMHPCB": "99,53",
|
||||||
|
"PMHCYM": "99,53",
|
||||||
|
"SAHPCB": "3,00",
|
||||||
|
"SAHCYM": "3,00",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "2,04",
|
||||||
|
"PCAPCYM": "2,04",
|
||||||
|
"TEUPCB": "133,12",
|
||||||
|
"TEUCYM": "133,12",
|
||||||
|
"CCVPCB": "2,52",
|
||||||
|
"CCVCYM": "2,52",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "20-21",
|
||||||
|
"PCB": "246,20",
|
||||||
|
"CYM": "246,20",
|
||||||
|
"COF2TD": "0,000114631042000000",
|
||||||
|
"PMHPCB": "104,32",
|
||||||
|
"PMHCYM": "104,32",
|
||||||
|
"SAHPCB": "3,90",
|
||||||
|
"SAHCYM": "3,90",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "2,05",
|
||||||
|
"PCAPCYM": "2,05",
|
||||||
|
"TEUPCB": "133,12",
|
||||||
|
"TEUCYM": "133,12",
|
||||||
|
"CCVPCB": "2,61",
|
||||||
|
"CCVCYM": "2,61",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "21-22",
|
||||||
|
"PCB": "248,08",
|
||||||
|
"CYM": "248,08",
|
||||||
|
"COF2TD": "0,000127585671000000",
|
||||||
|
"PMHPCB": "107,28",
|
||||||
|
"PMHCYM": "107,28",
|
||||||
|
"SAHPCB": "2,78",
|
||||||
|
"SAHCYM": "2,78",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "2,06",
|
||||||
|
"PCAPCYM": "2,06",
|
||||||
|
"TEUPCB": "133,12",
|
||||||
|
"TEUCYM": "133,12",
|
||||||
|
"CCVPCB": "2,64",
|
||||||
|
"CCVCYM": "2,64",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "22-23",
|
||||||
|
"PCB": "155,91",
|
||||||
|
"CYM": "249,41",
|
||||||
|
"COF2TD": "0,000130129026000000",
|
||||||
|
"PMHPCB": "108,02",
|
||||||
|
"PMHCYM": "108,39",
|
||||||
|
"SAHPCB": "2,93",
|
||||||
|
"SAHCYM": "2,94",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,35",
|
||||||
|
"PCAPCYM": "2,09",
|
||||||
|
"TEUPCB": "41,77",
|
||||||
|
"TEUCYM": "133,12",
|
||||||
|
"CCVPCB": "2,64",
|
||||||
|
"CCVCYM": "2,67",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Dia": "01/06/2021",
|
||||||
|
"Hora": "23-24",
|
||||||
|
"PCB": "156,50",
|
||||||
|
"CYM": "156,50",
|
||||||
|
"COF2TD": "0,000110367990000000",
|
||||||
|
"PMHPCB": "108,02",
|
||||||
|
"PMHCYM": "108,02",
|
||||||
|
"SAHPCB": "3,50",
|
||||||
|
"SAHCYM": "3,50",
|
||||||
|
"FOMPCB": "0,03",
|
||||||
|
"FOMCYM": "0,03",
|
||||||
|
"FOSPCB": "0,17",
|
||||||
|
"FOSCYM": "0,17",
|
||||||
|
"INTPCB": "0,00",
|
||||||
|
"INTCYM": "0,00",
|
||||||
|
"PCAPPCB": "0,35",
|
||||||
|
"PCAPCYM": "0,35",
|
||||||
|
"TEUPCB": "41,77",
|
||||||
|
"TEUCYM": "41,77",
|
||||||
|
"CCVPCB": "2,66",
|
||||||
|
"CCVCYM": "2,66",
|
||||||
|
"EDSRPCB": "0,00",
|
||||||
|
"EDSRCYM": "0,00"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user