La verdad es que esta entrada es un experimento de SEO, dado que el nunca bien ponderado Chema Alonso ha decidido spammear esta cadena de texto para que le redirija a su blog, he querido probar si Google tiene alguna forma inteligente de discriminar la importancia o popularidad de un blog a la hora de incluir una entrada en su índice.
Es evidente que no se quien es el jefe de los hackers, si que se que el director de datos de telefónica no lo es y, por lo que he visto, su misión es más dar visibilidad a los problemas de seguridad que intentar arreglarlos.
Si quisieramos, de todas maneras, evitar que los hackers se hiciesen con nuestras contraseñas lo más sencillo sería utilizar un gestor de contraseñas que solo las guardase en uno de nuestros dispositivos, sin copias en la red y con un método seguro y fiable de enviar las credenciales desde el móvil al ordenador (o el sistema que lo necesite), ahora mismo este sistema es nomorepass.
Además, para aumentar la seguridad física en nuestro hogar o en el apartamento que queremos alquilar y darnos todas las garantías, estamos trabajando en una cerradura inteligente de fácil instalación y muy, muy avanzada… Pero de eso hablaremos un poco más adelante.
A ver, en realidad esto ha sonado mejor de lo que realmente es, pero, ¿te gustaría poder decirle a tu casa que estás dentro para que sepa si hay que lanzas una alarma o simplemente saludarte? Pues algo muy similar vamos a poder hacer con home assistant, por lo que te recomiendo que te leas la entrada anterior si quieres continuar con ésta.
Si tienes home assistant ya instalado hay un concepto que puede parecer extraño al principio, pero que es fundamental para lo que queremos hacer, el concepto de «persona». Puedes acceder al menú de personas desde Configuración -> Personas:
Este menú te dará opción a crear todas las personas relevantes para tu casa y te permitirá hacerles seguimiento… Básicamente lo que queremos es saber si están dentro o fuera de la casa para tener esa información disponible para nuestras automatizaciones (o para saberlo cuando nos llega un paquete de Amazon y queremos saber si hay alguien en la casa, por ejemplo).
¿Seguimiento?
Para poder hacer el seguimiento de una persona necesitamos que ésta nos informe de una manera o de otra de su situación con respecto a la casa, eso en home assistant se hace con os device.trackers que son, ni más ni menos, que la parte de código que recibe la información de la situación de un dispositivo. Hay un montón de trackers que os invito a explorar para ver cual es el más adecuado para vosotros. Como mi objetivo es que el seguimiento sea transparente y consuma la menor cantidad posible de datos y energía os voy a proponer dos tackers que, además, son muy sencillos de configurar:
1. Aplicación de home assistant
Tenéis disponible en vuestra tienda favorita la aplicación home assistant que os da acceso remoto a vuestra instalación (bueno, lo de remoto lo veremos en otra entrada, que tiene su miga) y que, además, permite al móvil comunicarse con home assistant para darle datos sobre la localización del dispositivo (y otras cosas como si está cargando o no y la cantidad de carga restante que tiene).
Una vez instalada la aplicación veremos que aparecen entidades nuevas en home assistant y que podremos ponerlas en e interfaz o, como es el caso, utilizarla como sistema de seguimiento para una persona… Para ello solo tenemos que acceder al menú personas, crear la persona si todavía no existe y editarla, lo que nos llevará a una pantalla como esta:
En la parte de «Rastrear dispositivo» veremos que en el desplegable nos aparece un device_tracker con el nombre del móvil donde hemos instalado la aplicación. Lo seleccionamos, grabamos y, a partir de este momento la casa nos tendrá localizados.
2. Usando un tracker bluetooth
Esto está bien, pero igual no queremos que todos los miembros de la familia tengan que instalarse la aplicación móvil, así que buscando otro método para saber si están o no en casa me encontré con que todos en la familia tenemos activo el bluetooth del teléfono (para conectar con los altavoces, los cascos, el coche, o lo que sea…) si eso es así podríamos hacer que la raspberry (que tiene bluetooth integrado) nos localice siempre que estemos a una distancia que permita llegar al bluetooth de nuestro teléfono. Dicho y hecho, para configurar este comportamiento solo hay que usar el bluetooth tracker y poner lo siguiente en el archivo configuration.yml:
device_tracker:
- platform: bluetooth_tracker
Luego solo tenemos que reiniciar el sistema y automáticamente nos creará un archivo known_devices.yml que contendrá todos los dispositivos bluettoth que ha detectado y permite ponerles nombre y decidir si vamos a seguirlos o no (por defecto sigue a todos los nuevos, por lo que es recomendable cambiar ese comportamiento cuando ya estén detectados todos los dispositivos). Si no aparece vuestro móvil en un rato lo mejor es que pongas el móvil a buscar dispositivos bluetoot para tenerlo activo mientras reinicias home assistant y así te aseguras de que lo detecta.
Una vez detectados los móviles que nos interesa solo tenemos que volver a personas y repetir el mismo procedimiento… A partir de ese momento podremos saber si están en casa o no (o al menos los móviles) y verlo en el interfaz:
Creí, francamente, que ya había escrito sobre el tema de la domótica en mi blog, pero revisando me he encontrado que no he escrito casi nada sobre el tema, así que comienzo ahora a desvelaros, muy poco a poco, qué es esto de la automatización y cómo puedes controlar tu casa y hacerla más inteligente con un coste ridículo (y aprendiendo un montón).
Como resumen, la domótica aglutina todo lo que podemos controlar de manera remota 8o programar localmente) en nuestro hogar. Son esas cosas que nos permiten encender la calefacción horas antes de que lleguemos de un viaje, abrir y cerrar persianas sin que estemos o apagar y encender luces cuando se detecta nuestra presencia. Dado que esto es un campo muy amplio, os recomiendo que visitéis webs más especializadas para descubrir el montón de cosas que se pueden hacer. Yo, por mi parte, iré recopilando las cosas interesantes que voy haciendo por si os sirve de algo.
Lo primero…
Para poder «jugar» un poco con la domótica necesitamos algún controlador en el que centralizar todas estas opciones. En mi caso me he decidido por home assistant, que tiene un montón de información en internet y del que disponéis de plugins y librerías para cadsi todo. La instalación es tremendamente sencilla si vamos a utilizar una raspberry pi (recomiendo que sea la 4, pero la 3 también nos serviría igualmente). La guía de instalación para raspberry pi está bastante bien y la podéis encontrar en este enlace.
El proceso consiste, básicamente, en descargarte la imagen de internet, grabar con esa imagen una tarjeta SD y si tenéis conexión por cable simplemente meter la sd en la rasperry, enchufar el cable de red y esperar a que arranque, tendréis el sistema de configuracion en la url http://homeassistant.local:8123/. Si vais a usar wifi desde el primer momento el proceso es un poco más complicado, básicamente consiste en copiar este archivo (modifica a tu gusto el SSID y contraseña) en la particion de boot del SD que acabáis de grabar (en CONFIG/network/) y llámalo my-network:
[connection]
id=my-network
uuid=72111c67-4a5d-4d5c-925e-f8ee26efb3c3
type=802-11-wireless
[802-11-wireless]
mode=infrastructure
ssid=MI_SSID
# Uncomment below if your SSID is not broadcasted
#hidden=true
[802-11-wireless-security]
auth-alg=open
key-mgmt=wpa-psk
psk=MI_CONTRASEÑA_WIFI
[ipv4]
method=auto
[ipv6]
addr-gen-mode=stable-privacy
method=auto
En fin, una vez que tengáis home assistant instalado toca poner los datos tuyos y los del domicilio donde vas a instalarlo y el sistema se encargará de buscar por red las integraciones a las que pueda acceder directamente.
En siguientes entradas veremos aspectos interesantes sobre cómo configurarlo para tener acceso a dispositivos zigbee, a detectar presencia propia o a hacer automatizaciones… Por ahora intentad tener el controlador preparado e id buscando dispositivos para hacer de vuestra casa una casa inteligente.
Últimamente estoy muy metido en esto del CI/CD (Integración continúa/Despliegue continuo) que no significa, ni más ni menos, que las actualizaciones a los repositorios de código generan automáticamente todos los artefactos necesarios para poder comprobar que están correctos y que pueden desplegarse en producción, e incluso desplegarlos si así lo consideramos.
En el caso de servicios en internet de cualquier tipo (webs, APIs, etc.) el método de despliegue suele ser más sencillo de automatizar (básicamente generas un contenedor con una versión nueva y lo «empujas» al sistema de producción), más sencillo incluso si utilizamos kubernetes o ansible. Pero en el caso de distribución de aplicaciones a instalar en clientes es más complicado. En el caso que traemos aquí lo que queremos hacer es subir a la tienda de google play (y ya veremos qué hacemos con apple) una nueva versión de una aplicación móvil.
En principio debería ser sencillo, ya que solo tenemos que utilizar el API de Google Play para desarrolladores. Pero antes, tenemos que conseguir ciertas «autorizaciones» de google que no son tan triviales como deberían. Para haceros la tarea un poco más sencilla, aquí os dejo un script python que hace justo lo que queremos: subir a la tienda nuestro apk recién compilado al canal alpha (upload_apks.py)
"""Uploads an apk to the alpha track."""
import argparse
from googleapiclient import discovery
import httplib2
from oauth2client.service_account import ServiceAccountCredentials
from oauth2client import client
TRACK = 'alpha' # Can be 'alpha', beta', 'production' or 'rollout'
SERVICE_ACCOUNT_EMAIL = (
'ENTER_YOUR_SERVICE_ACCOUNT_EMAIL_HERE@developer.gserviceaccount.com')
# Declare command-line flags.
argparser = argparse.ArgumentParser(add_help=False)
argparser.add_argument('package_name',
help='The package name. Example: com.android.sample')
argparser.add_argument('apk_file',
nargs='?',
default='test.apk',
help='The path to the APK file to upload.')
argparser.add_argument('key_file',
nargs='?',
default='key.json',
help='key in json format for service account')
argparser.add_argument('version',
nargs='?',
default='New version',
help='Version name')
def main():
# Process flags and read their values.
flags = argparser.parse_args()
package_name = flags.package_name
apk_file = flags.apk_file
key_file = flags.key_file
version = flags.version
credentials = ServiceAccountCredentials.from_json_keyfile_name(
key_file,
scopes='https://www.googleapis.com/auth/androidpublisher')
http = httplib2.Http()
http = credentials.authorize(http)
service = discovery.build('androidpublisher', 'v3', http=http)
try:
edit_request = service.edits().insert(body={}, packageName=package_name)
result = edit_request.execute()
edit_id = result['id']
apk_response = service.edits().apks().upload(
editId=edit_id,
packageName=package_name,
media_body=apk_file).execute()
print ('Version code {} has been uploaded'.format(apk_response['versionCode']))
track_response = service.edits().tracks().update(
editId=edit_id,
track=TRACK,
packageName=package_name,
body={u'releases': [{
u'name': version,
u'versionCodes': [apk_response['versionCode']],
u'status': u'completed',
}]}).execute()
print ('Track {} is set for release(s) {}' .format (
track_response['track'], str(track_response['releases'])))
commit_request = service.edits().commit(
editId=edit_id, packageName=package_name).execute()
print ('Edit "{}" has been committed'.format(commit_request['id']))
except client.AccessTokenRefreshError:
print ('The credentials have been revoked or expired, please re-run the '
'application to re-authorize')
if __name__ == '__main__':
main()
Antes de poder ejecutar este código deberás instalar algunas librerías (o ponerlas en el Dockerfile)
Y ahora la parte más pesada… Los datos a rellenar en pc-api.json, para ello deberás configurar un proyecto API en la consola cloud de Google y crear una cuenta de servicio… Este no es un proceso inmediato, pero hay buenas instrucciones en la página de google.
Luego hay que ir a la sección de la Google Play Console al apartado Acceso a API, donde deberás vincular el proyecto que acabas de crear y crear las cuentas de servicio necesarias.
Para después en la sección de Usuarios y permisos dar permisos a la cuenta de servicio que acabamos de crear, al menos estos:
El tema de extraer la clave privada y eso ya os lo dejo para después por si alguien tiene curiosidad…
ACTUALIZACIÓN 4/01/2022
Como ahora Google solo deja subir bundles (.aab) dejo aquí el código modificado para poder hacerlo (según el tipo de archivo que elijamos):
#!/usr/bin/env python3
#
# Copyright 2014 Marta Rodriguez.
# Modified by Jose Antonio Espinosa (2021-2022)
#
# Licensed under the Apache License, Version 2.0 (the 'License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Uploads an apk/aab to the alpha track."""
import argparse
from googleapiclient import discovery
import httplib2
from oauth2client.service_account import ServiceAccountCredentials
from oauth2client import client
import os.path
import mimetypes
mimetypes.add_type("application/octet-stream", ".apk")
mimetypes.add_type("application/octet-stream", ".aab")
TRACK = 'alpha' # Can be 'alpha', beta', 'production' or 'rollout'
SERVICE_ACCOUNT_EMAIL = (
'ENTER_YOUR_SERVICE_ACCOUNT_EMAIL_HERE@developer.gserviceaccount.com')
# Declare command-line flags.
argparser = argparse.ArgumentParser(add_help=False)
argparser.add_argument('package_name',
help='The package name. Example: com.android.sample')
argparser.add_argument('apk_file',
nargs='?',
default='test.apk',
help='The path to the APK file to upload.')
argparser.add_argument('key_file',
nargs='?',
default='key.json',
help='key in json format for service account')
argparser.add_argument('version',
nargs='?',
default='New version',
help='Version name')
def main():
# Process flags and read their values.
flags = argparser.parse_args()
package_name = flags.package_name
apk_file = flags.apk_file
key_file = flags.key_file
version = flags.version
extension = os.path.splitext(apk_file)[1]
# Create an httplib2.Http object to handle our HTTP requests and authorize it
# with the Credentials. Note that the first parameter, service_account_name,
# is the Email address created for the Service account. It must be the email
# address associated with the key that was created.
credentials = ServiceAccountCredentials.from_json_keyfile_name(
key_file,
scopes='https://www.googleapis.com/auth/androidpublisher')
http = httplib2.Http()
http = credentials.authorize(http)
service = discovery.build('androidpublisher', 'v3', http=http)
try:
edit_request = service.edits().insert(body={}, packageName=package_name)
result = edit_request.execute()
edit_id = result['id']
if extension == '.apk':
apk_response = service.edits().apks().upload(
editId=edit_id,
packageName=package_name,
media_body=apk_file).execute()
else:
apk_response = service.edits().bundles().upload(
editId=edit_id,
packageName=package_name,
media_body=apk_file).execute()
print ('Version code {} has been uploaded'.format(apk_response['versionCode']))
track_response = service.edits().tracks().update(
editId=edit_id,
track=TRACK,
packageName=package_name,
body={u'releases': [{
u'name': version,
u'versionCodes': [apk_response['versionCode']],
u'status': u'completed',
}]}).execute()
print ('Track {} is set for release(s) {}' .format (
track_response['track'], str(track_response['releases'])))
commit_request = service.edits().commit(
editId=edit_id, packageName=package_name).execute()
print ('Edit "{}" has been committed'.format(commit_request['id']))
except client.AccessTokenRefreshError:
print ('The credentials have been revoked or expired, please re-run the '
'application to re-authorize')
if __name__ == '__main__':
main()
Aunque yo no soy muy fan de apple en nada (como podréis ver si miráis un poco en este blog), el hecho es que tuve que gastarme una cantidad ingente de dinero en comprarme un macbook pro en 2011 para tener la oportunidad de empezar a programar aplicaciones para iOS. Entonces no había otra manera, ahora, por suerte, si que la hay como podéis ver en este mismo blog.
Es la mayor inversión que he hecho nunca en un ordenador y, aunque mac os no es que sea el mejor sistema del mundo, el hardware si que estaba muy cuidado, la carcasa en aluminio y el teclado retroiluminado y amplio (además de una pantalla muy brillante) me hicieron tenerlo como portatil principal durante muchos años. Pero la obsolescencia programa de apple terminaría por llamar a la puerta. Primero fue el chip de la GPU que, aparentemente por exceso de calor, terminó por romperse y me obligaron a comprarme toda una nueva placa madre (coste superior a un portatil completo que no fuese apple), pero es que no contentos con esto dejaron de actualizar el sistema operativo en High Sierra y ya me he perdido 3 grandes actualizaciones. Después de que la «nueva» GPU terminase por romperse de nuevo decidí dejar de usarlo por un tiempo… Hasta ahora que he decidido ponerle un arranque dual y tener ubuntu y os x (lo que me permita apple) en el mismo ordenador (ahora mismo estoy escribiendo esto desde ubuntu en el macbook pro). Os comento en este post algunas cosas a hacer para resucitar un viejo macbook pro 2011 con la GPU radeon rota.
Lo primero es poder arrancar una vez que la tarjeta gráfica se ha estropeado, para ello lo que hay que hacer es arrancar en modo superusuario (arrancar con cmd+s pulsado) y en esa terminal escribir:
Una vez reiniciado ya con la pantalla normal (esto es temporal) habría que hacerlo un poco más permanente, para ello he creado un script que podríais lanzar desde cualquier distribución live (yo uso ubuntu) y que de hecho yo tengo almacenada en el usb arrancable (en la particion writable). El script es este:
echo "Ejecutar como root este script" printf "\x07\x00\x00\x00\x01\x00\x00\x00" > /sys/firmware/efi/efivars/gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9 chattr +i "/sys/firmware/efi/efivars/gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9" cd / umount /sys/firmware/efi/efivars/ echo "Ahora deberías reiniciar la máquina para que tenga efecto"
Arrancar con la live (tener pulsado la tecla alt mientras se arranca y luego seleccionar el disco arrancable de ubuntu) y ejecutar como root el script. Esto hace que el cambio sea permanente (hasta que se actualice de nuevo la información de la EFI, pero eso solo pasa con las instalaciones grandes del sistema operativo).
Lo siguiente ya es más entretenido… Actualizar el hardware (yo le he puesto dos ssd y estoy pensando en actualizar la memoria), instalar linux, intentar actualizar high sierra a otro sistema (yo he conseguido instalarle mojave), limpiarle por dentro y cambiar la pasta térmica (esto no es tan complicado pero hay que lidiar con la forma de integrar componentes que tiene mac). En fin, entretenimiento para rato.
Por suerte, parece que todo funciona (menos la maldita GPU de AMD) y puedo volver a usar el trasto cuando quiera.
Gestionar el consentimiento de las cookies
Si, es un coñazo, pero tengo que ponerte este aviso sobre las cookies y mi
Funcional
Siempre activo
El almacenamiento o acceso técnico es estrictamente necesario para el propósito legítimo de permitir el uso de un servicio específico explícitamente solicitado por el abonado o usuario, o con el único propósito de llevar a cabo la transmisión de una comunicación a través de una red de comunicaciones electrónicas.
Preferencias
El almacenamiento o acceso técnico es necesario para la finalidad legítima de almacenar preferencias no solicitadas por el abonado o usuario.
Estadísticas
El almacenamiento o acceso técnico que es utilizado exclusivamente con fines estadísticos.El almacenamiento o acceso técnico que se utiliza exclusivamente con fines estadísticos anónimos. Sin un requerimiento, el cumplimiento voluntario por parte de tu Proveedor de servicios de Internet, o los registros adicionales de un tercero, la información almacenada o recuperada sólo para este propósito no se puede utilizar para identificarte.
Marketing
El almacenamiento o acceso técnico es necesario para crear perfiles de usuario para enviar publicidad, o para rastrear al usuario en una web o en varias web con fines de marketing similares.