Esempio n. 1
0
async def cookie2user(cookie_str):
    '''
    Parse cookie and load user if cookie is valid.
    '''
    if not cookie_str:
        return None
    try:
        L = cookie_str.split('-')
        if len(L) != 3:
            return None
        uid, expires, sha1 = L
        if int(expires) < time.time():
            return None
        user = await User.find(uid)
        if user is None:
            return None
        s = '{}-{}-{}-{}'.format(uid, user.passwd, expires, _COOKIE_KEY)
        if sha1 != hashlib.sha1(s.encode('utf-8')).hexdigest():
            logger.info('invalid sha1')
            return None
        user.passwd = '******'
        return user
    except Exception as e:
        logger.exception(e)
        return None
Esempio n. 2
0
 def __on_mqtt_message(self, client, userdata, msg):
     try:
         logger.info("mqtt msg %s %s", msg.topic, msg.payload)
         data = json.loads(msg.payload)
         charge_info = None
         if msg.topic.startswith(MQTT_RESP_TOPIC):
             if "return_code" not in data:
                 logger.debug("mqtt msg hasn't return code")
             elif data["return_code"] == "400":
                 self.refresh_remote_token(force=True)
                 logger.error("retry last request, token was expired")
             elif data["return_code"] == "300":
                 logger.error('%s', data["return_code"])
             elif data["return_code"] != "0":
                 logger.error('%s : %s', data["return_code"], data["reason"])
                 if msg.topic.endswith("/VehicleState"):
                     charge_info = data["resp_data"]["charging_state"]
                     self.precond_programs[data["vin"]] = data["resp_data"]["precond_state"]["programs"]
         elif msg.topic.startswith(MQTT_EVENT_TOPIC):
             charge_info = data["charging_state"]
         if charge_info is not None and charge_info['remaining_time'] != 0 and charge_info['rate'] == 0:
             # fix a psa server bug where charge beginning without status api being properly updated
             logger.warning("charge begin but API isn't updated")
             sleep(60)
             self.wakeup(data["vin"])
     except KeyError:
         logger.exception("mqtt message:")
Esempio n. 3
0
    def get_data_france(start, end):
        start_str = start.strftime("%d/%m/%Y")
        end_str = end.strftime("%d/%m/%Y")
        try:
            res = requests.get(
                f"https://eco2mix.rte-france.com/curves/eco2mixWeb?type=co2&&dateDeb={start_str}"
                f"&dateFin={end_str}&mode=NORM",
                headers={
                    "Origin":
                    "https://www.rte-france.com",
                    "Referer":
                    "https://www.rte-france.com/eco2mix/les-emissions-de-co2-par-kwh-produit-en-france",
                })
        except RequestException:
            logger.exception("get_data_france: ")
            return None
        etree = ElT.fromstring(res.text)
        period_start = (start.hour + int(start.minute / 30)) * 4
        period_end = (end.hour + int(end.minute / 30)) * 4

        valeurs = etree.iter("valeur")
        co2_per_kw = []

        valeur = next(valeurs)
        while int(valeur.attrib["periode"]) != period_start:
            valeur = next(valeurs)
        while int(valeur.attrib["periode"]) != period_end:
            co2_per_kw.append(int(valeur.text))
            valeur = next(valeurs)
        try:
            return mean(co2_per_kw)
        except StatisticsError:
            return None
Esempio n. 4
0
 def call(self, car: Car, ext_temp: float = None):
     try:
         if self.token is None or len(self.token) == 0:
             logger.debug("No abrp token provided")
         elif car.vin in self.abrp_enable_vin:
             energy = car.status.get_energy('Electric')
             tlm = {"utc": int(datetime.timestamp(energy.updated_at)),
                    "soc": energy.level,
                    "speed": getattr(car.status.kinetic, "speed", None),
                    "car_model": car.get_abrp_name(),
                    "current": car.status.battery.current,
                    "is_charging": energy.charging.status == "InProgress",
                    "lat": car.status.last_position.geometry.coordinates[1],
                    "lon": car.status.last_position.geometry.coordinates[0],
                    "power": energy.consumption
                    }
             if ext_temp is not None:
                 tlm["ext_temp"] = ext_temp
             params = {"tlm": json.dumps(tlm), "token": self.token, "api_key": self.api_key}
             response = requests.request("POST", self.url, params=params, proxies=self.proxies,
                                         verify=self.proxies is None)
             logger.debug(response.text)
             return response.json()["status"] == "ok"
     except (AttributeError, IndexError, ValueError):
         logger.exception("abrp:")
     return False
Esempio n. 5
0
 def __get_charge_hour(self, vin):
     hour_str = self.vehicles_list.get_car_by_vin(vin).status.get_energy(
         'Electric').charging.next_delayed_time
     try:
         return parse_hour(hour_str)[:2]
     except IndexError:
         logger.exception("Can't get charge hour: %s", hour_str)
         return None
