[ jenkins ] login with AD

1) Download “Active Directory Plugin”

2) Manage Jenkins > Configure Global Security >

Enable Security : checked

Domain Name : whatever.com
Domain controller : what.whatever.com:9999

Bind DN : CN=wsm-admin,OU=Internal Services,OU=Service Account,OU=Thailand,DC=whatever,DC=th

Bind Password : XXXXX

TLS Configuration : JDK TrustStore

Group Membership Lookup Strategy : Recursive group queries

Security Realm : choose “Active Directory”

Authorization: choose Role-based strategy ( more : https://dsin.wordpress.com/2018/11/15/jenkins-role-strategy-plugin/ )
ref : https://medium.com/modern-stack/implementing-active-directory-based-security-in-jenkins-f78dbac929de

[ ReactJS ] optimization

  1. GraphQL cache / CDN cache
  2. remove unused 3rd party
  3. LazyLoad image ( more : https://dsin.wordpress.com/2019/08/08/reactjs-react-lazyload/ )
  4. Component based code spliting ( more : https://dsin.wordpress.com/2019/08/08/reactjs-route-based-code-splitting/ )
  5. Tree shaking ( more : https://dsin.wordpress.com/2019/08/07/create-react-app-analyze-the-bundle-size/ )
  6. Font preload / prefetch ( more : https://dsin.wordpress.com/2019/08/13/font-preload-v-s-prefetch/ )

[ font ] preload v.s. prefetch

Preload

link rel="preload" href="static/whatever/whatever.otf" as="font" />

WARNING:

The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it Please make sure it has an appropriate `as` value and it is preloaded intentionally.

The resource http://localhost:3000/static/whatever/whatever.otf was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it Please make sure it has an appropriate `as` value and it is preloaded intentionally.

Solution : use prefetch instead of preload

“preload” is a declarative fetch, allowing you to force the browser to make a request for a resource without blocking the document’s onload event.
“Prefetch” is a hint to the browser that a resource **might** be needed.

 

ref : https://developers.google.com/web/tools/lighthouse/audits/preload?utm_source=lighthouse&utm_medium=unknown

, https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf

[ db ] backup

backup schedule

  • full backup ( mysqldump )
  • incremental backup ( bin log )

RSYNC backup to S3 buckets

s3cmd sync --skip-existing --delete-removed /var/backups/ s3://dbbackup.whatever.com/whatever

aws s3 cp full_backup_${DATE}.tgz s3://whatever/full

[ MySQL ] Percona server

  • Percona server mysql
  • PMM ( Percona monitor and management )
    • install PMM client
yum install pmm-client
  • configure MySQL to be appropriate with PMM

add some parameters ( varied based on version )

  • configure PMM client
pmm-admin config ...

pmm-admin add mysql:metrics ...
  • verify if it is working
pmm-admin list

How to remove 

step 1)

pmm-admin purge

step 2) remove instance

pmm-admin rm

How to update PMM

  1. remove docker and download the new one

NOTE on DB : 

  • master / slave for online
  • backup
  • sponsor / data science ( dump data from GA every day . different login )
  • DR : Disaster recovery

 

[ IoT ] Auto jot temperature to Google Sheet

Chip

  1. NodeMCU v.3 ( arduino with ESP8266 wifi chip )
  2. DHT11 ( Temperature sensor )

Prepare Google Sheet

  1. New Google Sheet
  2. Tools > Script Editor > copy and paste script from here https://github.com/NishantSahay7/Upload-Sensor-Data-to-Google-Sheets-from-NodeMCU/blob/master/script_code.txt
function doGet(e) {
Logger.log( JSON.stringify(e) ); // view parameters
var result = 'Ok'; // assume success
if (e.parameter == 'undefined') {
result = 'No Parameters';
}
else {
var sheet_id = 'YOUR_GAS_ID_HERE'; // Spreadsheet ID
var sheet = SpreadsheetApp.openById(sheet_id).getActiveSheet(); // get Active sheet
var newRow = sheet.getLastRow() + 1;
var rowData = [];
rowData[0] = new Date(); // Timestamp in column A
for (var param in e.parameter) {
Logger.log('In for loop, param=' + param);
var value = stripQuotes(e.parameter[param]);
Logger.log(param + ':' + e.parameter[param]);
switch (param) {
case 'temperature': //Parameter
rowData[1] = value; //Value in column B
result = 'Written on column B';
break;
case 'humidity': //Parameter
rowData[2] = value; //Value in column C
result += ' ,Written on column C';
break;
default:
result = "unsupported parameter";
}
}
Logger.log(JSON.stringify(rowData));
// Write new row below
var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
newRange.setValues([rowData]);
}
// Return result of operation
return ContentService.createTextOutput(result);
}
/**
* Remove leading and trailing single or double quotes
*/
function stripQuotes( value ) {
return value.replace(/^["']|['"]$/g, "");
}

3. Publish > Deploy to web app

Who has access to this app : Anyone, even anonymous

Got the URL :

Example : https://script.google.com/macros/s/AKfycbxZGcTwqeDgF3MBMGj6FJeYD7mcUcyo2V6O20D6tRlLlP2M_wQ/exec

4. Test it

https://script.google.com/macros/s/AKfycbxZGcTwqeDgF3MBMGj6FJeYD7mcUcyo2V6O20D6tRlLlP2M_wQ/exec?temperature=1&humidity=2

Download Arduino IDE

NOTE : version 1.8.6 does not crash on MacOS Sierra version 10.12

Problem : Arduino IDE can’t find ESP8266WiFi.h file ( ref : https://stackoverflow.com/questions/50080260/arduino-ide-cant-find-esp8266wifi-h-file )

  1. Preferences > Additional Boards Manager URL : http://arduino.esp8266.com/stable/package_esp8266com_index.json
  2. Tools> Manage Library. Type “ESP8266” in the text box to search and install the ESP8266 software ( ESP8266  by ESP8266  community ) for Arduino IDE
  3. Tools > Board > NodeMCU 1.0 (Esp12e module / Esp12f module — ref : https://www.esp8266.com/viewtopic.php?p=58188#p58188 )

Download Project Example

  1. Download ZIP from https://github.com/KhonKaenMakerClub/EspGoogleApi
  2. In Ardunio IDE,
    1. Go to Sketch > Include Library > Add .ZIP Library…
    2. Go to File > Examples > INCOMPATIBLE > EspGoogleAPI > InsertGoogleSheets
    3. Put in the client_id / client_secret / sheet_id
    4. Put in wifi ssid and password ( WiFiMulti.addAP(“—ssid—“, “— password —“); )
    5. Sketch > Upload ( or short key Mac + U ) ( We can also test simple upload using example File > Examples > ESP8266 > Blink — LED blink software / File > Examples > ESP8266 > ESP8266Wifi > WiFiClient )

Problem :

Cannot detect USB on Serial port

Solution :

Download CP2102 USB to UART Bridge Controller ( download link : https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers )

For Windows XP, you will get `CP210x_VCP_Windows.zip` file, install it and you can see COM3 on device manager.

Silicon_Labs_CP210x_USB_to_UART_BRIDGE

For MacOS, you will get `Mac_OSX_VCP_Driver.zip`.

After install, plug the device, then go to Apple Menu > About This Mac > System Report...

Screen Shot 2019-08-21 at 8.38.21 PM.png

You can also see the following files

  • /dev/cu.SLAB_USBtoUART
  • /dev/tty.SLAB_USBtoUART

From Ardunio IDE,

Screen Shot 2019-08-21 at 8.31.59 PM.png

NOTE: I have tried CH34x_Install_V1.5.pkg and CH34x_Install_V1.4.pkg ( from https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-x-driver ), both are not working in my Macbook Air Sierra Version 10.2.

6. Tool > Serial Monitor ( Mac + Shift + M )

Choose : 115200 baud

7. Ardunio Code ( ref : https://github.com/NishantSahay7/Upload-Sensor-Data-to-Google-Sheets-from-NodeMCU/blob/master/arduino_code.txt )

How to get the fingerprint 

Screen Shot 2019-08-22 at 7.46.46 PM

#include
#include 

String readString;
const char* ssid = "SSID";
const char* password = "Password";

const char* host = "script.google.com";
const int httpsPort = 443;

WiFiClientSecure client;

const char* fingerprint = "46 B2 C3 44 9C 59 09 8B 01 B6 F8 BD 4C FB 00 74 91 2F EF F6";
String GAS_ID = "Put your GAS ID here";  // Replace by your GAS service id

void setup()
{

              WiFi.mode(WIFI_STA);
              WiFi.begin(ssid, password);

                              while (WiFi.status() != WL_CONNECTED) {
                                delay(500);
                                Serial.print(".");
                              }

              sendData(113,125);  // Send test data
}

void loop()
{

  int a,b;                       //a,b are variables to store sensor values
    a=1;
    b=1;
    sendData(a,b);               //This function uploads data to Google Sheets

}

void sendData(int x, int y)
{
  Serial.print("connecting to ");
  Serial.println(host);
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    return;
  }

  if (client.verify(fingerprint, host)) {
  Serial.println("certificate matches");
  } else {
  Serial.println("certificate doesn't match");
  }
  String string_x     =  String(x, DEC);
  String string_y     =  String(y, DEC);
  String url = "/macros/s/" + GAS_ID + "/exec?Value1=" + string_x + "&Value2=" + string_y;
  Serial.print("requesting URL: ");
  Serial.println(url);

  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
         "Host: " + host + "\r\n" +
         "User-Agent: BuildFailureDetectorESP8266\r\n" +
         "Connection: close\r\n\r\n");

  Serial.println("request sent");
  while (client.connected()) {
  String line = client.readStringUntil('\n');
  if (line == "\r") {
    Serial.println("headers received");
    break;
  }
  }
  String line = client.readStringUntil('\n');
  if (line.startsWith("{\"state\":\"success\"")) {
  Serial.println("esp8266/Arduino CI successfull!");
  } else {
  Serial.println("esp8266/Arduino CI has failed");
  }
  Serial.println("reply was:");
  Serial.println("==========");
  Serial.println(line);
  Serial.println("==========");
  Serial.println("closing connection");
}

DHT11 / NodeMCU 8266

+ : 3.3V

out (data out) : D3

– : GND

Sketch > Include Library > Manage Libraries > DHT Sensor Library

Sketch > Include Library > Manage Libraries > Adafruit Unified Sensor

#include
#include 

#define DHTTYPE DHT11
#define DHTPin D4;
DHT dht(DHTPin, DHT11);
void setup(){

dht.begin();

}
 float temperature, humidity;
temperature = dht.readTemperature(); // celsius
// Read temperature as Fahrenheit (isFahrenheit = true)
// float f = dht.readTemperature(true);
Serial.print("Temperature = ");
Serial.println(temperature);
humidity = dht.readHumidity();
Serial.print("Humidity = ");
Serial.println(humidity);

ref : https://www.praphas.com/forum/index.php?topic=355.0&fbclid=IwAR2ZyxVYOoZc014bbAOQjA3ljCcfRzclQpX_8xNX_IY1eZnxpIaj1Dp176M

, https://www.hackster.io/nishant_sahay7/sensor-data-upload-to-google-sheets-through-nodemcu-632358

, https://www.instructables.com/id/Interface-DHT11-Humidity-Sensor-Using-NodeMCU/

, https://www.microcontroller-project.com/interfacing-dht11-with-nodemcu.html

, https://www.myarduino.net/article/82/%E0%B8%AA%E0%B8%AD%E0%B8%99%E0%B9%83%E0%B8%8A%E0%B9%89%E0%B8%87%E0%B8%B2%E0%B8%99-nodemcu-esp8266-%E0%B9%80%E0%B8%8A%E0%B8%B7%E0%B9%88%E0%B8%AD%E0%B8%A1%E0%B8%95%E0%B9%88%E0%B8%AD-dht11-%E0%B9%80%E0%B8%8B%E0%B9%87%E0%B8%99%E0%B9%80%E0%B8%8B%E0%B8%AD%E0%B8%A3%E0%B9%8C%E0%B8%A7%E0%B8%B1%E0%B8%94%E0%B8%AD%E0%B8%B8%E0%B8%93%E0%B8%AB%E0%B8%A0%E0%B8%B9%E0%B8%A1%E0%B8%B4%E0%B9%81%E0%B8%A5%E0%B8%B0%E0%B8%84%E0%B8%A7%E0%B8%B2%E0%B8%A1%E0%B8%8A%E0%B8%B7%E0%B9%89%E0%B8%99-%E0%B9%81%E0%B8%AA%E0%B8%94%E0%B8%87%E0%B8%84%E0%B9%88%E0%B8%B2%E0%B8%9C%E0%B9%88%E0%B8%B2%E0%B8%99-wifi-web-server

Source : https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp

DebugLevel: CORE+WIFI