148 Commits

Author SHA1 Message Date
Senad Uka
7906e5a1a0 sms contains controller id 2016-12-30 17:22:51 +01:00
Senad Uka
db8def7235 sms sent every time 2016-12-30 17:18:04 +01:00
Senad Uka
c51755b96a log shows only temperatures 2016-12-30 17:14:08 +01:00
Senad Uka
f52bcbeb14 Merge pull request #34 from senaduka/farm_alarm
Farm alarm
2016-12-30 16:31:21 +01:00
Senad Uka
f579dabbcb alarm ignores network 2016-12-30 16:30:29 +01:00
Senad Uka
3eae1c71b7 farm alarm package rename 2016-12-30 16:30:29 +01:00
Senad Uka
d417dfaf04 Merge pull request #33 from senaduka/multiple_cameras_support
- added support for 2 cameras, changes in /controller/config/__init__.py
2016-12-28 14:34:17 +01:00
5074bc4903 - added support for 2 cameras, changes in /controller/config/__init__.py
- since this creates a new, merged image an additional tool named "imagemagick" is needed, see README.md
2016-12-28 14:27:56 +01:00
9b80df491f Update README.md 2016-12-28 13:04:46 +01:00
Senad Uka
4998a850e1 Merge pull request #32 from senaduka/fix_w1_thermo_readings
- added boundaries while reading w1 thermo sensor (-30 to +60 C)
2016-12-25 11:55:27 +01:00
2f86df4343 - added boundaries while reading w1 thermo sensor (-30 to +60 C)
- added (commented out) log entries - if needed uncomment them!
2016-12-25 11:08:48 +01:00
Senad Uka
f85b358b43 Merge pull request #31 from senaduka/fix_w1_thermo_readings
fixed w1 thermosensor reading algorithm in means of adding a loop and…
2016-12-19 09:47:01 +01:00
e3d6dc26dd fixed w1 thermosensor reading algorithm in means of adding a loop and CRC check 2016-12-19 09:13:43 +01:00
68161a3283 Update README.md 2016-12-18 21:10:17 +01:00
9fbb32b23f Update README.md 2016-12-18 21:04:12 +01:00
2ad03ff3ea Update README.md 2016-12-18 21:00:39 +01:00
3204debac8 hardware watchdog instructions 2016-11-28 16:04:52 +01:00
3f503fd622 Update README.md 2016-11-28 09:27:34 +01:00
c8392edf10 updated vpn settings 2016-11-28 09:26:44 +01:00
Senad Uka
00cdb541e3 Merge pull request #30 from senaduka/farm_alarm
apk
2016-11-19 11:37:46 +01:00
Senad Uka
8efae48345 apk 2016-11-19 11:06:54 +01:00
9d9b0e6464 Merge pull request #29 from senaduka/farm_alarm
Farm alarm
2016-11-19 11:06:52 +01:00
Senad Uka
1df732061f fixed bug with reasons 2016-11-19 08:39:36 +01:00
Senad Uka
d5d4ba872d reasons 2016-11-19 08:34:48 +01:00
Senad Uka
d17fd8f940 launcher icon / sms / manager on boot 2016-11-19 08:03:54 +01:00
Senad Uka
f937f0ac2c hiding controller id chooser 2016-11-19 05:03:50 +01:00
Senad Uka
3af4a6d24a android client almost ready 2016-11-18 08:33:46 +01:00
Senad Uka
cbeaf566b7 modified api and methods 2016-11-16 14:03:03 +01:00
Senad Uka
cb32e1a9f7 phone ping api flattened 2016-11-15 14:55:36 +01:00
Senad Uka
551471579f phone ping change 2016-11-14 15:53:35 +01:00
Senad Uka
85a7d6a72f modified phoneping 2016-11-14 15:15:03 +01:00
Senad Uka
ce71854ab1 added publication 2016-11-14 14:24:37 +01:00
1e8fb6ae78 Merge pull request #28 from senaduka/farm_alarm
Farm alarm
2016-10-30 09:04:59 +01:00
Senad Uka
319c0b6906 sms on every alarm 2016-10-30 08:48:57 +01:00
Senad Uka
ab309deb7e android app work in progress - added notification 2016-10-30 08:48:57 +01:00
Senad Uka
161aa72965 android app work in progress 2016-10-30 08:48:57 +01:00
Senad Uka
fd590daecf -100 for nonexistent sensor 2016-10-30 08:48:57 +01:00
Senad Uka
f93f1cbe13 fixed python 2016-10-30 08:48:33 +01:00
Senad Uka
16bf8c8f3e reading onewire sensors now works 2016-10-30 08:47:50 +01:00
Senad Uka
971ca889fc fixed router bug 2016-10-30 08:47:50 +01:00
Senad Uka
a8e37f2f48 reading onewire sensors 2016-10-30 08:47:50 +01:00
Senad Uka
7afe902f3f server side done 2016-10-30 08:45:53 +01:00
Senad Uka
d92e208221 alarm triggering / silencing works 2016-10-30 08:45:53 +01:00
Senad Uka
6108d75074 saving and temperature works 2016-10-30 08:45:53 +01:00
Senad Uka
31b355f381 ui and settings ready 2016-10-30 08:45:53 +01:00
a85be6c2b6 removed / at the end of PICTURE_URL 2016-10-09 00:27:49 +02:00
b6bb408abb set ip address to default 192.168.1.10 2016-10-08 23:51:54 +02:00
d770d11054 Update README.md 2016-10-08 23:30:58 +02:00
bfc1680a18 Update README.md 2016-10-08 22:18:37 +02:00
93625f6a5f Update README.md 2016-10-08 22:16:57 +02:00
58e31ddf6f Update README.md 2016-10-08 22:15:50 +02:00
36f8026713 */1 * * * * /usr/bin/python /home/pi/projects/tfm/controller/camera_send.py moved to activity.sh 2016-10-08 21:43:20 +02:00
1c22267069 Update README.md 2016-10-08 21:42:13 +02:00
bfb6634a76 capture and send to get a fresh image 2016-10-08 21:41:49 +02:00
7dc6519ca9 Update README.md 2016-10-08 21:23:22 +02:00
f67a1d34f1 Merge pull request #27 from senaduka/adding_images
Adding images
2016-10-08 18:50:33 +02:00
Senad Uka
314ea49eaa readme update 2016-10-08 18:48:19 +02:00
Senad Uka
980e35fd96 problems with camera not sending 2016-10-08 18:34:53 +02:00
Senad Uka
2da669b061 problems with state fixed 2016-10-08 18:29:52 +02:00
Senad Uka
5c58f9f28d problems with state 2016-10-08 18:26:11 +02:00
Senad Uka
761b67003b problems with state 2016-10-08 18:20:50 +02:00
Senad Uka
625d9f47ad problems with sending 2016-10-08 17:32:21 +02:00
Senad Uka
1ab87ca08d problems with sending 2016-10-08 17:16:36 +02:00
Senad Uka
45114ee10b syntax errors 2016-10-08 17:09:40 +02:00
Senad Uka
d74135e18f syntax errors 2016-10-08 16:59:22 +02:00
Senad Uka
aff83d948a zoblak logo 2016-10-08 16:55:15 +02:00
Senad Uka
10b5aa4946 fix syntax errors 2016-10-08 16:51:12 +02:00
Senad Uka
7aa9abc2fc fix syntax errors 2016-10-08 16:43:12 +02:00
Senad Uka
d06f991610 fix syntax errors 2016-10-08 16:39:14 +02:00
Senad Uka
4c1f3f9f43 picture controller scripts ready 2016-10-08 16:32:48 +02:00
Senad Uka
7c8863c214 picture sending scripts ready 2016-10-08 16:27:05 +02:00
Senad Uka
4b2b9526de picture display ready 2016-10-08 16:02:59 +02:00
Senad Uka
d469c91e3e picture api ready 2016-10-08 14:57:37 +02:00
Senad Uka
317fdb93ed picture client side ready 2016-10-01 17:01:37 +02:00
a594cc05d0 Merge pull request #26 from senaduka/manual_pump_control
manual override for pump
2016-07-02 10:19:57 +02:00
Senad Uka
656dee3fe6 manual override for pump 2016-07-02 10:18:18 +02:00
Senad Uka
d94ae908f4 Merge pull request #25 from senaduka/optional_temp_and_humid_print_water_level
fixed a bug in rendering the correct picture, due to changes of multi…
2016-06-19 14:12:45 +02:00
66442bf4de fixed a bug in rendering the correct picture, due to changes of multiple levels 2016-06-19 00:59:25 +02:00
Senad Uka
96bd7c2a8c Merge pull request #24 from senaduka/optional_temp_and_humid_print_water_level
temp humidity optional, water level printing
2016-06-12 13:57:56 +02:00
78f052a664 - failed temp and humidity reading wont prevent data sending
- printing of water level
2016-06-12 12:03:19 +02:00
Senad Uka
8fc028aaab fixed duplicate controller folder 2016-06-11 18:56:47 +02:00
Senad Uka
cc7aebc6f9 Merge pull request #23 from senaduka/config_pumping_levels_and_draining_period
Config pumping levels and draining period
2016-06-10 10:01:39 +02:00
e5d4c820d6 set both start and stop pumping levels by default to full 2016-06-09 21:56:26 +02:00
cfd7d677dd deleted draining period and amount from config file as this does not work like i thought it would 2016-06-09 20:56:42 +02:00
4872f4a910 expanded the water levels to be used to configure pumping levels and moved the water draining period to config file 2016-06-09 20:07:38 +02:00
Senad Uka
5c1f1629e7 Update __init__.py
removing canceling shutdown
2016-06-08 18:50:32 +02:00
46af39c7af Update README.md
changed the crontab info in means of changing
*/15 * * * * /usr/bin/python /home/pi/projects/tfm/controller/sensors.py "Automatski, Senad Uka" 120
*/1 * * * * /usr/bin/python /home/pi/projects/tfm/controller/sync_state.py "Automatski, Senad Uka" 120
to 
*/5 * * * * cd /home/pi/projects/tfm/controller && sh activity.sh
2016-06-08 13:18:08 +02:00
bcb84e4400 Update copy__init__.py.example 2016-06-08 13:12:36 +02:00
79651cb6af Merge pull request #22 from senaduka/local_safe_autonomy
Local safe autonomy
2016-06-08 11:15:04 +02:00
Senad Uka
bffab2bf26 Merge pull request #17 from senaduka/shell_script_to_unify_activities
created activity.sh to unify all activities in a specific order
2016-06-08 11:14:33 +02:00
Senad Uka
718968f57d readme 2016-06-08 10:45:32 +02:00
Senad Uka
f1d7232c10 network check script 2016-06-08 10:34:05 +02:00
Senad Uka
fec689a5bc dweet fix again 2016-06-08 10:03:17 +02:00
Senad Uka
533135013b dweet fix again 2016-06-08 10:01:55 +02:00
Senad Uka
e0e0f0d24c dweet fix 2016-06-08 09:48:36 +02:00
Senad Uka
b30af162a1 reboot time 2016-06-08 09:38:54 +02:00
Senad Uka
c11e6b29b1 dweet exception 2016-06-08 09:31:51 +02:00
Senad Uka
d2a2fae936 dweet source code 2016-06-08 09:30:06 +02:00
Senad Uka
a12a218e85 reboot canceling 2016-06-08 09:28:42 +02:00
Senad Uka
f8a8284944 added dweet and reboot 2016-06-08 09:16:44 +02:00
Senad Uka
f9defb8e2a fixed syntax error 4 2016-06-08 08:39:31 +02:00
Senad Uka
5ae36641a2 fixed syntax error 3 2016-06-08 08:31:58 +02:00
Senad Uka
62f9cabb83 fixed syntax error 2 2016-06-08 08:31:42 +02:00
Senad Uka
91027c5330 fixed syntax error 2016-06-08 08:28:48 +02:00
Senad Uka
7d434625ca Local autonomy test 1 2016-06-08 08:24:43 +02:00
Senad Uka
61bb6d0d4b Merge pull request #21 from senaduka/multipleWaterLevelSensors
Multiple level sensors added
2016-06-05 11:14:25 +02:00
1ae13f6fb1 Multiple level sensors added 2016-06-02 23:13:42 +02:00
db843163f2 Merge pull request #20 from senaduka/last_fill_time
Disabled temperature graph
2016-05-17 16:12:53 +02:00
Senad Uka
d2db89ffc0 Disabled temperature graph 2016-05-17 07:05:54 +02:00
336b82be3f Merge pull request #19 from senaduka/last_fill_time
Added last valve open time
2016-05-08 06:06:31 +02:00
Senad Uka
ac76654e2a Added last valve open time 2016-05-08 05:17:12 +02:00
2772baafbc Merge pull request #18 from senaduka/add_low_temperature
Lower temperature forecast
2016-05-02 18:13:22 +02:00
Senad Uka
3e0733bf3d Lower temperature forecast 2016-05-02 18:10:54 +02:00
Senad Uka
d9fa0bf2f5 Calculator done 2016-05-02 15:18:02 +02:00
Senad Uka
abff71ac06 Calculator done 2016-05-02 14:09:09 +02:00
90e43b8bd2 created activity.sh to unify all activities in a specific order 2016-04-23 14:32:31 +00:00
Senad Uka
5a4fdbbd00 reversed logic 2016-04-10 12:11:54 +02:00
Senad Uka
96c67a6d00 gitignore 2016-04-10 11:58:18 +02:00
Senad Uka
3b8fb3dce4 fixed bug with rpio 2016-04-10 11:57:13 +02:00
0b4a886de6 Merge pull request #16 from senaduka/add_weather_again
weather works
2016-04-10 10:56:23 +02:00
Senad Uka
79df9d05b4 weather works 2016-04-10 10:47:11 +02:00
4df30c3523 Merge pull request #15 from senaduka/graph_fixing
FIxed graphs / inverted the tankFull bit!
2016-04-09 09:48:02 +02:00
Senad Uka
f886530f5f upgraded mongo and packages 2016-04-09 07:51:11 +02:00
Senad Uka
98983ea50d FIxed bug with inverted the tankFull bit! 2016-04-09 07:29:24 +02:00
Senad Uka
c947980844 FIxed graphs / inverted the tankFull bit! 2016-04-09 07:11:08 +02:00
974f18e067 Merge pull request #14 from senaduka/pre_production_fixes
Pre production fixes
2016-03-26 10:29:01 +01:00
Senad Uka
534497e373 Fixed filling logic 2016-03-26 07:32:53 +01:00
Senad Uka
26052a9afc Created graphs without d3 ;) 2016-03-26 07:28:43 +01:00
Senad Uka
e9e808a1bc Merge pull request #13 from senaduka/image_vise
- fixed names to match barrell*
2016-03-25 20:19:17 +01:00
4197d06819 - fixed names to match barrell*
- added more tag to images
2016-03-22 21:54:13 +01:00
Senad Uka
36d1adc626 Fixed a typo 2016-03-20 08:00:14 +01:00
Senad Uka
2317ad3e61 Some css modifications 2016-03-20 07:54:20 +01:00
b2e619c2c9 Merge pull request #12 from senaduka/ui_modifications
Ui is completely changed
2016-03-19 09:30:36 +01:00
Senad Uka
748dd19a87 Ui is completely changed 2016-03-19 09:23:59 +01:00
Senad Uka
21d364bf52 Merge pull request #11 from senaduka/improved_icon_handling_and_pump_management
Added 4 new images for opening and closing out valve while barrell is…
2016-03-19 04:33:23 +01:00
5cd8420bcf Added 4 new images for opening and closing out valve while barrell is either full or not full... also tried to add additional constraints for pump handling in means of that the pump should not be pumping if the out valve is open or opening 2016-03-18 22:26:41 +01:00
Senad Uka
24a1b81b92 Merge pull request #10 from senaduka/barrel_image_handling
Added proper barrel image handling based on input / sensor readings
2016-03-13 19:00:51 +01:00
829d6cf338 Added proper barrel image handling based on input / sensor readings 2016-03-09 00:35:26 +01:00
a8ac425832 Merge pull request #9 from senaduka/in_valve_support
In valve support
2016-03-06 21:07:56 +01:00
Senad Uka
d15bc0e5a6 problem with python syntax 2016-03-06 14:49:26 +01:00
Senad Uka
ee828c544e syntax error fix 2016-03-06 14:47:42 +01:00
Senad Uka
28e5f7f1f0 safe key getting from the response 2016-03-06 14:46:42 +01:00
Senad Uka
ed8267b6ab ignore existing config 2016-03-06 14:14:26 +01:00
Senad Uka
99fdc768fc config/init.py removed 2016-03-06 14:13:25 +01:00
Senad Uka
c47e1be364 Finished in valve support 2016-03-06 14:07:33 +01:00
Senad Uka
8d9e42c147 reformatted code 2016-03-06 13:40:53 +01:00
Senad Uka
279e0f8652 Added suport for in valve 2016-03-06 13:40:53 +01:00
2395cc6ddf Merge pull request #8 from senaduka/optimize_subscriptions
Optimized subscriptions
2016-03-06 12:05:48 +01:00
169 changed files with 4046 additions and 360 deletions

