@ -0,0 +1,3 @@ | |||||
.gitsecret/keys/random_seed | |||||
!*.secret | |||||
mainboard/secrets.h |
@ -0,0 +1 @@ | |||||
mainboard/secrets.h:47167f6bfaa3da3dec08230c4a4ddf0b8685ce551846aee445890942f7ba1fa7 |
@ -1 +1,2 @@ | |||||
# YeetClock | |||||
# YeetClock | |||||
This is a personal project I made that is pretty cool alarm clock that also controls LED lights, shows the weather forecast, your 3D print's progress and the status of your self hosted self hosted services while also providing a mobile app so that you can control the led lights to your preference. |
@ -0,0 +1,14 @@ | |||||
*.iml | |||||
.gradle | |||||
/local.properties | |||||
/.idea/caches | |||||
/.idea/libraries | |||||
/.idea/modules.xml | |||||
/.idea/workspace.xml | |||||
/.idea/navEditor.xml | |||||
/.idea/assetWizardSettings.xml | |||||
.DS_Store | |||||
/build | |||||
/captures | |||||
.externalNativeBuild | |||||
.cxx |
@ -0,0 +1,8 @@ | |||||
# Default ignored files | |||||
/shelf/ | |||||
/workspace.xml | |||||
# Datasource local storage ignored files | |||||
/dataSources/ | |||||
/dataSources.local.xml | |||||
# Editor-based HTTP Client requests | |||||
/httpRequests/ |
@ -0,0 +1 @@ | |||||
Yeet Clock |
@ -0,0 +1,131 @@ | |||||
<component name="ProjectCodeStyleConfiguration"> | |||||
<code_scheme name="Project" version="173"> | |||||
<AndroidXmlCodeStyleSettings> | |||||
<option name="USE_CUSTOM_SETTINGS" value="true" /> | |||||
</AndroidXmlCodeStyleSettings> | |||||
<JetCodeStyleSettings> | |||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | |||||
</JetCodeStyleSettings> | |||||
<XML> | |||||
<option name="XML_KEEP_LINE_BREAKS" value="false" /> | |||||
<option name="XML_ALIGN_ATTRIBUTES" value="false" /> | |||||
<option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" /> | |||||
</XML> | |||||
<codeStyleSettings language="XML"> | |||||
<option name="FORCE_REARRANGE_MODE" value="1" /> | |||||
<indentOptions> | |||||
<option name="CONTINUATION_INDENT_SIZE" value="4" /> | |||||
</indentOptions> | |||||
<arrangement> | |||||
<rules> | |||||
<section> | |||||
<rule> | |||||
<match> | |||||
<AND> | |||||
<NAME>xmlns:android</NAME> | |||||
<XML_ATTRIBUTE /> | |||||
<XML_NAMESPACE>^$</XML_NAMESPACE> | |||||
</AND> | |||||
</match> | |||||
</rule> | |||||
</section> | |||||
<section> | |||||
<rule> | |||||
<match> | |||||
<AND> | |||||
<NAME>xmlns:.*</NAME> | |||||
<XML_ATTRIBUTE /> | |||||
<XML_NAMESPACE>^$</XML_NAMESPACE> | |||||
</AND> | |||||
</match> | |||||
<order>BY_NAME</order> | |||||
</rule> | |||||
</section> | |||||
<section> | |||||
<rule> | |||||
<match> | |||||
<AND> | |||||
<NAME>.*:id</NAME> | |||||
<XML_ATTRIBUTE /> | |||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | |||||
</AND> | |||||
</match> | |||||
</rule> | |||||
</section> | |||||
<section> | |||||
<rule> | |||||
<match> | |||||
<AND> | |||||
<NAME>.*:name</NAME> | |||||
<XML_ATTRIBUTE /> | |||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | |||||
</AND> | |||||
</match> | |||||
</rule> | |||||
</section> | |||||
<section> | |||||
<rule> | |||||
<match> | |||||
<AND> | |||||
<NAME>name</NAME> | |||||
<XML_ATTRIBUTE /> | |||||
<XML_NAMESPACE>^$</XML_NAMESPACE> | |||||
</AND> | |||||
</match> | |||||
</rule> | |||||
</section> | |||||
<section> | |||||
<rule> | |||||
<match> | |||||
<AND> | |||||
<NAME>style</NAME> | |||||
<XML_ATTRIBUTE /> | |||||
<XML_NAMESPACE>^$</XML_NAMESPACE> | |||||
</AND> | |||||
</match> | |||||
</rule> | |||||
</section> | |||||
<section> | |||||
<rule> | |||||
<match> | |||||
<AND> | |||||
<NAME>.*</NAME> | |||||
<XML_ATTRIBUTE /> | |||||
<XML_NAMESPACE>^$</XML_NAMESPACE> | |||||
</AND> | |||||
</match> | |||||
<order>BY_NAME</order> | |||||
</rule> | |||||
</section> | |||||
<section> | |||||
<rule> | |||||
<match> | |||||
<AND> | |||||
<NAME>.*</NAME> | |||||
<XML_ATTRIBUTE /> | |||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | |||||
</AND> | |||||
</match> | |||||
<order>ANDROID_ATTRIBUTE_ORDER</order> | |||||
</rule> | |||||
</section> | |||||
<section> | |||||
<rule> | |||||
<match> | |||||
<AND> | |||||
<NAME>.*</NAME> | |||||
<XML_ATTRIBUTE /> | |||||
<XML_NAMESPACE>.*</XML_NAMESPACE> | |||||
</AND> | |||||
</match> | |||||
<order>BY_NAME</order> | |||||
</rule> | |||||
</section> | |||||
</rules> | |||||
</arrangement> | |||||
</codeStyleSettings> | |||||
<codeStyleSettings language="kotlin"> | |||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | |||||
</codeStyleSettings> | |||||
</code_scheme> | |||||
</component> |
@ -0,0 +1,5 @@ | |||||
<component name="ProjectCodeStyleConfiguration"> | |||||
<state> | |||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" /> | |||||
</state> | |||||
</component> |
@ -0,0 +1,6 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="CompilerConfiguration"> | |||||
<bytecodeTargetLevel target="11" /> | |||||
</component> | |||||
</project> |
@ -0,0 +1,20 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="GradleMigrationSettings" migrationVersion="1" /> | |||||
<component name="GradleSettings"> | |||||
<option name="linkedExternalProjectsSettings"> | |||||
<GradleProjectSettings> | |||||
<option name="distributionType" value="DEFAULT_WRAPPED" /> | |||||
<option name="externalProjectPath" value="$PROJECT_DIR$" /> | |||||
<option name="gradleJvm" value="#JAVA_INTERNAL" /> | |||||
<option name="modules"> | |||||
<set> | |||||
<option value="$PROJECT_DIR$" /> | |||||
<option value="$PROJECT_DIR$/app" /> | |||||
</set> | |||||
</option> | |||||
<option name="useAutoImport" value="true" /> | |||||
</GradleProjectSettings> | |||||
</option> | |||||
</component> | |||||
</project> |
@ -0,0 +1,25 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="RemoteRepositoriesConfiguration"> | |||||
<remote-repository> | |||||
<option name="id" value="central" /> | |||||
<option name="name" value="Maven Central repository" /> | |||||
<option name="url" value="https://repo1.maven.org/maven2" /> | |||||
</remote-repository> | |||||
<remote-repository> | |||||
<option name="id" value="jboss.community" /> | |||||
<option name="name" value="JBoss Community repository" /> | |||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> | |||||
</remote-repository> | |||||
<remote-repository> | |||||
<option name="id" value="BintrayJCenter" /> | |||||
<option name="name" value="BintrayJCenter" /> | |||||
<option name="url" value="https://jcenter.bintray.com/" /> | |||||
</remote-repository> | |||||
<remote-repository> | |||||
<option name="id" value="Google" /> | |||||
<option name="name" value="Google" /> | |||||
<option name="url" value="https://dl.google.com/dl/android/maven2/" /> | |||||
</remote-repository> | |||||
</component> | |||||
</project> |
@ -0,0 +1,12 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="FrameworkDetectionExcludesConfiguration"> | |||||
<file type="web" url="file://$PROJECT_DIR$" /> | |||||
</component> | |||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK"> | |||||
<output url="file://$PROJECT_DIR$/build/classes" /> | |||||
</component> | |||||
<component name="ProjectType"> | |||||
<option name="id" value="Android" /> | |||||
</component> | |||||
</project> |
@ -0,0 +1 @@ | |||||
/build |
@ -0,0 +1,42 @@ | |||||
apply plugin: 'com.android.application' | |||||
apply plugin: 'kotlin-android' | |||||
apply plugin: 'kotlin-android-extensions' | |||||
android { | |||||
compileSdkVersion 29 | |||||
buildToolsVersion "29.0.3" | |||||
defaultConfig { | |||||
applicationId "com.yigitcolakoglu.yeetclock" | |||||
minSdkVersion 27 | |||||
targetSdkVersion 29 | |||||
versionCode 1 | |||||
versionName "1.0" | |||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | |||||
} | |||||
buildTypes { | |||||
release { | |||||
minifyEnabled false | |||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | |||||
} | |||||
} | |||||
} | |||||
dependencies { | |||||
implementation fileTree(dir: 'libs', include: ['*.jar']) | |||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" | |||||
implementation 'androidx.appcompat:appcompat:1.0.2' | |||||
implementation 'androidx.core:core-ktx:1.0.2' | |||||
implementation 'com.google.android.material:material:1.0.0' | |||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' | |||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' | |||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0' | |||||
implementation 'ca.antonious:materialdaypicker:0.7.2' | |||||
testImplementation 'junit:junit:4.12' | |||||
implementation 'com.android.volley:volley:1.1.1' | |||||
implementation 'com.google.code.gson:gson:2.8.5' | |||||
implementation 'com.google.code.gson:gson:2.8.6' | |||||
androidTestImplementation 'androidx.test:runner:1.1.1' | |||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' | |||||
} |
@ -0,0 +1,21 @@ | |||||
# Add project specific ProGuard rules here. | |||||
# You can control the set of applied configuration files using the | |||||
# proguardFiles setting in build.gradle. | |||||
# | |||||
# For more details, see | |||||
# http://developer.android.com/guide/developing/tools/proguard.html | |||||
# If your project uses WebView with JS, uncomment the following | |||||
# and specify the fully qualified class name to the JavaScript interface | |||||
# class: | |||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | |||||
# public *; | |||||
#} | |||||
# Uncomment this to preserve the line number information for | |||||
# debugging stack traces. | |||||
#-keepattributes SourceFile,LineNumberTable | |||||
# If you keep the line number information, uncomment this to | |||||
# hide the original source file name. | |||||
#-renamesourcefileattribute SourceFile |
@ -0,0 +1,24 @@ | |||||
package com.yigitcolakoglu.yeetclock | |||||
import androidx.test.platform.app.InstrumentationRegistry | |||||
import androidx.test.ext.junit.runners.AndroidJUnit4 | |||||
import org.junit.Test | |||||
import org.junit.runner.RunWith | |||||
import org.junit.Assert.* | |||||
/** | |||||
* Instrumented test, which will execute on an Android device. | |||||
* | |||||
* See [testing documentation](http://d.android.com/tools/testing). | |||||
*/ | |||||
@RunWith(AndroidJUnit4::class) | |||||
class ExampleInstrumentedTest { | |||||
@Test | |||||
fun useAppContext() { | |||||
// Context of the app under test. | |||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext | |||||
assertEquals("com.yigitcolakoglu.yeetclock", appContext.packageName) | |||||
} | |||||
} |
@ -0,0 +1,26 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |||||
package="com.yigitcolakoglu.yeetclock"> | |||||
<uses-permission android:name="android.permission.INTERNET" /> | |||||
<application | |||||
android:allowBackup="true" | |||||
android:icon="@mipmap/ic_launcher" | |||||
android:label="@string/app_name" | |||||
android:roundIcon="@mipmap/ic_launcher_round" | |||||
android:supportsRtl="true" | |||||
android:theme="@style/AppTheme" | |||||
android:networkSecurityConfig="@xml/network_security_config" | |||||
android:usesCleartextTraffic="true"> | |||||
<activity | |||||
android:name=".MainActivity" | |||||
android:label="@string/app_name" | |||||
android:theme="@style/AppTheme.NoActionBar"> | |||||
<intent-filter> | |||||
<action android:name="android.intent.action.MAIN"/> | |||||
<category android:name="android.intent.category.LAUNCHER"/> | |||||
</intent-filter> | |||||
</activity> | |||||
</application> | |||||
</manifest> |
@ -0,0 +1,24 @@ | |||||
package com.yigitcolakoglu.yeetclock | |||||
import android.os.Bundle | |||||
import com.google.android.material.floatingactionbutton.FloatingActionButton | |||||
import com.google.android.material.snackbar.Snackbar | |||||
import com.google.android.material.tabs.TabLayout | |||||
import androidx.viewpager.widget.ViewPager | |||||
import androidx.appcompat.app.AppCompatActivity | |||||
import android.view.Menu | |||||
import android.view.MenuItem | |||||
import com.yigitcolakoglu.yeetclock.ui.main.SectionsPagerAdapter | |||||
class MainActivity : AppCompatActivity() { | |||||
override fun onCreate(savedInstanceState: Bundle?) { | |||||
super.onCreate(savedInstanceState) | |||||
setContentView(R.layout.activity_main) | |||||
val sectionsPagerAdapter = SectionsPagerAdapter(this, supportFragmentManager) | |||||
val viewPager: ViewPager = findViewById(R.id.view_pager) | |||||
viewPager.adapter = sectionsPagerAdapter | |||||
val tabs: TabLayout = findViewById(R.id.tabs) | |||||
tabs.setupWithViewPager(viewPager) | |||||
} | |||||
} |
@ -0,0 +1,133 @@ | |||||
package com.yigitcolakoglu.yeetclock.ui.main | |||||
import android.content.Context | |||||
import android.net.Uri | |||||
import android.os.Bundle | |||||
import androidx.fragment.app.Fragment | |||||
import android.view.LayoutInflater | |||||
import android.view.View | |||||
import android.view.ViewGroup | |||||
import android.widget.Button | |||||
import android.widget.TimePicker | |||||
import android.widget.Toast | |||||
import ca.antonious.materialdaypicker.MaterialDayPicker | |||||
import com.android.volley.Request | |||||
import com.android.volley.Response | |||||
import com.android.volley.toolbox.StringRequest | |||||
import com.google.gson.Gson | |||||
import com.yigitcolakoglu.yeetclock.R | |||||
import java.lang.Math.floor | |||||
import java.lang.Math.toIntExact | |||||
import java.sql.Time | |||||
import java.time.DayOfWeek | |||||
import kotlin.math.pow | |||||
class AlarmFragment : Fragment() , View.OnClickListener{ | |||||
private var listener: OnFragmentInteractionListener? = null | |||||
override fun onCreate(savedInstanceState: Bundle?) { | |||||
super.onCreate(savedInstanceState) | |||||
} | |||||
override fun onCreateView( | |||||
inflater: LayoutInflater, container: ViewGroup?, | |||||
savedInstanceState: Bundle? | |||||
): View? { | |||||
val layout = inflater.inflate(R.layout.fragment_alarm, container, false) | |||||
val daySelector = layout.findViewById<MaterialDayPicker>(R.id.alarm_day_picker) | |||||
val timeSelector = layout.findViewById<TimePicker>(R.id.alarm_time_picker) | |||||
val updateButton = layout.findViewById<Button>(R.id.alarm_update_button) | |||||
updateButton.setOnClickListener(this) | |||||
timeSelector.setIs24HourView(true) | |||||
val url = "http://yeetclock.xyz/getcolor" | |||||
val stringRequest = StringRequest( | |||||
Request.Method.GET, url, | |||||
Response.Listener<String> { response -> | |||||
val gson = Gson() | |||||
val alarm = gson.fromJson(response, Alarm::class.java) | |||||
var enabled_days = arrayListOf<MaterialDayPicker.Weekday>() | |||||
for(i in alarm.days){ | |||||
when(i){ | |||||
0 -> enabled_days.add(MaterialDayPicker.Weekday.MONDAY) | |||||
1 -> enabled_days.add(MaterialDayPicker.Weekday.TUESDAY) | |||||
2 -> enabled_days.add(MaterialDayPicker.Weekday.WEDNESDAY) | |||||
3 -> enabled_days.add(MaterialDayPicker.Weekday.THURSDAY) | |||||
4 -> enabled_days.add(MaterialDayPicker.Weekday.FRIDAY) | |||||
5 -> enabled_days.add(MaterialDayPicker.Weekday.SATURDAY) | |||||
6 -> enabled_days.add(MaterialDayPicker.Weekday.SUNDAY) | |||||
} | |||||
} | |||||
daySelector.setSelectedDays(enabled_days.toList()) | |||||
val hour = alarm.time/3600 | |||||
val minute = (alarm.time%3600)/60 | |||||
timeSelector.hour = hour | |||||
timeSelector.minute = minute | |||||
}, | |||||
Response.ErrorListener { error -> | |||||
Toast.makeText(getActivity(),"Issue with GET request", Toast.LENGTH_SHORT).show() | |||||
}) | |||||
return layout | |||||
} | |||||
fun onButtonPressed(uri: Uri) { | |||||
listener?.onFragmentInteraction(uri) | |||||
} | |||||
override fun onAttach(context: Context) { | |||||
super.onAttach(context) | |||||
if (context is OnFragmentInteractionListener) { | |||||
listener = context | |||||
} | |||||
} | |||||
override fun onDetach() { | |||||
super.onDetach() | |||||
listener = null | |||||
} | |||||
interface OnFragmentInteractionListener { | |||||
fun onFragmentInteraction(uri: Uri) | |||||
} | |||||
companion object { | |||||
@JvmStatic | |||||
fun newInstance() = | |||||
AlarmFragment().apply {} | |||||
} | |||||
public override fun onClick(v: View?) { | |||||
val enabled_days = this.view?.findViewById<MaterialDayPicker>(R.id.alarm_day_picker)?.selectedDays | |||||
var new_days = arrayListOf<Int>(0,0,0,0,0,0,0) | |||||
if (enabled_days != null) { | |||||
for(i in enabled_days){ | |||||
when(i){ | |||||
MaterialDayPicker.Weekday.MONDAY -> new_days[0] = 1 | |||||
MaterialDayPicker.Weekday.TUESDAY -> new_days[1] = 1 | |||||
MaterialDayPicker.Weekday.WEDNESDAY -> new_days[2] = 1 | |||||
MaterialDayPicker.Weekday.THURSDAY -> new_days[3] = 1 | |||||
MaterialDayPicker.Weekday.FRIDAY -> new_days[4] = 1 | |||||
MaterialDayPicker.Weekday.SATURDAY -> new_days[5] = 1 | |||||
MaterialDayPicker.Weekday.SUNDAY -> new_days[6] = 1 | |||||
} | |||||
} | |||||
} | |||||
var days_int = 0 | |||||
for(i in 0..7){ | |||||
days_int += (2.0.pow(i)*new_days[i]).toInt() | |||||
} | |||||
val hour = this.view?.findViewById<TimePicker>(R.id.alarm_time_picker)?.hour?.times(3600) | |||||
val minute = this.view?.findViewById<TimePicker>(R.id.alarm_time_picker)?.minute?.times(60) | |||||
val url = "http://yeetclock.xyz/setAlarm?time=%d&days=%d" | |||||
val stringRequest = StringRequest( | |||||
Request.Method.GET, url.format(hour?.let { minute?.plus(it) },days_int), | |||||
Response.Listener<String> { response -> | |||||
}, | |||||
Response.ErrorListener { error -> | |||||
Toast.makeText(getActivity(),"Issue with GET request", Toast.LENGTH_SHORT).show() | |||||
}) | |||||
} | |||||
} | |||||
public class Alarm(val days:List<Int>, val time:Int) | |||||
@ -0,0 +1,205 @@ | |||||
package com.yigitcolakoglu.yeetclock.ui.main | |||||
import android.content.Context | |||||
import android.graphics.Color | |||||
import android.net.Uri | |||||
import android.os.Bundle | |||||
import android.util.Log | |||||
import android.view.LayoutInflater | |||||
import android.view.View | |||||
import android.view.ViewGroup | |||||
import android.widget.Button | |||||
import android.widget.SeekBar | |||||
import android.widget.TextView | |||||
import android.widget.Toast | |||||
import androidx.fragment.app.Fragment | |||||
import com.android.volley.Request | |||||
import com.android.volley.RequestQueue | |||||
import com.android.volley.Response | |||||
import com.android.volley.toolbox.BasicNetwork | |||||
import com.android.volley.toolbox.DiskBasedCache | |||||
import com.android.volley.toolbox.HurlStack | |||||
import com.android.volley.toolbox.StringRequest | |||||
import com.google.gson.Gson | |||||
import com.yigitcolakoglu.yeetclock.R | |||||
import java.io.File | |||||
class ColorPicker : Fragment(), SeekBar.OnSeekBarChangeListener, View.OnClickListener{ | |||||
// TODO: Rename and change types of parameters | |||||
private var listener: OnFragmentInteractionListener? = null | |||||
public var green: Int = 0 | |||||
public var red: Int = 0 | |||||
public var blue: Int = 0 | |||||
public var on: Boolean = true | |||||
val cache = DiskBasedCache(File("/"), 1024 * 1024) // 1MB cap | |||||
// Set up the network to use HttpURLConnection as the HTTP client. | |||||
val network = BasicNetwork(HurlStack()) | |||||
// Instantiate the RequestQueue with the cache and network. Start the queue. | |||||
val requestQueue = RequestQueue(cache, network).apply { | |||||
start() | |||||
} | |||||
override fun onCreate(savedInstanceState: Bundle?) { | |||||
super.onCreate(savedInstanceState) | |||||
} | |||||
override fun onCreateView( | |||||
inflater: LayoutInflater, container: ViewGroup?, | |||||
savedInstanceState: Bundle? | |||||
): View? { | |||||
val layout = inflater.inflate(R.layout.fragment_color_picker, container, false) | |||||
val colorPanel = layout.findViewById<TextView>(R.id.colorShow) | |||||
layout.findViewById<SeekBar>(R.id.green_seekbar).setOnSeekBarChangeListener(this) | |||||
layout.findViewById<SeekBar>(R.id.blue_seekbar).setOnSeekBarChangeListener(this) | |||||
layout.findViewById<SeekBar>(R.id.red_seekbar).setOnSeekBarChangeListener(this) | |||||
layout.findViewById<Button>(R.id.power_toggle).setOnClickListener(this) | |||||
val url = "http://yeetclock.xyz/getcolor" | |||||
val stringRequest = StringRequest( | |||||
Request.Method.GET, url, | |||||
Response.Listener<String> { response -> | |||||
var gson = Gson() | |||||
var led = gson.fromJson(response,Led::class.java) | |||||
red = led.RGB.get(0) | |||||
green = led.RGB.get(1) | |||||
blue = led.RGB.get(2) | |||||
on = led.ON == 1 | |||||
val r: SeekBar? = this.view?.findViewById<SeekBar>(R.id.red_seekbar) | |||||
val g: SeekBar? = this.view?.findViewById<SeekBar>(R.id.green_seekbar) | |||||
val b: SeekBar? = this.view?.findViewById<SeekBar>(R.id.blue_seekbar) | |||||
val button: Button? = this.view?.findViewById(R.id.power_toggle) | |||||
val palette: TextView? = this.view?.findViewById(R.id.colorShow) | |||||
palette!!.setBackgroundColor(Color.rgb(red,green,blue)) | |||||
Log.i("RED",r.toString()) | |||||
Log.i("GREEN",g.toString()) | |||||
Log.i("BLUE",b.toString()) | |||||
r?.setProgress(red) | |||||
g?.setProgress(green) | |||||
b?.setProgress(blue) | |||||
if (!on) { | |||||
r?.setVisibility(View.INVISIBLE) | |||||
g?.setVisibility(View.INVISIBLE) | |||||
b?.setVisibility(View.INVISIBLE) | |||||
palette?.setVisibility(View.INVISIBLE) | |||||
button?.setBackgroundColor(Color.BLACK) | |||||
button?.setTextColor(Color.WHITE) | |||||
}else{ | |||||
r?.setVisibility(View.VISIBLE) | |||||
g?.setVisibility(View.VISIBLE) | |||||
b?.setVisibility(View.VISIBLE) | |||||
palette?.setVisibility(View.VISIBLE) | |||||
button?.setBackgroundColor(Color.WHITE) | |||||
button?.setTextColor(Color.BLACK) | |||||
} | |||||
}, | |||||
Response.ErrorListener { error -> | |||||
Toast.makeText(getActivity(),"Issue with GET request",Toast.LENGTH_SHORT).show() | |||||
}) | |||||
requestQueue.add(stringRequest) | |||||
return layout | |||||
} | |||||
override fun onAttach(context: Context) { | |||||
super.onAttach(context) | |||||
if (context is OnFragmentInteractionListener) { | |||||
listener = context | |||||
} | |||||
} | |||||
override fun onDetach() { | |||||
super.onDetach() | |||||
listener = null | |||||
} | |||||
interface OnFragmentInteractionListener { | |||||
// TODO: Update argument type and name | |||||
fun onFragmentInteraction(uri: Uri) | |||||
} | |||||
companion object { | |||||
@JvmStatic | |||||
fun newInstance() = | |||||
ColorPicker().apply { | |||||
arguments = Bundle().apply { | |||||
} | |||||
} | |||||
} | |||||
public override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { | |||||
if (!fromUser){ | |||||
return | |||||
} | |||||
val g: Int = this.view?.findViewById<SeekBar>(R.id.green_seekbar)!!.progress | |||||
val r: Int = this.view?.findViewById<SeekBar>(R.id.red_seekbar)!!.progress | |||||
val b: Int = this.view?.findViewById<SeekBar>(R.id.blue_seekbar)!!.progress | |||||
red = r | |||||
blue = b | |||||
green = g | |||||
this.view?.findViewById<TextView>(R.id.colorShow)!!.setBackgroundColor(Color.rgb(r,g,b)) | |||||
val url = "http://yeetclock.xyz/setcolor?R=%d&G=%d&B=%d&O=%d" | |||||
Log.i("COLORS",url.format(r,b,g, if (on) 1 else 0)) | |||||
val stringRequest = StringRequest( | |||||
Request.Method.GET, url.format(r,g,b,if (on) 1 else 0), | |||||
Response.Listener<String> { response -> | |||||
}, | |||||
Response.ErrorListener { error -> | |||||
Toast.makeText(getActivity(),"Issue with GET request",Toast.LENGTH_SHORT).show() | |||||
}) | |||||
requestQueue.add(stringRequest) | |||||
} | |||||
public override fun onStartTrackingTouch(seekBar: SeekBar?) {} | |||||
public override fun onStopTrackingTouch(seekBar: SeekBar?) {} | |||||
public override fun onClick(v: View?) { | |||||
on = !on | |||||
val r: SeekBar? = this.view?.findViewById<SeekBar>(R.id.red_seekbar) | |||||
val g: SeekBar? = this.view?.findViewById<SeekBar>(R.id.green_seekbar) | |||||
val b: SeekBar? = this.view?.findViewById<SeekBar>(R.id.blue_seekbar) | |||||
val button: Button? = this.view?.findViewById(R.id.power_toggle) | |||||
val palette: TextView? = this.view?.findViewById(R.id.colorShow) | |||||
if (!on) { | |||||
r?.setVisibility(View.INVISIBLE) | |||||
g?.setVisibility(View.INVISIBLE) | |||||
b?.setVisibility(View.INVISIBLE) | |||||
palette?.setVisibility(View.INVISIBLE) | |||||
button?.setBackgroundColor(Color.BLACK) | |||||
button?.setTextColor(Color.WHITE) | |||||
val url = "http://yeetclock.xyz/setcolor?R=%d&G=%d&B=%d&O=0" | |||||
val stringRequest = StringRequest( | |||||
Request.Method.GET, url.format(red,green,blue), | |||||
Response.Listener<String> { response -> | |||||
}, | |||||
Response.ErrorListener { error -> | |||||
Log.i("ERROR",error.message) | |||||
Toast.makeText(getActivity(),"Issue with GET request",Toast.LENGTH_SHORT).show() | |||||
}) | |||||
requestQueue.add(stringRequest) | |||||
}else{ | |||||
r?.setVisibility(View.VISIBLE) | |||||
g?.setVisibility(View.VISIBLE) | |||||
b?.setVisibility(View.VISIBLE) | |||||
palette?.setVisibility(View.VISIBLE) | |||||
button?.setBackgroundColor(Color.WHITE) | |||||
button?.setTextColor(Color.BLACK) | |||||
val url = "http://yeetclock.xyz/setcolor?R=%d&G=%d&B=%d&O=1" | |||||
val stringRequest = StringRequest( | |||||
Request.Method.GET, url.format(red,green,blue), | |||||
Response.Listener<String> { response -> | |||||
}, | |||||
Response.ErrorListener { error -> | |||||
Log.i("ERROR",error.message) | |||||
Toast.makeText(getActivity(),"Issue with GET request",Toast.LENGTH_SHORT).show() | |||||
}) | |||||
requestQueue.add(stringRequest) | |||||
} | |||||
} | |||||
} | |||||
public class Led(val RGB:List<Int>, val ON:Int) | |||||
@ -0,0 +1,19 @@ | |||||
package com.yigitcolakoglu.yeetclock.ui.main | |||||
import androidx.lifecycle.LiveData | |||||
import androidx.lifecycle.MutableLiveData | |||||
import androidx.lifecycle.Transformations | |||||
import androidx.lifecycle.ViewModel | |||||
import androidx.lifecycle.ViewModelProvider | |||||
class PageViewModel : ViewModel() { | |||||
private val _index = MutableLiveData<Int>() | |||||
val text: LiveData<String> = Transformations.map(_index) { | |||||
"Hello world from section: $it" | |||||
} | |||||
fun setIndex(index: Int) { | |||||
_index.value = index | |||||
} | |||||
} |
@ -0,0 +1,59 @@ | |||||
package com.yigitcolakoglu.yeetclock.ui.main | |||||
import android.os.Bundle | |||||
import android.view.LayoutInflater | |||||
import android.view.View | |||||
import android.view.ViewGroup | |||||
import android.widget.TextView | |||||
import androidx.fragment.app.Fragment | |||||
import androidx.lifecycle.Observer | |||||
import androidx.lifecycle.ViewModelProviders | |||||
import com.yigitcolakoglu.yeetclock.R | |||||
/** | |||||
* A placeholder fragment containing a simple view. | |||||
*/ | |||||
class PlaceholderFragment : Fragment() { | |||||
private lateinit var pageViewModel: PageViewModel | |||||
override fun onCreate(savedInstanceState: Bundle?) { | |||||
super.onCreate(savedInstanceState) | |||||
pageViewModel = ViewModelProviders.of(this).get(PageViewModel::class.java).apply { | |||||
setIndex(arguments?.getInt(ARG_SECTION_NUMBER) ?: 1) | |||||
} | |||||
} | |||||
override fun onCreateView( | |||||
inflater: LayoutInflater, container: ViewGroup?, | |||||
savedInstanceState: Bundle? | |||||
): View? { | |||||
val root = inflater.inflate(R.layout.fragment_main, container, false) | |||||
val textView: TextView = root.findViewById(R.id.section_label) | |||||
pageViewModel.text.observe(this, Observer<String> { | |||||
textView.text = it | |||||
}) | |||||
return root | |||||
} | |||||
companion object { | |||||
/** | |||||
* The fragment argument representing the section number for this | |||||
* fragment. | |||||
*/ | |||||
private const val ARG_SECTION_NUMBER = "section_number" | |||||
/** | |||||
* Returns a new instance of this fragment for the given section | |||||
* number. | |||||
*/ | |||||
@JvmStatic | |||||
fun newInstance(sectionNumber: Int): PlaceholderFragment { | |||||
return PlaceholderFragment().apply { | |||||
arguments = Bundle().apply { | |||||
putInt(ARG_SECTION_NUMBER, sectionNumber) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,41 @@ | |||||
package com.yigitcolakoglu.yeetclock.ui.main | |||||
import android.content.Context | |||||
import androidx.fragment.app.Fragment | |||||
import androidx.fragment.app.FragmentManager | |||||
import androidx.fragment.app.FragmentPagerAdapter | |||||
import com.yigitcolakoglu.yeetclock.R | |||||
private val TAB_TITLES = arrayOf( | |||||
R.string.tab_text_1, | |||||
R.string.tab_text_2 | |||||
) | |||||
/** | |||||
* A [FragmentPagerAdapter] that returns a fragment corresponding to | |||||
* one of the sections/tabs/pages. | |||||
*/ | |||||
class SectionsPagerAdapter(private val context: Context, fm: FragmentManager) | |||||
: FragmentPagerAdapter(fm) { | |||||
override fun getItem(position: Int): Fragment { | |||||
// getItem is called to instantiate the fragment for the given page. | |||||
// Return a PlaceholderFragment (defined as a static inner class below). | |||||
if(position == 0){ | |||||
return ColorPicker.newInstance() | |||||
} | |||||
if(position == 1){ | |||||
return AlarmFragment.newInstance() | |||||
} | |||||
return PlaceholderFragment.newInstance(position + 1) | |||||
} | |||||
override fun getPageTitle(position: Int): CharSequence? { | |||||
return context.resources.getString(TAB_TITLES[position]) | |||||
} | |||||
override fun getCount(): Int { | |||||
// Show 2 total pages. | |||||
return 2 | |||||
} | |||||
} |
@ -0,0 +1,34 @@ | |||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:aapt="http://schemas.android.com/aapt" | |||||
android:width="108dp" | |||||
android:height="108dp" | |||||
android:viewportHeight="108" | |||||
android:viewportWidth="108"> | |||||
<path | |||||
android:fillType="evenOdd" | |||||
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z" | |||||
android:strokeColor="#00000000" | |||||
android:strokeWidth="1"> | |||||
<aapt:attr name="android:fillColor"> | |||||
<gradient | |||||
android:endX="78.5885" | |||||
android:endY="90.9159" | |||||
android:startX="48.7653" | |||||
android:startY="61.0927" | |||||
android:type="linear"> | |||||
<item | |||||
android:color="#44000000" | |||||
android:offset="0.0"/> | |||||
<item | |||||
android:color="#00000000" | |||||
android:offset="1.0"/> | |||||
</gradient> | |||||
</aapt:attr> | |||||
</path> | |||||
<path | |||||
android:fillColor="#FFFFFF" | |||||
android:fillType="nonZero" | |||||
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z" | |||||
android:strokeColor="#00000000" | |||||
android:strokeWidth="1"/> | |||||
</vector> |
@ -0,0 +1,74 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<vector | |||||
xmlns:android="http://schemas.android.com/apk/res/android" | |||||
android:height="108dp" | |||||
android:width="108dp" | |||||
android:viewportHeight="108" | |||||
android:viewportWidth="108"> | |||||
<path android:fillColor="#008577" | |||||
android:pathData="M0,0h108v108h-108z"/> | |||||
<path android:fillColor="#00000000" android:pathData="M9,0L9,108" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M19,0L19,108" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M29,0L29,108" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M39,0L39,108" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M49,0L49,108" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M59,0L59,108" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M69,0L69,108" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M79,0L79,108" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M89,0L89,108" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M99,0L99,108" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M0,9L108,9" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M0,19L108,19" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M0,29L108,29" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M0,39L108,39" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M0,49L108,49" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M0,59L108,59" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M0,69L108,69" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M0,79L108,79" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M0,89L108,89" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M0,99L108,99" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M19,29L89,29" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M19,39L89,39" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M19,49L89,49" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M19,59L89,59" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M19,69L89,69" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M19,79L89,79" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M29,19L29,89" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M39,19L39,89" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M49,19L49,89" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M59,19L59,89" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M69,19L69,89" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
<path android:fillColor="#00000000" android:pathData="M79,19L79,89" | |||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | |||||
</vector> |
@ -0,0 +1,3 @@ | |||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> | |||||
</selector> |
@ -0,0 +1,37 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.coordinatorlayout.widget.CoordinatorLayout | |||||
xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".MainActivity"> | |||||
<com.google.android.material.appbar.AppBarLayout | |||||
android:layout_height="wrap_content" | |||||
android:layout_width="match_parent" | |||||
android:theme="@style/AppTheme.AppBarOverlay"> | |||||
<TextView | |||||
android:id="@+id/title" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:gravity="center" | |||||
android:minHeight="?actionBarSize" | |||||
android:padding="@dimen/appbar_padding" | |||||
android:text="@string/app_name" | |||||
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"/> | |||||
<com.google.android.material.tabs.TabLayout | |||||
android:id="@+id/tabs" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
android:background="?attr/colorPrimary"/> | |||||
</com.google.android.material.appbar.AppBarLayout> | |||||
<androidx.viewpager.widget.ViewPager | |||||
android:id="@+id/view_pager" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"/> | |||||
</androidx.coordinatorlayout.widget.CoordinatorLayout> |
@ -0,0 +1,47 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".ui.main.AlarmFragment" > | |||||
<LinearLayout | |||||
android:id="@+id/linearLayout" | |||||
android:layout_width="349dp" | |||||
android:layout_height="wrap_content" | |||||
android:orientation="vertical" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintHorizontal_bias="0.5" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
app:layout_constraintVertical_bias="0.05"> | |||||
<ca.antonious.materialdaypicker.MaterialDayPicker | |||||
android:id="@+id/alarm_day_picker" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" /> | |||||
</LinearLayout> | |||||
<TimePicker | |||||
android:id="@+id/alarm_time_picker" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="72dp" | |||||
android:timePickerMode="spinner" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintHorizontal_bias="0.496" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/linearLayout" /> | |||||
<Button | |||||
android:id="@+id/alarm_update_button" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="48dp" | |||||
android:text="OK" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintHorizontal_bias="0.47" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/alarm_time_picker" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
@ -0,0 +1,38 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".ui.main.ColorPicker"> | |||||
<TextView | |||||
android:layout_width="241dp" | |||||
android:layout_height="130dp" | |||||
android:id="@+id/colorShow" app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" | |||||
android:layout_marginTop="68dp" /> | |||||
<SeekBar | |||||
android:layout_width="345dp" | |||||
android:layout_height="27dp" | |||||
android:id="@+id/red_seekbar" app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/colorShow" | |||||
android:layout_marginTop="40dp" android:max="255"/> | |||||
<SeekBar | |||||
android:layout_width="345dp" | |||||
android:layout_height="27dp" | |||||
android:id="@+id/green_seekbar" app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/red_seekbar" | |||||
android:layout_marginTop="32dp" android:max="255"/> | |||||
<SeekBar | |||||
android:layout_width="345dp" | |||||
android:layout_height="27dp" | |||||
android:id="@+id/blue_seekbar" app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/green_seekbar" | |||||
android:layout_marginTop="28dp" android:max="255"/> | |||||
<Button | |||||
android:text="ON" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:id="@+id/power_toggle" app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/blue_seekbar" | |||||
android:layout_marginTop="36dp" app:layout_constraintHorizontal_bias="0.498"/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
@ -0,0 +1,23 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:id="@+id/constraintLayout" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".ui.main.PlaceholderFragment"> | |||||
<TextView | |||||
android:id="@+id/section_label" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
tools:layout_constraintTop_creator="1" | |||||
android:layout_marginStart="@dimen/activity_horizontal_margin" | |||||
android:layout_marginEnd="@dimen/activity_horizontal_margin" | |||||
android:layout_marginTop="@dimen/activity_vertical_margin" | |||||
android:layout_marginBottom="@dimen/activity_vertical_margin" | |||||
tools:layout_constraintLeft_creator="1" | |||||
app:layout_constraintLeft_toLeftOf="parent" | |||||
app:layout_constraintTop_toTopOf="@+id/constraintLayout"/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
@ -0,0 +1,5 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> | |||||
<background android:drawable="@drawable/ic_launcher_background"/> | |||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/> | |||||
</adaptive-icon> |
@ -0,0 +1,5 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> | |||||
<background android:drawable="@drawable/ic_launcher_background"/> | |||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/> | |||||
</adaptive-icon> |
@ -0,0 +1,6 @@ | |||||
<resources> | |||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml | |||||
(such as screen margins) for screens with more than 820dp of available width. This | |||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> | |||||
<dimen name="activity_horizontal_margin">64dp</dimen> | |||||
</resources> |
@ -0,0 +1,6 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<resources> | |||||
<color name="colorPrimary">#008577</color> | |||||
<color name="colorPrimaryDark">#00574B</color> | |||||
<color name="colorAccent">#D81B60</color> | |||||
</resources> |
@ -0,0 +1,8 @@ | |||||
<resources> | |||||
<!-- Default screen margins, per the Android Design guidelines. --> | |||||
<dimen name="activity_horizontal_margin">16dp</dimen> | |||||
<dimen name="activity_vertical_margin">16dp</dimen> | |||||
<dimen name="appbar_padding">16dp</dimen> | |||||
<dimen name="fab_margin">16dp</dimen> | |||||
<dimen name="appbar_padding_top">8dp</dimen> | |||||
</resources> |
@ -0,0 +1,9 @@ | |||||
<resources> | |||||
<string name="app_name">Yeet Clock</string> | |||||
<string name="tab_text_1">Lights</string> | |||||
<string name="tab_text_2">Alarm</string> | |||||
<string name="tab_text_3">Settings</string> | |||||
<!-- TODO: Remove or change this placeholder text --> | |||||
<string name="hello_blank_fragment">Hello blank fragment</string> | |||||
</resources> |
@ -0,0 +1,20 @@ | |||||
<resources> | |||||
<!-- Base application theme. --> | |||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> | |||||
<!-- Customize your theme here. --> | |||||
<item name="colorPrimary">@color/colorPrimary</item> | |||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> | |||||
<item name="colorAccent">@color/colorAccent</item> | |||||
</style> | |||||
<style name="AppTheme.NoActionBar"> | |||||
<item name="windowActionBar">false</item> | |||||
<item name="windowNoTitle">true</item> | |||||
</style> | |||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/> | |||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/> | |||||
</resources> |
@ -0,0 +1,6 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<network-security-config> | |||||
<domain-config cleartextTrafficPermitted="true"> | |||||
<domain includeSubdomains="true">yeetclock.xyz</domain> | |||||
</domain-config> | |||||
</network-security-config> |
@ -0,0 +1,17 @@ | |||||
package com.yigitcolakoglu.yeetclock | |||||
import org.junit.Test | |||||
import org.junit.Assert.* | |||||
/** | |||||
* Example local unit test, which will execute on the development machine (host). | |||||
* | |||||
* See [testing documentation](http://d.android.com/tools/testing). | |||||
*/ | |||||
class ExampleUnitTest { | |||||
@Test | |||||
fun addition_isCorrect() { | |||||
assertEquals(4, 2 + 2) | |||||
} | |||||
} |
@ -0,0 +1,27 @@ | |||||
// Top-level build file where you can add configuration options common to all sub-projects/modules. | |||||
buildscript { | |||||
ext.kotlin_version = '1.3.71' | |||||
repositories { | |||||
google() | |||||
jcenter() | |||||
} | |||||
dependencies { | |||||
classpath 'com.android.tools.build:gradle:3.6.0-rc01' | |||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | |||||
// NOTE: Do not place your application dependencies here; they belong | |||||
// in the individual module build.gradle files | |||||
} | |||||
} | |||||
allprojects { | |||||
repositories { | |||||
google() | |||||
jcenter() | |||||
} | |||||
} | |||||
@ -0,0 +1,21 @@ | |||||
# Project-wide Gradle settings. | |||||
# IDE (e.g. Android Studio) users: | |||||
# Gradle settings configured through the IDE *will override* | |||||
# any settings specified in this file. | |||||
# For more details on how to configure your build environment visit | |||||
# http://www.gradle.org/docs/current/userguide/build_environment.html | |||||
# Specifies the JVM arguments used for the daemon process. | |||||
# The setting is particularly useful for tweaking memory settings. | |||||
org.gradle.jvmargs=-Xmx1536m | |||||
# When configured, Gradle will run in incubating parallel mode. | |||||
# This option should only be used with decoupled projects. More details, visit | |||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects | |||||
# org.gradle.parallel=true | |||||
# AndroidX package structure to make it clearer which packages are bundled with the | |||||
# Android operating system, and which are packaged with your app's APK | |||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn | |||||
android.useAndroidX=true | |||||
# Automatically convert third-party libraries to use AndroidX | |||||
android.enableJetifier=true | |||||
# Kotlin code style for this project: "official" or "obsolete": | |||||
kotlin.code.style=official |
@ -0,0 +1,6 @@ | |||||
#Wed May 20 22:21:07 EET 2020 | |||||
distributionBase=GRADLE_USER_HOME | |||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip | |||||
distributionPath=wrapper/dists | |||||
zipStorePath=wrapper/dists | |||||
zipStoreBase=GRADLE_USER_HOME |
@ -0,0 +1,172 @@ | |||||
#!/usr/bin/env sh | |||||
############################################################################## | |||||
## | |||||
## Gradle start up script for UN*X | |||||
## | |||||
############################################################################## | |||||
# Attempt to set APP_HOME | |||||
# Resolve links: $0 may be a link | |||||
PRG="$0" | |||||
# Need this for relative symlinks. | |||||
while [ -h "$PRG" ] ; do | |||||
ls=`ls -ld "$PRG"` | |||||
link=`expr "$ls" : '.*-> \(.*\)$'` | |||||
if expr "$link" : '/.*' > /dev/null; then | |||||
PRG="$link" | |||||
else | |||||
PRG=`dirname "$PRG"`"/$link" | |||||
fi | |||||
done | |||||
SAVED="`pwd`" | |||||
cd "`dirname \"$PRG\"`/" >/dev/null | |||||
APP_HOME="`pwd -P`" | |||||
cd "$SAVED" >/dev/null | |||||
APP_NAME="Gradle" | |||||
APP_BASE_NAME=`basename "$0"` | |||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |||||
DEFAULT_JVM_OPTS="" | |||||
# Use the maximum available, or set MAX_FD != -1 to use that value. | |||||
MAX_FD="maximum" | |||||
warn () { | |||||
echo "$*" | |||||
} | |||||
die () { | |||||
echo | |||||
echo "$*" | |||||
echo | |||||
exit 1 | |||||
} | |||||
# OS specific support (must be 'true' or 'false'). | |||||
cygwin=false | |||||
msys=false | |||||
darwin=false | |||||
nonstop=false | |||||
case "`uname`" in | |||||
CYGWIN* ) | |||||
cygwin=true | |||||
;; | |||||
Darwin* ) | |||||
darwin=true | |||||
;; | |||||
MINGW* ) | |||||
msys=true | |||||
;; | |||||
NONSTOP* ) | |||||
nonstop=true | |||||
;; | |||||
esac | |||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | |||||
# Determine the Java command to use to start the JVM. | |||||
if [ -n "$JAVA_HOME" ] ; then | |||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | |||||
# IBM's JDK on AIX uses strange locations for the executables | |||||
JAVACMD="$JAVA_HOME/jre/sh/java" | |||||
else | |||||
JAVACMD="$JAVA_HOME/bin/java" | |||||
fi | |||||
if [ ! -x "$JAVACMD" ] ; then | |||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | |||||
Please set the JAVA_HOME variable in your environment to match the | |||||
location of your Java installation." | |||||
fi | |||||
else | |||||
JAVACMD="java" | |||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |||||
Please set the JAVA_HOME variable in your environment to match the | |||||
location of your Java installation." | |||||
fi | |||||
# Increase the maximum file descriptors if we can. | |||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then | |||||
MAX_FD_LIMIT=`ulimit -H -n` | |||||
if [ $? -eq 0 ] ; then | |||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | |||||
MAX_FD="$MAX_FD_LIMIT" | |||||
fi | |||||
ulimit -n $MAX_FD | |||||
if [ $? -ne 0 ] ; then | |||||
warn "Could not set maximum file descriptor limit: $MAX_FD" | |||||
fi | |||||
else | |||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | |||||
fi | |||||
fi | |||||
# For Darwin, add options to specify how the application appears in the dock | |||||
if $darwin; then | |||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | |||||
fi | |||||
# For Cygwin, switch paths to Windows format before running java | |||||
if $cygwin ; then | |||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"` | |||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | |||||
JAVACMD=`cygpath --unix "$JAVACMD"` | |||||
# We build the pattern for arguments to be converted via cygpath | |||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | |||||
SEP="" | |||||
for dir in $ROOTDIRSRAW ; do | |||||
ROOTDIRS="$ROOTDIRS$SEP$dir" | |||||
SEP="|" | |||||
done | |||||
OURCYGPATTERN="(^($ROOTDIRS))" | |||||
# Add a user-defined pattern to the cygpath arguments | |||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then | |||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | |||||
fi | |||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh | |||||
i=0 | |||||
for arg in "$@" ; do | |||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | |||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | |||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | |||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | |||||
else | |||||
eval `echo args$i`="\"$arg\"" | |||||
fi | |||||
i=$((i+1)) | |||||
done | |||||
case $i in | |||||
(0) set -- ;; | |||||
(1) set -- "$args0" ;; | |||||
(2) set -- "$args0" "$args1" ;; | |||||
(3) set -- "$args0" "$args1" "$args2" ;; | |||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;; | |||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | |||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | |||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | |||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | |||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | |||||
esac | |||||
fi | |||||
# Escape application args | |||||
save () { | |||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | |||||
echo " " | |||||
} | |||||
APP_ARGS=$(save "$@") | |||||
# Collect all arguments for the java command, following the shell quoting and substitution rules | |||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | |||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong | |||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then | |||||
cd "$(dirname "$0")" | |||||
fi | |||||
exec "$JAVACMD" "$@" |
@ -0,0 +1,84 @@ | |||||
@if "%DEBUG%" == "" @echo off | |||||
@rem ########################################################################## | |||||
@rem | |||||
@rem Gradle startup script for Windows | |||||
@rem | |||||
@rem ########################################################################## | |||||
@rem Set local scope for the variables with windows NT shell | |||||
if "%OS%"=="Windows_NT" setlocal | |||||
set DIRNAME=%~dp0 | |||||
if "%DIRNAME%" == "" set DIRNAME=. | |||||
set APP_BASE_NAME=%~n0 | |||||
set APP_HOME=%DIRNAME% | |||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |||||
set DEFAULT_JVM_OPTS= | |||||
@rem Find java.exe | |||||
if defined JAVA_HOME goto findJavaFromJavaHome | |||||
set JAVA_EXE=java.exe | |||||
%JAVA_EXE% -version >NUL 2>&1 | |||||
if "%ERRORLEVEL%" == "0" goto init | |||||
echo. | |||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |||||
echo. | |||||
echo Please set the JAVA_HOME variable in your environment to match the | |||||
echo location of your Java installation. | |||||
goto fail | |||||
:findJavaFromJavaHome | |||||
set JAVA_HOME=%JAVA_HOME:"=% | |||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe | |||||
if exist "%JAVA_EXE%" goto init | |||||
echo. | |||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | |||||
echo. | |||||
echo Please set the JAVA_HOME variable in your environment to match the | |||||
echo location of your Java installation. | |||||
goto fail | |||||
:init | |||||
@rem Get command-line arguments, handling Windows variants | |||||
if not "%OS%" == "Windows_NT" goto win9xME_args | |||||
:win9xME_args | |||||
@rem Slurp the command line arguments. | |||||
set CMD_LINE_ARGS= | |||||
set _SKIP=2 | |||||
:win9xME_args_slurp | |||||
if "x%~1" == "x" goto execute | |||||
set CMD_LINE_ARGS=%* | |||||
:execute | |||||
@rem Setup the command line | |||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | |||||
@rem Execute Gradle | |||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | |||||
:end | |||||
@rem End local scope for the variables with windows NT shell | |||||
if "%ERRORLEVEL%"=="0" goto mainEnd | |||||
:fail | |||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | |||||
rem the _cmd.exe /c_ return code! | |||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | |||||
exit /b 1 | |||||
:mainEnd | |||||
if "%OS%"=="Windows_NT" endlocal | |||||
:omega |
@ -0,0 +1,2 @@ | |||||
include ':app' | |||||
rootProject.name='Yeet Clock' |
@ -0,0 +1,7 @@ | |||||
void setup{ | |||||
} | |||||
void loop{ | |||||
} |
@ -0,0 +1,309 @@ | |||||
#include <ESP8266WiFi.h> | |||||
#include <WiFiClient.h> | |||||
#include <ESP8266WebServer.h> | |||||
#include <EEPROM.h> | |||||
#include <ArduinoJson.h> | |||||
#include <NTPClient.h> | |||||
#include <WiFiUdp.h> | |||||
#include <SPI.h> | |||||
#include <Wire.h> | |||||
#include <Adafruit_GFX.h> | |||||
#include <Adafruit_SSD1306.h> | |||||
#include "tetris.h" | |||||
#include "secrets.h" | |||||
#define SCREEN_WIDTH 128 | |||||
#define SCREEN_HEIGHT 64 | |||||
#define OLED_RESET -1 | |||||
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); | |||||
ESP8266WebServer server(80); //Server on port 80 | |||||
WiFiUDP ntpUDP; | |||||
NTPClient timeClient(ntpUDP, "asia.pool.ntp.org", 10800); | |||||
char daysOfTheWeek[7][12] = { "Sunday","Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; | |||||
int days[7]; | |||||
int alarm; | |||||
int counter = 0; | |||||
bool reading_light = false; | |||||
int RGB[4] = {0,0,0,0}; | |||||
unsigned long previousMillis = 0; | |||||
int day_prev = -1; | |||||
bool alarm_ran = false; | |||||
// ESP8266 Network Variables | |||||
IPAddress staticIP(192, 168, 1, 4); | |||||
IPAddress gateway(192, 168, 1, 1); | |||||
IPAddress subnet(255, 255, 255, 0); | |||||
IPAddress dns(8, 8, 8, 8); | |||||
const char* deviceName = "yeetclock.xyz"; | |||||
void setup() { | |||||
// Set Pins | |||||
pinMode(14,OUTPUT); | |||||
pinMode(13,OUTPUT); | |||||
digitalWrite(13,LOW); | |||||
pinMode(15,OUTPUT); | |||||
pinMode(0,OUTPUT); | |||||
pinMode(2,OUTPUT); | |||||
// Start WiFi | |||||
WiFi.hostname(deviceName); | |||||
WiFi.config(staticIP, subnet, gateway, dns); | |||||
WiFi.begin(ssid, password); | |||||
Serial.begin(9600); // Start serial connection (Baudrate 9600) | |||||
while (WiFi.status() != WL_CONNECTED) { // Halt the program until WiFi connects | |||||
delay(500); | |||||
Serial.println("Waiting to connect…"); | |||||
} | |||||
Serial.print("IP address: "); // Print IP | |||||
Serial.println(WiFi.localIP()); | |||||
// Server settings | |||||
server.on("/setcolor", setColor); | |||||
server.on("/getcolor", getColor); | |||||
server.on("/setalarm", setAlarm); | |||||
server.on("/getalarm", getAlarm); | |||||
server.on("/getreading", getReadingLight); | |||||
server.on("/togglereading", toggleReadingLight); | |||||
server.on("/geteeprom", geteeprom); | |||||
server.on("/tone", playTone); | |||||
server.begin(); // Server begin | |||||
timeClient.begin(); // Start UDP time client | |||||
EEPROM.begin(16); // Start EEPROM with 16 bytes of space | |||||
alarm = read_alarm_time(); // Save alarm days & time to memory from EEPROM | |||||
read_alarm_date(days); | |||||
Serial.println("test"); // ESP8266 gives errors without this line idk why | |||||
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Test i2c connection | |||||
Serial.println(F("SSD1306 allocation failed")); | |||||
} | |||||
timeClient.update(); // Sync with time server | |||||
Serial.println("test2"); // Again, gives errors idk why | |||||
} | |||||
int bits_to_int(int bits[64]){ // Converts a binary integer to decimal int (Used to store the days that alarm is enabled) | |||||
int num; | |||||
for(int i=0;i<64;i++){ | |||||
num += pow(2,i)*bits[i]; | |||||
} | |||||
return num; | |||||
} | |||||
int read_alarm_time(){ // Reads alarm time from memory (ESP8266 gives errors without the debug lines) | |||||
int h = EEPROM.read(0); // Get h,m,s from eeprom | |||||
int m = EEPROM.read(5); | |||||
int s = EEPROM.read(7); | |||||
int alarm = 0; | |||||
Serial.println("\naaa"); | |||||
Serial.println(h); | |||||
Serial.println("bbb"); | |||||
Serial.println(m); | |||||
Serial.println("ccc"); | |||||
Serial.println(s); | |||||
alarm += h*3600; | |||||
alarm += m*60; | |||||
alarm += s; | |||||
return alarm; | |||||
} | |||||
void read_alarm_date(int days[]){ | |||||
int day_int; | |||||
day_int = EEPROM.read(10); | |||||
decimal_to_binary(day_int,days); | |||||
} | |||||
void decimal_to_binary(int decimal, int binary[]){ | |||||
int result = decimal; | |||||
Serial.print("Date decimal: "); | |||||
Serial.println(decimal); | |||||
int binary_length = 0; | |||||
for(int i=0; result>0; i++) { | |||||
binary_length += 1; | |||||
binary[i]=result%2; | |||||
result= result/2; | |||||
} | |||||
while(binary_length<7){ | |||||
binary[binary_length] = 0; | |||||
binary_length += 1; | |||||
} | |||||
} | |||||
void playTone(){ | |||||
double duration; | |||||
double freq; | |||||
for (int i = 0; i < server.args(); i++) { | |||||
if(server.argName(i) == "duration"){ | |||||
duration=server.arg(i).toDouble(); | |||||
} | |||||
if(server.argName(i) == "freq"){ | |||||
freq=server.arg(i).toDouble(); | |||||
} | |||||
} | |||||
tone(15,freq,duration*1000); | |||||
server.send(200, "text/plain", "OK"); | |||||
} | |||||
void setColor(){ | |||||
bool ON; | |||||
for (int i = 0; i < server.args(); i++) { | |||||
switch(server.argName(i).charAt(0)){ | |||||
case 'R': | |||||
analogWrite(0,server.arg(i).toInt()); | |||||
RGB[0] = server.arg(i).toInt(); | |||||
case 'G': | |||||
analogWrite(2,server.arg(i).toInt()); | |||||
RGB[1] = server.arg(i).toInt(); | |||||
case 'B': | |||||
analogWrite(14,server.arg(i).toInt()); | |||||
RGB[2] = server.arg(i).toInt(); | |||||
case 'O': | |||||
ON = server.arg(i).toInt(); | |||||
RGB[3] = server.arg(i).toInt(); | |||||
} | |||||
} | |||||
if(!ON){ | |||||
Serial.println("OFF"); | |||||
analogWrite(14,0); | |||||
analogWrite(0,0); | |||||
analogWrite(2,0); | |||||
} | |||||
server.send(200, "text/plain", "OK"); //Response to the HTTP request | |||||
} | |||||
void print_arr(int arr[],int size, String name){ | |||||
Serial.println("SHOWING ARRAY " + name); | |||||
for(int i=0;i<size;i++){ | |||||
Serial.println(arr[i]); | |||||
} | |||||
Serial.println("DONE"); | |||||
} | |||||
void setAlarm(){ | |||||
for (int i = 0; i < server.args(); i++) { | |||||
if(server.argName(i)=="time"){ | |||||
alarm = server.arg(i).toInt(); | |||||
int h = floor(alarm/3600); | |||||
int m = floor((alarm%3600)/60); | |||||
int s = alarm%60; | |||||
EEPROM.put(0,h); | |||||
EEPROM.commit(); | |||||
EEPROM.put(5,m); | |||||
EEPROM.commit(); | |||||
EEPROM.put(7,s); | |||||
EEPROM.commit(); | |||||
} | |||||
if(server.argName(i)=="days"){ | |||||
EEPROM.put(10,server.arg(i).toInt()); | |||||
} | |||||
} | |||||
EEPROM.commit(); | |||||
server.send(200,"text/plain","OK"); | |||||
} | |||||
void toggleReadingLight(){ | |||||
digitalWrite(13,!reading_light); | |||||
reading_light = !reading_light; | |||||
server.send(200,"text/plain","OK"); | |||||
} | |||||
void getReadingLight(){ | |||||
if(reading_light){ | |||||
server.send(200,"text/plain","ON"); | |||||
} else{ | |||||
server.send(200,"text/plain","OFF"); | |||||
} | |||||
} | |||||
void getAlarm(){ | |||||
int days[7]; | |||||
read_alarm_date(days); | |||||
int time = read_alarm_time(); | |||||
String response = "{\"days\":{"; | |||||
for(int i=0;i<7;i++){ | |||||
response += String(days[i]); | |||||
if(i != 6){ | |||||
response += ","; | |||||
} | |||||
} | |||||
response += "],\"time\":\""; | |||||
response += String(time) + "\"}"; | |||||
server.send(200,"application/json",response); | |||||
} | |||||
void getColor(){ | |||||
server.send(200, "application/json","{\"RGB\":[" + String(RGB[0]) + "," + String(RGB[1]) + "," + String(RGB[2]) + "], \"ON\":" + String(RGB[3]) + "}"); | |||||
} | |||||
void show_time(String time, String day){ | |||||
display.clearDisplay(); | |||||
display.setCursor(0,0); | |||||
display.setTextSize(2); | |||||
display.setTextColor(WHITE); | |||||
display.setCursor(16,0); | |||||
display.println(time); | |||||
display.setCursor(18,24); | |||||
display.println(day); | |||||
display.setTextSize(1); | |||||
display.setFont(); | |||||
display.setTextColor(WHITE); | |||||
display.setCursor(32,48); | |||||
display.println(WiFi.localIP()); | |||||
display.display(); | |||||
} | |||||
void geteeprom(){ | |||||
int data; | |||||
data = EEPROM.read(server.arg(0).toInt()); | |||||
server.send(200, "application/text",String(data)); | |||||
} | |||||
void loop() { | |||||
unsigned long currentMillis = millis(); | |||||
if (currentMillis - previousMillis >= 1000) { | |||||
int day = timeClient.getDay(); | |||||
if(day!=day_prev){ | |||||
day_prev = day; | |||||
alarm_ran=false; | |||||
} | |||||
previousMillis = currentMillis; | |||||
if(counter==300){ | |||||
counter=0; | |||||
Serial.println("test3"); | |||||
timeClient.update(); | |||||
Serial.println("test4"); | |||||
} | |||||
show_time(timeClient.getFormattedTime(),daysOfTheWeek[timeClient.getDay()]); | |||||
int time = timeClient.getHours()*3600 + timeClient.getMinutes()*60 + timeClient.getSeconds(); | |||||
Serial.println("TIME"); | |||||
Serial.println(time); | |||||
Serial.println(alarm); | |||||
Serial.println(timeClient.getDay()); | |||||
if (time > alarm && days[timeClient.getDay()] && !alarm_ran){ | |||||
alarm_ran = true; | |||||
analogWrite(0,255); | |||||
analogWrite(2,255); | |||||
analogWrite(14,255); | |||||
Serial.println("ALARM"); | |||||
playTetris(); | |||||
analogWrite(0,0); | |||||
analogWrite(2,0); | |||||
analogWrite(14,0); | |||||
} | |||||
counter += 1; | |||||
} | |||||
server.handleClient(); | |||||
} |
@ -0,0 +1,90 @@ | |||||
#define NOTE_B0 31 | |||||
#define NOTE_C1 33 | |||||
#define NOTE_CS1 35 | |||||
#define NOTE_D1 37 | |||||
#define NOTE_DS1 39 | |||||
#define NOTE_E1 41 | |||||
#define NOTE_F1 44 | |||||
#define NOTE_FS1 46 | |||||
#define NOTE_G1 49 | |||||
#define NOTE_GS1 52 | |||||
#define NOTE_A1 55 | |||||
#define NOTE_AS1 58 | |||||
#define NOTE_B1 62 | |||||
#define NOTE_C2 65 | |||||
#define NOTE_CS2 69 | |||||
#define NOTE_D2 73 | |||||
#define NOTE_DS2 78 | |||||
#define NOTE_E2 82 | |||||
#define NOTE_F2 87 | |||||
#define NOTE_FS2 93 | |||||
#define NOTE_G2 98 | |||||
#define NOTE_GS2 104 | |||||
#define NOTE_A2 110 | |||||
#define NOTE_AS2 117 | |||||
#define NOTE_B2 123 | |||||
#define NOTE_C3 131 | |||||
#define NOTE_CS3 139 | |||||
#define NOTE_D3 147 | |||||
#define NOTE_DS3 156 | |||||
#define NOTE_E3 165 | |||||
#define NOTE_F3 175 | |||||
#define NOTE_FS3 185 | |||||
#define NOTE_G3 196 | |||||
#define NOTE_GS3 208 | |||||
#define NOTE_A3 220 | |||||
#define NOTE_AS3 233 | |||||
#define NOTE_B3 247 | |||||
#define NOTE_C4 262 | |||||
#define NOTE_CS4 277 | |||||
#define NOTE_D4 294 | |||||
#define NOTE_DS4 311 | |||||
#define NOTE_E4 330 | |||||
#define NOTE_F4 349 | |||||
#define NOTE_FS4 370 | |||||
#define NOTE_G4 392 | |||||
#define NOTE_GS4 415 | |||||
#define NOTE_A4 440 | |||||
#define NOTE_AS4 466 | |||||
#define NOTE_B4 494 | |||||
#define NOTE_C5 523 | |||||
#define NOTE_CS5 554 | |||||
#define NOTE_D5 587 | |||||
#define NOTE_DS5 622 | |||||
#define NOTE_E5 659 | |||||
#define NOTE_F5 698 | |||||
#define NOTE_FS5 740 | |||||
#define NOTE_G5 784 | |||||
#define NOTE_GS5 831 | |||||
#define NOTE_A5 880 | |||||
#define NOTE_AS5 932 | |||||
#define NOTE_B5 988 | |||||
#define NOTE_C6 1047 | |||||
#define NOTE_CS6 1109 | |||||
#define NOTE_D6 1175 | |||||
#define NOTE_DS6 1245 | |||||
#define NOTE_E6 1319 | |||||
#define NOTE_F6 1397 | |||||
#define NOTE_FS6 1480 | |||||
#define NOTE_G6 1568 | |||||
#define NOTE_GS6 1661 | |||||
#define NOTE_A6 1760 | |||||
#define NOTE_AS6 1865 | |||||
#define NOTE_B6 1976 | |||||
#define NOTE_C7 2093 | |||||
#define NOTE_CS7 2217 | |||||
#define NOTE_D7 2349 | |||||
#define NOTE_DS7 2489 | |||||
#define NOTE_E7 2637 | |||||
#define NOTE_F7 2794 | |||||
#define NOTE_FS7 2960 | |||||
#define NOTE_G7 3136 | |||||
#define NOTE_GS7 3322 | |||||
#define NOTE_A7 3520 | |||||
#define NOTE_AS7 3729 | |||||
#define NOTE_B7 3951 | |||||
#define NOTE_C8 4186 | |||||
#define NOTE_CS8 4435 | |||||
#define NOTE_D8 4699 | |||||
#define NOTE_DS8 4978 | |||||
#define REST 0 |
@ -0,0 +1,50 @@ | |||||
#include "notes.h" | |||||
int tempo=144; | |||||
int melody[] = { | |||||
NOTE_E5, 4, NOTE_B4,8, NOTE_C5,8, NOTE_D5,4, NOTE_C5,8, NOTE_B4,8, | |||||
NOTE_A4, 4, NOTE_A4,8, NOTE_C5,8, NOTE_E5,4, NOTE_D5,8, NOTE_C5,8, | |||||
NOTE_B4, -4, NOTE_C5,8, NOTE_D5,4, NOTE_E5,4, | |||||
NOTE_C5, 4, NOTE_A4,4, NOTE_A4,8, NOTE_A4,4, NOTE_B4,8, NOTE_C5,8, | |||||
NOTE_D5, -4, NOTE_F5,8, NOTE_A5,4, NOTE_G5,8, NOTE_F5,8, | |||||
NOTE_E5, -4, NOTE_C5,8, NOTE_E5,4, NOTE_D5,8, NOTE_C5,8, | |||||
NOTE_B4, 4, NOTE_B4,8, NOTE_C5,8, NOTE_D5,4, NOTE_E5,4, | |||||
NOTE_C5, 4, NOTE_A4,4, NOTE_A4,4, REST, 4, | |||||
NOTE_E5, 4, NOTE_B4,8, NOTE_C5,8, NOTE_D5,4, NOTE_C5,8, NOTE_B4,8, | |||||
NOTE_A4, 4, NOTE_A4,8, NOTE_C5,8, NOTE_E5,4, NOTE_D5,8, NOTE_C5,8, | |||||
NOTE_B4, -4, NOTE_C5,8, NOTE_D5,4, NOTE_E5,4, | |||||
NOTE_C5, 4, NOTE_A4,4, NOTE_A4,8, NOTE_A4,4, NOTE_B4,8, NOTE_C5,8, | |||||
NOTE_D5, -4, NOTE_F5,8, NOTE_A5,4, NOTE_G5,8, NOTE_F5,8, | |||||
NOTE_E5, -4, NOTE_C5,8, NOTE_E5,4, NOTE_D5,8, NOTE_C5,8, | |||||
NOTE_B4, 4, NOTE_B4,8, NOTE_C5,8, NOTE_D5,4, NOTE_E5,4, | |||||
NOTE_C5, 4, NOTE_A4,4, NOTE_A4,4, REST, 4, | |||||
NOTE_E5,2, NOTE_C5,2, | |||||
NOTE_D5,2, NOTE_B4,2, | |||||
NOTE_C5,2, NOTE_A4,2, | |||||
NOTE_GS4,2, NOTE_B4,4, REST,8, | |||||
NOTE_E5,2, NOTE_C5,2, | |||||
NOTE_D5,2, NOTE_B4,2, | |||||
NOTE_C5,4, NOTE_E5,4, NOTE_A5,2, | |||||
NOTE_GS5,2, | |||||
}; | |||||
int notes=sizeof(melody)/sizeof(melody[0])/2; | |||||
int wholenote = (60000 * 4) / tempo; | |||||
int divider = 0, noteDuration = 0; | |||||
void playTetris(){ | |||||
for (int thisNote = 0; thisNote < notes * 2; thisNote = thisNote + 2) { | |||||
divider = melody[thisNote + 1]; | |||||
if (divider > 0) { | |||||
noteDuration = (wholenote) / divider; | |||||
} else if (divider < 0) { | |||||
noteDuration = (wholenote) / abs(divider); | |||||
noteDuration *= 1.5; | |||||
} | |||||
tone(15, melody[thisNote], noteDuration*0.9); | |||||
delay(noteDuration); | |||||
noTone(15); | |||||
} | |||||
} |