Archive for the ‘Otomasi dan Robotika’ Category


Hari ini ada kunjungan schneider electric. Dan presentasi tetang IoT… Yang saya tanyakan bagaimanakan menambahkan expert knowledge pada sistem analisanya..misal dari vendor mesin kita. Ternyata itu property mereka dan tidak di open… Rahasia dapurnya đŸ˜€


lanjutan dari https://tarecha.wordpress.com/2019/02/22/unboxing-atomic-pi/ unboxing.

ini first bootnya ya

unboxing atomic pi

Posted: 22 Februari 2019 in Otomasi dan Robotika

well ini video unboxing ya… nanti vlog berikutnya coba startup atomic pi


View this post on Instagram

AC Hemat Energi versi mahasiswa

A post shared by Agung Tarecha (@agungtarecha) on


Arduino MKR GSM 1400

Arduino MKR GSM 1400

 

link project https://create.arduino.cc/editor/agung.tarecha/d8337cc3-c228-408d-a4a5-6727c2f11e3c/preview

Assalamu’alaikum Wr. Wb.

jadi… kemarin ada kebutuhan notifikasi ke user agar dapat info secepatnya jika suhu diluar batas normal, dari PLC keluar kontak kering, dry contact dimana sama seperti Environmux yang dry contact yang contact no contact , sambung putus, open close. jadi gimana caranya agar user tahu. kalau pakai bot python ngirim telegram masih ribet. seperti project saya yang weather logger suhu bila diluar range maka kirim email, ada program python yang harus dijalankan dari jadi service. sehingga tergantung. saya bikin sistem pakai arduino mkr gsm 1400 agar simpel dan independen. karena cuman dry contact dari plc. plc nya sendiri kirim tegangan 24 volt yang nanti disambungkan relay, dari relay tersebut disambungkan arduino. kira2 begitu. nanti jam 1 an saya upload video nya deh.

oh ya hal yang beda adalah saya gak pakai arduino ide di windows seperti biasa, sekarang nyoba arduino cloud. tapi sebelum itu kita rangkai dlu yuk.

  1. schematic

    schematic

    schematic

    pinout arduino

    pinout arduino

    soldering

    soldering

    2. Cloud arduino Create

    oke masuk ke https://create.arduino.cc/, ya ini agak berbeda ya, compile nya di cloud, nanti install plugin agar bisa komunikasi serial dengan arduino, kelebihannya adalah kita gk ribet urusan plugin, kalau di desktop harus install plugin kalau gk ada, kalau di cloud sudah tersedia, cman belum coba yang nodemcu sih, kemarin pakai arduino ide download xtensanya dlu 100 mega an. dan juga karena file kita disimpan di cloud jadi gk bingung nyari misal hilang, dan file nya akan sama kalau saya pakai laptop rumah dan komputer pabrik. tingal play. oke let’s start

    masuk dlu ke https://create.arduino.cc/ .
    masuk

    Create Editor

    Create Editor

    lalu login, bikin akunnya dilewati ya. silahkan bikin sendiri dlu, masukkan user password kalau sudah bikin akun. lalu download pluginnya, install,.. saran saya matikan antivirus dulu . install seperti biasa hingga pluginnya jalan

  2. plugin install

    plugin install

plugin jalan

plugin jalan

berikut interfacenya

interface arduino web editor

interface arduino web editor

select board dan portnya

select board dan port

select board dan port

berikut versi video nya

3. code
kira2 seperti ini codingnya, bisa dilihat, saya malas njelasin. intinya kalau input on togle dari off dia akan jalankan perintah kirim sms


#include <MKRGSM.h>


// initialize the library instance
GSM gsmAccess;
GSM_SMS sms;

const byte  input1 = 2;   
const byte  input2 = 3;
const byte  input3 = 4;
const byte  input4 = 5;
const byte led = 6;     //internal led di pin 6, buat indikator contact
const byte ledready = 7; // led merah besar untuk menandakan system ready

boolean lastButtonState1 = 0;   //variable menampung state button yang terakhir agar
boolean lastButtonState2 = 0;   //togle status , tidak on terus atau off terus selama loop
boolean lastButtonState3 = 0;  
boolean lastButtonState4 = 0;  