7
.gitignore vendored
View File

@@ -1,3 +1,6 @@
# configuration
controller/config/__init__.py
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
@@ -14,7 +17,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
@@ -55,3 +57,6 @@ docs/_build/
# PyBuilder
target/
# meteor
app.tar.gz

8
android/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures

1
android/.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
Farm Alarm

22
android/.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
<entry name="!?*.aj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

View File

@@ -0,0 +1,3 @@
<component name="CopyrightManager">
<settings default="" />
</component>

6
android/.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

24
android/.idea/gradle.xml generated Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-2.14.1" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="myModules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

19
android/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

9
android/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/android.iml" filepath="$PROJECT_DIR$/android.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>
</project>

12
android/.idea/runConfigurations.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

9
android/FarmAlarm/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild

22
android/FarmAlarm/.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
<entry name="!?*.aj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

View File

@@ -0,0 +1,3 @@
<component name="CopyrightManager">
<settings default="" />
</component>

6
android/FarmAlarm/.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

19
android/FarmAlarm/.idea/gradle.xml generated Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-2.14.1" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

46
android/FarmAlarm/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

9
android/FarmAlarm/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/FarmAlarm.iml" filepath="$PROJECT_DIR$/FarmAlarm.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>
</project>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

6
android/FarmAlarm/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>

