Code Monkey home page Code Monkey logo

Comments (36)

djansen1987 avatar djansen1987 commented on September 4, 2024 1

Hi all, sorry for the late response. Currently (still) sick and there for do not have time and energy to work on it. Maybe someone can make a pull request and test it with an SAJ portal user. I am okay to merge it. Otherwise somewhere next weekend I might be able to work on it.

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024 1

thank you for merging and releasing @djansen1987

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

I managed to make it work temporarily by:

  • replacing the domain in the sensor.py
  • forcing it not to verify SSL certificates (seems like the cert chain is broken and HASS rejects it):
    session = async_create_clientsession(hass,False).

from sajesolar.

teamMOYA avatar teamMOYA commented on September 4, 2024

The same is happening to me. My plant is gone in the "old platform".

from sajesolar.

miguelzx avatar miguelzx commented on September 4, 2024

I managed to make it work temporarily by:

* replacing the  domain in the sensor.py

* forcing it not to verify SSL certificates (seems like the cert chain is broken and HASS rejects it):
  session = async_create_clientsession(hass,False).

Hola puede explicarlo mejor, es que no lo pillo gracias

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

@teamMOYA is your kit branded as SAJ or some other white label (eg. Greenheiss)?

from sajesolar.

arnauplan avatar arnauplan commented on September 4, 2024

Hi, the exact same thing is happening to me but I did what you said and it still doesn't work. Can you explain exactly what needs to be changed?
I have GreenHeiss.
Thanks!

from sajesolar.

teamMOYA avatar teamMOYA commented on September 4, 2024

@teamMOYA is your kit branded as SAJ or some other white label (eg. Greenheiss)?

Mine are rebranded as "Solarprofit", but they don't have a web like Saj and Greenheiss. I'll have to wait for the new web access update.

from sajesolar.

arnauplan avatar arnauplan commented on September 4, 2024

I managed to make it work temporarily by:

  • replacing the domain in the sensor.py
  • forcing it not to verify SSL certificates (seems like the cert chain is broken and HASS rejects it):
    session = async_create_clientsession(hass,False).

Where do you change the domain to inside sensor.py?
Do you change https://fop.saj-electric.com/saj to https://esaj-home.saj-electric.com/ or something?

from sajesolar.

miguelzx avatar miguelzx commented on September 4, 2024

Hello, I also had that problem.

My Greenheiss h1 inverter. I use an old integration 1.3.1 which I already have working.

Right now everything works perfectly for me

replacing the domain in the sensor.py

I leave a copy of my sensor.py, in case it helps you, but remember that I use 1.3.1

"""
Alternative for the SAJ local API sensor. Unfortunally there is no public api.
This Sensor will read the private api of the eSolar portal at https://fop.saj-electric.com/
"""

import asyncio
from homeassistant.helpers.aiohttp_client import async_create_clientsession
from datetime import timedelta
import datetime
import calendar

from functools import reduce
import logging
from typing import Final

import aiohttp
import async_timeout
import voluptuous as vol

import re
from bs4 import BeautifulSoup

from homeassistant.components.sensor import (
    PLATFORM_SCHEMA,
    STATE_CLASS_TOTAL_INCREASING,
    SensorEntity,
    SensorEntityDescription,
)
from homeassistant.const import (
    CONF_RESOURCES,
    CONF_USERNAME,
    CONF_PASSWORD,
    CONF_SENSORS,
    CONF_DEVICE_ID,
    DEVICE_CLASS_ENERGY,
    DEVICE_CLASS_POWER,
    ENERGY_KILO_WATT_HOUR,
    POWER_WATT,
    PERCENTAGE,

)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle, dt

def add_months(sourcedate, months):
    month = sourcedate.month - 1 + months
    year = sourcedate.year + month // 12
    month = month % 12 + 1
    day = min(sourcedate.day, calendar.monthrange(year,month)[1])
    return datetime.date(year, month, day)

def add_years(d, years):
    try:
        return d.replace(year = d.year + years)
    except ValueError:
        return d + (date(d.year + years, 1, 1) - date(d.year, 1, 1))

BASE_URL = 'https://inversores-style.greenheiss.com/cloud/login'
_LOGGER = logging.getLogger(__name__)

MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=3)

SENSOR_PREFIX = 'esolar '
ATTR_MEASUREMENT = "measurement"
ATTR_SECTION = "section"

SENSOR_LIST = {
    "nowPower",
    "runningState",
    "devOnlineNum",
    "todayElectricity",
    "monthElectricity",
    "yearElectricity",
    "totalElectricity",
    "todayGridIncome",
    "income",
    "lastUploadTime",
    "totalPlantTreeNum",
    "totalReduceCo2",
    "todayAlarmNum",
    "plantuid",
    "plantname",
    "currency",
    "address",
    "isOnline",
    "status",
    "peakPower",
    #sec & h1
    "pvElec",
    "useElec",
    "buyElec",
    "sellElec",
    "buyRate",
    "sellRate",
    "selfUseRate",
    "totalBuyElec",
    "totalConsumpElec",
    "totalSellElec",
    "selfConsumedRate1",
    "selfConsumedRate2",
    "selfConsumedEnergy1",
    "selfConsumedEnergy2",
    "plantTreeNum",
    "reduceCo2",
    "totalGridPower",
    "totalLoadPower",
    "totalPvgenPower",
    "totalPvEnergy",
    "totalLoadEnergy",
    "totalBuyEnergy",
    "totalSellEnergy",
    #h1
    "chargeElec",
    "dischargeElec",
    "batCapcity",
    "isAlarm",
    "batCurr",
    "batEnergyPercent",
    "batteryDirection",
    "batteryPower",
    "gridDirection",
    "gridPower",
    "h1Online",
    "outPower",
    "outPutDirection",
    "pvDirection",
    "pvPower",
    "solarPower",
    #h1s2
    "h1s2_pv_volt_1",
    "h1s2_pv_current_1",
    "h1s2_pv_power_1",
    "h1s2_pv_volt_2",
    "h1s2_pv_current_2",
    "h1s2_pv_power_2",
    "h1s2_pv_volt_3",
    "h1s2_pv_current_3",
    "h1s2_pv_power_3",
    "h1s2_bat_volt",
    "h1s2_bat_current",
    "h1s2_bat_power",
    "h1s2_bat_total_charge",
    "h1s2_bat_total_discharge",
    "h1s2_load_power",
    "h1s2_grid_volt_1",
    "h1s2_grid_current_1",
    "h1s2_grid_power_1",
    "h1s2_grid_volt_2",
    "h1s2_grid_current_2",
    "h1s2_grid_power_2",
    "h1s2_grid_volt_3",
    "h1s2_grid_current_3",
    "h1s2_grid_power_3",
}