boolean buttonState1 = 0;       //sama kyk diatas, read status button saat ini
boolean buttonState2 = 0;
boolean buttonState3 = 0;
boolean buttonState4 = 0;


char penerimaSMS1[] = "081232619895";    //daftar nomer telepon 
char penerimaSMS2[] = "085646491192";
char penerimaSMS3[] = "081232619895";
char penerimaSMS4[] = "085646491192";
char penerimaSMS5[] = "081232619895";
char penerimaSMS6[] = "085646491192";

void setup() {
  pinMode(ledready, OUTPUT);
  digitalWrite(ledready, HIGH);       //off kan led tanda ready, aktif low, jika high akan mati
  
    // initialize the button pin as a input:
  pinMode(input1, INPUT);
  pinMode(input2, INPUT);
  pinMode(input3, INPUT);
  pinMode(input4, INPUT);
  pinMode(led, OUTPUT);

  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Serial OK");

  // initialize serial communication:

  
  Serial.println("SMS Messages Sender");

  // connection state
  boolean connected = false;

  // Start GSM shield
  // If your SIM has PIN, pass it as a parameter of begin() in quotes
  Serial.print("Connecting Network");
  while (!connected) {
    Serial.print(".");
    if (gsmAccess.begin() == GSM_READY) {
      connected = true;
      Serial.println("Jaringan Konek");
    } else {
      Serial.println("Jaringan Tidak Konek");
      delay(1000);
    }
     
  }

  Serial.println("SYSTEM READY !");
  digitalWrite(ledready, LOW);                  //system ready, led merah dinyalakan
}

void kirimSMS1ON()
{
  char txtMsg[] = "Suhu Channel 1 di luar batas normal";
  sms.beginSMS(penerimaSMS1);
  sms.print(txtMsg);
  sms.endSMS();
  
  sms.beginSMS(penerimaSMS2);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nKirim SMS alarm Channel 1 COMPLETE!\n");
}

void kirimSMS1OFF()
{
  char txtMsg[] = "Suhu Channel 1 kembali ke batas normal";
  sms.beginSMS(penerimaSMS1);
  sms.print(txtMsg);
  sms.endSMS();
  
  sms.beginSMS(penerimaSMS2);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nKirim SMS normal Channel 1 COMPLETE!\n");
}

void kirimSMS2ON()
{
  char txtMsg[] = "Suhu Channel 2 di luar batas normal";
  sms.beginSMS(penerimaSMS1);
  sms.print(txtMsg);
  sms.endSMS();
  
  sms.beginSMS(penerimaSMS2);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nKirim SMS alarm Channel 2 COMPLETE!\n");
}

void kirimSMS2OFF()
{
  char txtMsg[] = "Suhu Channel 2 kembali ke batas normal";
  sms.beginSMS(penerimaSMS1);
  sms.print(txtMsg);
  sms.endSMS();
  
  sms.beginSMS(penerimaSMS2);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nKirim SMS normal Channel 2 COMPLETE!\n");
}

void kirimSMS3ON()
{
  char txtMsg[] = "Suhu Channel 3 di luar batas normal";
  sms.beginSMS(penerimaSMS1);
  sms.print(txtMsg);
  sms.endSMS();
  
  sms.beginSMS(penerimaSMS2);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nKirim SMS alarm Channel 3 COMPLETE!\n");
}

void kirimSMS3OFF()
{
  char txtMsg[] = "Suhu Channel 3 kembali ke batas normal";
  sms.beginSMS(penerimaSMS1);
  sms.print(txtMsg);
  sms.endSMS();
  
  sms.beginSMS(penerimaSMS2);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nKirim SMS normal Channel 3 COMPLETE!\n");
}

void kirimSMS4ON()
{
  char txtMsg[] = "Suhu Channel 4 di luar batas normal";
  sms.beginSMS(penerimaSMS1);
  sms.print(txtMsg);
  sms.endSMS();
  
  sms.beginSMS(penerimaSMS2);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nKirim SMS alarm Channel 4 COMPLETE!\n");
}

