mercoledì 8 novembre 2017

GNSS Android 8

Tempo fa avevo provato l'applicazione demo delle nuovi API per GNSS di Android. Adesso e' disponibile una applicazione per verificare i dati salvati nel file dati (link). La applicazione Linux e' scaricabile da qui

https://github.com/google/gps-measurement-tools/releases/download/2.4.0.0/GnssAnalysisLinuxV2.4.0.0.zip

Per installare la applicazione si usa un web installer che permette di installare anche il runtime di Matlab senza la necessita' di avere una licenza

La applicazione e' installata di default in

/usr/local/Desktop/GnssAnalysisFiles/application

per lanciare l'applicazione si usa

./run_GnssAnalysisApp.sh ../../../MATLAB/MATLAB_Runtime/v901/

A questo punto si importa il file derivante da Android. In questo caso il file deriva da un Nexus 9 e quindi sono disponibili anche i dati GLONASS



 
Per usare Analyze and Plot si deve essere collegati ad Internet perche' devono essere scaricati in automatico i file delle effemeridi dei satelliti.

Al termine si puo' cliccare sull'icona del robottino verde per ottenere un report in formato HTML

Dalla lettura del file si vedono i test riusciti e quelli falliti. Per esempio


 

The GPS reference threshold is set to 38 dBHz. Well built phones, 
in open sky, have GPS satellites stronger than this threshold. 
GLONASS threshold is 2.5dB lower, since GLO signal is 2.5dB weaker, 
(see GPS and GLONASS ICDs).

For your log file the C/No results are:
GPS, mean of strongest 4 median C/No = 35.6 dBHz
Pass/fail reference threshold = 38.0 dBHz
Errors. Signals -2.4 dB compared to reference
FAIL BECAUSE OF WEAK SIGNALS
GLO, mean of strongest 4 median C/No = 36.0 dBHz
Pass/fail reference threshold = 35.5 dBHz
PASS








Come output si hanno anche i file .mat, .nmea e .derived 

martedì 7 novembre 2017

Motore acceso??

Il problema e' questo : e' possibile determinare se una macchina ferma ha il motore acceso o meno usando un telefono Android??

Si tratta di un problema per una app che dovevo fare ma che poi non ha mai visto la luce e la risposta e' si'....usando la FFT sui dati dell'accelerometro

Il primo grafico e' relativo ad una misura di 30 secondi a macchina ferma e spenta, il secondo sempre su una acquisizione di 30 secondi a macchina ferma ed accesa al minimo del motore



E' abbastanza evidente una frequenza di risonanza della macchina su tutti e tre gli assi intorno ai 40 Hz (il motore girava intorno ai 900 rpm ma quello che si registra e' la vibrazione di tutta la struttura)

venerdì 20 ottobre 2017

Foto ed imageview su Android

Aggiornamento: facendo delle prove con Nexus 5x e Nexus 9 ho scoperto che l'immagine risulta ruotata di 90° nonostante non ci siano modifiche nel codice
A questo link viene descritto il medesimo problema

Un sistema per una app che scatta una foto e mette il risultato in una imageview ed effettua il salvataggio (gestione dei permessi di scrittura non gestita..vedi post precedenti)



-----------------------------------------------
package com.example.lucainnocenti.photonotation;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;


public class MainActivity extends AppCompatActivity {
    private static final int CAMERA_REQUEST = 1888;
    private ImageView foto;
    private Bitmap ff;


    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        foto = (ImageView) findViewById(R.id.imageView);
        Button scatto = (Button) findViewById(R.id.button);


        scatto.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View view) {
                Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(camera, CAMERA_REQUEST);
            }
        });


    }
    protected void onActivityResult(int requestCode,int resultCode, Intent data)
    {
        if (requestCode== CAMERA_REQUEST && resultCode == Activity.RESULT_OK){
            ff = (Bitmap) data.getExtras().get("data");
            foto.setImageBitmap(ff);
            foto.setImageURI(data.getData());
            Bitmap bm=((BitmapDrawable)foto.getDrawable()).getBitmap();
            saveImageFile(bm);
        }

    }

    public String saveImageFile(Bitmap bitmap) {
        FileOutputStream out = null;
        String filename = getFilename();
        try {
            out = new FileOutputStream(filename);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Log.d("luca22","Errore");
        }
        return filename;
    }

    private String getFilename() {
        File file = new File(Environment.getExternalStorageDirectory()
                .getPath(), "TestFolder");
        if (!file.exists()) {
            file.mkdirs();
        }
        String uriSting = (file.getAbsolutePath() + "/"                + System.currentTimeMillis() + ".jpg");
        Log.d("luca22",uriSting);
        return uriSting;
    }
}