1
android/FarmAlarm/app/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

Binary file not shown.

View File

@@ -0,0 +1,34 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.1"
defaultConfig {
applicationId "com.zoblak.farm"
minSdkVersion 15
targetSdkVersion 24
versionCode 101
versionName "1.0.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:design:24.2.1'
compile 'com.android.support:support-v4:24.2.1'
compile 'com.android.support:support-vector-drawable:24.2.1'
testCompile 'junit:junit:4.12'
compile 'com.android.volley:volley:1.0.0'
}

View File

@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/senadu/Android/Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# 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 *;
#}

View File

@@ -0,0 +1,26 @@
package com.zoblak.farm;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.zoblak.apps.farmalarm", appContext.getPackageName());
}
}

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zoblak.farm">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="com.zoblak.farm.MainScreen"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="agrar.zoblak.com" />
</intent-filter>
</activity>
<service
android:name="com.zoblak.farm.AlarmPollingService"
android:exported="false" />
<service
android:name="com.zoblak.farm.SoundPlayingService"
android:exported="false" />
<receiver
android:name="com.zoblak.farm.PeriodicalPingReceiver"
android:enabled="true"
android:exported="true" />
<activity
android:name="com.zoblak.farm.SettingsActivity"
android:label="@string/title_activity_settings"
android:parentActivityName="com.zoblak.farm.MainScreen"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.zoblak.farm.MainScreen" />
</activity>
<receiver
android:name="com.zoblak.farm.BootBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@@ -0,0 +1,134 @@
package com.zoblak.farm;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
/**
* Helper class for showing and canceling alarm
* notifications.
* <p>
* This class makes heavy use of the {@link NotificationCompat.Builder} helper
* class to create notifications in a backward-compatible way.
*/
public class AlarmNotification {
/**
* The unique identifier for this type of notification.
*/
private static final String NOTIFICATION_TAG = "Alarm";
/**
* Shows the notification, or updates a previously shown notification of
* this type, with the given parameters.
* <p>
* TODO: Customize this method's arguments to present relevant content in
* the notification.
* <p>
* TODO: Customize the contents of this method to tweak the behavior and
* presentation of alarm notifications. Make
* sure to follow the
* <a href="https://developer.android.com/design/patterns/notifications.html">
* Notification design guidelines</a> when doing so.
*
* @see #cancel(Context)
*/
public static void notify(final Context context,
final String message, final int number) {
final Resources res = context.getResources();
// This image is used as the notification's large icon (thumbnail).
// TODO: Remove this if your notification has no relevant thumbnail.
final Bitmap picture = BitmapFactory.decodeResource(res, R.drawable.ic_stat_zoblak);
final String ticker = message;
final String title = res.getString(
R.string.alarm_notification_title_template, message);
final String text = message;
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
// Set appropriate defaults for the notification light, sound,
// and vibration.
.setDefaults(Notification.DEFAULT_ALL)
// Set required fields, including the small icon, the
// notification title, and text.
.setSmallIcon(R.drawable.ic_stat_zoblak)
.setContentTitle(title)
.setContentText(text)
// All fields below this line are optional.
// Use a default priority (recognized on devices running Android
// 4.1 or later)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Provide a large icon, shown with the notification in the
// notification drawer on devices running Android 3.0 or later.
.setLargeIcon(picture)
// Set ticker text (preview) information for this notification.
.setTicker(ticker)
// Show a number. This is useful when stacking notifications of
// a single type.
.setNumber(number)
// If this notification relates to a past or upcoming event, you
// should set the relevant time information using the setWhen
// method below. If this call is omitted, the notification's
// timestamp will by set to the time at which it was shown.
// TODO: Call setWhen if this notification relates to a past or
// upcoming event. The sole argument to this method should be
// the notification timestamp in milliseconds.
//.setWhen(...)
// Set the pending intent to be initiated when the user touches
// the notification.
.setContentIntent(
PendingIntent.getActivity(
context,
0,
new Intent(context, MainScreen.class),
PendingIntent.FLAG_UPDATE_CURRENT))
// Automatically dismiss the notification when it is touched.
.setAutoCancel(true);
notify(context, builder.build());
}
@TargetApi(Build.VERSION_CODES.ECLAIR)
private static void notify(final Context context, final Notification notification) {
final NotificationManager nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
nm.notify(NOTIFICATION_TAG, 0, notification);
} else {
nm.notify(NOTIFICATION_TAG.hashCode(), notification);
}
}
/**
* Cancels any notifications of this type previously shown using
* {@link #notify(Context, String, int)}.
*/
@TargetApi(Build.VERSION_CODES.ECLAIR)
public static void cancel(final Context context) {
final NotificationManager nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
nm.cancel(NOTIFICATION_TAG, 0);
} else {
nm.cancel(NOTIFICATION_TAG.hashCode());
}
}
}