void kirimSMS4OFF()
{
  char txtMsg[] = "Suhu Channel 4 kembali ke batas normal";
  sms.beginSMS(penerimaSMS1);
  sms.print(txtMsg);
  sms.endSMS();
  
  sms.beginSMS(penerimaSMS2);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nKirim SMS normal Channel 4 COMPLETE!\n");
}


void loop() {
  
  buttonState1 = digitalRead(input1);
  buttonState2 = digitalRead(input2);
  buttonState3 = digitalRead(input3);
  buttonState4 = digitalRead(input4);


  if (buttonState1 != lastButtonState1) {

    if (buttonState1 == HIGH) {
     Serial.println("Input 1 ON");
     digitalWrite(led, HIGH);
     kirimSMS1ON();
    } else {
      
      Serial.println("Input 1 OFF");
      digitalWrite(led, LOW);
      kirimSMS1OFF();
    }
  
    delay(50);
  }
  lastButtonState1 = buttonState1;
  
  if (buttonState2!= lastButtonState2) {

    if (buttonState2 == HIGH) {
     Serial.println("Input 2 ON");
     digitalWrite(led, HIGH);
    kirimSMS2ON();
    } else {

      Serial.println("Input 2 OFF");
      digitalWrite(led, LOW);
      kirimSMS2OFF();
    }
  
    delay(50);
  }
  lastButtonState2 = buttonState2;
  
  if (buttonState3 != lastButtonState3) {

    if (buttonState3 == HIGH) {
     Serial.println("Input 3 ON");
     digitalWrite(led, HIGH);
     kirimSMS3ON();
    } else {

      Serial.println("Input 3 OFF");
      digitalWrite(led, LOW);
      kirimSMS3OFF();
    }
  
    delay(50);
  }
  lastButtonState3 = buttonState3;
  
  if (buttonState4 != lastButtonState4) {

    if (buttonState4 == HIGH) {
     Serial.println("Input 4 ON");
     digitalWrite(led, HIGH);
     kirimSMS4ON();
    } else {

      Serial.println("Input 4 OFF");
      digitalWrite(led, LOW);
      kirimSMS4OFF();
    }
  
    delay(50);
  }
  lastButtonState4 = buttonState4;





}

 

4. trial

Serial monitor

Serial monitor

SMS diterima

SMS diterima

 

hasil trial


Analisa data

Video

Analisa data
alamat server slave di ralat di http://appscenter.aio.co.id/weatherlogger/

alamat master logger di http://weatherlogger.ap.ngrok.io/

Oke saya lanjutkan. remind lagi ini adalah seri berantai dari posting berikut ya

  1. https://tarecha.wordpress.com/2015/10/26/project-raspberry-pi/
  2. https://tarecha.wordpress.com/2017/06/05/project-weather-logger-part-1/
  3. https://tarecha.wordpress.com/2017/06/26/project-weather-logger-part-2-tambahan-sensor-tekanan-udara/
  4. https://tarecha.wordpress.com/2017/07/01/project-weather-logger-part-3-komunikasi-udp/
  5. https://tarecha.wordpress.com/2017/07/15/project-weather-logger-part-4-simpan-di-server-mysql/
  6. https://tarecha.wordpress.com/2017/07/24/project-weather-logger-part-5-view-data-dan-export/
  7. https://tarecha.wordpress.com/2017/07/25/project-weather-logger-part-6-plot-graphic/
  8. https://tarecha.wordpress.com/2017/07/29/project-weather-logger-part-7-ngrok-http-tunneling/
  9. https://tarecha.wordpress.com/2017/08/27/project-weather-logger-part-8-ganti-sensor-bme280/
  10. https://tarecha.wordpress.com/2017/09/03/project-weather-logger-part-9-sync-data/
  11. https://tarecha.wordpress.com/2018/01/13/project-weather-logger-part-10-notifikasi-email-dan-autostart-dan-backup/
  12. https://tarecha.wordpress.com/2018/02/02/project-weather-logger-part-11-bot-twitter/

Assalamu’alaikum Wr. Wb.

lama gak nulis jadi kangen. ya semakin kesini semakin rumit ya. banyak sekali bahasa pemprograman yang di gunakan, C, python, PHP, dan sekarang matlab. sepertinya saya programmer multi talenta. infrastruktur bisa, elektronika bisa, program bisa. ya kalau jadi programmer ya repot capek di depan komputer terus, tapi kalau hobi oke lah. bagi anda yang tidak mendalami IT sebaiknya jangan baca tulisan ini ya, mubadzir. mending baca Al Qur’an…. sok yes kayak baca tiap hari saja he he.

