Multiple changes and improvements

* Base and NicotineBase separated
* Importer bugfixed
* Mixer improved
This commit is contained in:
2019-07-09 02:10:56 +02:00
parent 6e662f0263
commit 922d9f09dd
14 changed files with 302 additions and 44 deletions

View File

@ -35,6 +35,13 @@ class Base
return $this->components;
}
public function getComponentPercent(string $component): float
{
return array_key_exists($component, $this->components)
? $this->components[$component]
: 0;
}
public static function parseComponents(string $base)
{
$found = [];

View File

@ -12,6 +12,14 @@ class Ingredient implements IngredientInterface
protected $base;
/**
* Ingredient constructor
*
* @param string The name of the ingredient
* @param string|null The brand of the ingredient
* @param float Percent
* @param string The base mix (Default PG100)
*/
public function __construct(string $name, ?string $brand=null, float $percent=0.0, string $base="PG100")
{
$this->name = $name;
@ -52,4 +60,12 @@ class Ingredient implements IngredientInterface
return $this->base;
}
/**
* {@inheritDoc}
*/
public function getSpecificGravity(): ?float
{
return null;
}
}

View File

@ -34,4 +34,11 @@ interface IngredientInterface
*/
public function getBase(): ?string;
/**
* Return the ASG in g/mL for the specific flavor, or null if not available.
*
* @return float|null
*/
public function getSpecificGravity(): ?float;
}

View File

@ -5,19 +5,49 @@ namespace NoccyLabs\Juicer\Ingredient;
class NicotineBase
{
const MASS_NICOTINE = 1.01;
protected $base;
protected $strength;
/**
* NicotineBase constructor
*
* @param Base The base mix of the nicotine base
* @param int The strength of the nic base (eg. 18)
*/
public function __construct(Base $base, int $strength)
{
$this->base = $base;
$this->nicotineStrength = $strength;
$this->strength = $strength;
}
/**
* Get the Apparent Specific Gravity of the nicotine mixture taking
* in account the base mix and nicotine strength.
*
* @return float
*/
public function getSpecificGravity(): float
{
return 0.0;
// 18mg/ml is 1.8% nicotine
$nicotinePercent = $this->strength / 1000;
// Figure out how much the remaining percent is
$baseRemain = 1.0 - $nicotinePercent;
$base = $this->base->getComponents();
$remainVg = $baseRemain * ($base['VG'] / 100);
$remainPg = $baseRemain * ($base['PG'] / 100);
$sgNic = $nicotinePercent * self::MASS_NICOTINE;
$sgVg = $remainVg * Base::MASS_VG;
$sgPg = $remainPg * Base::MASS_PG;
return $sgNic + $sgVg + $sgPg;
}
}

View File

