Search code examples
laravellaravel-5fakerlaravel-seeding

Laravel Seeding with Faker DateTime


Okay so i am developing an application which receives some real time sensor readings from a device and stores it in a table inside the database. According to the use case the device will remain active for at least 8 hours each day and after a specified interval (lets say 1 minute ) will transmit its sensor readings to the server which will then be saved inside the database table as previously stated. One of the features that this application provides is that it allows you to briefly analyze the historical sensor data of a particular device in the system, which may span well over a year or two depending upon when the device was activated. For example if a device was activated on Aug 10, 2016, then it has been transmitting data since then by an interval of 1 minute for at least 8 hours each day to the current point in time.

How can i create such dummy data to simulate this scenario ? ( As i need it to test the feature that i am working on ).

I have tried using the DateTime methods of the Faker library but none of them seem to fit my needs.

Any help would be appreciated. Thanx

EDIT 1: This is the ReadingTableSeeder.php class so far.

<?php

use App\Models\Reading;
use Illuminate\Database\Seeder;

class ReadingTableSeeder extends Seeder
{
/**
 * Run the database seeds.
 *
 * @return void
 */
public function run()
{
    $faker = Faker\Factory::create();

    // LOOP BODY START

    $dateTime = // Here i need to create datetime

    Reading::create([
        'device_key' => '60:01:94:37:D1:34',
        'temp' => $faker->randomFloat($nbMaxDecimals = 2, $min = 0, $max = 50.00),
        'hum' => $faker->randomFloat($nbMaxDecimals = 2, $min = 0, $max = 50.00),
        'oxygen' => $faker->randomFloat($nbMaxDecimals = 2, $min = 0, $max = 50.00),
        'created_at' => $dateTime,
        'updated_at' => $dateTime
    ]);

    // LOOP BODY END

  }
}

The loop will start from the point the device was activated and will create a new reading each iteration after interval of 1 minute.


Solution

  • Code for one day would look like:

    $date = now(); // helper for Carbon::now()
    
    foreach (range(1, 480) as $i) { // 8*60 minutes
    
        //do something with $date
    
        $date->addMinute(); // increments by a minute
    }
    

    Code for multiple days would look like:

    $date = now(); // helper for Carbon::now()
    foreach (range(1, 365) as $day) {
        foreach (range(1, 480) as $i) { //8*60
    
            //do something with $date
    
            $date->addMinute(); // increments by a minute
        }
    
        $date->subMinutes(480)->addDay(); // subtract 480 minutes and increment by a day
    }
    

    Note: code for one day will create 480 inserts (for a year 480*365), maybe better approach would be to run it only once and just use sqldump / import before running your test-suite


    You need to initialize $date correctly, lets say device is going to start at 8 in the morning, you may do the following:

    $date = now()->endOfDay()->subHours(16); // 2018-03-25 07:59:59.999999
    // or
    $date = (new Carbon\Carbon('today noon'))->subHours(4); // 2018-03-25 08:00:00.0