oke setelah data suhu, tekanan, dan kelembapan didapatkan lalu apa lagi sekarang, ya dianalisa, kalau saya sih kurang faham analisa numerik yang intinya nanti jadi keluar rumus, seperti pada link no 1 diatas waktu matakuliah metode numeri yang intinya jadi keluar rumus. kalau dulu pakai excel. klo gk salah pakai polynom… sekarang coba pakai matlab untuk curve fitting nya menggunakan fourier. apa itu. tentah lah.. saya sendiri juga kurang paham, tapi mari kita implementasikan dulu ya.

1. Sumber data dari database getdata.php

kenapa sih ambil datanya lewat php ? gk langsung nembak mysql server ? ya sepertinya anda butuh baca bab sebelum ini. kalau gk salah di sync data. intinya port 80 gak kan di blok di web hosting makanya pakai php. sebagai API. oke kita buat getdata.php. intinya sama dengan getsync.php bedanya cman sedikit di statement where nya saja. dan tidak perlu naruh jumlah baris yang akan di sync karena tidak dibutuhkan. berikut codenya


<?php include "config.php";
//if (true)
if(isset($_POST['k'])) {
//if (true)
if( $_POST['k'] ==$key)
//jika variabel k sama dengan key makan proses input.
//ini untuk autentikasi meski sebenarnya metode ini sangat mudah dibobol pakai wireshark untuk lihat datanya
{ $sync =$_POST['sync'];
$idnode = $_POST['idnode'];
$startdate = $_POST['startdate'];
$enddate = $_POST['enddate'];
//$idnode = 'N1';
//$startdate = "2018-03-01 00:00";
//$enddate = "2018-03-02 00:00";
//$limit = "2";

$query = "select iddata,idnode,hum,temp,press,waktu from masterdata where idnode='$idnode' and waktu between $startdate and $enddate order by iddata asc";
$data = mysqli_query($conn, $query); if ($data->num_rows==0)
{
echo "i#No new data";
}
else
{
//melempar nilai last id untuk di save csv. karena ini jalan di server lokal maka kemungkinan diskoneknya kecil
//belum coba ke slave server yang tidak ada auto incrementnya
while ($row = mysqli_fetch_array($data, MYSQL_ASSOC))
{
echo $row['iddata'].','.$row['idnode'].','.$row['hum'].','.$row['temp'].','.$row['press'].','.$row['waktu'].'#';

}

}

}
else
{
echo "i#Key Salah#Periksa Key";
}
}
else
{
echo "i#Tidak post#Periksa Post";
}

?>

2. program matlab untuk menarik data

matlab narik data

matlab narik data

3. curve fitting.

buka app. curve fitting. tinggal sumbu x dipasang x. sumbu Y dipasang suhu. hasilnya keluar rumus tersebut. gampang kan ?

intinya ada banyak metode untuk curve fittingnya, nanti keluar equation… fungsinya apa ? ya bisa digunakan untuk peramalan suhu di kemudian hari.

kalau jumlah datanya lebih banyak maka rumusnya juga berbeda karena suhu sendiri fluktuasinya sangat cepat. nanti bisa dikombinasi dengan perubahan tekanan dan kelembapan. apakah ketiga

elemen tersebut saling mempengaruhi ? ya pasti, namun bagaimana cara mengetahui hubungannya ? pakai rumus ini kira2. tapi sederhananya suhu dan kelembapan berbanding terbalik, dan kelembapan dan tekanan berbanding lurus. kalau suhu naik kelembapan turun, tekanan juga turun. kira2 begitu yang saya amati,

Curve Fiting

Curve Fiting Fourier paling mendekati

Curve Fiting Polynom

Curve Fiting Polynom

terima kasih semoga bermanfaat

Wassalamu’alaikum Wr. Wb.


Assalamu’alaikum Wr. Wb.

hasil akhir

hasil akhir

alamat server slave di ralat di http://appscenter.aio.co.id/weatherlogger/