View File

@@ -0,0 +1,100 @@
package com.zoblak.farm;
/**
* Created by senadu on 11/15/16.
*/
public class AlarmPingResponse {
private String controller;
public AlarmPingResponse(String controller) {
this.controller = controller;
}
private Boolean alarmTriggered = false;
private Boolean tooHot = false;
private Boolean tooCold = false;
private Boolean boxSilent = false;
private Boolean phoneSilent = false;
private Boolean serverError = false;
public Boolean getAlarmTriggered() {
return alarmTriggered;
}
public void setAlarmTriggered(Boolean alarmTriggered) {
this.alarmTriggered = alarmTriggered;
}
public Boolean getTooHot() {
return tooHot;
}
public void setTooHot(Boolean tooHot) {
this.tooHot = tooHot;
}
public Boolean getTooCold() {
return tooCold;
}
public void setTooCold(Boolean tooCold) {
this.tooCold = tooCold;
}
public Boolean getBoxSilent() {
return boxSilent;
}
public void setBoxSilent(Boolean boxSilent) {
this.boxSilent = boxSilent;
}
public Boolean getPhoneSilent() {
return phoneSilent;
}
public void setPhoneSilent(Boolean phoneSilent) {
this.phoneSilent = phoneSilent;
}
public Boolean getServerError() {
return serverError;
}
public void setServerError(Boolean serverError) {
this.serverError = serverError;
}
public String toNotificationMessage() {
String message = "Sve je OK!";
if(getAlarmTriggered()) {
if (getAlarmTriggered()) {
message = "Alarm pokrenut! ";
}
if (getTooHot()) {
message += "Temperatura previsoka!";
}
if (getTooCold()) {
message += "Temperatura preniska!";
}
if (getBoxSilent()) {
message += "Zoblak kutija se nije javila na vrijeme!";
}
if (getPhoneSilent()) {
message += "Ni jedan telefon se nije javio na vrijeme! ";
}
if (getServerError()) {
message += "Ne radi internet na telefonu! ";
}
}
return message;
}
}

View File