Azimuth Pitch e Roll su Android N

Gestione dei sensori con RotationMatrix su Android



--------------------------------------------------------------
package com.example.lucainnocenti.sensori;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity implements SensorEventListener{

    private SensorManager mSensorManager;
    private final float[] mAccelerometerReading = new float[3];
    private final float[] mMagnetometerReading = new float[3];

    private final float[] mRotationMatrix = new float[9];
    private final float[] mOrientationAngles = new float[3];
    private Sensor mAccelerometer;
    private Sensor mMagnetometer;

    private double az;
    private double pi;
    private double ro;


    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);


    }

    @Override    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    @Override    protected void onResume() {
        super.onResume();

        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
        mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);

    }

    @Override    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this);
    }

    @Override    public void onSensorChanged(SensorEvent event) {

        if (event.sensor == mAccelerometer) {
            System.arraycopy(event.values, 0, mAccelerometerReading, 0, mAccelerometerReading.length);
        }
        else if (event.sensor == mMagnetometer) {
            System.arraycopy(event.values, 0, mMagnetometerReading, 0, mMagnetometerReading.length);
        }
        updateOrientationAngles();
    }


    public void updateOrientationAngles() {
        mSensorManager.getRotationMatrix(mRotationMatrix, null, mAccelerometerReading, mMagnetometerReading);
        mSensorManager.getOrientation(mRotationMatrix, mOrientationAngles);
        az = Math.toDegrees(mOrientationAngles[0]);
        pi = Math.toDegrees(mOrientationAngles[1]);
        ro = Math.toDegrees(mOrientationAngles[2]);
        Log.d("orienta", "Az:"+String.valueOf(az)+" Pi:"+String.valueOf(pi)+" Ro:"+String.valueOf(ro));

    }
}

GPS su Android N

Un esempio di uso del GPS su Android N con getione dei permessi. Evidenziate in giallo le parti di codice di gestione dei permessi


---------------------------------------------------
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.lucainnocenti.gpstest">
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />


    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
---------------------------------------------------



---------------------------------------------------
package com.example.lucainnocenti.gpstest;

import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity implements LocationListener{

    LocationManager locationManager;
    String provider;
    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        provider = locationManager.getBestProvider(new Criteria(), false);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            checkLocationPermission();
            return;
        }
        Location location = locationManager.getLastKnownLocation(provider);

        if (location != null) {

            Log.i("Location Info", "Location achieved!");

        } else {

            Log.i("Location Info", "No location :(");

        }
    }

    @Override    protected void onResume() {
        super.onResume();

        if (checkLocationPermission()) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                locationManager.requestLocationUpdates(provider, 400, 1, this);
            }
        }

    }

    @Override    protected void onPause() {
        super.onPause();

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            checkLocationPermission();
            return;
        }
        locationManager.removeUpdates(this);

    }

    @Override    public void onLocationChanged(Location location) {

        Double lat = location.getLatitude();
        Double lng = location.getLongitude();

        Log.i("Location info: Lat", lat.toString());
        Log.i("Location info: Lng", lng.toString());

    }

    @Override    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override    public void onProviderEnabled(String provider) {

    }

    @Override    public void onProviderDisabled(String provider) {

    }

    public void getLocation(View view) {

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        Location location = locationManager.getLastKnownLocation(provider);

        onLocationChanged(location);


    }

    public boolean checkLocationPermission() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.ACCESS_FINE_LOCATION)) {


                new AlertDialog.Builder(this)
                        .setTitle("Permesso GPS")
                        .setMessage("Permesso GPS")
                        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                            @Override                            public void onClick(DialogInterface dialogInterface, int i) {
                                //Prompt the user once explanation has been shown                                ActivityCompat.requestPermissions(MainActivity.this,
                                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                        MY_PERMISSIONS_REQUEST_LOCATION);
                            }
                        })
                        .create()
                        .show();


            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
            }
            return false;
        } else {
            return true;
        }
    }

    @Override    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_LOCATION: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        locationManager.requestLocationUpdates(provider, 400, 1, this);
                    }

                } else {

                    // permission denied,

                }
                return;
            }

        }
    }
}