alamat master logger di http://weatherlogger.ap.ngrok.io/

Oke saya lanjutkan. remind lagi ini adalah seri berantai dari posting berikut ya

  1. https://tarecha.wordpress.com/2015/10/26/project-raspberry-pi/
  2. https://tarecha.wordpress.com/2017/06/05/project-weather-logger-part-1/
  3. https://tarecha.wordpress.com/2017/06/26/project-weather-logger-part-2-tambahan-sensor-tekanan-udara/
  4. https://tarecha.wordpress.com/2017/07/01/project-weather-logger-part-3-komunikasi-udp/
  5. https://tarecha.wordpress.com/2017/07/15/project-weather-logger-part-4-simpan-di-server-mysql/
  6. https://tarecha.wordpress.com/2017/07/24/project-weather-logger-part-5-view-data-dan-export/
  7. https://tarecha.wordpress.com/2017/07/25/project-weather-logger-part-6-plot-graphic/
  8. https://tarecha.wordpress.com/2017/07/29/project-weather-logger-part-7-ngrok-http-tunneling/
  9. https://tarecha.wordpress.com/2017/08/27/project-weather-logger-part-8-ganti-sensor-bme280/
  10. https://tarecha.wordpress.com/2017/09/03/project-weather-logger-part-9-sync-data/
  11. https://tarecha.wordpress.com/2018/01/13/project-weather-logger-part-10-notifikasi-email-dan-autostart-dan-backup/

oke semakin kesini IoT akan semakin rumit dan kompleks. ya sebenernya bikin ini gk bisa langsung jadi uang berapa. tapi setiap percobaan akan menambah skill kita dalam koding dan analisa alur sistem.

untuk bikin BOT Twitter kita harus mengaktifkan aplikasinya dahulu . saya ambil contoh tutorial berikut untuk mengaktifkan twitter. http://nodotcom.org/python-twitter-tutorial.html

1. Mematikan notif sms

hal ini penting agar bot kita banyak tweet gk perlu sms. cukup menganggu nanti. coba akses https://twitter.com/settings/devices dan matikan notifikasinya dengan login dahulu

matikan Notifikasi SMS

matikan Notifikasi SMS

2. buat aplikasi tweet

Twitter Apps -> Create New App -> Leave Callback URL empty -> Create your Twitter application.

Create Aplication

Create Aplication

3. ganti permission tweet write.

masuk ke aplikasi yang sudah dibuat dan masuk ke tab permission

Ganti Write

Ganti Write

4. ambil token dan generate access

sama seperti yang link tutorial diatas. untuk membuat access key klik generate customer key and secret dan generate access token.

Access Token, Access Token Secret, Consumer Key (API Key), Consumer Secret (API Secret). yang dibutuhkan adalah value dari id berikut. dan ingat ini rahasia

Get Token

Get Token

5. buat file tweet universal sebagai modul

untuk bisa pakai paket tweepy maka harus install dahulu. caranya di windows lumayan gampang. caranya pakai pip install

Install modul Tweepy dengan PIP Install

Install modul Tweepy dengan PIP Install

 

buat file python sebagai berikut. meski saya tahu ada double nya karena ada penulisan yang double buat akses key nya. tapi yang penting jalan dulu. dari tutorial asli diatas saya tambahkan kirim tweet gambar sehingga bisa tweet gambar lalu menghapus gambar yang sudah di tweet.

simpan dengan nama tweetsend.py

import tweepy
import os

def get_api(cfg):
  auth = tweepy.OAuthHandler(cfg['consumer_key'], cfg['consumer_secret'])
  auth.set_access_token(cfg['access_token'], cfg['access_token_secret'])
  return tweepy.API(auth)

def kirimtweet(isi):
  # Fill in the values noted in previous step here
  cfg = { 
    "consumer_key"        : "customer key dari step diatas",
    "consumer_secret"     : "customer screet dari step diatas",
    "access_token"        : "access token dari step diatas",
    "access_token_secret" : "access token key dari step diatas" 
    }

  api = get_api(cfg)
  tweet = isi
  status = api.update_status(status=tweet) 
  # Yes, tweet is called 'status' rather confusing


