<?php
/**
* @license Silk Software House Sp. Z O.O.
*/
declare(strict_types=1);
namespace App\Entity;
use App\Entity\Interfaces\ChannelInterface;
use App\Entity\Traits\IdTrait;
use App\Entity\Traits\TimePreUpdateTrait;
use App\Entity\Traits\TimeTrait;
use App\Validator\Constraints as AppAssert;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* A one-shot temperature alarm for one configured measurement channel.
*
* @ORM\Entity(repositoryClass="App\Repository\TemperatureNotificationRepository")
* @ORM\Table(
* name="temperature_notifications",
* indexes={
* @ORM\Index(name="IDX_TEMPERATURE_NOTIFICATION_USER", columns={"user_id"}),
* @ORM\Index(name="IDX_TEMPERATURE_NOTIFICATION_CHANNEL", columns={"channel_setting_id"}),
* @ORM\Index(name="IDX_TEMPERATURE_NOTIFICATION_PENDING", columns={"channel_setting_id", "id"}, options={"where": "(triggered_at IS NULL)"})
* },
* uniqueConstraints={
* @ORM\UniqueConstraint(name="UNIQ_TEMPERATURE_NOTIFICATION_PENDING", columns={"user_id", "channel_setting_id", "temperature_trigger", "direction", "email"}, options={"where": "(triggered_at IS NULL)"})
* }
* )
* @ORM\HasLifecycleCallbacks()
*/
class TemperatureNotification implements ChannelInterface
{
use IdTrait;
use TimeTrait;
use TimePreUpdateTrait;
public const DIRECTION_ABOVE = 'above';
public const DIRECTION_BELOW = 'below';
public const DIRECTIONS = [
self::DIRECTION_ABOVE,
self::DIRECTION_BELOW,
];
public const MINIMUM_TEMPERATURE = -273.15;
public const MAXIMUM_TEMPERATURE = 1416833.0;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", nullable=false)
*/
private User $user;
/**
* @AppAssert\ChannelNotBlank()
*
* @ORM\ManyToOne(targetEntity="App\Entity\ChannelSetting", cascade={"persist"})
* @ORM\JoinColumn(name="channel_setting_id", nullable=false)
*/
private ChannelSetting $channelSetting;
/**
* @Assert\NotNull()
* @Assert\Range(min="-273.15", max="1416833")
*
* @ORM\Column(name="temperature_trigger", type="float", nullable=false, options={"comment": "Temperature in degrees Celsius that triggers this notification."})
*/
private float $temperatureTrigger;
/**
* @Assert\Choice(choices={"above", "below"})
*
* @ORM\Column(name="direction", type="string", length=16, nullable=false, options={"default": "above", "comment": "Alarm direction: above or below."})
*/
private string $direction = self::DIRECTION_ABOVE;
/**
* @ORM\Column(name="triggered_at", type="datetime", nullable=true, options={"comment": "When this notification was triggered."})
*/
private ?DateTime $triggeredAt = null;
/**
* @Assert\Email()
*
* @ORM\Column(name="email", type="string", length=255, nullable=true)
*/
private ?string $email = null;
public function getUser(): ?User
{
return $this->user ?? null;
}
public function setUser(User $user): self
{
$this->user = $user;
return $this;
}
public function getChannelSetting(): ?ChannelSetting
{
return $this->channelSetting ?? null;
}
public function setChannelSetting(ChannelSetting $channelSetting): self
{
$this->channelSetting = $channelSetting;
return $this;
}
public function getTemperatureTrigger(): ?float
{
return $this->temperatureTrigger ?? null;
}
public function setTemperatureTrigger(float $temperatureTrigger): self
{
$this->temperatureTrigger = $temperatureTrigger;
return $this;
}
public function getDirection(): string
{
return $this->direction;
}
public function setDirection(string $direction): self
{
$this->direction = $direction;
return $this;
}
public function getTriggeredAt(): ?DateTime
{
return $this->triggeredAt;
}
public function setTriggeredAt(?DateTime $triggeredAt): self
{
$this->triggeredAt = $triggeredAt;
return $this;
}
public function getIsTriggered(): bool
{
return null !== $this->triggeredAt;
}
public function isTriggeredBy(float $temperature): bool
{
if (!isset($this->temperatureTrigger)) {
return false;
}
if (self::DIRECTION_ABOVE === $this->direction) {
return $temperature >= $this->temperatureTrigger;
}
return self::DIRECTION_BELOW === $this->direction
&& $temperature <= $this->temperatureTrigger;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): self
{
$this->email = $email;
return $this;
}
public function getMeasurement(): ?Measurement
{
if (!isset($this->channelSetting) || !$this->channelSetting->getMeasurementSetting()) {
return null;
}
return $this->channelSetting->getMeasurementSetting()->getMeasurement();
}
public function hasChannel(): bool
{
return isset($this->channelSetting);
}
}