@@ -0,0 +1,74 @@
package com.zoblak.farm;
import android.app.IntentService;
import android.content.Intent;
import android.content.Context;
import android.os.PowerManager;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p>
* TODO: Customize class - update intent actions, extra parameters and static
* helper methods.
*/
public class AlarmPollingService extends IntentService {
// TODO: Rename actions, choose action names that describe tasks that this
// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
private static final String ACTION_PING = "com.zoblak.apps.farmalarm.action.PING";
private static final String ACTION_STOP_ALARM = "com.zoblak.apps.farmalarm.action.STOP_ALARM";
// TODO: Rename parameters
private static final String CONTROLLERS = "com.zoblak.apps.farmalarm.extra.CONTROLLLERS";
private AlarmResponseHandler handler;
public AlarmPollingService() {
super("AlarmPollingService");
}
/**
* Starts this service to perform action Foo with the given parameters. If
* the service is already performing a task this action will be queued.
*
* @see IntentService
*/
public static void startActionPing(Context context, String controllers) {
Intent intent = new Intent(context, AlarmPollingService.class);
intent.setAction(ACTION_PING);
intent.putExtra(CONTROLLERS, controllers);
context.startService(intent);
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_PING.equals(action)) {
final String controllers = intent.getStringExtra(CONTROLLERS);
handleActionPing(controllers);
}
}
}
/**
* Handle action Foo in the provided background thread with the provided
* parameters.
*/
private void handleActionPing(String controllers) {
PowerManager powerManager = (PowerManager) this.getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"AlarmPingerWakeLock");
wakeLock.acquire();
ZoblakClient zc = new ZoblakClient(controllers);
handler = new AlarmResponseHandler(this,zc.PingServer());
handler.handle();
wakeLock.release();
}
}

View File

@@ -0,0 +1,31 @@
package com.zoblak.farm;
import android.content.Context;
/**
* Created by senadu on 11/15/16.
*/
public class AlarmResponseHandler {
AlarmPingResponse response;
Context context;
public AlarmResponseHandler(Context context, AlarmPingResponse response) {
this.response = response;
this.context = context;
}
public void handle() {
if (response.getAlarmTriggered()) {
AlarmNotification.notify(context, response.toNotificationMessage(), 1);
SoundPlayingService.startPlayingAlarm(context);
}
}
}

View File

@@ -0,0 +1,109 @@
package com.zoblak.farm;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
* to be used with AppCompat.
*/
public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
private AppCompatDelegate mDelegate;
@Override
protected void onCreate(Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getDelegate().onPostCreate(savedInstanceState);
}
public ActionBar getSupportActionBar() {
return getDelegate().getSupportActionBar();
}
public void setSupportActionBar(@Nullable Toolbar toolbar) {
getDelegate().setSupportActionBar(toolbar);
}
@Override
public MenuInflater getMenuInflater() {
return getDelegate().getMenuInflater();
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
@Override
public void setContentView(View view) {
getDelegate().setContentView(view);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().setContentView(view, params);
}
@Override
public void addContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().addContentView(view, params);
}
@Override
protected void onPostResume() {
super.onPostResume();
getDelegate().onPostResume();
}
@Override
protected void onTitleChanged(CharSequence title, int color) {
super.onTitleChanged(title, color);
getDelegate().setTitle(title);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getDelegate().onConfigurationChanged(newConfig);
}
@Override
protected void onStop() {
super.onStop();
getDelegate().onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
getDelegate().onDestroy();
}
public void invalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu();
}
private AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, null);
}
return mDelegate;
}
}

View File

@@ -0,0 +1,15 @@
package com.zoblak.farm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BootBroadcastReceiver extends BroadcastReceiver {
public BootBroadcastReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
MainScreen.setupAlarmManager(context);
}
}

View File

@@ -0,0 +1,83 @@
package com.zoblak.farm;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import java.lang.System;
public class MainScreen extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setupAlarmManager(this);
}
public static void setupAlarmManager(Context context) {
AlarmManager alarmMgr;
PendingIntent alarmIntent;
Intent intent = new Intent(context, PeriodicalPingReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
int PERIOD_IN_MS = 2 * 60 * 1000; // 2 minutes
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
// Hopefully your alarm will have a lower frequency than this!
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(),
PERIOD_IN_MS, alarmIntent);
}
@Override
protected void onResume() {
super.onResume();
SoundPlayingService.stopPlayingAlarm(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main_screen, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -0,0 +1,39 @@
package com.zoblak.farm;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
/**
* A placeholder fragment containing a simple view.
*/
public class MainScreenFragment extends Fragment {
public MainScreenFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main_screen, container, false);
WebView webView = (WebView)view.findViewById(R.id.main_web_view);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.getContext());
String controllers = prefs.getString("controllers", "");
webView.loadUrl("http://agrar.zoblak.com/alarm?controller_id=" + controllers);
return view;
}
}

View File

@@ -0,0 +1,24 @@
package com.zoblak.farm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class PeriodicalPingReceiver extends BroadcastReceiver {
public PeriodicalPingReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String controllers = prefs.getString("controllers", null);
Boolean isAlarmOn = prefs.getBoolean("alarm_set", false);
if(isAlarmOn && controllers != null) {
AlarmPollingService.startActionPing(context, controllers);
}
}
}

View File