def kirimtweetgambar(isi,gambarpath):
  # Fill in the values noted in previous step here
  cfg = { 
    "consumer_key"        : "customer key dari step diatas",
    "consumer_secret"     : "customer screet dari step diatas",
    "access_token"        : "access token dari step diatas",
    "access_token_secret" : "access token key dari step diatas" 
    }

  api = get_api(cfg)
  tweet = isi
  status = api.update_with_media(gambarpath,status=tweet)
  os.remove(gambarpath)

6. membuat tweet dengan gambar
ini bagian yang lumayan sulit karena belum nemu caranya. tapi akhirnya nemu juga.
pertama ==>install selenium pakai pip install. karena punya saya sudah ada maka tulisannya sudah ada . dan schedule juga sekalian

PIP Instal selenium dan schedule

PIP Instal selenium dan schedule

kedua ==> download firefox driver gecko https://github.com/mozilla/geckodriver/releases

Download sesuai OS

Download sesuai OS

kemudian exstrak geckodriver.exe di folder yang sama dengan file python untuk tweet nya. misal di document C:\Users\<bama user>\Desktop\program python agung

buka advanced tab. environment variabel. di pathnya masukkan tambahi ” C:\Users\<bama user>\Desktop\program python agung; ”

Penambahan path environment variable

Penambahan path environment variable

 

bikin coding berikut di folder yang sama dengan tweetsend.py karena nanti import file tersebut

 


from selenium import webdriver
import tweetsend
import datetime
import schedule
import time
import sys

global waktu

i=0
global jumtweet
jumtweet = 0
jadwal = "23:59"


def job():
    try:
        waktu = datetime.datetime.now().strftime('%Y-%m-%d')
        path = 'C:\\Users\\mtarecha\\Desktop\\program python agung\\firefoximage.png'        
        source = 'http://appscenter.aio.co.id/weatherlogger/grafiklast24hourdate.php?node=N1&tgl='+ waktu
        pesan = 'Selamat malam, berikut informasi cuaca di Rumah selama 24 jam terakhir detail di '+source
       
       
        driver = webdriver.Firefox()
        driver.set_window_size(800, 800)
        driver.implicitly_wait(5)
        driver.get(source)
 
       
        driver.save_screenshot(path)
        driver.quit()   
        tweetsend.kirimtweetgambar(pesan,path)
        global jumtweet
        jumtweet += 1
    except Exception as e:
        print 'Error Message '+ str(e)
        print('Error on line {}'.format(sys.exc_info()[-1].tb_lineno), type(e).__name__, e)
        print "General Error Unexpected error:", sys.exc_info()[0]
        
    
schedule.every().day.at(jadwal).do(job)

while True:
    schedule.run_pending()
    print i
    i+=1
    print 'Jumlah kirim '+str(jumtweet)
    time.sleep(2)



hasilnya akan tweet jam 23:59 dengan gambar berikut. nanti di counting sudah tweet berapa kali

Tweet BOT

Tweet BOT

 

7. membuat file grafiklast24hour dengan input tanggal sehingga ketika di tweet gambar ada link yang bisa diklik dan menampilkan grafik informatif javascript nya . sebenarnya sama dengan grafiklast24hour.php cman dikasi parameter tanggal saat ini
berikut grafiklast24hourdata.php

<?php include "header.php"; include "config.php"; if(isset($_GET['node'])&&isset($_GET['tgl'])) { $idnode = $_GET['node']; $tgl = $_GET['tgl']; } $query = "select unix_timestamp(waktu)*1000 as x,temp,hum,press,waktu from masterdata where idnode='$idnode' and date(waktu)= '$tgl' order by waktu asc"; $querysummary = "select min(temp) as mintemp, round(avg(temp),2) as avgtemp, max(temp) as maxtemp, min(hum) as minhum, round(avg(hum),2) as avghum, max(hum) as maxhum, min(press) as minpress, round(avg(press),2) as avgpress, max(press) as maxpress from masterdata where idnode='$idnode' and date(waktu)= '$tgl' order by waktu asc"; $data = mysqli_query($conn, $query); $dataPointstemp = array(); $dataPointshum = array(); $dataPointspress = array(); while ($row = mysqli_fetch_array($data, MYSQL_ASSOC)) { array_push($dataPointstemp,array('x'=>$row['x'],'y'=>$row['temp']));
	array_push($dataPointshum, array('x'=>$row['x'],'y'=>$row['hum']));
	array_push($dataPointspress, array('x'=>$row['x'],'y'=>$row['press']));
}

