<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title><![CDATA[jmtella - TIP's, Ejercicios y Ejemplos]]></title>
		<link>https://jmtella.com/foro/</link>
		<description />
		<language>es</language>
		<lastBuildDate>Sun, 05 Apr 2026 11:55:48 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>60</ttl>
		<image>
			<url>https://jmtella.com/foro/images/misc/rss.png</url>
			<title><![CDATA[jmtella - TIP's, Ejercicios y Ejemplos]]></title>
			<link>https://jmtella.com/foro/</link>
		</image>
		<item>
			<title>TIP: ver la direccion de la ONT en routers movistar</title>
			<link>https://jmtella.com/foro/forum/ejercicios-y-ejemplos/57311-tip-ver-la-direccion-de-la-ont-en-routers-movistar</link>
			<pubDate>Mon, 16 Feb 2026 13:55:33 GMT</pubDate>
			<description>Por defecto la configuracion no la muestra, y es necesario saberla si queremos sustituir un rounter por otro de otros model con ONT incorporada o...</description>
			<content:encoded><![CDATA[Por defecto la configuracion no la muestra, y es necesario saberla si queremos sustituir un rounter por otro de otros model con ONT incorporada o bien queremos poner una ONT                     dun router aparte.<br />
<br />
La manera de ver la dioreccion es acceder al router pero en diredcto a laa pagina &quot;instalacion&quot;:<br />
<br />
<a href="https://192.168.1.1/instalacion" target="_blank">https://192.168.1.1/instalacion</a><br />
<br />
Esto nos mostrará la dir de la ONT. Si mustra más de 14 digitos, solo son validos los 14 primeros.]]></content:encoded>
			<category domain="https://jmtella.com/foro/forum/ejercicios-y-ejemplos"><![CDATA[TIP's, Ejercicios y Ejemplos]]></category>
			<dc:creator>jmtella</dc:creator>
			<guid isPermaLink="true">https://jmtella.com/foro/forum/ejercicios-y-ejemplos/57311-tip-ver-la-direccion-de-la-ont-en-routers-movistar</guid>
		</item>
		<item>
			<title>TIP - Geolocalización en ordenadores sin adaptador WiFi</title>
			<link>https://jmtella.com/foro/forum/ejercicios-y-ejemplos/57147-tip-geolocalización-en-ordenadores-sin-adaptador-wifi</link>
			<pubDate>Wed, 14 Jan 2026 09:30:59 GMT</pubDate>
			<description>Como sabeis, la geolocalización en windows se basa en varios metodos: 
 
* Si existe chip de geolocalizacion, usará este. 
* Pero en ordenadores sin...</description>
			<content:encoded><![CDATA[Como sabeis, la geolocalización en windows se basa en varios metodos:<br />
<br />
* Si existe chip de geolocalizacion, usará este.<br />
* Pero en ordenadores sin el chip, se usan varios metodos basados en la IP.<br />
<br />
En este segundo caso, es donde pueden existir problemas y no lo caliza bien la geolocalizacion, Por ejemplo, en un ordenador de sobremesa, estando en Madrid. a mi me dice:<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Código:</div>
	<pre class="bbcode_code notranslate" style="max-height:calc(30 *  + 2 * var(--bbcode-padding) + var(--h-scrollbar-allowance));">=== Prueba de geolocalización Windows (WinRT) ===
Modo: adaptive | Presupuesto total: 20s
Solicitando una posición...

Acceso del sistema: ALLOWED
Estado inicial del proveedor: NOT_INITIALIZED
✔ Posición obtenida:
  Timestamp:       2026-01-14 09:13:38
  Lat, Lon:        53.348700, -6.260700
  Precisión (m):   10000.0
  Altitud (m):     0.0
  Fuente:          IP_ADDRESS
  Estado proveedor:NOT_INITIALIZED
  Modo usado:      HIGH (intentos=2, 0.377s)</pre>
</div>Lo cual es incorrecto, ya que corresponde a una localizacion cercana a Dublin. Cualquier navegador (Google maaps por ejemplo) da la situacion invorrecta.<br />
<br />
Pero si dicho ordenador le ponemos un adaptador WiFi (aunque esté sin conectar a WiFi -esto es lo importante) ya usa otros metodos<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Código:</div>
	<pre class="bbcode_code notranslate" style="max-height:calc(30 *  + 2 * var(--bbcode-padding) + var(--h-scrollbar-allowance));">=== Prueba de geolocalización Windows (WinRT) ===
Modo: adaptive | Presupuesto total: 20s
Solicitando una posición...

Acceso del sistema: ALLOWED
Estado inicial del proveedor: NOT_INITIALIZED
✔ Posición obtenida:
  Timestamp:       2026-01-14 09:13:58
  Lat, Lon:        40.435924, -3.701747
  Precisión (m):   81.0
  Altitud (m):     0.0
  Fuente:          WI_FI
  Estado proveedor:NOT_INITIALIZED
  Modo usado:      DEFAULT (intentos=1, 0.134s)</pre>
</div>La cual es la correcta.<ul><li>Antes: IP_ADDRESS, 10000 m, ~0.37s → fallback por IP.</li>
<li>Ahora con el dongle Wi-Fi “en el aire”: WI_FI, ~81 m, ~0.13s → triangulación por BSSID (aunque sin asociar a ninguna una red).</li>
</ul>Si se quiere dejarlo “redondo” en sobremesas:<ul><li>Mantener el adaptador Wi-Fi habilitado (aunque no uses Wi-Fi para internet), o</li>
<li>Definir una <b>Ubicación predeterminada</b> en Windows como plan B cuando no haya señales (útil si algún día se deshabilita el dongle).</li>
</ul><br />
El programa python para las salidas anteriores es el que dejo debajo en el spoiler.<br />
<br />
Es necesariop tener instalado el winsdk;<br />
<br />
pip install winsdk<br />
<br />
Pero para que lo compiler el pip es necesario igualmente tener instalado el visual code 2022 ya que si no no compila.<br />
<br />
​<div style="padding: 3px; background-color: #FFFFFF; border: 1px solid #d8d8d8; font-size: 1em;"><div style="text-transform: uppercase; border-bottom: 1px solid #CCCCCC; margin-bottom: 3px; font-size: 0.8em; font-weight: bold; display: block;"><span onClick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') {  this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.innerHTML = '<b>Spoiler: </b><a href=\'#\' onClick=\'return false;\'>ocultar</a>'; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerHTML = '<b>Spoiler: </b><a href=\'#\' onClick=\'return false;\'>mostrar</a>'; }" /><b>Spoiler: </b><a href="#" onClick="return false;">mostrar</a></span></div><div class="quotecontent"><div style="display: none;"><br />
<div class="bbcode_container">
	<div class="bbcode_description">Código:</div>
	<pre class="bbcode_code notranslate" style="max-height:calc(30 *  + 2 * var(--bbcode-padding) + var(--h-scrollbar-allowance));">#!/usr/bin/env python3
# geo.py — Test de geolocalización WinRT (Windows) con modo adaptativo opcional.
# Uso rápido:
#   python geo.py
#   python geo.py --help

import sys, os, math, asyncio, datetime, time
import argparse

# ---- Comprobación winsdk ----------------------------------------------
try:
    from winsdk.windows.devices.geolocation import (
        Geolocator,
        PositionAccuracy,
        PositionStatus,
        GeolocationAccessStatus,
    )
except Exception:
    print(&quot;Falta el paquete 'winsdk'. Instálalo con: pip install winsdk&quot;)
    sys.exit(1)

# ---- Utilidades --------------------------------------------------------
def status_name(s):
    m = {
        PositionStatus.NOT_INITIALIZED: &quot;NOT_INITIALIZED&quot;,
        PositionStatus.NO_DATA: &quot;NO_DATA&quot;,
        PositionStatus.DISABLED: &quot;DISABLED&quot;,
        PositionStatus.NOT_AVAILABLE: &quot;NOT_AVAILABLE&quot;,
        PositionStatus.READY: &quot;READY&quot;,
        PositionStatus.INITIALIZING: &quot;INITIALIZING&quot;,
    }
    return m.get(s, str(s))

def access_name(a):
    m = {
        GeolocationAccessStatus.ALLOWED: &quot;ALLOWED&quot;,
        GeolocationAccessStatus.DENIED: &quot;DENIED&quot;,
        GeolocationAccessStatus.UNSPECIFIED: &quot;UNSPECIFIED&quot;,
    }
    return m.get(a, str(a))

def _nan_to_none(x):
    if x is None:
        return None
    try:
        return None if (isinstance(x, float) and math.isnan(x)) else x
    except Exception:
        return x

def src_name(c):
    src = getattr(c, &quot;position_source&quot;, None)
    return getattr(src, &quot;name&quot;, src)

async def watch_status(geo, verbose: bool, seconds=20):
    if not verbose:
        return
    last = None
    for _ in range(int(seconds * 2)):
        s = status_name(geo.location_status)
        if s != last:
            print(f&quot;&#91;{datetime.datetime.now().strftime('%H:%M:%S')}&#93; Estado proveedor: {s}&quot;)
            last = s
        await asyncio.sleep(0.5)

# ---- Intentos ----------------------------------------------------------
async def _try_default(geo: Geolocator, t: int, max_age_s: int, target_acc_m: float):
    start = time.perf_counter()
    geo.desired_accuracy = PositionAccuracy.DEFAULT
    if hasattr(geo, &quot;desired_accuracy_in_meters&quot;):
        try:
            # “Pista” para que se quede en proveedor de red si vale
            geo.desired_accuracy_in_meters = max(int(target_acc_m), 100)
        except Exception:
            pass
    try:
        if max_age_s &gt; 0:
            from datetime import timedelta
            pos = await asyncio.wait_for(
                geo.get_geoposition_async(timedelta(seconds=max_age_s), timedelta(seconds=t)),
                timeout=t + 1
            )
        else:
            pos = await asyncio.wait_for(geo.get_geoposition_async(), timeout=t)
        return pos, time.perf_counter() - start, None
    except Exception as e:
        return None, time.perf_counter() - start, e

async def _try_high(geo: Geolocator, t: int):
    start = time.perf_counter()
    geo.desired_accuracy = PositionAccuracy.HIGH
    try:
        pos = await asyncio.wait_for(geo.get_geoposition_async(), timeout=t)
        return pos, time.perf_counter() - start, None
    except Exception as e:
        return None, time.perf_counter() - start, e

def pack_result(geo: Geolocator, pos, mode_used: str, attempts: int, elapsed_s: float):
    c = pos.coordinate
    p = c.point.position
    data = {
        &quot;timestamp&quot;: getattr(c, &quot;timestamp&quot;, None),
        &quot;latitude&quot;: p.latitude,
        &quot;longitude&quot;: p.longitude,
        &quot;altitude_m&quot;: _nan_to_none(getattr(p, &quot;altitude&quot;, None)),
        &quot;accuracy_m&quot;: getattr(c, &quot;accuracy&quot;, None),
        &quot;altitude_accuracy_m&quot;: getattr(c, &quot;altitude_accuracy&quot;, None),
        &quot;speed_m_s&quot;: getattr(c, &quot;speed&quot;, None),
        &quot;heading_deg&quot;: getattr(c, &quot;heading&quot;, None),
        &quot;source&quot;: src_name(c),
        &quot;provider_status&quot;: status_name(getattr(geo, &quot;location_status&quot;, None)),
        &quot;mode_used&quot;: mode_used,
        &quot;attempts&quot;: attempts,
        &quot;elapsed_s&quot;: round(elapsed_s, 3),
    }
    return data

# ---- Lógica principal adaptativa ---------------------------------------
async def get_position(mode: str, timeout_total: int, t_default: int, t_high: int,
                       target_acc_m: float, max_age_s: int, warmup: float,
                       verbose: bool, no_escalate: bool):
    # Acceso
    access = await Geolocator.request_access_async()
    print(f&quot;Acceso del sistema: {access_name(access)}&quot;)
    if access != GeolocationAccessStatus.ALLOWED:
        return None, 2, &quot;Acceso denegado por Windows (habilita Ubicación para apps de escritorio).&quot;

    geo = Geolocator()
    print(f&quot;Estado inicial del proveedor: {status_name(geo.location_status)}&quot;)

    if warmup &gt; 0:
        # Pequeño warm-up (especialmente útil si hay WWAN/GNSS)
        status_task = asyncio.create_task(watch_status(geo, verbose, seconds=max(warmup, 3)))
        await asyncio.sleep(min(max(warmup, 0.5), 10.0))
        status_task.cancel()

    # Modo forzado
    if mode == &quot;high&quot;:
        pos, dt, err = await _try_high(geo, max(1, timeout_total))
        if pos:
            return pack_result(geo, pos, &quot;HIGH&quot;, 1, dt), 0, None
        return None, 3, f&quot;Timeout/err en HIGH ({timeout_total}s): {repr(err)}&quot;

    if mode == &quot;default&quot;:
        pos, dt, err = await _try_default(geo, max(1, timeout_total), max_age_s, target_acc_m)
        if pos:
            return pack_result(geo, pos, &quot;DEFAULT&quot;, 1, dt), 0, None
        return None, 3, f&quot;Timeout/err en DEFAULT ({timeout_total}s): {repr(err)}&quot;

    # Modo adaptativo
    attempts = 0
    t_remain = max(1, timeout_total)

    # Reparto de tiempos si no se especificaron
    if t_default &lt;= 0 and t_high &lt;= 0:
        t_default = max(1, min(t_remain - 1, int(t_remain * 0.6)))
        t_high = max(0, t_remain - t_default)

    # 1) DEFAULT
    td = min(t_default if t_default &gt; 0 else t_remain, t_remain)
    attempts += 1
    if verbose:
        print(f&quot;&#91;ADAPT&#93; DEFAULT (t={td}s, max_age={max_age_s}s, target_acc={target_acc_m}m)&quot;)
    pos, dt1, err1 = await _try_default(geo, td, max_age_s, target_acc_m)
    t_remain -= td
    if pos:
        c = pos.coordinate
        acc = getattr(c, &quot;accuracy&quot;, 9999) or 9999
        src = src_name(c)
        if verbose:
            print(f&quot;&#91;ADAPT&#93; DEFAULT → src={src}, acc={acc}m&quot;)
        if no_escalate or acc &lt;= target_acc_m or src in (&quot;WIFI&quot;, &quot;GNSS&quot;) or t_remain &lt;= 0:
            return pack_result(geo, pos, &quot;DEFAULT&quot;, attempts, dt1), 0, None

    # 2) HIGH (si queda presupuesto)
    if t_remain &gt; 0 and not no_escalate:
        th = min(t_high if t_high &gt; 0 else t_remain, t_remain)
        attempts += 1
        if verbose:
            print(f&quot;&#91;ADAPT&#93; HIGH (t={th}s)&quot;)
        pos2, dt2, err2 = await _try_high(geo, th)
        if pos2:
            return pack_result(geo, pos2, &quot;HIGH&quot;, attempts, dt1 + dt2), 0, None
        return None, 3, f&quot;Timeout/err: DEFAULT({td}s) y HIGH({th}s). &quot; \
                        f&quot;err_default={repr(err1)} err_high={repr(err2)}&quot;

    # Sin presupuesto tras DEFAULT
    return None, 3, f&quot;Timeout/err en DEFAULT ({td}s): {repr(err1)}&quot;

# ---- CLI ----------------------------------------------------------------
def parse_args():
    p = argparse.ArgumentParser(
        description=&quot;Prueba de geolocalización Windows (WinRT) con modo adaptativo.&quot;
    )
    p.add_argument(&quot;--mode&quot;, choices=&#91;&quot;adaptive&quot;, &quot;default&quot;, &quot;high&quot;&#93;, default=&quot;adaptive&quot;,
                   help=&quot;Estrategia de obtención. Por defecto: adaptive.&quot;)
    p.add_argument(&quot;--timeout&quot;, type=int, default=20,
                   help=&quot;Presupuesto total de tiempo en segundos (por defecto 20).&quot;)
    p.add_argument(&quot;--t-default&quot;, type=int, default=0,
                   help=&quot;Tiempo (s) para DEFAULT dentro del modo adaptativo. Si 0, se reparte automáticamente.&quot;)
    p.add_argument(&quot;--t-high&quot;, type=int, default=0,
                   help=&quot;Tiempo (s) para HIGH dentro del modo adaptativo. Si 0, se reparte automáticamente.&quot;)
    p.add_argument(&quot;--target-acc&quot;, type=float, default=150.0,
                   help=&quot;Precisión objetivo en metros para considerar suficiente DEFAULT (por defecto 150).&quot;)
    p.add_argument(&quot;--max-age&quot;, type=int, default=0,
                   help=&quot;Aceptar caché de hasta X segundos en DEFAULT (por defecto 0 = solo posiciones frescas).&quot;)
    p.add_argument(&quot;--warmup&quot;, type=float, default=0.0,
                   help=&quot;Warm-up en segundos antes de pedir posición (p.ej. 3–6s si hay WWAN).&quot;)
    p.add_argument(&quot;--no-escalate&quot;, action=&quot;store_true&quot;,
                   help=&quot;No escalar a HIGH nunca (solo DEFAULT).&quot;)
    p.add_argument(&quot;--json&quot;, action=&quot;store_true&quot;,
                   help=&quot;Salida en JSON (una línea).&quot;)
    p.add_argument(&quot;--verbose&quot;, &quot;-v&quot;, action=&quot;store_true&quot;,
                   help=&quot;Más trazas (estados de proveedor, etapas adaptativas).&quot;)
    # Nuevo: solo &lt;3.14, por si quieres forzar selector legacy
    p.add_argument(&quot;--force-selector&quot;, action=&quot;store_true&quot;,
                   help=&quot;(Solo &lt;3.14) Forzar WindowsSelectorEventLoopPolicy. No usar salvo necesidad.&quot;)
    return p.parse_args()

def _maybe_force_selector(force_flag: bool):
    &quot;&quot;&quot;Evita deprecations en 3.14+: solo fuerza selector en &lt;3.14 si el usuario lo pide
       (flag --force-selector o env GEO_FORCE_SELECTOR=1).&quot;&quot;&quot;
    try:
        if not sys.platform.startswith(&quot;win&quot;):
            return
        if sys.version_info &gt;= (3, 14):
            return  # nada que hacer en 3.14+
        want = force_flag or os.getenv(&quot;GEO_FORCE_SELECTOR&quot;) in (&quot;1&quot;,&quot;true&quot;,&quot;TRUE&quot;)
        if want and hasattr(asyncio, &quot;WindowsSelectorEventLoopPolicy&quot;):
            asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())  # ok en &lt;3.14
    except Exception:
        pass

def main():
    if not sys.platform.startswith(&quot;win&quot;):
        print(&quot;Este test solo está soportado en Windows.&quot;)
        sys.exit(1)

    args = parse_args()
    # En 3.13.x funcionará sin tocar la policy; solo si lo pides explícitamente:
    _maybe_force_selector(args.force_selector)

    if not args.json:
        print(&quot;=== Prueba de geolocalización Windows (WinRT) ===&quot;)
        print(f&quot;Modo: {args.mode} | Presupuesto total: {args.timeout}s\nSolicitando una posición...\n&quot;)

    data, code, err = asyncio.run(get_position(
        mode=args.mode,
        timeout_total=args.timeout,
        t_default=args.t_default,
        t_high=args.t_high,
        target_acc_m=args.target_acc,
        max_age_s=args.max_age,
        warmup=args.warmup,
        verbose=args.verbose,
        no_escalate=args.no_escalate
    ))

    if err:
        if args.json:
            import json
            print(json.dumps({&quot;ok&quot;: False, &quot;error&quot;: err, &quot;code&quot;: code}, default=str))
        else:
            print(&quot;No se pudo obtener posición.&quot;)
            print(&quot;Motivo:&quot;, err)
            print(&quot;&quot;&quot;
Pistas para habilitarlo:
  1) Configuración → Privacidad y seguridad → Ubicación:
     • Activar &quot;Servicios de ubicación&quot;.
     • Activar &quot;Permitir que las aplicaciones de escritorio accedan a tu ubicación&quot;.
  2) Servicio de Windows &quot;Geolocalización&quot; (lfsvc) en ejecución.
  3) En Windows Server: comprobar directivas en gpedit.msc
     (Equipo → Plantillas administrativas → Componentes de Windows → 'Ubicación y sensores').
  4) Si el equipo tiene SIM/WWAN y no hay GNSS, prueba con --mode adaptive o --no-escalate,
     o añade --warmup 4 y acepta caché con --max-age 300.
&quot;&quot;&quot;)
        sys.exit(code or 2)

    # Éxito
    if args.json:
        import json
        print(json.dumps({&quot;ok&quot;: True, &quot;data&quot;: data}, default=str))
    else:
        print(&quot;✔ Posición obtenida:&quot;)
        ts = data&#91;&quot;timestamp&quot;&#93;
        if isinstance(ts, datetime.datetime):
            ts_str = ts.strftime(&quot;%Y-%m-%d %H:%M:%S&quot;)
        else:
            ts_str = str(ts)
        print(f&quot;  Timestamp:       {ts_str}&quot;)
        print(f&quot;  Lat, Lon:        {data&#91;'latitude'&#93;:.6f}, {data&#91;'longitude'&#93;:.6f}&quot;)
        print(f&quot;  Precisión (m):   {data&#91;'accuracy_m'&#93;}&quot;)
        print(f&quot;  Altitud (m):     {data&#91;'altitude_m'&#93;}&quot;)
        print(f&quot;  Fuente:          {data&#91;'source'&#93;}&quot;)
        print(f&quot;  Estado proveedor:{data&#91;'provider_status'&#93;}&quot;)
        print(f&quot;  Modo usado:      {data&#91;'mode_used'&#93;} (intentos={data&#91;'attempts'&#93;}, {data&#91;'elapsed_s'&#93;}s)&quot;)

if __name__ == &quot;__main__&quot;:
    main()
​
​</pre>
</div></div></div></div><br />
​]]></content:encoded>
			<category domain="https://jmtella.com/foro/forum/ejercicios-y-ejemplos"><![CDATA[TIP's, Ejercicios y Ejemplos]]></category>
			<dc:creator>jmtella</dc:creator>
			<guid isPermaLink="true">https://jmtella.com/foro/forum/ejercicios-y-ejemplos/57147-tip-geolocalización-en-ordenadores-sin-adaptador-wifi</guid>
		</item>
	</channel>
</rss>