@@ -0,0 +1,207 @@
package com.zoblak.farm;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.support.v7.app.ActionBar;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.RingtonePreference;
import android.text.TextUtils;
import android.view.MenuItem;
import android.support.v4.app.NavUtils;
import java.util.List;
/**
* A {@link PreferenceActivity} that presents a set of application settings. On
* handset devices, settings are presented as a single list. On tablets,
* settings are split by category, with category headers shown to the left of
* the list of settings.
* <p>
* See <a href="http://developer.android.com/design/patterns/settings.html">
* Android Design: Settings</a> for design guidelines and the <a
* href="http://developer.android.com/guide/topics/ui/settings.html">Settings
* API Guide</a> for more information on developing a Settings UI.
*/
public class SettingsActivity extends AppCompatPreferenceActivity {
/**
* A preference value change listener that updates the preference's summary
* to reflect its new value.
*/
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
String stringValue = value.toString();
if (preference instanceof ListPreference) {
// For list preferences, look up the correct display value in
// the preference's 'entries' list.
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(stringValue);
// Set the summary to reflect the new value.
preference.setSummary(
index >= 0
? listPreference.getEntries()[index]
: null);
} else if (preference instanceof RingtonePreference) {
// For ringtone preferences, look up the correct display value
// using RingtoneManager.
if (TextUtils.isEmpty(stringValue)) {
// Empty values correspond to 'silent' (no ringtone).
//preference.setSummary(R.string.pref_ringtone_silent);
} else {
Ringtone ringtone = RingtoneManager.getRingtone(
preference.getContext(), Uri.parse(stringValue));
if (ringtone == null) {
// Clear the summary if there was a lookup error.
preference.setSummary(null);
} else {
// Set the summary to reflect the new ringtone display
// name.
String name = ringtone.getTitle(preference.getContext());
preference.setSummary(name);
}
}
} else {
// For all other preferences, set the summary to the value's
// simple string representation.
preference.setSummary(stringValue);
}
return true;
}
};
/**
* Helper method to determine if the device has an extra-large screen. For
* example, 10" tablets are extra-large.
*/
private static boolean isXLargeTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
}
/**
* Binds a preference's summary to its value. More specifically, when the
* preference's value is changed, its summary (line of text below the
* preference title) is updated to reflect the value. The summary is also
* immediately updated upon calling this method. The exact display format is
* dependent on the type of preference.
*
* @see #sBindPreferenceSummaryToValueListener
*/
private static void bindPreferenceSummaryToValue(Preference preference) {
// Set the listener to watch for value changes.
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
// Trigger the listener immediately with the preference's
// current value.
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.getContext())
.getString(preference.getKey(), ""));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupActionBar();
}
/**
* Set up the {@link android.app.ActionBar}, if the API is available.
*/
private void setupActionBar() {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
// Show the Up button in the action bar.
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
if (!super.onMenuItemSelected(featureId, item)) {
NavUtils.navigateUpFromSameTask(this);
}
return true;
}
return super.onMenuItemSelected(featureId, item);
}
/**
* {@inheritDoc}
*/
@Override
public boolean onIsMultiPane() {
return isXLargeTablet(this);
}
/**
* {@inheritDoc}
*/
@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.pref_headers, target);
}
/**
* This method stops fragment injection in malicious applications.
* Make sure to deny any unknown fragments here.
*/
protected boolean isValidFragment(String fragmentName) {
return PreferenceFragment.class.getName().equals(fragmentName)
|| GeneralPreferenceFragment.class.getName().equals(fragmentName);
}
/**
* This fragment shows general preferences only. It is used when the
* activity is showing a two-pane settings UI.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class GeneralPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_general);
setHasOptionsMenu(true);
// Bind the summaries of EditText/List/Dialog/Ringtone preferences
// to their values. When their values change, their summaries are
// updated to reflect the new value, per the Android Design
// guidelines.
bindPreferenceSummaryToValue(findPreference("controllers"));
bindPreferenceSummaryToValue(findPreference("period_minutes"));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
startActivity(new Intent(getActivity(), SettingsActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
}

View File

@@ -0,0 +1,73 @@
package com.zoblak.farm;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.IBinder;
/**
* Created by senadu on 11/18/16.
*/
public class SoundPlayingService extends Service
{
private Ringtone ringtone;
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
startTheAlarm();
return START_NOT_STICKY;
}
@Override
public void onDestroy()
{
stopTheAlarm();
}
public static void startPlayingAlarm(Context context) {
Intent startIntent = new Intent(context, SoundPlayingService.class);
context.startService(startIntent);
}
public static void stopPlayingAlarm(Context context) {
Intent startIntent = new Intent(context, SoundPlayingService.class);
context.stopService(startIntent);
}
@SuppressWarnings("deprecation")
private void startTheAlarm() {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
ringtone = RingtoneManager.getRingtone(this, notification);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AudioAttributes attributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
ringtone.setAudioAttributes(attributes);
} else {
ringtone.setStreamType(AudioManager.STREAM_ALARM);
}
ringtone.play();
}
public void stopTheAlarm() {
if(ringtone != null && ringtone.isPlaying()) {
ringtone.stop();
}
}
}

View File

@@ -0,0 +1,131 @@
package com.zoblak.farm;
import android.util.JsonReader;
import android.util.JsonToken;
import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Created by senadu on 11/14/16.
*/
public class ZoblakClient {
private String controllers;
public ZoblakClient(String controllers) {
this.controllers = controllers;
}
public AlarmPingResponse PingServer() {
HttpURLConnection urlConnection = null;
AlarmPingResponse result = new AlarmPingResponse(controllers);
URL url = null;
try {
url = new URL("http://agrar.zoblak.com/api/v1.0/alarm/" + controllers + "/phonePing");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000);
urlConnection.setConnectTimeout(15000);
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write("{}");
writer.flush();
writer.close();
os.close();
urlConnection.connect();
InputStream in = urlConnection.getInputStream();
String jsonString = convertStreamToString(in);
Log.e("JsonString", jsonString);
JsonReader jr = new JsonReader(new StringReader(jsonString));
result = readResponse(jr);
} catch (MalformedURLException e) {
Log.e("zoblakClient", "malformed: " + e.getLocalizedMessage());
} catch (IOException e) {
Log.e("zoblakClient", "ioexception: " + e.getLocalizedMessage());
result.setAlarmTriggered(false);
result.setServerError(false);
}
if (urlConnection != null) urlConnection.disconnect();
return result; // if no response then
}
private AlarmPingResponse readResponse(JsonReader reader) {
AlarmPingResponse result = new AlarmPingResponse(controllers);
try {
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("alarmTriggered") && reader.peek() != JsonToken.NULL) {
result.setAlarmTriggered(reader.nextBoolean());
} else if (name.equals("tooHot") && reader.peek() != JsonToken.NULL) {
result.setTooHot(reader.nextBoolean());
} else if (name.equals("tooCold") && reader.peek() != JsonToken.NULL) {
result.setTooCold(reader.nextBoolean());
} else if (name.equals("boxSilent") && reader.peek() != JsonToken.NULL) {
result.setBoxSilent(reader.nextBoolean());
} else {
reader.skipValue();
}
}
} catch (IOException e) {
Log.e("zoblakClient", "reading result: " + e.getLocalizedMessage());
}
return result;
}
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm1,15h-2v-6h2v6zm0,-8h-2V7h2v2z" />
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M11.5,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2zm6.5,-6v-5.5c0,-3.07 -2.13,-5.64 -5,-6.32V3.5c0,-0.83 -0.67,-1.5 -1.5,-1.5S10,2.67 10,3.5v0.68c-2.87,0.68 -5,3.25 -5,6.32V16l-2,2v1h17v-1l-2,-2z" />
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01,-.25 1.97,-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0,-4.42,-3.58,-8,-8,-8zm0 14c-3.31 0,-6,-2.69,-6,-6 0,-1.01.25,-1.97.7,-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4,-4,-4,-4v3z" />
</vector>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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"
android:fitsSystemWindows="true"
tools:context="com.zoblak.farm.MainScreen">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main_screen" />
</android.support.design.widget.CoordinatorLayout>

View File