@ -3,18 +3,26 @@
namespace NoccyLabs\Juicer\Recipe\Importer;
use NoccyLabs\Juicer\Recipe\RecipeInterface;
use NoccyLabs\Juicer\Ingredient\IngredientInterface;
use NoccyLabs\Juicer\Recipe\Recipe;
use NoccyLabs\Juicer\Ingredient\Ingredient;
/**
* Import recipes from Json
*
*/
class JsonImporter
{
/**
* Import a recipe from json
*
* @param string The json string to parse and import
* @return RecipeInterface
*/
public function import(string $json): RecipeInterface
{
$data = json_decode($json);
$recipe = new Recipe();
$recipe->setRecipeName(@$data->recipe);
$recipe->setRecipeAuthor(@$data->author);
@ -29,6 +37,12 @@ class JsonImporter
return $recipe;
}
/**
* Import a recipe from json contained in a file
*
* @param string The filename to read and import
* @return RecipeInterface
*/
public function readFromFile(string $filename): RecipeInterface
{
$fd = fopen($filename, "r");

View File

@ -22,47 +22,96 @@ class MeasuredIngredient implements IngredientInterface
/** @var float Weight in grams (g) */
protected $weight;
public function __construct(string $name, ?string $brand, string $base, float $asg, float $percent, float $volume)
/**
* MeasuredIngredient constructor
*
* @param IngredientInterface|string The ingredient
* @param float The percent of the ingredient to use
* @param float The volume of the ingredient to mix (in mL)
* @param string The base of the ingredient, override any set on ingredient
*/
public function __construct($ingredient, float $percent, float $volume, string $base=null)
{
$this->name = $name;
$this->brand = $brand;
$this->base = $base;
if ($ingredient instanceof IngredientInterface) {
$asg = $ingredient->getSpecificGravity();
$this->name = $ingredient->getFlavorName();
$this->brand = $ingredient->getFlavorBrand();
$this->base = $base??$ingredient->getBase();
} else {
$asg = null;
$this->name = $ingredient;
$this->base = $base??"PG100";
}
if (!$asg) {
$base = new Base($this->base);
$asg = $base->getSpecificGravity();
}
$this->asg = $asg;
$this->percent = $percent;
$this->volume = $volume;
$this->weight = $volume * $asg;
}
/**
*
* @return string
*/
public function getFlavorName(): string
{
return $this->name;
}
/**
*
* @return string|null
*/
public function getFlavorBrand(): ?string
{
return $this->brand;
}
/**
*
* @return string|null
*/
public function getBase(): ?string
{
return $this->base;
}
/**
*
* @return float
*/
public function getPercent(): float
{
return $this->percent;
}
/**
*
* @return float
*/
public function getSpecificGravity(): float
{
return $this->asg;
}
/**
*
* @return float
*/
public function getVolume(): float
{
return $this->volume;
}
/**
*
* @return float
*/
public function getWeight(): float
{
return $this->weight;

View File

@ -0,0 +1,31 @@
<?php
namespace NoccyLabs\Juicer\Recipe\Mixer;
use NoccyLabs\Juicer\Ingredient\Base;
use NoccyLabs\Juicer\Recipe\RecipeInterface;
class MeasuredRecipe
{
public function __construct(RecipeInterface $recipe, array $mixedIngredients)
{
}
public function getTotalFlavorMl()
{
}
public function getTotalFlavorPercent()
{
}
public function getTotalFlavorGrams()
{
}
}

View File

@ -12,17 +12,47 @@ class Mixer
public function mixRecipe(RecipeInterface $recipe, int $volume, Base $base, int $nicotineStrength, ?NicotineBase $nicotineBase=null)
{
// Array holding our final list
$mixed = [];
$targetVg = 0;
$targetPg = 0;
$components = $base->getComponents();
if (array_key_exists('VG', $components) && $components['VG'] > 0) {
$mixed[] = new MeasuredIngredient("VG", null, "VG100", Base::MASS_VG, 100, $volume);
$targetVg = $components['VG'];
}
if (array_key_exists('PG', $components) && $components['PG'] > 0) {
$mixed[] = new MeasuredIngredient("PG", null, "PG100", Base::MASS_PG, 100, $volume);
$targetPg = $components['PG'];
}
$addedVg = 0;
$addedPg = 0;
foreach ($recipe->getIngredients() as $ingredient) {
$ingredientBase = new Base($ingredient->getBase());
$ingredientPercent = $ingredient->getPercent();
$floatPercent = $ingredientPercent / 100;
$addedVg += $floatPercent * $ingredientBase->getComponentPercent('VG');
$addedPg += $floatPercent * $ingredientBase->getComponentPercent('PG');
}
if ($targetVg > $addedVg) {
$remainingVg = max(0, $targetVg - $addedVg);
$mixed[] = new MeasuredIngredient("VG", $remainingVg, $volume * ($remainingVg/100), "VG100");
}
if ($targetPg > $addedPg) {
$remainingPg = max(0, $targetPg - $addedPg);
$mixed[] = new MeasuredIngredient("PG", $remainingPg, $volume * ($remainingPg/100), "PG100");
}
foreach ($recipe->getIngredients() as $ingredient) {
$ingredientBase = new Base($ingredient->getBase());
$ingredientPercent = $ingredient->getPercent();
$floatPercent = $ingredientPercent / 100;
$mixed[] = new MeasuredIngredient($ingredient, $ingredientPercent, $volume * $floatPercent);
}
return $mixed;