SENSOR_TYPES: Final[tuple[SensorEntityDescription]] = (
    SensorEntityDescription(
        key="nowPower",
        name="nowPower",
        icon="mdi:solar-power",
        native_unit_of_measurement=POWER_WATT,
        device_class=DEVICE_CLASS_POWER,
    ),
    SensorEntityDescription(
        key="runningState",
        name="runningState",
        icon="mdi:solar-panel",
    ),
    SensorEntityDescription(
        key="devOnlineNum",
        name="devOnlineNum",
        icon="mdi:solar-panel",
    ),
    SensorEntityDescription(
        key="todayElectricity",
        name="todayElectricity",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
    ),
    SensorEntityDescription(
        key="monthElectricity",
        name="monthElectricity",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
    ),
    SensorEntityDescription(
        key="yearElectricity",
        name="yearElectricity",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
    ),
    SensorEntityDescription(
        key="totalElectricity",
        name="totalElectricity",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    SensorEntityDescription(
        key="selfUseRate",
        name="selfUseRate",
        icon="mdi:solar-panel",
    ),
    SensorEntityDescription(
        key="totalBuyElec",
        name="totalBuyElec",
        icon="mdi:solar-panel",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    SensorEntityDescription(
        key="totalConsumpElec",
        name="totalConsumpElec",
        icon="mdi:solar-panel",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
    ),
    SensorEntityDescription(
        key="totalSellElec",
        name="totalSellElec",
        icon="mdi:solar-panel",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    SensorEntityDescription(
        key="todayGridIncome",
        name="todayGridIncome",
        icon="mdi:currency-eur",
    ),
    SensorEntityDescription(
        key="income",
        name="income",
        icon="mdi:currency-eur",
    ),
    SensorEntityDescription(
        key="lastUploadTime",
        name="lastUploadTime",
        icon="mdi:timer-sand",
    ),
    SensorEntityDescription(
        key="totalPlantTreeNum",
        name="totalPlantTreeNum",
        icon="mdi:tree",
    ),
    SensorEntityDescription(
        key="totalReduceCo2",
        name="totalReduceCo2",
        icon="mdi:molecule-co2",
    ),
    SensorEntityDescription(
        key="todayAlarmNum",
        name="todayAlarmNum",
        icon="mdi:alarm",
    ),
    SensorEntityDescription(
        key="plantuid",
        name="plantuid",
        icon="mdi:api",
    ),
    SensorEntityDescription(
        key="plantname",
        name="plantname",
        icon="mdi:api",
    ),
    SensorEntityDescription(
        key="currency",
        name="currency",
        icon="mdi:solar-panel",
    ),
    SensorEntityDescription(
        key="address",
        name="address",
        icon="mdi:solar-panel",
    ),
    SensorEntityDescription(
        key="isOnline",
        name="isOnline",
        icon="mdi:api",
    ),
    SensorEntityDescription(
        key="status",
        name="status",
        icon="mdi:api",
    ),
    SensorEntityDescription(
        key="peakPower",
        name="peakPower",
        icon="mdi:solar-panel",
        native_unit_of_measurement=POWER_WATT,
        device_class=DEVICE_CLASS_POWER,
    ),
    SensorEntityDescription(
        key="pvElec",
        name="pvElec",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
    ),
    SensorEntityDescription(
        key="useElec",
        name="useElec",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    SensorEntityDescription(
        key="buyElec",
        name="buyElec",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    SensorEntityDescription(
        key="sellElec",
        name="sellElec",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    SensorEntityDescription(
        key="buyRate",
        name="buyRate",
        icon="mdi:solar-panel",
    ),
    SensorEntityDescription(
        key="sellRate",
        name="sellRate",
        icon="mdi:solar-panel",
    ),
    SensorEntityDescription(
        key="selfConsumedRate1",
        name="selfConsumedRate1",
        icon="mdi:solar-panel",
    ),
    SensorEntityDescription(
        key="selfConsumedRate2",
        name="selfConsumedRate2",
        icon="mdi:solar-panel",
    ),
    SensorEntityDescription(
        key="selfConsumedEnergy1",
        name="selfConsumedEnergy1",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
    ),
    SensorEntityDescription(
        key="selfConsumedEnergy2",
        name="selfConsumedEnergy2",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
    ),
    SensorEntityDescription(
        key="plantTreeNum",
        name="plantTreeNum",
        icon="mdi:tree",
    ),
    SensorEntityDescription(
        key="reduceCo2",
        name="reduceCo2",
        icon="mdi:molecule-co2",
    ),
    SensorEntityDescription(
        key="totalGridPower",
        name="totalGridPower",
        icon="mdi:solar-panel",
        native_unit_of_measurement=POWER_WATT,
    ),
    SensorEntityDescription(
        key="totalLoadPower",
        name="totalLoadPower",
        icon="mdi:solar-panel",
        native_unit_of_measurement=POWER_WATT,
        device_class=DEVICE_CLASS_POWER,
    ),
    SensorEntityDescription(
        key="totalPvgenPower",
        name="totalPvgenPower",
        icon="mdi:solar-panel",
        native_unit_of_measurement=POWER_WATT,
    ),
    SensorEntityDescription(
        key="totalPvEnergy",
        name="totalPvEnergy",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    SensorEntityDescription(
        key="totalLoadEnergy",
        name="totalLoadEnergy",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    SensorEntityDescription(
        key="totalBuyEnergy",
        name="totalBuyEnergy",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    SensorEntityDescription(
        key="totalSellEnergy",
        name="totalSellEnergy",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    #h1
    SensorEntityDescription(
        key="batCapcity",
        name="batCapcity",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="A·h"
    ),
    SensorEntityDescription(
        key="isAlarm",
        name="isAlarm",
        icon="mdi:solar-panel-large",
    ),
    SensorEntityDescription(
        key="batCurr",
        name="batCurr",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="A"
    ),
    SensorEntityDescription(
        key="batEnergyPercent",
        name="batEnergyPercent",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=PERCENTAGE,
    ),
    SensorEntityDescription(
        key="batteryDirection",
        name="batteryDirection",
        icon="mdi:solar-panel-large",
    ),
    SensorEntityDescription(
        key="batteryPower",
        name="batteryPower",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=POWER_WATT,
    ),
    SensorEntityDescription(
        key="gridPower",
        name="gridPower",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=POWER_WATT,
    ),
    SensorEntityDescription(
        key="h1Online",
        name="h1Online",
        icon="mdi:solar-panel-large",
    ),
    SensorEntityDescription(
        key="outPower",
        name="outPower",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=POWER_WATT,
    ),
    SensorEntityDescription(
        key="outPutDirection",
        name="outPutDirection",
        icon="mdi:solar-panel-large",
    ),
    SensorEntityDescription(
        key="pvPower",
        name="pvPower",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=POWER_WATT,

    ),
    SensorEntityDescription(
        key="solarPower",
        name="solarPower",
        icon="mdi:solar-panel-large",
    ),
    SensorEntityDescription(
        key="chargeElec",
        name="chargeElec",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    SensorEntityDescription(
        key="dischargeElec",
        name="dischargeElec",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement=ENERGY_KILO_WATT_HOUR,
        device_class=DEVICE_CLASS_ENERGY,
        state_class=STATE_CLASS_TOTAL_INCREASING,
    ),
    #h1s2
    SensorEntityDescription(
        key="h1s2_pv_volt_1",
        name="h1s2_pv_volt_1",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="V"
    ),
    SensorEntityDescription(
        key="h1s2_pv_current_1",
        name="h1s2_pv_current_1",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="A"
    ),
    SensorEntityDescription(
        key="h1s2_pv_power_1",
        name="h1s2_pv_power_1",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="W"
    ),
    SensorEntityDescription(
        key="h1s2_pv_volt_2",
        name="h1s2_pv_volt_2",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="V"
    ),
    SensorEntityDescription(
        key="h1s2_pv_current_2",
        name="h1s2_pv_current_2",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="A"
    ),
    SensorEntityDescription(
        key="h1s2_pv_power_2",
        name="h1s2_pv_power_2",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="W"
    ),
    SensorEntityDescription(
        key="h1s2_pv_volt_3",
        name="h1s2_pv_volt_3",
        icon="mdi:solar-panel-large",
    ),
    SensorEntityDescription(
        key="h1s2_pv_current_3",
        name="h1s2_pv_current_3",
        icon="mdi:solar-panel-large",
    ),
    SensorEntityDescription(
        key="h1s2_pv_power_3",
        name="h1s2_pv_power_3",
        icon="mdi:solar-panel-large",
    ),
    SensorEntityDescription(
        key="h1s2_bat_volt",
        name="h1s2_bat_volt",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="V"
    ),
    SensorEntityDescription(
        key="h1s2_bat_current",
        name="h1s2_bat_current",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="A"
    ),
    SensorEntityDescription(
        key="h1s2_bat_power",
        name="h1s2_bat_power",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="W"
    ),
    SensorEntityDescription(
        key="h1s2_bat_total_charge",
        name="h1s2_bat_total_charge",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="Ah"
    ),
    SensorEntityDescription(
        key="h1s2_bat_total_discharge",
        name="h1s2_bat_total_discharge",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="Ah"
    ),
    SensorEntityDescription(
        key="h1s2_load_power",
        name="h1s2_load_power",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="W"
    ),
    SensorEntityDescription(
        key="h1s2_grid_volt_1",
        name="h1s2_grid_volt_1",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="V"

    ),
    SensorEntityDescription(
        key="h1s2_grid_current_1",
        name="h1s2_grid_current_1",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="A"

    ),
    SensorEntityDescription(
        key="h1s2_grid_power_1",
        name="h1s2_grid_power_1",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="W"

    ),
    SensorEntityDescription(
        key="h1s2_grid_volt_2",
        name="h1s2_grid_volt_2",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="V"

    ),
    SensorEntityDescription(
        key="h1s2_grid_current_2",
        name="h1s2_grid_current_2",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="A"

    ),
    SensorEntityDescription(
        key="h1s2_grid_power_2",
        name="h1s2_grid_power_2",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="W"

    ),
    SensorEntityDescription(
        key="h1s2_grid_volt_3",
        name="h1s2_grid_volt_3",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="V"
    ),
    SensorEntityDescription(
        key="h1s2_grid_current_3",
        name="h1s2_grid_current_3",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="A"

    ),
    SensorEntityDescription(
        key="h1s2_grid_power_3",
        name="h1s2_grid_power_3",
        icon="mdi:solar-panel-large",
        native_unit_of_measurement="W"

    ),
)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Required(CONF_USERNAME): cv.string,
        vol.Required(CONF_PASSWORD): cv.string,
        vol.Required(CONF_RESOURCES, default=list(SENSOR_LIST)): vol.All(
            cv.ensure_list, [vol.In(SENSOR_LIST)]
        ),
        vol.Optional(CONF_SENSORS, default="None"): cv.string,
        vol.Optional(CONF_DEVICE_ID, default="None"): cv.string,
    }
)

async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):

    """Setup the SAJ eSolar sensors."""

    session = async_create_clientsession(hass,False)
    data = SAJeSolarMeterData(session, config.get(CONF_USERNAME), config.get(CONF_PASSWORD), config.get(CONF_SENSORS), config.get(CONF_DEVICE_ID))
    await data.async_update()

    entities = []
    for description in SENSOR_TYPES:
        if description.key in config[CONF_RESOURCES]:
            sensor = SAJeSolarMeterSensor(description, data, config.get(CONF_SENSORS))
            entities.append(sensor)
    async_add_entities(entities, True)
    return True

class SAJeSolarMeterData(object):
    """Handle eSolar object and limit updates."""

    def __init__(self, session, username, password, sensors, sec_sn):
        """Initialize the data object."""

        self._session = session
        self._url = BASE_URL
        self.username = username
        self.password = password
        self.sensors = sensors
        self.sec_sn = sec_sn
        self._data = None

    @Throttle(MIN_TIME_BETWEEN_UPDATES)
    async def async_update(self):
        """Download and update data from SAJeSolar."""

        try:

            today = datetime.date.today()
            clientDate = today.strftime('%Y-%m-%d')

            # Login to eSolar API
            url = 'https://inversores-style.greenheiss.com/cloud/login'
            payload = {
                'lang': 'en',
                'username': self.username,
                'password': self.password,
                'rememberMe': 'true'
            }
            headers_login = {
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
                'Accept-Encoding': 'gzip, deflate, br',
                'Accept-Language': 'nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7',
                'Cache-Control': 'max-age=0',
                'Connection': 'keep-alive',
                'Content-Type': 'application/x-www-form-urlencoded',
                'Cookie': 'org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=en; op_esolar_lang=en',
                'DNT': '1',
                'Host': 'inversores-style.greenheiss.com',
                'Origin': 'https://inversores-style.greenheiss.com',
                'Referer': 'https://inversores-style.greenheiss.com/cloud/login',
                'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
                'sec-ch-ua-mobile': '?0',
                'Sec-Fetch-Dest': 'document',
                'Sec-Fetch-Mode': 'navigate',
                'Sec-Fetch-Site': 'same-origin',
                'Sec-Fetch-User': '?1',
                'Upgrade-Insecure-Requests': '1',
                'User-Agent'
                : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
            }
            response = await self._session.post(url, headers=headers_login, data=payload)

            if response.status != 200:
                _LOGGER.error(f"{response.url} returned {response.status}")
                return


            # Get API Plant info from Esolar Portal
            url2 = 'https://inversores-style.greenheiss.com/cloud/monitor/site/getUserPlantList'
            headers = {
                'Connection': 'keep-alive',
                'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
                'Accept': 'application/json, text/javascript, */*; q=0.01',
                'DNT': '1',
                'X-Requested-With': 'XMLHttpRequest',
                'sec-ch-ua-mobile': '?0',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36',
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                'Origin': 'https://inversores-style.greenheiss.com',
                'Sec-Fetch-Site': 'same-origin',
                'Sec-Fetch-Mode': 'cors',
                'Sec-Fetch-Dest': 'empty',
                'Referer': 'https://inversores-style.greenheiss.com/cloud/monitor/home/index',
                'Accept-Language': 'nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7'
            }

            payload2= f"pageNo=&pageSize=&orderByIndex=&officeId=&clientDate={clientDate}&runningState=&selectInputType=1&plantName=&deviceSn=&type=&countryCode=&isRename=&isTimeError=&systemPowerLeast=&systemPowerMost="
            response2 = await self._session.post(url2, headers=headers, data=payload2)

            if response2.status != 200:
                _LOGGER.error(f"{response2.url} returned {response2.status}")
                return

            plantInfo = await response2.json()
            plantuid = plantInfo['plantList'][0]['plantuid']


            # Get API Plant Solar Details
            url3 = "https://inversores-style.greenheiss.com/cloud/monitor/site/getPlantDetailInfo"
            payload3= f"plantuid={plantuid}&clientDate={clientDate}"

            response3 = await self._session.post(url3, headers=headers, data=payload3)

            if response3.status != 200:
                _LOGGER.error(f"{response3.url} returned {response3.status}")
                return

            plantDetails = await response3.json()
            plantDetails.update(plantInfo)


            # getPlantDetailChart2
            plantuid = plantDetails['plantList'][0]['plantuid']
            deviceSnArr = plantDetails['plantDetail']['snList'][0]
            previousChartDay = today - timedelta(days=1)
            nextChartDay = today + timedelta(days = 1)
            chartDay = today.strftime('%Y-%m-%d')
            previousChartMonth = add_months(today,-1).strftime('%Y-%m')
            nextChartMonth = add_months(today, 1).strftime('%Y-%m')
            chartMonth = today.strftime('%Y-%m')
            previousChartYear = add_years(today, -1).strftime('%Y')
            nextChartYear = add_years(today, 1).strftime('%Y')
            chartYear = today.strftime('%Y')
            epochmilliseconds = round(int((datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1)).total_seconds() * 1000))

            url4 = f"https://inversores-style.greenheiss.com/cloud/monitor/site/getPlantDetailChart2?plantuid={plantuid}&chartDateType=1&energyType=0&clientDate={clientDate}&deviceSnArr={deviceSnArr}&chartCountType=2&previousChartDay={previousChartDay}&nextChartDay={nextChartDay}&chartDay={chartDay}&previousChartMonth={previousChartMonth}&nextChartMonth={nextChartMonth}&chartMonth={chartMonth}&previousChartYear={previousChartYear}&nextChartYear={nextChartYear}&chartYear={chartYear}&elecDevicesn=&_={epochmilliseconds}"

            response4 = await self._session.post(url4, headers=headers)

            if response4.status != 200:
                _LOGGER.error(f"{response4.url} returned {response4.status}")
                return

            plantcharts = await response4.json()
            plantDetails.update(plantcharts)


            # H1 Module
            if self.sensors == "h1":
                # getStoreOrAcDevicePowerInfo
                url_getStoreOrAcDevicePowerInfo = f"https://inversores-style.greenheiss.com/cloud/monitor/site/getStoreOrAcDevicePowerInfo?plantuid=&devicesn={deviceSnArr}&_={epochmilliseconds}"

                response_getStoreOrAcDevicePowerInfo = await self._session.post(url_getStoreOrAcDevicePowerInfo, headers=headers)

                if response_getStoreOrAcDevicePowerInfo.status != 200:
                    _LOGGER.error(f"{response_getStoreOrAcDevicePowerInfo.url} returned {response_getStoreOrAcDevicePowerInfo.status}")
                    return

                result_getStoreOrAcDevicePowerInfo = await response_getStoreOrAcDevicePowerInfo.json()
                plantDetails.update(result_getStoreOrAcDevicePowerInfo)
                _LOGGER.debug(result_getStoreOrAcDevicePowerInfo)

                url5 = f"https://inversores-style.greenheiss.com/cloud/cloudMonitor/deviceInfo?devicesn={deviceSnArr}"
                response5 = await self._session.get(url5, headers=headers)
                if response5.status != 200:
                    _LOGGER.error(f"{response5.url} returned {response5.status}")


                html = await response5.text()

                soup = BeautifulSoup(html, "lxml")
                span = soup.select(".real_num span")

                h1s2= {
                    "h1s2": {
                        "h1s2_pv_volt_1":re.sub(r'[^0-9.]', '', (span[0].text).split("/")[0]),
                        "h1s2_pv_current_1":re.sub(r'[^0-9.]', '', (span[0].text).split("/")[1]),
                        "h1s2_pv_power_1":re.sub(r'[^0-9.]', '', (span[0].text).split("/")[2]),

                        "h1s2_pv_volt_2":re.sub(r'[^0-9.]', '', (span[1].text).split("/")[0]),
                        "h1s2_pv_current_2":re.sub(r'[^0-9.]', '', (span[1].text).split("/")[1]),
                        "h1s2_pv_power_2":re.sub(r'[^0-9.]', '', (span[1].text).split("/")[2]),

                        "h1s2_pv_volt_3":re.sub(r'[^0-9.]', '', (span[2].text).split("/")[0]),
                        "h1s2_pv_current_3":re.sub(r'[^0-9.]', '', (span[2].text).split("/")[1]),
                        "h1s2_pv_power_3":re.sub(r'[^0-9.]', '', (span[2].text).split("/")[2]),

                        "h1s2_bat_volt":re.sub(r'[^0-9.]', '', (span[3].text).split("/")[0]),
                        "h1s2_bat_current":re.sub(r'[^0-9.\-]', '', (span[3].text).split("/")[1]),
                        "h1s2_bat_power":re.sub(r'[^0234567891.\-]', '', (span[3].text).split("/")[2]),

                        "h1s2_bat_total_charge":re.sub(r'[^0-9.]', '', (span[4].text).split("/")[0]),
                        "h1s2_bat_total_discharge":re.sub(r'[^0-9.]', '', (span[4].text).split("/")[1]),

                        "h1s2_load_power":re.sub(r'[^0-9.]', '', span[5].text),

                        "h1s2_grid_volt_1":re.sub(r'[^0-9.]', '', (span[6].text).split("/")[0]),
                        "h1s2_grid_current_1":re.sub(r'[^0-9.]', '', (span[6].text).split("/")[1]),
                        "h1s2_grid_power_1":re.sub(r'[^0-9.]', '', (span[6].text).split("/")[2]),

                        "h1s2_grid_volt_2":re.sub(r'[^0-9.]', '', (span[7].text).split("/")[0]),
                        "h1s2_grid_current_2":re.sub(r'[^0-9.]', '', (span[7].text).split("/")[1]),
                        "h1s2_grid_power_2":re.sub(r'[^0-9.]', '', (span[7].text).split("/")[2]),

                        "h1s2_grid_volt_3":re.sub(r'[^0-9.]', '', (span[8].text).split("/")[0]),
                        "h1s2_grid_current_3":re.sub(r'[^0-9.]', '', (span[8].text).split("/")[1]),
                        "h1s2_grid_power_3":re.sub(r'[^0-9.]', '', (span[8].text).split("/")[2]),

                        "h1s2_pv_volt_1":re.sub(r'[^0-9.]', '', (span[0].text).split("/")[0]),
                        "h1s2_pv_current_1":re.sub(r'[^0-9.]', '', (span[0].text).split("/")[1]),
                        "h1s2_pv_power_1":re.sub(r'[^0-9.]', '', (span[0].text).split("/")[2]),

                        "h1s2_pv_volt_2":re.sub(r'[^0-9.]', '', (span[1].text).split("/")[0]),
                        "h1s2_pv_current_2":re.sub(r'[^0-9.]', '', (span[1].text).split("/")[1]),
                        "h1s2_pv_power_2":re.sub(r'[^0-9.]', '', (span[1].text).split("/")[2]),

                        "h1s2_pv_volt_3":re.sub(r'[^0-9.]', '', (span[2].text).split("/")[0]),
                        "h1s2_pv_current_3":re.sub(r'[^0-9.]', '', (span[2].text).split("/")[1]),
                        "h1s2_pv_power_3":re.sub(r'[^0-9.]', '', (span[2].text).split("/")[2]),

                        "h1s2_bat_volt":re.sub(r'[^0-9.]', '', (span[3].text).split("/")[0]),
                        "h1s2_bat_current":re.sub(r'[^0-9.]', '', (span[3].text).split("/")[1]),
                        "h1s2_bat_power":re.sub(r'[^0-9.]', '', (span[3].text).split("/")[2]),

                        "h1s2_bat_total_charge":re.sub(r'[^0-9.]', '', (span[4].text).split("/")[0]),
                        "h1s2_bat_total_discharge":re.sub(r'[^0-9.]', '', (span[4].text).split("/")[1]),

                        "h1s2_load_power":re.sub(r'[^0-9.]', '', span[5].text),

                        "h1s2_grid_volt_1":re.sub(r'[^0-9.]', '', (span[6].text).split("/")[0]),
                        "h1s2_grid_current_1":re.sub(r'[^0-9.]', '', (span[6].text).split("/")[1]),
                        "h1s2_grid_power_1":re.sub(r'[^0-9.]', '', (span[6].text).split("/")[2]),

                        "h1s2_grid_volt_2":re.sub(r'[^0-9.]', '', (span[7].text).split("/")[0]),
                        "h1s2_grid_current_2":re.sub(r'[^0-9.]', '', (span[7].text).split("/")[1]),
                        "h1s2_grid_power_2":re.sub(r'[^0-9.]', '', (span[7].text).split("/")[2]),

                        "h1s2_grid_volt_3":re.sub(r'[^0-9.]', '', (span[8].text).split("/")[0]),
                        "h1s2_grid_current_3":re.sub(r'[^0-9.]', '', (span[8].text).split("/")[1]),
                        "h1s2_grid_power_3":re.sub(r'[^0-9.]', '', (span[8].text).split("/")[2])
                    }
                }

                plantDetails.update(h1s2)




            elif self.sensors == "None":
                self._data = plantDetails
            else:
                # Data = plantdetails
                self._data = plantDetails



            # Sec module
            if self.sensors == "saj_sec":

                # getPlantMeterModuleList
                url_module = "https://inversores-style.greenheiss.com/cloud/saj/cloudmonitor/plantMeterModule/getPlantMeterModuleList"

                payload_module = f"pageNo=&pageSize=&plantUid={plantuid}"

                response_module = await self._session.post(url_module, headers=headers, data=payload_module)

                if response_module.status != 200:
                    _LOGGER.error(f"{response_module.url} returned {response_module.status}")
                    return

                getPlantMeterModuleList = await response_module.json()

                temp_getPlantMeterModuleList = dict()
                temp_getPlantMeterModuleList["getPlantMeterModuleList"] = getPlantMeterModuleList

                plantDetails.update(temp_getPlantMeterModuleList)

                moduleSn = plantDetails["getPlantMeterModuleList"]['moduleList'][0]['moduleSn']

                # -Debug- Sec module serial number
                _LOGGER.debug(moduleSn)


                # findDevicePageList
                url_findDevicePageList = "https://inversores-style.greenheiss.com/cloud/cloudMonitor/device/findDevicePageList"

                payload_findDevicePageList = f"officeId=1&pageNo=&pageSize=&orderName=1&orderType=2&plantuid={plantuid}&deviceStatus=&localDate={chartMonth}&localMonth={chartMonth}"

                response_findDevicePageList = await self._session.post(url_findDevicePageList, headers=headers, data=payload_findDevicePageList)

                if response_findDevicePageList.status != 200:
                    _LOGGER.error(f"{response_findDevicePageList.url} returned {response_findDevicePageList.status}")
                    return

                findDevicePageList = await response_findDevicePageList.json()

                temp_findDevicePageList = dict()
                temp_findDevicePageList["findDevicePageList"] = findDevicePageList

                plantDetails.update(temp_findDevicePageList)

                # getPlantMeterDetailInfo
                url_getPlantMeterDetailInfo = "https://inversores-style.greenheiss.com/cloud/monitor/site/getPlantMeterDetailInfo"

                payload_getPlantMeterDetailInfo = f"plantuid={plantuid}&clientDate={clientDate}"

                response_getPlantMeterDetailInfo = await self._session.post(url_getPlantMeterDetailInfo, headers=headers, data=payload_getPlantMeterDetailInfo)

                if response_getPlantMeterDetailInfo.status != 200:
                    _LOGGER.error(f"{response_getPlantMeterDetailInfo.url} returned {response_getPlantMeterDetailInfo.status}")
                    return

                getPlantMeterDetailInfo = await response_getPlantMeterDetailInfo.json()

                temp_getPlantMeterDetailInfo = dict()
                temp_getPlantMeterDetailInfo["getPlantMeterDetailInfo"] = getPlantMeterDetailInfo

                plantDetails.update(temp_getPlantMeterDetailInfo)

                # getPlantMeterEnergyPreviewInfo
                url_getPlantMeterEnergyPreviewInfo = f"https://inversores-style.greenheiss.com/cloud/monitor/site/getPlantMeterEnergyPreviewInfo?plantuid={plantuid}&moduleSn={moduleSn}&_={epochmilliseconds}"

                response_getPlantMeterEnergyPreviewInfo = await self._session.get(url_getPlantMeterEnergyPreviewInfo, headers=headers)

                if response_getPlantMeterEnergyPreviewInfo.status != 200:
                    _LOGGER.error(f"{response_getPlantMeterEnergyPreviewInfo.url} returned {response_getPlantMeterEnergyPreviewInfo.status}")
                    return

                getPlantMeterEnergyPreviewInfo = await response_getPlantMeterEnergyPreviewInfo.json()

                temp_getPlantMeterEnergyPreviewInfo = dict()
                temp_getPlantMeterEnergyPreviewInfo["getPlantMeterEnergyPreviewInfo"] = getPlantMeterEnergyPreviewInfo

                plantDetails.update(temp_getPlantMeterEnergyPreviewInfo)

                # Get Sec Meter details
                url_getPlantMeterChartData = f"https://inversores-style.greenheiss.com/cloud/monitor/site/getPlantMeterChartData?plantuid={plantuid}&chartDateType=1&energyType=0&clientDate={clientDate}&deviceSnArr=&chartCountType=2&previousChartDay={previousChartDay}&nextChartDay={nextChartDay}&chartDay={chartDay}&previousChartMonth={previousChartMonth}&nextChartMonth={nextChartMonth}&chartMonth={chartMonth}&previousChartYear={previousChartYear}&nextChartYear={nextChartYear}&chartYear={chartYear}&moduleSn={moduleSn}&_={epochmilliseconds}"

                response_getPlantMeterChartData = await self._session.post(url_getPlantMeterChartData, headers=headers)

                if response_getPlantMeterChartData.status != 200:
                    _LOGGER.error(f"{response_getPlantMeterChartData.url} returned {response_getPlantMeterChartData.status}")
                    return

                getPlantMeterChartData = await response_getPlantMeterChartData.json()

                temp_getPlantMeterChartData = dict()
                temp_getPlantMeterChartData["getPlantMeterChartData"] = getPlantMeterChartData

                plantDetails.update(temp_getPlantMeterChartData)

                # Data = plantdetails including Sec module
                self._data = plantDetails
            elif self.sensors == "None":
                self._data = plantDetails
            else:
                # Data = plantdetails Wtihout Sec module
                self._data = plantDetails

        # Error logging
        except aiohttp.ClientError:
            _LOGGER.error("Cannot poll eSolar using url: %s")
            return
        except asyncio.TimeoutError:
            _LOGGER.error("Timeout error occurred while polling eSolar using url: %s")
            return
        except Exception as err:
            _LOGGER.error("Unknown error occurred while polling eSolar: %s", err)
            self._data = None
            return


        # -Debug- Cookies and Data
        _LOGGER.debug(self._session.cookie_jar.filter_cookies("https://inversores-style.greenheiss.com"))
        _LOGGER.debug(self._data)


        # logout session
        url_logout = "https://inversores-style.greenheiss.com/cloud/logout"
        response_logout = await self._session.post(url_logout, headers=headers)

        if response_logout.status != 200:
            _LOGGER.error(f"{response_logout.url} returned {response_logout.status}")
            return


        # Clear session and cookies
        self._session.cookie_jar.clear()
        self._session.close()

    @property
    def latest_data(self):
        """Return the latest data object."""
        if self._data:
            return self._data

        _LOGGER.error("return data NONE")
        return None

class SAJeSolarMeterSensor(SensorEntity):
    """Collecting data and return sensor entity."""

    def __init__(self, description: SensorEntityDescription, data, sensors):
        """Initialize the sensor."""
        self.entity_description = description
        self._data = data

        self._state = None
        self.sensors = sensors
        self._type = self.entity_description.key
        self._attr_icon = self.entity_description.icon
        self._attr_name = SENSOR_PREFIX + self.entity_description.name
        self._attr_state_class = self.entity_description.state_class
        self._attr_native_unit_of_measurement = self.entity_description.native_unit_of_measurement
        self._attr_device_class = self.entity_description.device_class
        self._attr_unique_id = f"{SENSOR_PREFIX}_{self._type}"

        self._discovery = False
        self._dev_id = {}

    @property
    def state(self):
        """Return the state of the sensor. (total/current power consumption/production or total gas used)"""
        return self._state

    async def async_update(self):
        """Get the latest data and use it to update our sensor state."""

        await self._data.async_update()
        energy = self._data.latest_data

        if energy:
            if self._type == 'devOnlineNum':
                if 'devOnlineNum' in energy['plantDetail']:
                    if energy['plantDetail']["devOnlineNum"] is not None:
                        self._state = int(energy['plantDetail']["devOnlineNum"])
            if self._type == 'nowPower':
                if 'nowPower' in energy['plantDetail']:
                    if energy['plantDetail']["nowPower"] is not None:
                        self._state = float(energy['plantDetail']["nowPower"])
            if self._type == 'runningState':
                if 'runningState' in energy['plantDetail']:
                    if energy['plantDetail']["runningState"] is not None:
                        self._state = int(energy['plantDetail']["runningState"])
            if self._type == 'todayElectricity':
                if 'todayElectricity' in energy['plantDetail']:
                    if energy['plantDetail']["todayElectricity"] is not None:
                        self._state = float(energy['plantDetail']["todayElectricity"])
            if self._type == 'monthElectricity':
                if 'monthElectricity' in energy['plantDetail']:
                    if energy['plantDetail']["monthElectricity"] is not None:
                        self._state = float(energy['plantDetail']["monthElectricity"])
            if self._type == 'yearElectricity':
                if 'yearElectricity' in energy['plantDetail']:
                    if energy['plantDetail']["yearElectricity"] is not None:
                        self._state = float(energy['plantDetail']["yearElectricity"])
            if self._type == 'totalElectricity':
                if 'totalElectricity' in energy['plantDetail']:
                    if energy['plantDetail']["totalElectricity"] is not None:
                        self._state = float(energy['plantDetail']["totalElectricity"])
            if self._type == 'todayGridIncome':
                if 'todayGridIncome' in energy['plantDetail']:
                    if energy['plantDetail']["todayGridIncome"] is not None:
                        self._state = float(energy['plantDetail']["todayGridIncome"])
            if self._type == 'income':
                if 'income' in energy['plantDetail']:
                    if energy['plantDetail']["income"] is not None:
                        self._state = float(energy['plantDetail']["income"])
            if self._type == 'selfUseRate':
                if 'selfUseRate' in energy['plantDetail']:
                    if energy['plantDetail']["selfUseRate"] is not None:
                        self._state = energy['plantDetail']["selfUseRate"]
            if self._type == 'totalBuyElec':
                if 'totalBuyElec' in energy['plantDetail']:
                    if energy['plantDetail']["totalBuyElec"] is not None:
                        self._state = float(energy['plantDetail']["totalBuyElec"])
            if self._type == 'totalConsumpElec':
                if 'totalConsumpElec' in energy['plantDetail']:
                    if energy['plantDetail']["totalConsumpElec"] is not None:
                        self._state = float(energy['plantDetail']["totalConsumpElec"])
            if self._type == 'totalSellElec':
                if 'totalSellElec' in energy['plantDetail']:
                    if energy['plantDetail']["totalSellElec"] is not None:
                        self._state = float(energy['plantDetail']["totalSellElec"])





            if self._type == 'todayAlarmNum':
                if 'todayAlarmNum' in energy['plantDetail']:
                    if energy['plantDetail']["todayAlarmNum"] is not None:
                        self._state = (energy['plantDetail']["todayAlarmNum"])
            if self._type == 'todayAlarmNum':
                if 'todayAlarmNum' in energy['plantDetail']:
                    if energy['plantDetail']["todayAlarmNum"] is not None:
                        self._state = (energy['plantDetail']["todayAlarmNum"])
            if self._type == 'lastUploadTime':
                if 'lastUploadTime' in energy['plantDetail']:
                    if energy['plantDetail']["lastUploadTime"] is not None:
                        self._state = (energy['plantDetail']["lastUploadTime"])
            if self._type == 'totalPlantTreeNum':
                if 'totalPlantTreeNum' in energy['plantDetail']:
                    if energy['plantDetail']["totalPlantTreeNum"] is not None:
                        self._state = (energy['plantDetail']["totalPlantTreeNum"])
            if self._type == 'totalReduceCo2':
                if 'totalReduceCo2' in energy['plantDetail']:
                    if energy['plantDetail']["totalReduceCo2"] is not None:
                        self._state = (energy['plantDetail']["totalReduceCo2"])
            if self._type == 'todayAlarmNum':
                if 'todayAlarmNum' in energy['plantDetail']:
                    if energy['plantDetail']["todayAlarmNum"] is not None:
                        self._state = (energy['plantDetail']["todayAlarmNum"])


            if self._type == 'currency':
                if 'currency' in energy['plantList'][0]:
                    if energy['plantList'][0]["currency"] is not None:
                        self._state = (energy['plantList'][0]["currency"])
            if self._type == 'plantuid':
                if 'plantuid' in energy['plantList'][0]:
                    if energy['plantList'][0]["plantuid"] is not None:
                        self._state = (energy['plantList'][0]["plantuid"])
            if self._type == 'plantname':
                if 'plantname' in energy['plantList'][0]:
                    if energy['plantList'][0]["plantname"] is not None:
                        self._state = (energy['plantList'][0]["plantname"])
            if self._type == 'currency':
                if 'currency' in energy['plantList'][0]:
                    if energy['plantList'][0]["currency"] is not None:
                        self._state = (energy['plantList'][0]["currency"])
            if self._type == 'isOnline':
                if 'isOnline' in energy['plantList'][0]:
                    if energy['plantList'][0]["isOnline"] is not None:
                        self._state = (energy['plantList'][0]["isOnline"])
            if self._type == 'address':
                if 'address' in energy['plantList'][0]:
                    if energy['plantList'][0]["address"] is not None:
                        self._state = (energy['plantList'][0]["address"])


            if self._type == 'peakPower':
                if 'peakPower' in energy:
                    if energy["peakPower"] is not None:
                        self._state = float(energy["peakPower"])
            if self._type == 'status':
                if 'status' in energy:
                    if energy["status"] is not None:
                        self._state = (energy["status"])

            ########################################################################## SAJ h1
            if self.sensors == "h1":
                if self._type == 'chargeElec':
                    if 'chargeElec' in energy['viewBean']:
                        if energy['viewBean']["chargeElec"] is not None:
                            self._state = float(energy['viewBean']["chargeElec"])
                if self._type == 'dischargeElec':
                    if 'dischargeElec' in energy['viewBean']:
                        if energy['viewBean']["dischargeElec"] is not None:
                            self._state = float(energy['viewBean']["dischargeElec"])
                if self._type == 'buyElec':
                    if 'pvElec' in energy['viewBean']:
                        if energy['viewBean']["buyElec"] is not None:
                            self._state = float(energy['viewBean']["buyElec"])
                if self._type == 'buyRate':
                    if 'buyRate' in energy['viewBean']:
                        if energy['viewBean']["buyRate"] is not None:
                            self._state = energy['viewBean']["buyRate"]
                if self._type == 'pvElec':
                    if 'pvElec' in energy['viewBean']:
                        if energy['viewBean']["pvElec"] is not None:
                            self._state = float(energy['viewBean']["pvElec"])
                if self._type == 'selfConsumedEnergy1':
                    if 'selfConsumedEnergy1' in energy['viewBean']:
                        if energy['viewBean']["selfConsumedEnergy1"] is not None:
                            self._state = float(energy['viewBean']["selfConsumedEnergy1"])
                if self._type == 'selfConsumedEnergy2':
                    if 'selfConsumedEnergy2' in energy['viewBean']:
                        if energy['viewBean']["selfConsumedEnergy2"] is not None:
                            self._state = float(energy['viewBean']["selfConsumedEnergy2"])
                if self._type == 'selfConsumedRate1':
                    if 'selfConsumedRate1' in energy['viewBean']:
                        if energy['viewBean']["selfConsumedRate1"] is not None:
                            self._state = energy['viewBean']["selfConsumedRate1"]
                if self._type == 'selfConsumedRate2':
                    if 'selfConsumedRate2' in energy['viewBean']:
                        if energy['viewBean']["selfConsumedRate2"] is not None:
                            self._state = energy['viewBean']["selfConsumedRate2"]
                if self._type == 'sellElec':
                    if 'sellElec' in energy['viewBean']:
                        if energy['viewBean']["sellElec"] is not None:
                            self._state = float(energy['viewBean']["sellElec"])
                if self._type == 'sellRate':
                    if 'sellRate' in energy['viewBean']:
                        if energy['viewBean']["sellRate"] is not None:
                            self._state = energy['viewBean']["sellRate"]
                if self._type == 'useElec':
                    if 'useElec' in energy['viewBean']:
                        if energy['viewBean']["useElec"] is not None:
                            self._state = float(energy['viewBean']["useElec"])
                # storeDevicePower
                if self._type == 'batCapcity':
                    if 'batCapcity' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['batCapcity'] is not None:
                            self._state = float(energy["storeDevicePower"]["batCapcity"])
                if self._type == 'isAlarm':
                    if 'isAlarm' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['isAlarm'] is not None:
                            self._state = int(energy["storeDevicePower"]["isAlarm"])
                if self._type == 'batCurr':
                    if 'batCurr' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['batCurr'] is not None:
                            self._state = float(energy["storeDevicePower"]["batCurr"])
                if self._type == 'batEnergyPercent':
                    if 'batEnergyPercent' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['batEnergyPercent'] is not None:
                            self._state = float(energy["storeDevicePower"]["batEnergyPercent"])
                if self._type == 'batteryDirection':
                    if 'batteryDirection' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['batteryDirection'] is not None:
                            if energy["storeDevicePower"]["batteryDirection"] == 0:
                                self._state = "Standby"
                            elif energy["storeDevicePower"]["batteryDirection"] == 1:
                                self._state = "Descarga"
                            elif energy["storeDevicePower"]["batteryDirection"] == -1:
                                self._state = "Carga"
                            else:
                                self._state = f'Unknown: {energy["storeDevicePower"]["batteryDirection"]}'
                if self._type == 'batteryPower':
                    if 'batteryPower' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['batteryPower'] is not None:
                            self._state = float(energy["storeDevicePower"]["batteryPower"])
                if self._type == 'gridDirection':
                    if 'gridDirection' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['gridDirection'] is not None:
                            self._state = float(energy["storeDevicePower"]["gridDirection"])
                if self._type == 'gridPower':
                    if 'gridPower' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['gridPower'] is not None:
                            self._state = float(energy["storeDevicePower"]["gridPower"])
                if self._type == 'h1Online':
                    if 'isOnline' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['isOnline'] is not None:
                            self._state = int(energy["storeDevicePower"]["isOnline"])
                if self._type == 'outPower':
                    if 'outPower' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['outPower'] is not None:
                            self._state = float(energy["storeDevicePower"]["outPower"])
                if self._type == 'outPutDirection':
                    if 'outPutDirection' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['outPutDirection'] is not None:
                            self._state = float(energy["storeDevicePower"]["outPutDirection"])
                if self._type == 'pvDirection':
                    if 'pvDirection' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['pvDirection'] is not None:
                            self._state = int(energy["storeDevicePower"]["pvDirection"])
                if self._type == 'pvPower':
                    if 'pvPower' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['pvPower'] is not None:
                            self._state = float(energy["storeDevicePower"]["pvPower"])
                if self._type == 'solarPower':
                    if 'solarPower' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['solarPower'] is not None:
                            self._state = float(energy["storeDevicePower"]["solarPower"])
                if self._type == 'totalLoadPower':
                    if 'totalLoadPower' in energy["storeDevicePower"]:
                        if energy["storeDevicePower"]['totalLoadPower'] is not None:
                            self._state = float(energy["storeDevicePower"]['totalLoadPower'])


                ########################################################################## CUSTOM SENSORS H1 S2

                if self._type == 'h1s2_pv_volt_1':
                    if 'h1s2_pv_volt_1' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_pv_volt_1'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_pv_volt_1"])
                if self._type == 'h1s2_pv_current_1':
                    if 'h1s2_pv_current_1' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_pv_current_1'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_pv_current_1"])
                if self._type == 'h1s2_pv_power_1':
                    if 'h1s2_pv_power_1' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_pv_power_1'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_pv_power_1"])
                if self._type == 'h1s2_pv_volt_2':
                    if 'h1s2_pv_volt_2' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_pv_volt_2'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_pv_volt_2"])
                if self._type == 'h1s2_pv_current_2':
                    if 'h1s2_pv_current_2' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_pv_current_2'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_pv_current_2"])
                if self._type == 'h1s2_pv_power_2':
                    if 'h1s2_pv_power_2' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_pv_power_2'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_pv_power_2"])
                if self._type == 'h1s2_pv_volt_3':
                    if 'h1s2_pv_volt_3' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_pv_volt_3'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_pv_volt_3"])
                if self._type == 'h1s2_pv_current_3':
                    if 'h1s2_pv_current_3' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_pv_current_3'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_pv_current_3"])
                if self._type == 'h1s2_pv_power_3':
                    if 'h1s2_pv_power_3' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_pv_power_3'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_pv_power_3"])
                if self._type == 'h1s2_bat_volt':
                    if 'h1s2_bat_volt' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_bat_volt'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_bat_volt"])
                if self._type == 'h1s2_bat_current':
                    if 'h1s2_bat_current' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_bat_current'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_bat_current"])
                if self._type == 'h1s2_bat_power':
                    if 'h1s2_bat_power' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_bat_power'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_bat_power"])
                if self._type == 'h1s2_bat_total_charge':
                    if 'h1s2_bat_total_charge' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_bat_total_charge'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_bat_total_charge"])
                if self._type == 'h1s2_bat_total_discharge':
                    if 'h1s2_bat_total_discharge' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_bat_total_discharge'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_bat_total_discharge"])
                if self._type == 'h1s2_load_power':
                    if 'h1s2_load_power' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_load_power'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_load_power"])
                if self._type == 'h1s2_grid_volt_1':
                    if 'h1s2_grid_volt_1' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_grid_volt_1'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_grid_volt_1"])
                if self._type == 'h1s2_grid_current_1':
                    if 'h1s2_grid_current_1' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_grid_current_1'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_grid_current_1"])
                if self._type == 'h1s2_grid_power_1':
                    if 'h1s2_grid_power_1' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_grid_power_1'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_grid_power_1"])
                if self._type == 'h1s2_grid_volt_2':
                    if 'h1s2_grid_volt_2' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_grid_volt_2'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_grid_volt_2"])
                if self._type == 'h1s2_grid_current_2':
                    if 'h1s2_grid_current_2' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_grid_current_2'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_grid_current_2"])
                if self._type == 'h1s2_grid_power_2':
                    if 'h1s2_grid_power_2' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_grid_power_2'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_grid_power_2"])
                if self._type == 'h1s2_grid_volt_3':
                    if 'h1s2_grid_volt_3' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_grid_volt_3'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_grid_volt_3"])
                if self._type == 'h1s2_grid_current_3':
                    if 'h1s2_grid_current_3' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_grid_current_3'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_grid_current_3"])
                if self._type == 'h1s2_grid_power_3':
                    if 'h1s2_grid_power_3' in energy["h1s2"]:
                        if energy["h1s2"]['h1s2_grid_power_3'] is not None:
                            self._state = float(energy["h1s2"]["h1s2_grid_power_3"])

            ########################################################################## Sec module Sensors:
            if self.sensors == "saj_sec":
                # getPlantMeterChartData - viewBeam
                if self._type == 'pvElec':
                    if 'pvElec' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["pvElec"] is not None:
                            self._state = float(energy["getPlantMeterChartData"]['viewBean']["pvElec"])
                if self._type == 'useElec':
                    if 'useElec' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["useElec"] is not None:
                            self._state = float(energy["getPlantMeterChartData"]['viewBean']["useElec"])
                if self._type == 'buyElec':
                    if 'buyElec' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["buyElec"] is not None:
                            self._state = float(energy["getPlantMeterChartData"]['viewBean']["buyElec"])
                if self._type == 'sellElec':
                    if 'sellElec' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["sellElec"] is not None:
                            self._state = float(energy["getPlantMeterChartData"]['viewBean']["sellElec"])
                if self._type == 'selfConsumedEnergy1':
                    if 'selfConsumedEnergy1' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["selfConsumedEnergy1"] is not None:
                            self._state = float(energy["getPlantMeterChartData"]['viewBean']["selfConsumedEnergy1"])
                if self._type == 'selfConsumedEnergy2':
                    if 'selfConsumedEnergy2' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["selfConsumedEnergy2"] is not None:
                            self._state = float(energy["getPlantMeterChartData"]['viewBean']["selfConsumedEnergy2"])
                if self._type == 'reduceCo2':
                    if 'reduceCo2' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["reduceCo2"] is not None:
                            self._state = float(energy["getPlantMeterChartData"]['viewBean']["reduceCo2"])


                if self._type == 'buyRate':
                    if 'buyRate' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["buyRate"] is not None:
                            self._state = (energy["getPlantMeterChartData"]['viewBean']["buyRate"])
                if self._type == 'sellRate':
                    if 'sellRate' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["sellRate"] is not None:
                            self._state = (energy["getPlantMeterChartData"]['viewBean']["sellRate"])
                if self._type == 'selfConsumedRate1':
                    if 'selfConsumedRate1' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["selfConsumedRate1"] is not None:
                            self._state = (energy["getPlantMeterChartData"]['viewBean']["selfConsumedRate1"])
                if self._type == 'selfConsumedRate2':
                    if 'selfConsumedRate2' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["selfConsumedRate2"] is not None:
                            self._state = (energy["getPlantMeterChartData"]['viewBean']["selfConsumedRate2"])
                if self._type == 'plantTreeNum':
                    if 'plantTreeNum' in energy["getPlantMeterChartData"]['viewBean']:
                        if energy["getPlantMeterChartData"]['viewBean']["plantTreeNum"] is not None:
                            self._state = (energy["getPlantMeterChartData"]['viewBean']["plantTreeNum"])


                # dataCountList
                if self._type == 'totalGridPower':
                    if 'dataCountList' in energy:
                        if energy["getPlantMeterChartData"]['dataCountList'][4][-1] is not None:
                            self._state = float(energy["getPlantMeterChartData"]['dataCountList'][3][-1])
                if self._type == 'totalLoadPower':
                    if 'dataCountList' in energy:
                        if energy["getPlantMeterChartData"]['dataCountList'][4][-1] is not None:
                            self._state = float(energy["getPlantMeterChartData"]['dataCountList'][2][-1])
                if self._type == 'totalPvgenPower':
                    if 'dataCountList' in energy:
                        if energy["getPlantMeterChartData"]['dataCountList'][4][-1] is not None:
                            self._state = float(energy["getPlantMeterChartData"]['dataCountList'][4][-1])


                # getPlantMeterDetailInfo
                if self._type == 'totalPvEnergy':
                    if 'totalPvEnergy' in energy["getPlantMeterDetailInfo"]['plantDetail']:
                        if energy["getPlantMeterDetailInfo"]['plantDetail']["totalPvEnergy"] is not None:
                            self._state = (energy["getPlantMeterDetailInfo"]['plantDetail']["totalPvEnergy"])
                if self._type == 'totalLoadEnergy':
                    if 'totalLoadEnergy' in energy["getPlantMeterDetailInfo"]['plantDetail']:
                        if energy["getPlantMeterDetailInfo"]['plantDetail']["totalLoadEnergy"] is not None:
                            self._state = (energy["getPlantMeterDetailInfo"]['plantDetail']["totalLoadEnergy"])
                if self._type == 'totalBuyEnergy':
                    if 'totalBuyEnergy' in energy["getPlantMeterDetailInfo"]['plantDetail']:
                        if energy["getPlantMeterDetailInfo"]['plantDetail']["totalBuyEnergy"] is not None:
                            self._state = (energy["getPlantMeterDetailInfo"]['plantDetail']["totalBuyEnergy"])
                if self._type == 'totalSellEnergy':
                    if 'totalSellEnergy' in energy["getPlantMeterDetailInfo"]['plantDetail']:
                        if energy["getPlantMeterDetailInfo"]['plantDetail']["totalSellEnergy"] is not None:
                            self._state = (energy["getPlantMeterDetailInfo"]['plantDetail']["totalSellEnergy"])


            # -Debug- adding sensor
            _LOGGER.debug(f"Device: {self._type} State: {self._state}")

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

@teamMOYA check if by any chance your credentials work on the greenheiss url mentioned in my first comment. you might be lucky and could use the modified version that @miguelzx posted (which I guess is the same I did)

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

@teamMOYA seems like solar the profit login is at https://inversor.saj-electric.com/cloud?login

my credentials work as well there. pretty sure they just reskin the system with different logos and colors. you probably can use the greenheiss url or this one.

from sajesolar.

miguelzx avatar miguelzx commented on September 4, 2024

@teamMOYA check if by any chance your credentials work on the greenheiss url mentioned in my first comment. you might be lucky and could use the modified version that @miguelzx posted (which I guess is the same I did)

Hello, yes that's correct, that's what you said, thanks for the help.

That is the file as I have it, in case it is of any help to you.

Since yesterday I spent a hellish afternoon. Restoring backups, and thinking that the problem is that I had updated home assistant

from sajesolar.

djansen1987 avatar djansen1987 commented on September 4, 2024

i have a couple of account to test and develop with but all of them seem to work on the original portal so i am guessing it is only the greenheiss that stopped working. If there is anyone willing to share their login details i will see if i can add a option to the configuration yaml to switch to the correct url.

from sajesolar.

arnauplan avatar arnauplan commented on September 4, 2024

Hello, I also had that problem.

My Greenheiss h1 inverter. I use an old integration 1.3.1 which I already have working.

Right now everything works perfectly for me

replacing the domain in the sensor.py

I leave a copy of my sensor.py, in case it helps you, but remember that I use 1.3.1

Thank you!!

from sajesolar.

djansen1987 avatar djansen1987 commented on September 4, 2024

@arnauplan @santiagozky @teamMOYA

Please be aware that the sensor.py above has more changes then only the domainname/url. !!Use at your own risk!!.

@miguelzx could you explain why you have change the H1 part and use beautiful soup to do this? Per my understanding the use of beautiful soup is not permitted by home assistant.

addition: the code used is a very old version of my custom integration. It still uses the old energy StateClass which are not supported by home assistant

from sajesolar.

djansen1987 avatar djansen1987 commented on September 4, 2024

@teamMOYA

The same is happening to me. My plant is gone in the "old platform".

Is your plant available in the new portal or do you have to go to the greenheiss portal ?

from sajesolar.

teamMOYA avatar teamMOYA commented on September 4, 2024

Is your plant available in the new portal or do you have to go to the greenheiss portal ?

from sajesolar.

elboletaire avatar elboletaire commented on September 4, 2024

@teamMOYA is your kit branded as SAJ or some other white label (eg. Greenheiss)?

Mine are rebranded as "Solarprofit", but they don't have a web like Saj and Greenheiss. I'll have to wait for the new web access update.

You can still use any of the saj websites with your Solarprofit credentials.

So I guess having a way to configure our endpoint in the addon should suffice, although some websites may have different structure or calls, and that could complicate things.

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

@djansen1987 I could provide you my credentials if that would help

from sajesolar.

Txetxo1979 avatar Txetxo1979 commented on September 4, 2024

Has the easiest way been found to be able to see the sensors again? I am new to home assistant.

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

@Txetxo1979 so far, it seems to find out in which portal you can find your info (greenheiss, solarprofit, etc) and then modify the sensor.py file of the extension to replace the SAJ url with the one that works for you.

from sajesolar.

djansen1987 avatar djansen1987 commented on September 4, 2024

@djansen1987 I could provide you my credentials if that would help

That would help a lot. Could you send it to [email protected] promise to handle it with care!

from sajesolar.

Txetxo1979 avatar Txetxo1979 commented on September 4, 2024

@Txetxo1979 so far, it seems to find out in which portal you can find your info (greenheiss, solarprofit, etc) and then modify the sensor.py file of the extension to replace the SAJ url with the one that works for you.

My URL is https://esaj-home.saj-electric.com/login
but I don't know where I can go to change the extension in sensor.py

from sajesolar.

djansen1987 avatar djansen1987 commented on September 4, 2024

@Txetxo1979 so far, it seems to find out in which portal you can find your info (greenheiss, solarprofit, etc) and then modify the sensor.py file of the extension to replace the SAJ url with the one that works for you.

My URL is https://esaj-home.saj-electric.com/login but I don't know where I can go to change the extension in sensor.py

This is the new portal, the api is completely changed on that site. Implementing that is almost like starting from scratch.. don't know if i got time for this soon.

from sajesolar.

miguelzx avatar miguelzx commented on September 4, 2024

@arnauplan @santiagozky @teamMOYA

Please be aware that the sensor.py above has more changes then only the domainname/url. !!Use at your own risk!!.

@miguelzx could you explain why you have change the H1 part and use beautiful soup to do this? Per my understanding the use of beautiful soup is not permitted by home assistant.

addition: the code used is a very old version of my custom integration. It still uses the old energy StateClass which are not supported by home assistant

Hello, my language is not English, so I hope the translator works well.

The version that is theirs, which as I mentioned is 1.3.1, which has worked well for me, until that happened. I use the latest version of home assistan and with my inverter, which is a saj clone, it works perfectly.

What I did was put it in sensor.py, it was replace

https://inversor.saj-electric.com/cloud?login, by https://inversores-style.greenheiss.com/cloud/logou.

and this session = async_create_clientsession(hass,False)

What did the previous colleague say?

from sajesolar.

Txetxo1979 avatar Txetxo1979 commented on September 4, 2024

@Txetxo1979 so far, it seems to find out in which portal you can find your info (greenheiss, solarprofit, etc) and then modify the sensor.py file of the extension to replace the SAJ url with the one that works for you.

My URL is https://esaj-home.saj-electric.com/login but I don't know where I can go to change the extension in sensor.py

This is the new portal, the api is completely changed on that site. Implementing that is almost like starting from scratch.. don't know if i got time for this soon.

Thank you so much.
I just saw that I also have the information at https://inversor.saj-electric.com/cloud?login
What should I do then to be able to have the information in home assistant?

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

@miguelzx
Hola Miguel,
Yo tambien uso 1.3.1. no he actualizado a la nueva version.
el codigo tiene puesto directamente el dominio de saj en varios lugares. Tengo una version que lo actualiza con el dominio de greenheiss.

CUIDADO:tiene algunos cambios mas porque en mi caso que no tengo bateria, reportaba algunos valores en el sensor equivocado (despues de la linea 1136).
Anexo mi fichero tal cual lo tengo. Compararlo con el fichero que tienes en custom_components/saj_esolar/sensor.py de tu instalación de Home Assistant.
mi sensor.py tal cual lo tengo. it https://gist.github.com/santiagozky/311e830cffd0b54d2fa115162c5ad73c

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

@Txetxo1979 if you dont mind reverting to 1.3.1. (which is what I still use), you could adjust my gist above to point to your url. just adjust these lines:

BASE_HOST = 'inversores-style.greenheiss.com'
BASE_DOMAIN = 'https://'+BASE_HOST
BASE_URL = BASE_DOMAIN+'/cloud'

caution: I did additional changes between lines 1138 and 1150 because of a mismatch in my data, probably because I dont have a battery (see #41), you could skip those changes.

from sajesolar.

elboletaire avatar elboletaire commented on September 4, 2024

@santiagozky why are you recommending people downgrading and updating a lower version? Latest version can be changed and fixed the same way 😕

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

@elboletaire I havent recommended anyone to downgrade. Im merely offering the solution I have for myself. Im on 1.3.1 because I had previous changes that I dont want to reapply on newer versions.

from sajesolar.

78lobo78 avatar 78lobo78 commented on September 4, 2024

Hello, when will the esolar platform be updated so that the sensors work well?

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

I tried making a change but I've never done anything in python or HASS, so it's taking me quite a long.
I might keep giving it a shot, but I cannot make promises on how long it will take me. for those waiting, if you have a minimum programming experience you might be able to adjust it manually replacing all the urls in the sensor.py file.

from sajesolar.

santiagozky avatar santiagozky commented on September 4, 2024

I opened a PR for this. @djansen1987 feel free to make any adjustment or recommendation you wish. particularly the configuration part.
#67

from sajesolar.

matly006 avatar matly006 commented on September 4, 2024

Good evening. I have an h1 inverter and valid credentials for both the https://esaj-home.saj-electric.com/index portal and for the old https://fop.saj-electric.com/saj.

If I can help, I'd be happy to help

from sajesolar.

djansen1987 avatar djansen1987 commented on September 4, 2024

Hi All, thanks to the work of @santiagozky this should now working in the latest version. Please read the release notes to known what to do. Thanks all for the input and patients!

https://github.com/djansen1987/SAJeSolar/releases/tag/v1.5.1

from sajesolar.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.