@@ -0,0 +1,9 @@
<fragment 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/fragment"
android:name="com.zoblak.farm.MainScreenFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:layout="@layout/fragment_main_screen" />

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_main_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.zoblak.farm.MainScreenFragment"
tools:showIn="@layout/activity_main_screen">
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main_web_view"
></WebView>
</RelativeLayout>

View File

@@ -0,0 +1,10 @@
<menu 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"
tools:context="com.zoblak.farm.MainScreen">
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,9 @@
<resources>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>

View File

@@ -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>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>

View File

@@ -0,0 +1,6 @@
<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="fab_margin">16dp</dimen>
</resources>

View File

@@ -0,0 +1,39 @@
<resources>
<string name="app_name">Farm Alarm</string>
<string name="action_settings">Podešavanje</string>
<string name="title_activity_settings">Podešavanje</string>
<!-- Strings related to Settings -->
<!-- Example General settings -->
<string name="pref_header_general">Generalno</string>
<string name="pref_title_add_friends_to_messages">Add friends to messages</string>
<string-array name="pref_example_list_titles">
<item>Always</item>
<item>When possible</item>
<item>Never</item>
</string-array>
<string-array name="pref_example_list_values">
<item>1</item>
<item>0</item>
<item>-1</item>
</string-array>
<string name="alarm_notification_title_template">Alarm: %1$s</string>
<!-- TODO: remove this placeholder text -->
<string name="alarm_notification_placeholder_text_template">You said %1$s and lorem ipsum dolor
sit amet, consectetur adipiscing elit. Etiam non enim magna. Morbi dictum, velit vel semper
venenatis, magna odio volutpat velit, at ullamcorper nulla lacus sed turpis. Pellentesque
vitae metus elit, nec tincidunt tellus. Integer sed nisl sem, ullamcorper ornare lacus. Duis
ac mauris sed massa congue volutpat. Donec sed erat sit amet turpis viverra rhoncus sit amet
nec magna. Donec lacinia ligula at libero volutpat volutpat nec nec tortor.
</string>
<string name="action_share">Share</string>
<string name="action_reply">Reply</string>
</resources>

View File

@@ -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>

View File

@@ -0,0 +1,28 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- NOTE: EditTextPreference accepts EditText attributes. -->
<!-- NOTE: EditTextPreference's summary should be set to its value by the activity code. -->
<SwitchPreference
android:defaultValue="false"
android:title="Uključiti alram"
android:key="alarm_set" />
<EditTextPreference
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="Kontroler"
android:key="controllers"
android:summary="Broj koji jedinstveno određuje vašu Zoblak kutiju" />
<EditTextPreference
android:defaultValue="7"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="Period provjere"
android:key="period_minutes"
android:summary="Koliko često telefon provjerava da li je alarm uključen (u minutama)" />
<!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to
dismiss it. -->
<!-- NOTE: ListPreference's summary should be set to its value by the activity code. -->
</PreferenceScreen>

View File

@@ -0,0 +1,10 @@
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<!-- These settings headers are only used on tablets. -->
<header
android:fragment="com.zoblak.farm.SettingsActivity$GeneralPreferenceFragment"
android:icon="@drawable/ic_info_black_24dp"
android:title="@string/pref_header_general" />
</preference-headers>

View File

@@ -0,0 +1,17 @@
package com.zoblak.farm;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}

View File

@@ -0,0 +1,29 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@@ -0,0 +1,17 @@
# 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

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Sat Oct 15 06:26:29 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

160
android/FarmAlarm/gradlew vendored Executable file
View File

@@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# 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
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# 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
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" ] ; 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
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
android/FarmAlarm/gradlew.bat vendored Normal file
View File

@@ -0,0 +1,90 @@
@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
@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=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@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 Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_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=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
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

View File

@@ -0,0 +1 @@
include ':app'

View File

@@ -10,3 +10,4 @@ notices-for-facebook-graph-api-2
1.2.0-meteor-platform-split
1.2.0-cordova-changes
1.2.0-breaking-changes
1.3.0-split-minifiers-package

View File

@@ -12,7 +12,6 @@ session # Client-side reactive dictionary for your app
jquery # Helpful client-side library
tracker # Meteor's client-side reactive programming library
standard-minifiers # JS/CSS minifiers run for production mode
es5-shim # ECMAScript 5 compatibility for older browsers.
ecmascript # Enable ECMAScript2015+ syntax in app code
@@ -24,3 +23,10 @@ selaias:meteor-simpleweather
u2622:persistent-session
percolate:synced-cron
rzymek:moment-locale-bs
peppelg:bootstrap-3-modal
fortawesome:fontawesome
mfpierre:chartist-js
standard-minifier-css
standard-minifier-js
iron:router
accolver:twilio-meteor

View File

@@ -1 +1 @@
METEOR@1.2.1
METEOR@1.3.1

View File