Scrittura JSON su Android N

Un esempio semplice per scrivere un file JSON e gestire in permessi di scrittura su Android 7 e successivi
Nel codice le parti in azzurro sono quelle relative alla gestione dei permessi mentre quelle in giallo sono per la gestione della creazione del JSON


---------------------------------------
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.lucainnocenti.jsontester">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />



    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

---------------------------------------


---------------------------------------
package com.example.lucainnocenti.jsontester;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.JsonWriter;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;


public class MainActivity extends AppCompatActivity {
    private int requestCode;
    private int grantResults[];
    private FileOutputStream out;
    private JsonWriter writer;
    private File card;
    private File file;

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
        onRequestPermissionsResult(requestCode, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, grantResults);
        Button pulsante =(Button) findViewById(R.id.button);
        pulsante.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View view) {
                card = Environment.getExternalStorageDirectory();
                file = new File (card.getAbsolutePath(),"dati.json");
                try {
                    out = new FileOutputStream(file);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                try {
                    writer = new JsonWriter(new OutputStreamWriter(out,"UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                try {
                    writer.beginObject();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    writer.name("nome").value("Luca");
                    writer.name("cognome").value("Innocenti");
                } catch (IOException e) {
                    e.printStackTrace();
                }

                try {
                    writer.endObject();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                ;


            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 1: {

                // If request is cancelled, the result arrays are empty.                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    Log.d("permission", "granted");
                } else {


                    Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();

                    onDestroy();
                }
                return;
            }
        }
    }
}

giovedì 19 ottobre 2017

Bash ftp script

uno script bash per inviare dati in FTP
un paio di dettagli

  1. per usare le wildcard si devono i comandi mdel ed mput
  2. Per usare mput con la wildcard ci si deve prima spostare nella directory in cui sono contenuti i file mediante lcd perche' mput non permette di inserire il path completo ma solo il nome file
  3. ftp -ni indica una sessione non interattiva e in modalita' autologin
  4. quote serve ad inviare il contenuto della variabile al server remoto
------------------------------------------------------------------------------
#!/bin/sh
HOST="ftp.xxxxxxxxx.it"
USER="xxxxxxxx@aruba.it"
PASSWD="xxxxx"

ftp -ni $HOST<<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
cd xxxxxx/yyyy/zzzzz/
mdel *
lcd /home/luca/
binary
mput *.ics
quit
END_SCRIPT
exit 0


SSH e disconnessione sessione

Succede piuttosto spesso di dover utilizzare una connessione remota in SSH e lanciare dei comandi (tipicamente delle query). Tipicamente quando si chiude una sessione ssh si uccidono anche tutti i processi che si erano aperti nella sezione. Per risolvere questo problema viene in aiuto il comando nohup

ssh luca@ip.ip.ip.ip "nohup /home/luca/comando> /dev/null 2>&1 &"

con la sintassi sopra riportata si lancia comando sia SSH senza che il suo processo venga chiuso al termine della sessione

FTP Client su Midnight Commander

A volte puo' essere utile avere un client FTP che funzioni su una shell testuale, in particolare quando si usa una connessione SSH. Una soluzione molto comoda e' quella di utlizzare Midnight Commander

Per prima cosa si deve creare e popolare il file netrc

touch ~/.netrc
chmod 600 ~/.netrc
nano ~/.netrc

A questo punto si inseriscono le configurazioni di connessione al server FTP con la sintassi

machine ftp.test.it login luca password test

a questo punto si apre Midnight Commander, Left (o Right) -> FTP Link e si digita l'indirizzo del server FTP. In questo modo in uno dei due pannelli viene mostrato il contenuto della directory FTP



mercoledì 11 ottobre 2017

SSTV


Slow Scan Television e' un metodo per inviare immagini/video utilizzando lo stesso canale radio impiegato anche per le comunicazioni voce ed ha origini che si perdono agli albori dell'esplorazione spaziale per inviare immagini dalle sonde verso Terra (anche le prime missioni Apollo utilizzavano SSTV)



La cosa divertente e' che oggi con due semplici terminali Android si puo' effettuare la codifica e decodifica di immagini in SSTV con le applicazioni gratuite SSTV Encoder e Robot36 (che e' il nome di uno dei formati previsti)

Il formato dati e' variabile in dimensione e numero di colori..una immagine in bianco e nero di 120x120 pixel impiega al minimo 8 secondi per essere trasmessa (e ricevuta)



Attualmente e' possibile ricevere immagini via SSTV dalla stazione spaziale internazionale


martedì 10 ottobre 2017

Draft su Lyx

Qui viene indicato come inserire in filigrana una scritta (tipicamente Draft) su un documento editato con Lyx

Qui si inizia scaricando il  pacchetto da qui. Si decomprime e si lancia il file Make...su Centos 7 per terminare correttamente la compilazione e' necessario oltre al pacchetto Lyx anche gv (ghostview)




al termine si copiano i file draftcopy.sty e draftcopy.cfg nella stessa directory dove si trova il file che si sta editando

si modifica quindi il Latex Preamble in Lyx menu Document/Settings/LaTex Preamble con il codice
\usepackage{draftcopy}

per ottenere il risultato si deve fare il preview con pdflatex


lunedì 9 ottobre 2017

Modificare grandezza delle iconde desktop di Centos 7

Le icone sul desktop di Centos 7 sono fastidiosamente grandi, indipendentemente dalla risoluzione. Come si risolve ?? cosi'

 gsettings set org.gnome.nautilus.icon-view default-zoom-level small

per creare uno shortcut sul desktop di una applicazione la via piu' semplice e' copiare il file .desktop da /usr/share/applications/ in /home/user/Desktop

venerdì 6 ottobre 2017

Piu' o meno.....

..... stavo lavorando sulla stessa idea un anno e mezzo fa


bravo a chi e' riuscito a passare dall'idea alla realizzazione e soprattutto alla validazione

giovedì 5 ottobre 2017

Giocando con Emacs

puo' essere cervellotico usare emacs...ma alla fine impazzisci ed inizi ad apprezzarlo

M indica il tasto Meta che sui PC e' tasto ALT di sinistra
C indica il tasto CTRL

Per creare un nuovo file C-x C-f e poi si digita il nome del nuovo file. Si aprira' quindi un buffer.

Per aprire un file esistente C-x C-f poi si puo' digitare il nome oppure si digita Enter e si aprira' un mini file manager da cui selezionare il file desiderato

Per salvare il file C-x C-s

Per selezionare e fare copia/incolla si seleziona mediante C + Spazio per iniziare la selezione e poi con le frecce si seleziona l'area desiderata.
Per fare copia si preme M+W.
Per incollare (Yank nel linguaggio Emacs) C+y

Per effettuare la ricerca di una stringa C+s
Per fare search and replace M-%

Per spostarsi tra i vari buffer aperti (che sarebbero il corrispondente dei tab sugli editor moderni)
C+ x freccia destra
C + x freccia sinistra

Per spostarsi invece tra le varie finestre
C + x seguito da o

per chiudere un buffer che non server piu'
C + x k

per aprire una shell in un buffer
M + x shell
per aprire una shell e contemporaneamente lanciare un comando
M + !  [comando]


Emacs ha il proprio gestore dei pacchetti per le estensioni (ELPA e MELPA). Per abilitare MELPA su Centos 7 si deve creare il file .emacs nella propria home e si aggiungono le seguenti righe

------------------------------------------------------------------
(require 'package) ;; You might already have this line
(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
                    (not (gnutls-available-p))))
       (url (concat (if no-ssl "http" "https") "://melpa.org/packages/")))
  (add-to-list 'package-archives (cons "melpa" url) t))
(when (< emacs-major-version 24)
  ;; For important compatibility libraries like cl-lib
  (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
(package-initialize) ;; You might already have this line
--------------------------------------------------------------------


Per ottenere la lista ELPA dei plugin di Emacs si digita

M-x list-packages

a questo punto scorrendo la lista facendo Enter si entra nella scheda dell'estensione che si apre come un nuovo buffer. Dentro questo si trova il pulsante Install

Per rimuovere una estensione di riapre di nuovo la lista di ELPA, si cerca la riga desiderata (si puo' fare la ricerca con C-s come stringa); una volta trovato si digita d (per marcare per la cancellazione) e poi x (per la cancellazione)

Web development
si apre in un buffer la pagina html che si vuole modificare. Si digitando quindi i due comandi in successione

M-x httpd-start
M-x impatient-mode

si apre quindi il browser e si punta al seguente indirizzo

http://localhost:8080/imp/

qui si troveranno elencati i buffer html aperti in emacs. Cliccando si apre la pagina. Ogni modifica fatta su Emacs viene immediatamente mostrata sul browser. Uno dei problemi che ho notato e' che la modifica avviene in una porzione della pagina fuori dallo schermo (per esempio in basso su una schermata molto lunga) si viene riportati sempre alla testa della pagina

JSON development
M-x package-install Enter
json-mode Enter

per aprire il modo (come per tutti i modi maggiori)
M-x json-mode

per formattare poi i campi in modo che siano leggibili
C-c C-f

Python development
M-x python-mode
C-c C-z apre una shell pyton
C-c C-c esegue lo script nel buffer selezionato

per vedere i risultati si deve cercare il buffer dove ci sono i risultati dello script con C-x freccia destra/sinistra



mercoledì 27 settembre 2017

Giocando con Lyx

E' dai tempi della tesi di dottorato che non utilizzavo piu' Lyx e mi sono decisamente arrugginito.
Questo e' un piccolo promemoria


  • Per creare una immagine al centro della pagina si crea una float figure, si inserisce la foto e subito prima si clicca CTRL+L per inserire il tag \centering
  • Per inserire l'indice si deve selezionare TOC e non index (promemoria stupido ma e' un errore che ho fatto)
  • Per modificare il font di un testo diverso da quello di default si seleziona, tasto destro -> Text Style -> Customized->Shape->Italic per esempio
  • Per creare uno spazio verticale nel testo CTRL+L e tag \bigskip
  • Per creare uno spazio verticale od orizzontale arbitrario si usa CTRL+L e tag \vpanthom{1} e hpanthom{1} .. il numero puo' cambiare a seconda del bisogno
  • Per togliere l'ndentazione al primo rigo di un paragrafo CTRL+L tag \noindent
  • Per creare dei link automatici dal TOC verso le varie sezioni e subsezioni si apra Document-> Settings->PDF properties e si clicca su Hyperref Support
  • per togliere il numero dalla prima pagina subito dopo i tag del titolo (e degli eventuali autori e data) si deve aggiungere CTRL + L \thispagestyle{empty}. In questo modo si nasconde solo la numerazione ma le pagine iniziano da 1 gia' dalla prima pagina
  • Per inserire un line break si digita CTRL+Enter 
  • Gli oggetti float non si spezzano su piu' pagine. Se si ha una tabella float piu' grande del foglio sparira' sul fondo della pagina

martedì 26 settembre 2017

Pulizia tubazioni lavatrice

La lavatrice gìa' vista qui ha smesso di nuovo di funzionare ma questo volta il problema era che alla fine del lavaggio l'acqua non veniva scaricata.
Aprendo lo sportellino in basso per la pulizia filtro mostrava presenza di sporco ma niente di straordinario. Con il filtro rimosso e mettendo il programma di scarico si vedeva la ventola della pompa che girava...quindi non si tratta di un problema di pompa bruciata..non resta che passare allo smontaggio



Al di sotto del cestello e' presente un raccordo a tre vie di colore nero ed a soffietto. Una volta disconesso il soffietto dalla base del cestello e' emerso il problema. ... un tappo di sapone di colore nero.



Una volta rimosso a mano lo sporco ho provato a mettere acqua in alto nel soffietto per vedere se usciva dalla botola del filtro. Niente da fare....ho dovuto rimuovere completamente il soffietto (con tre fascette a pressione per niente simpatiche) per trovare che tutto il condotto per una lunghezza di 15 centimetri era pieno di sapone


La domanda finale non e' come mai ha smesso di funzionare....piuttosto come faceva a funzionare in quelle condizioni

mercoledì 20 settembre 2017

Licenze software

Quando anche il tuo ente "pubblico" non paga le licenze software ti rendi conto di quanto e' considerato il lavoro del programmatore



mercoledì 13 settembre 2017

Inazuma Eleven Go : la sfida padre-figlio

il pargolo mi ha sfidato a disegnare un personaggio di Inazuma Eleven Go: uno io, uno lui...unica regola ..io non potevo usare la gomma

Federico

Luca

Ransomware su QNap

Un paio di giorni fa e' successa una cosa strana (o meglio imprevista)

Accedendo ai dati dati aziendali di backup posti su una unita' QNap, questi risultavano compromessi (o meglio criptati) e nella migliore tradizione dei ransomware era presente la seguente richiesta di riscatto

questo il contenuto del file  ### DECRYPT MY FILES ###.txt.

------------------------------
*** ALL YOUR WORK AND PERSONAL FILES HAVE BEEN ENCRYPTED ***
To decrypt your files you need to buy the special software – «Nemesis decryptor»
You can find out the details / buy decryptor + key / ask questions by email: al-capone@mortalkombat.su
Your personal ID: 68XXXXXX
------------------------------


il nome del file e' stato modificato come segue

luca.ext in luca.ext.id_68xxxxx_[al-capone@mortalkombat.su].wfg65

avendo su un backup il file originale e' possibile vedere che l'aumento di dimensione del file e' esiguo (passando da 961.224 byte a 961.260 byte)

gli ultimi 5 caratteri dell'estensione sono casuali
Utilizzando un servizio on line e' possibile verificare(con questo servizio) che il ransomware e' una variante di CryptOn(Nemesis) conosciuta come Crypt36 ed al momento non sembra esserci una chiave di decrittazione pubblica


e fino a qui niente di nuovo...e' abbastanza chiara anche la variante del ransomware su cui si ha a che fare
La cosa veramente curiosa e' che nessuno dei PC che accedevano al QNap risultava avere problemi di sorta...normalmente i ransomware criptano i dati del PC e di tutte le condivisioni a cui ha accesso ... non in questo caso


Guardando i bollettini di sicurezza e sapendo che il QNap era esposto su Internet e' saltato fuori il bollettino CVE-2017-7494 su una vulnerabilita' di Samba (su QNap gira un sistema operativo derivato Linux con Samba) che permette l'esecuzione di codice arbitrario...e' tale la similitudine con WannaCry che e' stata soprannominata SambaCry)

Conoscendo le (scarse) competenze del responsabile dell'unita', non ho dubbi che ci fosse una condivisione in scrittura esposta su Internet

Peraltro ho trovato un documento recente su altre vulnerabilita' di un firmware recente (https://safeandsavvy.f-secure.com/2017/04/12/new-nas-vulnerabilities-are-pretty-much-as-bad-as-they-get/)


  

Gallium OS su Chromebook Acer CB3-131

ChromeOS puo' essere un sistema operativo troppo limitato per l'uso quotidiano ma di sicure l'hardware su cui gira (i portatili della serie Chromebook) e' interessante perche' a prezzi ragionevoli (sull'usato) si trovano dispositivi solidi e con una durata della batteria di tutto rispetto


Vale quindi la pena prendere possesso dell'hardware installando una versione distribuzione Linux apposita per Chromebook
Per prima cosa si deve abilitare la modalita' sviluppatore premendo i tasti Esc-Refresh-Power e premendo successivamente CTRL+D disabilitando la verifica del sistema operativo

A questo punto si dovrebbe partire installando Gallium OS ma prima, dato che uso un Acer CB3-131, e' necessario modificare il firmware del boot in modo da permettere l'avvio di Gallium
Per fare cio' si avvia ChromeOS, si apre una shell e si digita

cd; curl -LO https://mrchromebox.tech/firmware-util.sh && sudo bash firmware-util.sh

e si procede con l'opzione 1

si prepara quindi una chiavetta USB con l'immagine di Gallium specifica per il proprio hardware (nel mio caso BayTrail), la si inserisce nel ChromeBook e si avvia. Alla prima schermata di digita CTRL + L ed Esc quando compare la sigla SeaBios scegliendo poi il dispositivo di avvio (in questo caso la chiavetta.....attenzione e' meglio scegliere una compatibile con USB 3 per velocizzare il sistema) e si avvia quindi Gallium.

Pur essendo possibile installare Gallium sul disco interno ho preferito evitare in modo da usufruire anche di ChromeOS quando mi necessita



LLama3 Anita

A seguito di questo post ho provato a vedere ho provato a vedere cosa accadeva ad utilizzare un modello specifico per la lingua italiana in...