Esempio n. 6
0
 def __get_charge_hour(self, vin):
     data = self.get_vehicle_info(vin)
     hour_str = data.get_energy('Electric').charging.next_delayed_time
     try:
         return parse_hour(hour_str)[:2]
     except IndexError:
         logger.exception("Can't get charge hour: %s", hour_str)
         return None
Esempio n. 7
0
 def get_otp_code(self):
     try:
         otp_code = self.otp.get_otp_code()
     except ConfigException:
         logger.exception("get_otp_code:")
         self.load_otp(force_new=True)
         otp_code = self.otp.get_otp_code()
     save_otp(self.otp)
     return otp_code
Esempio n. 8
0
 def get_vehicles(self):
     try:
         res = self.api().get_vehicles_by_device()
         for vehicle in res.embedded.vehicles:
             self.vehicles_list.add(Car(vehicle.vin, vehicle.id, vehicle.brand, vehicle.label))
         self.vehicles_list.save_cars()
     except (ApiException, InvalidHeader):
         logger.exception("get_vehicles:")
     return self.vehicles_list
Esempio n. 9
0
 def __keep_mqtt(self):  # avoid token expiration
     timeout = 3600 * 24  # 1 day
     if len(self.vehicles_list) > 0:
         try:
             self.wakeup(self.vehicles_list[0].vin)
         except RateLimitException:
             logger.exception("__keep_mqtt")
     t = threading.Timer(timeout, self.__keep_mqtt)
     t.setDaemon(True)
     t.start()
Esempio n. 10
0
 def __refresh_vehicle_info(self):
     if self.info_refresh_rate is not None:
         while True:
             try:
                 logger.debug("refresh_vehicle_info")
                 for car in self.vehicles_list:
                     self.get_vehicle_info(car.vin)
                 for callback in self.info_callback:
                     callback()
             except:  # pylint: disable=bare-except
                 logger.exception("refresh_vehicle_info: ")
             sleep(self.info_refresh_rate)
Esempio n. 11
0
 def __get_charge_hour(self, vin):
     reg = r"PT([0-9]{1,2})H([0-9]{1,2})?"
     data = self.get_vehicle_info(vin)
     hour_str = data.get_energy('Electric').charging.next_delayed_time
     try:
         hour_minute = re.findall(reg, hour_str)[0]
         hour = int(hour_minute[0])
         if hour_minute[1] == '':
             minute = 0
         else:
             minute = hour_minute[1]
         return hour, minute
     except IndexError:
         logger.exception("Can't get charge hour: %s", hour_str)
         return None
Esempio n. 12
0
def finishOtp(n_clicks, code_pin, sms_code):  # pylint: disable=unused-argument
    ctx = callback_context
    if ctx.triggered:
        try:
            otp_session = new_otp_session(sms_code, code_pin,
                                          config.myp.remote_client.otp)
            config.myp.remote_client.otp = otp_session
            config.myp.save_config()
            config.start_remote_control()
            return dbc.Alert([
                "OTP config finish !!! ",
                html.A("Go to home", href=request.url_root)
            ],
                             color="success")
        except Exception as e:
            res = str(e)
            logger.exception("finishOtp:")
            return dbc.Alert(res, color="danger")
    raise PreventUpdate()
Esempio n. 13
0
 def __on_mqtt_message(self, client, userdata, msg):
     try:
         logger.info("mqtt msg received: %s %s", msg.topic, msg.payload)
         logger.debug("client: %s userdata: %s", client, userdata)
         data = json.loads(msg.payload)
         charge_info = None
         if msg.topic.startswith(MQTT_RESP_TOPIC):
             if "return_code" not in data:
                 logger.debug("mqtt msg hasn't return code")
             elif data["return_code"] == "400":
                 self._refresh_remote_token(force=True)
                 if self.last_request:
                     logger.warning(
                         "last request is send again, token was expired")
                     last_request = self.last_request
                     self.last_request = None
                     self.publish(last_request, store=False)
                 else:
                     logger.error(
                         "Last request might have been send twice without success"
                     )
             elif data["return_code"] != "0":
                 logger.error('%s : %s', data["return_code"],
                              data.get("reason", "?"))
         elif msg.topic.startswith(MQTT_EVENT_TOPIC):
             charge_info = data["charging_state"]
             self.precond_programs[
                 data["vin"]] = data["precond_state"]["programs"]
         if charge_info is not None and charge_info['remaining_time'] != 0:
             try:
                 car = self.vehicles_list.get_car_by_vin(
                     vin=msg.topic.split("/")[-1])
                 if car and car.status.get_energy(
                         'Electric').charging.status != INPROGRESS:
                     # fix a psa server bug where charge beginning without status api being properly updated
                     logger.warning("charge begin but API isn't updated")
                     sleep(60)
                     self.wakeup(data["vin"])
             except (IndexError, AttributeError, RateLimitException):
                 logger.exception("on_mqtt_message:")
     except KeyError:
         logger.exception("on_mqtt_message:")