@@ -1,88 +1,104 @@
accounts-base@1.2.2
accounts-password@1.1.4
accolver:twilio-meteor@1.10.1
accounts-base@1.2.5
accounts-password@1.1.7
allow-deny@1.0.3
amplify@1.0.0
autoupdate@1.2.4
babel-compiler@5.8.24_1
babel-runtime@0.1.4
base64@1.0.4
binary-heap@1.0.4
blaze@2.1.3
blaze-html-templates@1.0.1
blaze-tools@1.0.4
boilerplate-generator@1.0.4
caching-compiler@1.0.0
caching-html-compiler@1.0.2
callback-hook@1.0.4
check@1.1.0
coffeescript@1.0.11
ddp@1.2.2
ddp-client@1.2.1
ddp-common@1.2.2
ddp-rate-limiter@1.0.0
ddp-server@1.2.2
deps@1.0.9
diff-sequence@1.0.1
ecmascript@0.1.6
ecmascript-runtime@0.2.6
ejson@1.0.7
email@1.0.8
es5-shim@4.1.14
fastclick@1.0.7
geojson-utils@1.0.4
handlebars@1.0.4
hot-code-push@1.0.0
html-tools@1.0.5
htmljs@1.0.5
http@1.1.1
huttonr:bootstrap3@3.3.6_6
huttonr:bootstrap3-assets@3.3.6_2
id-map@1.0.4
jquery@1.11.4
json@1.0.3
launch-screen@1.0.4
less@2.5.1
livedata@1.0.15
localstorage@1.0.5
logging@1.0.8
meteor@1.1.10
meteor-base@1.0.1
minifiers@1.1.7
minimongo@1.0.10
mobile-experience@1.0.1
mobile-status-bar@1.0.6
momentjs:moment@2.11.2
mongo@1.1.3
mongo-id@1.0.1
nimble:restivus@0.8.7
autoupdate@1.2.7
babel-compiler@6.6.1
babel-runtime@0.1.7
base64@1.0.7
binary-heap@1.0.7
blaze@2.1.6
blaze-html-templates@1.0.3
blaze-tools@1.0.7
boilerplate-generator@1.0.7
caching-compiler@1.0.3
caching-html-compiler@1.0.5
callback-hook@1.0.7
check@1.1.3
coffeescript@1.0.16
ddp@1.2.4
ddp-client@1.2.4
ddp-common@1.2.4
ddp-rate-limiter@1.0.3
ddp-server@1.2.5
deps@1.0.11
diff-sequence@1.0.4
ecmascript@0.4.2
ecmascript-runtime@0.2.9
ejson@1.0.10
email@1.0.11
es5-shim@4.5.9
fastclick@1.0.10
fortawesome:fontawesome@4.5.0
fourseven:scss@3.4.1
geojson-utils@1.0.7
hot-code-push@1.0.3
html-tools@1.0.8
htmljs@1.0.8
http@1.1.4
huttonr:bootstrap3@3.3.6_10
huttonr:bootstrap3-assets@3.3.6_3
id-map@1.0.6
iron:controller@1.0.12
iron:core@1.0.11
iron:dynamic-template@1.0.12
iron:layout@1.0.12
iron:location@1.0.11
iron:middleware-stack@1.1.0
iron:router@1.0.13
iron:url@1.0.11
jquery@1.11.7
launch-screen@1.0.10
less@2.5.7
livedata@1.0.17
localstorage@1.0.8
logging@1.0.11
meteor@1.1.13
meteor-base@1.0.3
mfpierre:chartist-js@1.6.1
minifier-css@1.1.10
minifier-js@1.1.10
minimongo@1.0.13
mobile-experience@1.0.3
mobile-status-bar@1.0.11
modules@0.5.2
modules-runtime@0.6.2
momentjs:moment@2.12.0
mongo@1.1.6
mongo-id@1.0.3
nimble:restivus@0.8.10
npm-bcrypt@0.7.8_2
npm-mongo@1.4.39_1
observe-sequence@1.0.7
ordered-dict@1.0.4
percolate:synced-cron@1.3.0
promise@0.5.1
random@1.0.5
rate-limit@1.0.0
reactive-dict@1.1.3
reactive-var@1.0.6
reload@1.1.4
retry@1.0.4
routepolicy@1.0.6
npm-mongo@1.4.42
observe-sequence@1.0.10
ordered-dict@1.0.6
peppelg:bootstrap-3-modal@1.0.4
percolate:synced-cron@1.3.2
promise@0.6.6
random@1.0.8
rate-limit@1.0.3
reactive-dict@1.1.6
reactive-var@1.0.8
reload@1.1.7
retry@1.0.6
routepolicy@1.0.9
rzymek:moment-locale-bs@2.9.0
selaias:meteor-simpleweather@0.6.8
service-configuration@1.0.5
session@1.1.1
sha@1.0.4
simple:json-routes@2.0.1
spacebars@1.0.7
spacebars-compiler@1.0.7
srp@1.0.4
standard-minifiers@1.0.2
templating@1.1.5
templating-tools@1.0.0
tracker@1.0.9
selaias:meteor-simpleweather@0.7.0
service-configuration@1.0.8
session@1.1.4
sha@1.0.6
simple:json-routes@2.1.0
spacebars@1.0.10
spacebars-compiler@1.0.10
srp@1.0.7
standard-minifier-css@1.0.5
standard-minifier-js@1.0.5
templating@1.1.8
templating-tools@1.0.3
tracker@1.0.12
u2622:persistent-session@0.4.4
ui@1.0.8
underscore@1.0.4
url@1.0.5
webapp@1.2.3
webapp-hashing@1.0.5
ui@1.0.10
underscore@1.0.7
url@1.0.8
webapp@1.2.7
webapp-hashing@1.0.8

20
app/client/alarm.html Normal file
View File

@@ -0,0 +1,20 @@
<template name="alarm">
<div class="hello">
<div class="jumbotron text-center center-block" >
{{#with state}}
{{#if alarmTriggered}}
<strong class="bg-danger">{{ pretty_reasons alarmReasons }}</strong>
<img src="/images/alarm.gif" class="img-responsive center-block" id="alarm_image" />
<button id="stop_alarm" class="btn btn-danger"> <i class="fa fa-ban"></i> Prekini </button>
{{/if}}
{{/with}}
{{#with last_reading}}
<div class="huge_text"> {{ all_temperatures }}</div>
<div>{{pretty_time created_at}}</div>
{{/with}}
<button id="run_alarm_settings" class="btn btn-default"> <i class="fa fa-wrench"></i> Podešavanje </button>
</div>
</div>
</template>

73
app/client/alarm.js Normal file
View File

@@ -0,0 +1,73 @@
function sensor_data_collection() {
var controllerId = Session.get('controller_id');
return SensorData.find({
controllerId: controllerId
}, {
sort: {
created_at: -1
},
limit: 3
});
}
function last_sensor_reading() {
var controller = Session.get('controller_id');
var result = null;
if (controller) {
result = sensor_data_collection();
}
if (result && result.count() > 0) {
return result.fetch()[0];
} else {
return {}
}
}
Template.alarm.helpers({
last_reading: last_sensor_reading,
state: function() {
return Meteor.zoblak.client.controller_state().state;
},
pretty_time: function(time) {
return moment(time).format("DD.MM.YYYY, HH:mm")
},
all_temperatures: function() {
var result = "";
var temperatures = last_sensor_reading().temperatures;
for (var i in temperatures) {
result += '' + parseFloat(temperatures[i]).toFixed(1) + ' °C ';
}
return result;
},
pretty_reasons: function(reasons) {
var results = "";
if(reasons.tooHot) {
results += "Temperatura previsoka!";
}
if(reasons.tooCold) {
results += "Temperatura preniska!";
}
if(reasons.phoneSilent) {
results += "Mobitel nedostupan! Provjerite internet!";
}
if(reasons.boxSilent) {
results += "Zoblak kutija se ne javlja! Provjerite internet!";
}
return results;
}
});
Template.alarm.events({
'click #run_alarm_settings': function() {
Modal.show('alarm_settings');
},
'click #stop_alarm': function() {
let controller_id = Meteor.zoblak.client.controller_state().controller_id;
Meteor.call('stopTheAlarm', controller_id);
}
});
Template.alarm.helpers({
});

Some files were not shown because too many files have changed in this diff Show More