Главная ошибка у вас в первой строке.
Выражение
Math.floor(Math.random(1, 3)) * 1000
вычисляется один раз при запуске, и потом только с этим интервалом и работает.
Я бы делал немножко по другому: несколько флагов, которые переключаются независимыми таймерами, через 300, 500, 700 миллисекунд, например (основано на ряде простых чисел).
Когда все три флага совпали - моргаем лампочкой. Такие таймеры дадут довольно длинную псевдослучайную последовательность без очевидных шаблонных повторений.
(function(){
var a = b = c = true, lamp = document.querySelector('.lamp')
setInterval(function(){
if (a && b && c) {
lamp.classList.add('off')
setTimeout(function(){
lamp.classList.remove('off')
}, 40) // это три кадра при 60 fps
}
}, 200)
setInterval(function(){ a = !a }, 300)
setInterval(function(){ b = !b }, 500)
setInterval(function(){ c = !c }, 700)
})()
числа в таймерах можно подправить на свой вкус
https://jsfiddle.net/wo78t98z/UPD: Вариант на css
У враппера желтый фон, поверх два прозрачных псевдоэлемента и пнг-шка с лампочкой.
У псевдоэлементов и пнг-шки независимые таймеры, которые кратковременно моргают черным.
.lamp::before,
.lamp::after {
background: transparent;
animation: blink 7.5s step-start infinite;
}
.lamp::after {
animation-duration: 13s;
}
.lamp img {
animation: blink 3s step-start infinite;
}
@keyframes blink {
0%, 1% { background: #000; }
100% { background: transparent; }
}
https://jsfiddle.net/wo78t98z/1/