Esempio n. 14
0
 def _refresh_remote_token(self, force=False):
     bad_remote_token = self.remoteCredentials.refresh_token is None
     if not force and not bad_remote_token and self.remoteCredentials.last_update:
         last_update: datetime = self.remoteCredentials.last_update
         if (datetime.now() - last_update).total_seconds() < MQTT_TOKEN_TTL:
             return True
     try:
         self.manager.refresh_token_now()
         if bad_remote_token:
             logger.error("remote_refresh_token isn't defined")
         else:
             res = self.manager.post(
                 REMOTE_URL + self.account_info.client_id,
                 json={
                     "grant_type": "refresh_token",
                     "refresh_token": self.remoteCredentials.refresh_token
                 },
                 headers=self.headers)
             data = res.json()
             logger.debug("refresh_remote_token: %s", data)
             if "access_token" in data:
                 self.remoteCredentials.access_token = data["access_token"]
                 self.remoteCredentials.refresh_token = data[
                     "refresh_token"]
                 bad_remote_token = False
             else:
                 logger.error(
                     "can't refresh_remote_token: %s\n Create a new one",
                     data)
                 bad_remote_token = True
         if bad_remote_token:
             otp_code = self.get_otp_code()
             res = self.get_remote_access_token(otp_code)
         self.remote_token_last_update = datetime.now()
         self.mqtt_client.username_pw_set(
             "IMA_OAUTH_ACCESS_TOKEN", self.remoteCredentials.access_token)
         return True
     except (RequestException, RateLimitException) as e:
         logger.exception("Can't refresh remote token %s", e)
         sleep(60)
         return False
Esempio n. 15
0
 def process(self):
     now = datetime.now()
     try:
         vehicle_status = self.psacc.vehicles_list.get_car_by_vin(
             self.vin).get_status()
         status = vehicle_status.get_energy('Electric').charging.status
         level = vehicle_status.get_energy('Electric').level
         logger.info("charging status of %s is %s, battery level: %d",
                     self.vin, status, level)
         if status == "InProgress":
             self.force_update()
             if level >= self.percentage_threshold and self.retry_count < 2:
                 logger.info("Charge threshold is reached, stop the charge")
                 self.control_charge_with_ack(False)
             elif self._next_stop_hour is not None:
                 if self._next_stop_hour < now:
                     self._next_stop_hour += timedelta(days=1)
                     logger.info("it's time to stop the charge")
                     self.control_charge_with_ack(False)
                 else:
                     next_in_second = (self._next_stop_hour -
                                       now).total_seconds()
                     if next_in_second < self.psacc.info_refresh_rate:
                         periodicity = next_in_second
                         thread = threading.Timer(periodicity, self.process)
                         thread.setDaemon(True)
                         thread.start()
         else:
             if self._next_stop_hour is not None and self._next_stop_hour < now:
                 self._next_stop_hour += timedelta(days=1)
             self.retry_count = 0
     except (AttributeError, ValueError):
         logger.exception(
             "Probably can't retrieve all information from API:")
     except:  # pylint: disable=bare-except
         logger.exception("Charge control:")
Esempio n. 16
0
def get_control_tabs(config):
    tabs = []
    for car in config.myp.vehicles_list:
        if car.label is None:
            label = car.vin
        else:
            label = car.label
        myp: MyPSACC = config.myp
        el = []
        buttons_row = []
        if config.remote_control:
            try:
                preconditionning_state = car.status.preconditionning.air_conditioning.status != "Disabled"
                charging_state = car.status.get_energy(
                    'Electric').charging.status == "InProgress"
                cards = {
                    "Battery": {
                        "text": [
                            card_value_div(
                                "battery_value",
                                "%",
                                value=convert_value_to_str(
                                    car.status.get_energy('Electric').level))
                        ],
                        "src":
                        "assets/images/battery-charge.svg"
                    },
                    "Mileage": {
                        "text": [
                            card_value_div(
                                "mileage_value",
                                "km",
                                value=convert_value_to_str(
                                    car.status.timed_odometer.mileage))
                        ],
                        "src":
                        "assets/images/mileage.svg"
                    }
                }
                el.append(
                    dbc.Container(dbc.Row(children=create_card(cards)),
                                  fluid=True))
                buttons_row.extend([
                    Button(
                        REFRESH_SWITCH, car.vin,
                        html.Img(src="assets/images/sync.svg", width="50px"),
                        myp.remote_client.wakeup).get_html(),
                    Switch(CHARGE_SWITCH, car.vin, "Charge",
                           myp.remote_client.charge_now,
                           charging_state).get_html(),
                    Switch(PRECONDITIONING_SWITCH, car.vin, "Preconditioning",
                           myp.remote_client.preconditioning,
                           preconditionning_state).get_html()
                ])
            except (AttributeError, TypeError):
                logger.exception("get_control_tabs:")
        if not config.offline:
            buttons_row.append(
                Switch(ABRP_SWITCH, car.vin, "Send data to ABRP",
                       myp.abrp.enable_abrp, car.vin
                       in config.myp.abrp.abrp_enable_vin).get_html())
        tabs.append(
            dbc.Tab(label=label,
                    id="tab-" + car.vin,
                    children=[dbc.Row(buttons_row), *el]))
    return dbc.Tabs(id="control-tabs", children=tabs)