$lastTemp = end($dataPointstemp)['y'];
$lastHum = end($dataPointshum)['y'];
$lastPress = end($dataPointspress)['y'];
//ambil tanggal start date dan end date
$firstupdateU = reset($dataPointstemp)['x']/1000;
$lastupdateU =end($dataPointstemp)['x']/1000;
$firstupdate = date("d F Y H:i:s",$firstupdateU);
$lastupdate = date("d F Y H:i:s",$lastupdateU);

//bikin strip garis pembagi per pukul 00:00
$firstupdatetengahmalam = date("d F Y  H:i:s",$firstupdateU);
$begin = (new DateTime( $firstupdatetengahmalam ))->setTime(0,0);
$end = new DateTime( $lastupdate );
$begin = $begin->modify( '+1 day' );
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);

$datasummary = mysqli_query($conn, $querysummary);
$summary = mysqli_fetch_assoc($datasummary);



?>

<body style="padding-top: 3px;">




<div id="chartContainer"></div>


<div style="position: absolute;top:420px;left:50px;">
<?php include "summary.php"; ?>
</div>

</body>

bagian bawah dari file yang sama



<script type="text/javascript">
$(function () {
    var chart = new CanvasJS.Chart("chartContainer", {
        theme: "theme",
        zoomEnabled: true,
		exportEnabled: true,
        animationEnabled: false,
		axisY: 
		{
			title: "Suhu C dan Kelembapan %",
            titleFontFamily: "arial",
            titleFontSize: 12,
            includeZero: false,
			suffix: " C / %"
        },
		axisY2: 
		{
            title: "Pressure hPa",
            titleFontFamily: "arial",
            titleFontSize: 12,
            includeZero: false,
			lineColor: "#86b402",
            suffix: " hPa"            
        },
        title: 
		{
            text: "Graphic Weather Logger of <?php echo $idnode;?>"
        },
	subtitles:[
		{
			text: "by Mochamad Agung Tarecha"
		
			
		},
		{
			
			text: "<?php echo "Time range from ".$firstupdate ." to ". $lastupdate;?>"
			
		}
		],
		
		axisX:
		{   stripLines: [
		<?php
			foreach($daterange as $date)
			{
			
						
				echo "{";
				echo "value: ".(string)$date->format("U").'000,';			
				echo "showOnTop: false";           
				echo "},";
			}
		?>
            
            ],
			valueFormatString: "DD MMM YYYY HH:mm"
		},
		toolTip: 
		{
            shared: true
        },
        data: [
        {
			
            type: "line",
			xValueType: "dateTime",
			xValueFormatString:"DD MMM YYYY HH:mm:ss",
			showInLegend: true,		
			name: "Suhu C",							
            dataPoints: <?php echo json_encode($dataPointstemp, JSON_NUMERIC_CHECK); ?>
        },
		{
			
            type: "line",
			xValueType: "dateTime",
			xValueFormatString:"DD MMM YYYY HH:mm:ss",
			showInLegend: true,
			name: "Humidity %",			
            dataPoints: <?php echo json_encode($dataPointshum, JSON_NUMERIC_CHECK); ?>
        },
		
	{
            type: "line",
            axisYType: "secondary",
			xValueType: "dateTime",
			xValueFormatString:"DD MMM YYYY HH:mm:ss",	
            name: "Pressure hPa",
			showInLegend: true,
            dataPoints: <?php echo json_encode($dataPointspress, JSON_NUMERIC_CHECK); ?>
        }
		
        ],
		legend: {
                cursor: "pointer",
				horizontalAlign: "center",
				verticalAlign: "bottom",
                itemclick: function (e) {
                    if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
                        e.dataSeries.visible = false;
                    }
                    else {
                        e.dataSeries.visible = true;
                    }
                    chart.render();
                }
            }
    });
    chart.render();
});
</script>
</html>

berikut hasil akhirnya

hasil akhir

hasil akhir